Skip to content

feat(G4): the session remembers what it was told - #67

Merged
pmanko merged 6 commits into
mainfrom
feat/g4-session-guidance
Aug 24, 2026
Merged

feat(G4): the session remembers what it was told#67
pmanko merged 6 commits into
mainfrom
feat/g4-session-guidance

Conversation

@pmanko

@pmanko pmanko commented Aug 24, 2026

Copy link
Copy Markdown
Member

Delivery gate G4 — layered context, stacked on G3b (#66). Companion Hub prompt: pmanko/med-agent-hub#21.

What a session now carries

An instruction that mattered on turn two mattered on turn five, and the only thing accumulating in a session was the list of instructions — text the prompt explicitly ranks below the current one, so a correction had to be repeated to survive. Three bounded layers now ride on every revision request:

Layer Rule
Guidance ≤20 active entries, delivered verbatim in pin order
Verified examples ≤3 kept versions from this session, same source and catalog, ranked by word overlap then newest turn then stable id
Relevant failure the one prior failure, and only while it is still the last thing that happened

Decisions worth reviewing

  • Verbatim, always. The gateway does not tidy what a person wrote — the wording is the instruction. Mutation-tested: adding a .strip() turns a test red.
  • Append-only. Unpinning or replacing appends a lifecycle event and leaves the text; a turn's evidence keeps meaning what it meant when it ran. Past the cap the oldest stop being delivered and nothing is forgotten.
  • Precedence is stated, not implied. Position reads as authority to a model, so guidance says it outranks the retained history but not the current instruction, and that a later entry wins a conflict. Examples and failures are labelled evidence, not commands.
  • Empty layers are absent, not empty objects a model pays tokens to read past.
  • Negotiated. Catalyst deploys ahead of the Hub, so a Hub that has not advertised catalyst.query.session-context.v1 is not sent the layer. Handing it over to be silently ignored is worse than withholding it — the guidance would look delivered and change nothing.
  • Counted before sending. Overflow is a refusal, not a truncation that would drop the pinned guidance while the turn still looked like it honoured it. A profile naming no exact tokenizer cannot be counted; a character-count substitute under-counts exactly this dense JSON.

Evidence

  • 328 passed, 3 skipped (gateway) · 692 passed (hub, in the companion PR).
  • 30 new tests. Every guard mutation-tested: normalising the text, dropping omissions, exceeding three examples, feeding a turn its own answer, ignoring overlap ranking, delivering empty layers, uncapped delivery, deleting instead of appending, sharing guidance across sessions, excluding the output reserve, and tolerating a missing tokenizer — each turns a test red.
  • Kept on purpose: the current turn is excluded from its own examples at the call site even though it cannot appear in prior turns yet; that mutant survives at the service level and the rule is covered where it is decided.

sessionContext is optional in the revision contract and writerOutcome optional on the turn, so readers written before Phase 1 keep working.

@pmanko
pmanko changed the base branch from feat/g3-writer-outcomes to main August 24, 2026 08:34
pmanko added 6 commits August 24, 2026 01:34
An instruction that mattered on turn two mattered on turn five, and the
only thing accumulating in a session was the list of instructions --
text the prompt explicitly ranks below the current one, so a correction
had to be repeated to survive.

Guidance entries are durable, ordered, and delivered verbatim: the
gateway does not tidy what a person wrote, because the wording is the
instruction. They are append-only -- unpinning or replacing appends a
lifecycle event and leaves the text where it is, so a turn's evidence
keeps meaning what it meant when it ran.

Twenty entries are delivered. Past that the oldest stop being delivered
and nothing is forgotten; the omission is recorded where the request is
assembled. Entries never cross sessions.
A person pins an instruction from the composer, or accepts one from a
failed turn's finding; the session then carries its active guidance
wherever it is read, so a reload shows what the writer will be told.

Unpinning stops delivery and keeps the record. Blank text is refused at
the edge rather than stored and ignored.
Three bounded layers ride on a generation request: what a person pinned,
what already worked in this session, and the one failure this attempt
should not repeat.

Their order is fixed because position reads as authority to a model, and
their precedence is stated rather than implied -- guidance says it
outranks the retained history but not the current instruction, and that
a later entry wins a conflict; examples and failures say they are
evidence, not commands.

Nothing is summarised. Guidance travels exactly as written, because the
wording is the instruction. Anything a cap excludes is recorded as an
omission with its reason. An empty layer is left out rather than
delivered as an empty object nobody can learn from.

Examples are ranked by word overlap with the request, then newest turn,
then stable id, so the same session always selects the same three -- and
a turn never receives its own answer.
Guidance, verified examples, and the one prior failure now reach the
writer. A composer pin takes effect on the next turn, which is what a
person expects from pinning something rather than editing the turn they
already sent.

Verified examples come from kept versions -- a turn selected it and it
survived -- against the same source and catalog. The prior failure is
carried only while it is still the last thing that happened; once a turn
succeeds it is history, not the mistake to avoid.

sessionContext is optional in the revision contract, so a request built
before Phase 1 stays valid.

Kept on purpose: the current turn is excluded from its own examples at
the call site even though it cannot appear in prior turns yet, and an
incomplete turn has no selected version to offer. The rule is covered
where it is decided, in select_verified_examples.
Catalyst deploys ahead of the Hub, so a Hub that has not advertised the
session-context contract is not sent one. Handing over a layer it may
silently ignore is worse than withholding it: the guidance would look
delivered and change nothing.

The in-process engine reads the Phase 1 shape, so local discovery
advertises it and the layer flows today.
A profile declares its window, its output reserve, and the exact
tokenizer; the fully rendered messages are counted against them before
the model is called, so an overflow is a refusal rather than a silent
truncation. Truncation is the failure that matters here: it would drop
the guidance a person pinned and leave the turn looking like it had been
honoured.

A profile naming no exact tokenizer cannot be counted at all. A
character-count substitute is wrong in the direction that hurts -- it
under-counts the dense, punctuation-heavy JSON this context is made of.

Every omission travels with its reason, so the evidence says what was
left out and why.
@pmanko
pmanko force-pushed the feat/g4-session-guidance branch from 11d4ec4 to f5ba4ab Compare August 24, 2026 08:35
@pmanko
pmanko merged commit 6b3a893 into main Aug 24, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant