docs(hooks): document ephemeral semantics on stateful providers - #105
Merged
Brian Krabach (bkrabach) merged 1 commit intoAug 28, 2026
Merged
Conversation
The ephemeral flag on HookResult/context_injection is enforced client-side only -- it controls whether Amplifier's local context module persists the injection, not what a stateful provider does with the message once it is sent. Hook authors currently have no documentation of the gap. Adds a concise 'Ephemeral Semantics on Stateful Providers' section to docs/HOOKS_API.md covering: - user/assistant-role injections ride the delta once, then persist server-side for the rest of the chain (no retraction API); repeated injections accumulate, bounded in practice by prompt caching + compaction chain resets - system-role injections ARE retractable on these providers (per-request instructions typically replace the chain root's) - never omit the system/instructions field on a chained request -- omission can clear it entirely rather than falling back - content already echoed into a visible assistant reply is permanent conversation history regardless of later retraction - stateless full-rebuild providers are unaffected; there, ephemeral additionally serves as a cache-breakpoint placement hint Also adds a one-sentence pointer from the ephemeral field's docstring (python/amplifier_core/models.py) to the new doc section. Docs and docstrings only -- zero behavior changes. Findings live-probed against a stateful, previous_response_id- chaining Responses-API provider on 2026-08-28 (probe script + results available on request). 🤖 Generated with [Amplifier](https://github.com/microsoft/amplifier) Co-Authored-By: Amplifier <240397093+microsoft-amplifier@users.noreply.github.com>
Collaborator
Author
|
Admin merge notice: this PR is self-authored (docs/docstrings only, zero |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The
ephemeralflag onHookResult/context injection (docs/HOOKS_API.md,python/amplifier_core/models.py) is enforced client-side only — itcontrols whether Amplifier's local context module persists the injection,
not what a given provider does with the message once it's sent. On
providers that chain conversation state server-side (rather than
re-sending the full transcript every turn), the real semantics diverge
from what "not stored in conversation history" implies, and hook authors
currently have no documentation of the gap.
This is a docs/docstrings-only PR — zero behavior changes.
What's added
A new "Ephemeral Semantics on Stateful Providers" section in
docs/HOOKS_API.md(worded provider-agnostically), covering:user/assistant-role injections ride the delta once, then persistin the provider's server-held state for the rest of the chain — no
retraction API. Repeated injections accumulate; bounded in practice
because accumulated history rides the provider's own prompt caching once
past its auto-cache token floor, and a context-compaction event (which
resets the chain) flushes it.
system-role injections are different and generally areretractable — providers in this category typically re-derive the
per-request system/instructions field from the current turn rather than
the chain root, so withdrawing it makes it disappear. This is the
mechanism mode enter/exit relies on.
has been sent — omission can clear the provider's system prompt
entirely rather than falling back to an earlier value.
permanent conversation history on these providers, regardless of later
retraction of the field that prompted it.
remote drop; there,
ephemeraladditionally serves only as acache-breakpoint placement hint.
Also adds a one-sentence pointer from the
ephemeralfield's docstring inpython/amplifier_core/models.pyto the new doc section, and aone-line "Provider caveat" cross-reference from the existing field bullet
in
docs/HOOKS_API.md.Why / evidence
Findings are live-probed, not theoretical. A standalone probe script (no
Amplifier imports) was run against a stateful,
previous_response_id-chaining Responses-API-style provider on 2026-08-28:
instructionsreplaced the chain root's (
U1_verdict: REPLACE) — confirmssystem-role retractability.
NONCE_BRAVO) injected on turn 1 was stillvisible to the model on turn 2 with no re-send (
U2_verdict: CONFIRMED)— confirms delta persistence with no retraction.
SECRET_CHARLIE)remained visible on turn 3 even after the field that introduced it was
no longer sent (
R3_lingering_verdict: LINGERS) — confirms echoedcontent becomes permanent history.
instructionsentirely on a chained request cleared themodel's view of the previously-set secret rather than falling back to
the chain root's value (
U5_verdict: CLEARED_ON_OMIT).chained turns: input token count grew monotonically, the model's own
count of visible marker copies matched the request count exactly
(
case4_verdict: COUNT_CONFIRMS_ACCUMULATION, model replied "4" for 4injections), and cached-token accounting showed the accumulated history
rides free once past the provider's auto-cache floor (turn 3 wrote a
1329-token cache entry; turn 4 read all 1329 back as cached tokens).
Probe script and raw results available on request (kept outside this repo
per house convention — not committed here to avoid depending on this
specific probe/task history from a public doc).
Testing
Docs and one docstring string only.
python -m py_compileon themodified module succeeds;
python_checkreports only pre-existingwarnings unrelated to this change (verified against the pre-change file).
No code paths, schemas, or defaults changed.
🤖 Generated with Amplifier