Skip to content

fix(prompt-cache): stabilize architect request prefixes - #2780

Draft
zaxbysauce wants to merge 11 commits into
mainfrom
codex/issue-2759-prompt-cache
Draft

zaxbysauce wants to merge 11 commits into
mainfrom
codex/issue-2759-prompt-cache

Conversation

@zaxbysauce

@zaxbysauce zaxbysauce commented Sep 14, 2026

Copy link
Copy Markdown
Collaborator

Closes #2759

Summary

  • Move all session-bound architect system-enhancer guidance, including the conditional /swarm command rule, out of the cache-sensitive system tail and into one trailing host-renderable user-role carrier.
  • Preserve stable conversation prefixes across turns while retaining strict Qwen/Gemma single-system rendering, unified injection-budget accounting, delayed realtime-nudge acknowledgement, and one-shot compaction suppression.
  • Add registered-host acceptance coverage plus strengthened adversarial, restored-session, prefixed-agent, memory, knowledge, accounting, and legacy-mode regressions.

Invariant audit

  • 1 (plugin init): touched - src/index.ts registration/composition changed without adding startup I/O or awaits; bun run build passed and node scripts/repro-704.mjs completed T1/T2/T3 in 40.6/37.1/26.7 ms against the 400 ms ceiling.
  • 2 (runtime portability): touched - the plugin entry composition changed using portable TypeScript only; build passed and node --input-type=module -e "await import('./dist/index.js')" succeeded.
  • 3 (subprocesses): not touched - no subprocess implementation changed.
  • 4 (.swarm containment): not touched - no runtime storage path or root-resolution behavior changed.
  • 5 (plan durability): not touched - no plan ledger, projection, checkpoint, or schema behavior changed.
  • 6 (test_runner safety): not touched - validation used shell/CI-equivalent per-file isolation, never a broad test_runner scope.
  • 7 (test writing): touched - all tests use bun:test, changed files pass the FR-006 ratchet, and check:mock-cleanup, check:test-tmpdir, and the 15-file CI-equivalent isolation run passed.
  • 8 (session state): touched - the request staging is a request-local WeakMap; the one-shot compaction marker is session-keyed, capped at 500, consumed on the next messages pass, and cleared on session deletion; compaction/restoration tests pass.
  • 9 (guardrails/retry): not touched - retry, circuit, authorization, and guardrail policy semantics are unchanged.
  • 10 (chat/system msg): touched - registered-host tests prove in-place mutation, zero message-surface system roles, stable prefix ordering, trailing renderable carriers, strict-model preservation, and final-accounting carrier exclusion.
  • 11 (tool registration): not touched - no tool metadata, manifest, barrel, or agent-map entry changed; the registration checker still reports 133 coherent tools.
  • 12 (release/cache): touched - added docs/releases/pending/issue-2759-prompt-cache-prefix.md; release-owned version files and cache behavior are unchanged.

Test plan

  • Frozen issue-tracer acceptance checks: C1-C3 RED on origin/main and GREEN on this commit; C4-C5 GREEN on both; frozen suite 7/7.
  • bun run test:unit:ci <15 affected files> - all 15 files passed individually (195 tests, 0 failures).
  • bun run typecheck, bun run lint:ci, bun run build, Node ESM import, and node scripts/repro-704.mjs.
  • Full quality-contract checks, including registration, invariants, mock cleanup, events/retention/citations, portability, temp paths, test cap, and bun run package:smoke.
  • bun run check:pre-push - enforced drift check and registry citations passed (two known non-blocking ruleset-divergence notices).
  • CI cycle 1 FR-011 repaired with the canonical canonicalMkdtemp helper and locally validated; refreshed MiniMax M3 high-effort implementation review and GLM 5.3 high-effort final critic both APPROVE on commit dd1953ed4a3a65aa3de75a918ca480208fabdcfe / tree f8bd5c8dc30dea854dc5aafc0bdd81437d0b3992.
  • Bounded repository validator completed 686 items before its exact 900-second whole-run deadline; the remaining 2,952 items were never started. Its patch-related stale harness failures were migrated and pass above; unrelated environment-limited results were one Windows temp cleanup EBUSY, sandbox-denied production-store probes, and an environment-specific swarm-model CLI-list exit.

@github-actions

Copy link
Copy Markdown
Contributor

Drift check report

Found 2 drift finding(s): 0 error, 0 warning, 2 notice.

required-check-contract (2)

  • 🔵 notice scripts/required-check-contract.json: [RULESET_DIVERGENCE] intended-required context "drift" is not yet required by the captured ruleset
  • 🔵 notice scripts/required-check-contract.json: [RULESET_DIVERGENCE] intended-required context "drift" is not present for every expected event in captured external workflow evidence

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

It reworks invariant-10 chat/system message hook composition and globally repositions guidance carriers to the message-array tail for all sessions, a high-blast-radius change in a historically fragile area that warrants final human review despite its thorough test coverage.

Pull request overview

This PR resolves issue #2759: the architect's ~100K-token stable request prefix was failing provider prompt caching because per-step guidance rewrote the cache-sensitive system[1] tail and directive carriers were unshifted ahead of history. The fix leverages OpenCode v1.18.3's actual hook order (messages.transform runs before system.transform) to move all session-bound architect guidance off the system surface and into one trailing, host-renderable user-role carrier, keeping the conversation prefix byte-stable across turns.

Changes:

  • Stages the architect system-enhancer + conditional /swarm command rule early in messages.transform (request-local WeakMap), delivers it late as a single fenced user-role carrier, then partitions all guidance carriers to the array tail before final accounting; the system.transform path returns early for that same request via the new shared isSessionBoundArchitect predicate so no second ledger is begun.
  • Adds a bounded, session-keyed one-shot compaction-suppression marker, a chat.message model-identity relay, envelope-token budget reservation (guidance-carrier-fence), and deferred realtime-learning-nudge commit tied to successful carrier delivery.
  • Teaches recency/agent scans in memory, knowledge, and final-accounting to skip trailing carriers; migrates system-surface tests to registered-host message-boundary assertions.
File summaries
File Description
src/index.ts Adds architect staging/delivery steps, compaction marker (bounded, session-cleaned), model-identity relay, and reorders the messages chain.
src/hooks/host-boundary.ts New isSessionBoundArchitect shared single-delivery-owner predicate.
src/hooks/system-guidance-carrier.ts Adds moveGuidanceCarriersToEnd (in-place tail partition) and guidanceCarrierEnvelopeTokens.
src/hooks/system-enhancer.ts Adds surface option, deferred nudge state, and envelope-token reservation.
src/context/role-filter.ts Accepts an explicit agent override for the messages-surface delivery.
src/hooks/final-context-accounting.ts, knowledge-injector.ts, memory/injector.ts Skip trailing guidance carriers when selecting the latest real user message.
src/services/injection-budget.ts Adds guidance-carrier-fence producer.
src/observability/catalog.ts Updates producer line citations (909/1937/1957) after index.ts growth.
scripts/retention-registry.data.ts Updates injector citation line numbers.
docs/engineering-invariants.md, docs/releases/pending/issue-2759-*.md Documents the #2759 invariant and ships the release fragment.
Test files (unit/integration/adversarial) Registered-host coverage for prefix stability, carrier partition, compaction bridge, cold-identity fallback, and migrated security assertions.
Review details
  • Files reviewed: 28/28 changed files
  • Comments generated: 0
  • Review effort level: Balanced

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@zaxbysauce

Copy link
Copy Markdown
Collaborator Author

🤖 Multi-Stage PR Review

Pipeline: MiniMax-M2.7-highspeed (orientation) (context pack) → MiniMax-M2.7-highspeed (explorer) + MiniMax-M2.7-highspeed (explorer B) (parallel explore, distinct lenses) → GLM-5-turbo (critique) ↔ GLM-5-turbo (critique) (cross-critique) → MiniMax-M2.7-highspeed (fallback arbiter) (arbiter: blind-spot + synthesize)
Commit reviewed: 7a7a234fb283


🔍 PR Intent

Reconstructed obligation list from PR description, issue #2759, and diff:

  • O-001 Move architect system-enhancer guidance out of the cache-sensitive system tail → trailing host-renderable user-role carrier
  • O-002 Preserve stable conversation prefix across architect turns (byte-identical history prefix)
  • O-003 Retain strict Qwen/Gemma single-system rendering boundary
  • O-004 Preserve injection-budget accounting (unified token ledger)
  • O-005 Compaction-aware one-shot suppression (live-turn guidance excluded from compaction summaries)
  • O-006 Registered-host acceptance coverage proving in-place mutation, zero message-surface system roles, stable prefix ordering
  • O-007 Advisory guidance is fail-open (enhancer failures must not block request composition)

📦 Implementation Summary

The PR implements a two-phase staging pipeline for architect guidance within messages.transform: an early stage runs the full system-enhancer against a request-local array and stores the result in a WeakMap<messages, staged>, while a late delivery stage runs role-filtering + command banner, wraps the result in a fenced user-role guidance carrier, moves all carriers to the message-array tail, then final accounting skips those carriers when finding the last real user message. The system hook skips architect enhancement entirely when surface === 'system'. A one-shot compaction marker suppresses the immediately following architect bridge turn. The test suite is migrated from direct hook invocation to registered-host messages.transform coverage.


✅ / ⚠️ / ❌ Intended vs Actual

Obligation Status Evidence
O-001 (carrier delivery) SUPPORTED src/index.ts:3191–3231 — staged system strings filtered, wrapped in carrier via appendGuidanceCarrier
O-002 (stable prefix) SUPPORTED tests/integration/prompt-cache-prefix-stability-2759.test.ts AC1 — consecutive requests keep history prefix byte-stable
O-003 (strict model boundary) SUPPORTED tests/integration/prompt-cache-prefix-stability-2759.test.ts AC4 — strict Qwen collapses to one entry, carrier trails in messages
O-004 (budget accounting) SUPPORTED src/hooks/system-enhancer.ts:1296 — reserved envelope tokens subtracted; fence overhead recorded as guidance-carrier-fence producer
O-005 (compaction suppression) SUPPORTED src/index.ts:3165_architectCompactionPending.delete(sessionID) consumed; _architectCompactionPending.set(sessionID, true) set on compaction; tests/unit/hooks/compaction-host-hook-2533.test.ts covers suppression + session-deletion cleanup
O-006 (registered-host coverage) SUPPORTED New prompt-cache-prefix-stability-2759.test.ts, updated full-auto.regression.test.ts, turbo.regression.test.ts, handoff-security-adversarial.test.ts
O-007 (fail-open advisory) SUPPORTED Both catch blocks are intentional fail-open; PR explicitly states this
O-008 (session state bounded) SUPPORTED _architectCompactionPending capped at 500 via capSessionMap; cleared on session deletion at src/index.ts:3655

🚨 Confirmed Findings

None. All three confirmed findings were challenged and refuted (see §6 below).


🔬 Unverified but Plausible Risks

None identified at structural-confidence threshold.


🧪 Test / Coverage Gaps

  • Gap: moveGuidanceCarriersToEnd — single partition test exists; no test for the in-place "array.length = 0 + loop push" idiom surviving through multiple consecutive transforms on the same array.
    • Evidence: tests/unit/hooks/system-guidance-carrier.test.ts tests the function in isolation; integration coverage through the chain is implicit.
    • Verdict: Low confidence this is a real gap — the function is pure and well-tested in isolation; the chain-level test AC1 (consecutive architect turns) exercises the full pipeline.

📋 Shipped-vs-Claimed Gaps

  • Gap: None — the PR's invariant audit (12 invariants) accurately reflects the changed surfaces.

🔁 Validation Provenance

Confirmed findings reviewed — all dropped:

  1. [HIGH] src/index.ts:3135 — enhancer catch drops deferred nudgesDROPPED. stagedArchitectGuidanceByMessages.set() is inside the try block before enhancer() runs; if enhancer throws, set never executes, so no stale entry exists. The PR explicitly designates the enhancer as advisory with fail-open semantics; missing guidance is not a defect.

  2. [HIGH] src/index.ts:3231 — delivery catch drops fence overheadDROPPED. This is intentional documented fail-open ("guidance is fail-open at this boundary"). deliveredGuidanceDelta gates the nudge commits and fence overhead recording; on failure the host receives the unmodified message array. This is not silent data loss — it is the stated contract.

  3. [LOW] src/index.ts:3349 — WeakMap concurrency riskDROPPED. Architect requests are sequential (single-threaded orchestrator). The delivery step immediately deletes after .get(), so even if the same messages array were somehow reused, the second call gets null and returns early. The request-local WeakMap pattern is correct for this use case.

Blind-spot pass — no new findings added. Scrutinized: WeakMap lifecycle (clean on GC), envelope token reservation (bounded, single call site), compaction marker cap (capSessionMap enforces 500), role-filter agent fallback (mirrors existing pattern), delivery step identity resolution (three-way fallback), moveGuidanceCarriersToEnd array mutation (preserves relative order), and isGuidanceCarrier skips in knowledge/memory injectors (correct — carriers must not be counted as user messages).


📝 Merge Recommendation

[APPROVE]

Check Result
No CRITICAL findings
No unresolved STEALTH_CHANGE
No UNSUPPORTED obligations
Test coverage adequate
No hardcoded secrets
All async errors handled ✅ (fail-open by design)
Input validation present
No broken agent role boundaries
Prompt format contracts intact
Lockfile consistent ✅ (scripts/retention-registry.data.ts line citation update only)

🔒 Reviewed by a 3-model cross-family adversarial debate (architect → dual-lens parallel explorers → cross-critique → arbiter) for high recall with low false-positive noise. Findings are advisory — verify before acting.

@zaxbysauce

Copy link
Copy Markdown
Collaborator Author

Swarm PR Review — PR #2780

Reviewed: 37ee0ce8be11aa105ef97a829ef6038a6a90df1c...7a7a234fb283be75bfc86b29f973ab8e97143c4c (Profile B, Claude Code, depth tier L — 2091+880 lines / 28 files)
Pipeline: 6/6 base dimensions + 11/11 risk families evaluated (5 matched → dispatched) → 4 independent reviewer chunks → 2 critic challenges on HIGH/MEDIUM-borderline findings → synthesis.

PR intent

Fixes #2759: the architect's ~100K-token system prefix should hit the provider's prompt cache every turn, but per-step content (directive carriers, budget/nudge guidance) was being unshifted ahead of history and rewriting system[1], defeating caching. Mechanism: move per-turn architect guidance out of the cache-sensitive system array and into a trailing, host-renderable role:'user' "guidance carrier" message, staged via a request-local WeakMap and delivered after the whole messages.transform chain runs.

Closes #2759 — claim-integrity: PARTIALLY MET

The core mechanism is sound and does fix the steady-state case (verified structurally and by a registered-host runtime probe: warm turns produce exactly one stable system entry with the guidance riding the trailing carrier). However, on an identity-cold turn — e.g. a fresh/restored session where the plugin's own chat.message hook hasn't yet run — the system-surface guard and the messages-surface guard resolve "is this the architect" through asymmetric identity ladders and both can fire, causing duplicate guidance delivery and variance returning to the system array on that turn (see F-001). That is a narrower recurrence of the exact regression #2759 exists to remove, not the full 100%-of-turns bug, but the issue is not fully closed as claimed.

Confirmed findings

F-001 — MEDIUM — Architect-identity resolution is asymmetric between the two transform surfaces, causing duplicate guidance delivery + ledger corruption on identity-cold turns
Files: src/hooks/system-enhancer.ts:1147-1168, src/hooks/host-boundary.ts:103-115,226-241, src/index.ts:3143-3269, src/services/injection-budget.ts:247-262
Status: CONFIRMED by independent reviewer, UPHELD by critic (capped from an initial HIGH candidate to MEDIUM)
Evidence type: EXECUTION_PROVEN — reproduced end-to-end against the real registered plugin host (src/index.ts server()): cold identity (no chat.message, info.agent:'architect' only) → output.system grows 1→6 entries with duplicated guidance blocks (3073/3177 bytes identical across both surfaces) and beginTurnLedger advances generation 1→2, discarding the first surface's producer records. The warm control path (real chat.message fired first) is clean.
Why it matters: messages.transform's identity resolution (resolveMessageTransformContext) has a fallback to the last user message's info.agent; system.transform's guard (isSessionBoundArchitect) does not — it only consults swarmState.activeAgent/agentSessions. The PR's diff removes a comment stating activeAgent is cold on a session's first turn and replaces it with the opposite claim, unbacked by any test or host-contract fixture — and the critic found in-repo evidence the new claim is wrong (docs/releases/v7.13.2.md:24, src/hooks/host-boundary.ts:34-35 both independently state turn-1 activeAgent is empty).
Severity capped at MEDIUM (not HIGH) because: duplicated content is byte-identical (redundant, not contradictory), impact is bounded to one turn per session and self-corrects from turn 2 onward, the PR is still net-better than the pre-fix every-turn variance, and the ledger-corruption pathway is gated behind a non-default budget-ceiling config and fails permissive.
Suggested fix: publish the messages-surface stage's already-resolved identity (stagedArchitectGuidanceByMessages/src/index.ts:3196-3200) request-scoped so the system-surface guard reads the same ladder, making both surfaces order-independent.
Falsification probe: drive the registered host twice for one architect session with info.agent:'architect' on the last user message — (a) fire chat.message first, (b) don't — assert output.system.length === 1 and exactly one guidance delivery in both cases.

F-002 — MEDIUM — No acceptance test exercises the identity-cold path that F-001 proves defective
Files: tests/integration/prompt-cache-prefix-stability-2759.test.ts:130-156,227-315
Status: CONFIRMED, UPHELD by critic
Every test in the PR's headline acceptance suite (AC1-AC6) pre-seeds swarmState.activeAgent before invoking the transform chain. This is the coverage gap that let F-001 ship undetected — same root cause as F-001, not an independent issue.
Suggested fix: add the F-001 falsification probe above as a permanent regression test.

F-003 — LOW — Silent error-swallowing on the new guidance delivery path lacks production-visible logging
Files: src/index.ts:3265 (catch #2 only — catch #1 at :3202 is defensive-only/unreachable, the enhancer it wraps is already safeHook-wrapped)
Status: CONFIRMED (narrowed), critic DOWNGRADED from an initial HIGH candidate to LOW
The bare catch {} around appendGuidanceCarrier+delivery genuinely preempts the codebase's normal safeHook warn-path, but warn() is itself debug-gated (OPENCODE_SWARM_DEBUG=1) and silent in production regardless — so this is not actually a regression in production detectability. The envelope-budget "phantom claim" concern raised by the explorer lane was disproven (the turn ledger is discarded every turn; no drift persists).
Suggested fix: bind the caught error and call criticalWarn (not warn, which is a production no-op) in the one reachable catch (src/index.ts:3265); add one throw-injection regression test on the delivery step.

F-004 — LOW — Coverage regression: "sessionless global-fallback" scenario dropped from hook-integration tests (but still covered at the state layer)
Files: src/commands/turbo.regression.test.ts:382, src/commands/full-auto.regression.test.ts:337
Status: CONFIRMED (merged from 3 independently-found duplicate candidates: TF-001/TI-001/TI-002)
Both regression files renamed a test from "banner shows if ANY session has turbo/full-auto with no sessionID" to "delivers the banner for an explicitly identified session," switching the invocation from no-sessionID to an explicit one. The underlying production branch (state.ts hasActiveTurboMode/hasActiveFullAuto) remains covered by direct unit tests (turbo.regression.test.ts:351, full-auto.regression.test.ts:283) and remains reachable in production (full-auto-intercept.ts:955 passes an optional sessionID) — so this is a narrow hook-integration coverage gap, not a behavior regression or dead code.
Suggested fix: add one registeredGuidanceMessages(undefined) case with a second session flagged, asserting the banner still appears.

Pre-existing / not introduced by this PR (informational, no action required)

  • ST-001 (LOW) — guidance now rides as role:'user' content rather than system; this delivery mechanism and its fence-forgery mitigation (neutralizeFenceMarkup) are inherited from [Workstream H] PR 01 of 15: Verify current host guidance delivery and close only the remaining delivery gaps #2526, not new here. Model-adherence strength is outside static-analysis reach.
  • ST-002 / UIB-002 (LOW, merged) — role-filter.ts's input.agent preference traces to host-stamped UserMessage.info.agent only; reviewer verified no plugin-authored carrier can be selected by that fallback (carriers carry no agent field). No hijack path found.
  • UIB-001 (LOW) — several messages.transform consumers rely on composeHandlers array ordering rather than an explicit isGuidanceCarrier guard; verified safe under current ordering, pre-existing fragility.
  • UR-003 (LOW) — stale doc comment at system-enhancer.ts:1114-1116 now inaccurately claims to be the "only" call site handed a Model (second site is src/index.ts:3160-3169); functionally safe (setLiveContextWindow guards against overwrite), doc-only.
  • RP-002 (info) — a second createSystemEnhancerHook instance is now constructed at init; verified its maintenance-scan dedup guards remain correct for the dual-instance pattern.
  • New, reviewer-found (not from any lane)src/commands/turbo.regression.test.ts:383-386 builds a second test session via a shallow object spread that shares mutable Map/Set references (gateLog, reviewerCallCount, etc.) with the first, unlike the deleted version which constructed fresh collections; contained by afterEach, but worth a follow-up fix (construct fresh collections + explicit teardown of the second sessionID).

Disproved candidates (false positives — listed per hard rule #10)

  • CST-002 / RP-001 — hypothesized concurrent-messages.transform double-fire risk. Disproved: staging is keyed on messages array object identity via WeakMap, so two concurrent transforms with distinct arrays each independently stage/deliver — this is correct behavior, not a race.
  • IA-002 — one-shot compaction-marker consumption by "whichever session's turn runs next." Disproved as a defect: the PR's own comment documents this as the intended semantic (bounded to one suppressed turn, fail-open).
  • TF-003 — comment ambiguity flag on an aggregate test assertion. Disproved: the toEqual against an all-true literal is genuinely discriminating and fails-RED pre-fix on the exact obligation it targets.
  • EX-001 (reviewer-found candidate, not from original lanes) — hypothesized "total guidance loss" when the compaction-suppression marker and the architect-turn guard both skip the same turn. Downgraded to LOW/near-disproved: existing tests (compaction-host-hook-2533.test.ts:215-221,241-248,251-282) already assert this exact double-skip is the intended, tested design for the compaction-summary turn itself, not a silent loss on a normal turn.

Suppressed candidates

0 — all 24 candidates across 11 lanes were routed to reviewers per the noise-budget policy (no LOW-confidence/no-evidence suppression applied).

Test-plan claim spot-checks (informational)

  • "7/7 frozen suite" — count reconciles (7 tests named AC1-AC6), but the PR body's "C1-C5" naming doesn't map to any identifier in the diff (docs or tests) — auditability gap, not a defect (TF-002).
  • Invariant-audit claims (1,2,7,8,10,12 touched / 3,4,5,6,9,11 not touched) — spot-checked, no false claims found.

Verdict: REQUEST_CHANGES

Two independently-confirmed, critic-upheld MEDIUM findings share one root cause (F-001/F-002) with execution-proven evidence of the exact regression class this PR exists to fix, occurring on identity-cold turns. None of the three independent validation passes (2 reviewers spanning this cluster, 1 critic) returned a clean approve. Recommended before merge: apply the F-001 fix (unify identity resolution across the two transform surfaces) or explicitly narrow the PR's claim to "warm-path only" and file a fast-follow for the cold-path gap; add the F-002 regression test; apply the small F-003 logging fix. F-004 and the informational items are non-blocking.


🤖 Generated with Claude Code via /swarm-pr-review (Profile B)

https://claude.ai/code/session_018Dyn1ZZeykr3EGUqVuSuau

@zaxbysauce

Copy link
Copy Markdown
Collaborator Author

🤖 Multi-Stage PR Review

Pipeline: MiniMax-M2.7-highspeed (orientation) (context pack) → MiniMax-M2.7-highspeed (explorer) + MiniMax-M2.7-highspeed (explorer B) (parallel explore, distinct lenses) → GLM-5-turbo (critique) ↔ GLM-5-turbo (critique) (cross-critique) → MiniMax-M2.7-highspeed (fallback arbiter) (arbiter: blind-spot + synthesize)
Commit reviewed: dd1953ed4a3a


PR Reviewer — opencode-swarm

🔍 PR Intent

Reconstructed from PR description, linked issue #2759, and diff.

  • O-001: Move architect per-step system-enhancer guidance from cache-sensitive system[1] to a trailing host-renderable user-role carrier — preserve stable conversation prefix across architect turns for prompt-cache reuse
  • O-002: Preserve strict Qwen/Gemma single-system rendering boundary
  • O-003: Add one-shot suppression so live-turn guidance is not copied into compaction summaries
  • O-004: Add compaction-aware one-shot suppression so live-turn guidance is not copied into compaction summaries
  • O-005: Retain injection-budget accounting and final-context accounting parity
  • O-006: Deliver /swarm command banner on the same trailing carrier path
  • O-007: Update all downstream consumers (knowledge-injector, final-context-accounting, memory injector, role-filter) to skip guidance carriers when scanning for latest real user message

📦 Implementation Summary

The PR restructures the architect guidance delivery path by:

  1. Staging at messages.transform start (messagesTransformArchitectEnhancerStage): detects session-bound architect, runs the full system-enhancer against a request-local WeakMap-keyed staging array
  2. Delivery at messages.transform end (messagesTransformArchitectEnhancerDeliveryStep): role-filters the staged strings, appends the conditional /swarm command banner, writes one fenced user-role carrier to the message array tail
  3. System hook skips architect: createSystemEnhancerHook with surface: 'system' returns early for isSessionBoundArchitect — no dynamic system tail, no second ledger
  4. Terminal partition: moveGuidanceCarriersToEnd reorders to keep persisted prefix stable (real messages first, carriers last)
  5. Carrier exclusion guards: isGuidanceCarrier checks added to every backward-iteration last-user scan across knowledge-injector, final-context-accounting, and memory injector
  6. Compaction bridge suppression: _architectCompactionPending Map (capped 500) set on compacting event, consumed on the immediately following messages pass

✅ / ⚠️ / ❌ Intended vs Actual

Obligation Status Evidence (file:line)
O-001 SUPPORTED src/index.ts:3123–3216 — WeakMap staging at start, delivery at end; src/hooks/system-guidance-carrier.ts:274–292moveGuidanceCarriersToEnd partitions to tail
O-002 SUPPORTED src/hooks/system-enhancer.ts:1157–1163 — system hook early-returns for session-bound architect; strict model collapse unchanged on system boundary
O-003 SUPPORTED src/index.ts:345–347,4563–4571_architectCompactionPending Map with 500-cap, set on compacting, consumed on next messages pass
O-004 SUPPORTED tests/unit/hooks/compaction-host-hook-2533.test.ts:167–281 — explicit suppression tests for pre/post-compaction turns
O-005 SUPPORTED src/hooks/final-context-accounting.ts:122,217isGuidanceCarrier skips carrier for pressure warning injection; src/hooks/system-enhancer.ts:3068 — surface-tagged ledger emission
O-006 SUPPORTED src/index.ts:2039–2043architectMessagesCommandRuleHook registered on messages surface; called in delivery step
O-007 SUPPORTED src/hooks/knowledge-injector.ts:754,858,1001,1280; src/hooks/final-context-accounting.ts:125,217; src/memory/injector.ts:646,722 — all backward scans guarded

🚨 Confirmed Findings

Only one finding survived challenge. Findings 1–4 were all refuted (see § Validation provenance).

[HIGH] messagesTransformArchitectEnhancerStage guard accesses sessionID.length before null-check on sessionID

  • Location: src/index.ts:3151
  • Why it matters: If mctx.sessionID is undefined (no message in output.messages carries a sessionID), the guard typeof sessionID === 'string' evaluates to 'undefined' === 'string'false, so execution falls through to sessionID.length which throws TypeError: Cannot read properties of undefined (reading 'length'). This crashes the entire messages.transform chain for that request.
  • Evidence:
    // src/index.ts:3149–3151
    const mctx = resolveMessageTransformContext(output);
    const sessionID = mctx.sessionID;       // could be undefined
    if (typeof sessionID === 'string') {    // typeof undefined === 'undefined', not 'string' → guard FAILS
        sessionID.length                     // ← TypeError here when sessionID is undefined
    resolveMessageTransformContext at src/hooks/host-boundary.ts:168 only sets sessionID from m.info?.sessionID if it is a non-empty string — if no message carries one, sessionID remains undefined.
  • Fix direction: Change the guard to sessionID && typeof sessionID === 'string' so that an undefined sessionID causes an early return rather than a crash. Alternatively, since isSessionBoundArchitect already handles undefined/empty-string inputs correctly by returning false, the guard could simply be removed or rewritten as if (!isSessionBoundArchitect(sessionID, mctx.agent)) return;.

🔬 Unverified but Plausible Risks

  • Risk: moveGuidanceCarriersToEnd is called on every messages.transform pass as the final structure-mutating step. For sessions with many guidance carriers (accumulated over a long conversation), the O(n) partition + two-push loops do not re-use push(...carriers) to avoid engine argument limits, but they do clear messages.length = 0 and repopulate. Object identity is preserved, but downstream code that holds a reference to a specific index (not the array itself) would observe a stale index.
    • Why suspicious: The loop-based push pattern is specifically used to avoid the argument-limit risk documented at src/context/role-filter.ts:300. However, the clear-and-rebuild pattern changes indices even though individual objects are not recreated.
    • What would verify it: A scan for any code that captures messages[i] before the final partition step and relies on that index remaining valid post-partition. The isGuidanceCarrier guards and the messages.indexOf(carrier) lookups in tests both use the post-partition array, so they are safe. The risk would require a consumer that captures a reference to a specific array index during the messages chain and uses it after the partition step.

🧪 Test / Coverage Gaps

  • Gap: No unit test directly exercises messagesTransformArchitectEnhancerStage with a output.messages array where no message carries a sessionID. The new integration test prompt-cache-prefix-stability-2759.test.ts always stamps sessionID into its test messages. The guard at line 3151 (typeof sessionID === 'string') would misbehave (throw) if hit with undefined sessionID, but there is no test covering this path.
    • Evidence: All test fixtures in prompt-cache-prefix-stability-2759.test.ts and system-render-boundary-registered.test.ts pass sessionID in info.sessionID. The guard is exercised only in the happy path.

📋 Shipped-vs-Claimed Gaps

  • Gap: The PR description claims "strict Qwen/Gemma system rendering remains on the system boundary." The system hook does early-return for session-bound architect, so strict-model collapse now happens on zero system entries (the base header only). The integration test AC4 (tests/integration/prompt-cache-prefix-stability-2759.test.ts) passes [STEP GUIDANCE STRICT] through the messages carrier for a strict model, and the system-render-boundary unit test confirms the system array is collapsed to one entry — but the test seed includes [STEP GUIDANCE STRICT] in the system array, which would not happen in production for session-bound architect (the system hook returns early). The test is not wrong (it tests the boundary collapse logic in isolation), but it does not prove that the system array fed to applySystemRenderBoundary in production would actually contain the guidance string. This is a test-vs-implementation gap: the test seeds what the production system hook would not produce.
    • Evidence: tests/integration/prompt-cache-prefix-stability-2759.test.ts:217–220 feeds [STEP GUIDANCE STRICT] into the system array directly. The production path (src/hooks/system-enhancer.ts:1157–1163) returns early for isSessionBoundArchitect, so the system array would only contain the base header.

🔁 Validation provenance

Findings DROPPED (with reason):

# Finding Why dropped
1 isGuidanceCarrier false positive — real user message skipped by downstream All carriers are created via appendGuidanceCarrier which always stamps swarm-guidance: prefix; isGuidanceCarrier matches only that prefix; moveGuidanceCarriersToEnd uses the same check — consistency is guaranteed by construction
2 isGuidanceCarrier false negative — carrier treated as user speech All carrier creation goes through appendGuidanceCarrier; appendGuidanceCarrier always stamps the prefix; isGuidanceCarrier matches that same prefix — no FN path in the production code
3 resolveMessageTransformContext could return null/undefined resolveMessageTransformContext returns MessageTransformContext (non-nullable object); the type is confirmed in src/hooks/host-boundary.ts:168–192 — always a valid object
4 enhancer() rejected promise leaks as unhandled rejection try { await enhancer(...) } catch { ... } catches rejected promises — await re-throws promise rejections into the catch block

Blind-spot finding ADDED: The typeof sessionID === 'string' guard at line 3151 accesses sessionID.length when sessionID could be undefined, causing a TypeError. Confirmed by tracing resolveMessageTransformContextsessionID is only assigned from m.info?.sessionID when it is a non-empty string; if no message carries one, sessionID remains undefined.


📝 Merge Recommendation

[APPROVE_WITH_FIXES]

One HIGH finding requires a one-line fix to the guard at src/index.ts:3151. Once typeof sessionID === 'string' is strengthened to sessionID && typeof sessionID === 'string' (or replaced with an isSessionBoundArchitect call), the PR is ready to merge.

Check Result
No CRITICAL findings
No unresolved STEALTH_CHANGE ✅ (compaction bridge, carrier routing, and strict-model boundary are all documented in the release note and engineering-invariants entry)
No UNSUPPORTED obligations
Test coverage adequate ⚠️ (HIGH finding 1 is untested — add one test for undefined sessionID path)
No hardcoded secrets
All async errors handled
Input validation present ✅ (WeakMap prevents cross-request leakage; guidanceCarrierEnvelopeTokens handles null fence; deductProducerEmission covers fence overhead)
No broken agent role boundaries ✅ (isSessionBoundArchitect is shared by both surfaces; role-filter system hook updated to accept agent input)
Prompt format contracts intact ✅ (system boundary early-return preserves strict collapse; carrier is user-role, host-renderable)
Lockfile consistent ✅ (no new dependencies added)

🔒 Reviewed by a 3-model cross-family adversarial debate (architect → dual-lens parallel explorers → cross-critique → arbiter) for high recall with low false-positive noise. Findings are advisory — verify before acting.

@zaxbysauce
zaxbysauce force-pushed the codex/issue-2759-prompt-cache branch from dd1953e to e66ba34 Compare September 15, 2026 03:09
@zaxbysauce

Copy link
Copy Markdown
Collaborator Author

🤖 Multi-Stage PR Review

Pipeline: MiniMax-M2.7-highspeed (orientation) (context pack) → MiniMax-M2.7-highspeed (explorer) (explore → candidates) → MiniMax-M2.7-highspeed (fallback arbiter) (challenge + blind-spot)
Commit reviewed: a0ce0f6c0b9a


🔍 PR Intent

Reconstructed from PR description, linked issue #2759, and diff.

  • O-001: Move architect enhancer guidance out of output.system and into a trailing host-renderable user-role carrier so the system tail remains stable across architect turns
  • O-002: Use OpenCode's messages.transform-before-system.transform invocation order to stage architect guidance during the messages phase and deliver it at the end
  • O-003: Preserve strict Qwen/Gemma system rendering boundary
  • O-004: Suppress architect bridge guidance for the messages pass immediately after compaction
  • O-005: Retain injection-budget accounting and real-time nudge semantics for the messages-surface variant
  • O-006: Migrate existing system-enhancer unit tests to registered-host integration style (host-visible user-role carrier, stable system surface)

📦 Implementation Summary

The PR adds a two-stage messages-transform pipeline for session-bound architect calls: an early stage (messagesTransformArchitectEnhancerStage) stages enhancer output in a request-local WeakMap, and a late stage (messagesTransformArchitectEnhancerDeliveryStep) role-filters, combines with the command banner, appends one fenced user-role carrier, and records fence overhead. A new moveGuidanceCarriersToEnd step partitions all carriers to the message-array tail. The system hook now returns early for session-bound architects (isSessionBoundArchitect guard). The compaction hook sets a one-shot _architectCompactionPending marker consumed on the next messages pass. 20+ unit tests were migrated to registered-host style asserting the host-visible carrier surface and stable system surface.


✅ / ⚠️ / ❌ Intended vs Actual

Obligation Status Evidence
O-001 SUPPORTED src/index.tsmessagesTransformArchitectEnhancerDeliveryStep appends one appendGuidanceCarrier; moveGuidanceCarriersToEnd partitions to tail
O-002 SUPPORTED src/index.ts:3123–3300 — staging WeakMap + early/late stage pair matches messages→system invocation order
O-003 SUPPORTED src/hooks/system-enhancer.ts:1157–1165isSessionBoundArchitect guard returns early; applySystemRenderBoundary untouched for non-architect
O-004 SUPPORTED src/index.ts:4556–4563_architectCompactionPending.set; :3133compactionPending = _architectCompactionPending.delete(sessionID) before predicate
O-005 SUPPORTED src/hooks/system-enhancer.tssurface param flows through all recordProducerEmission/recordRealtimeLearningNudge calls; deductProducerEmission in role-filter for removed fragments
O-006 SUPPORTTED 20+ tests migrated; expectStableArchitectSystem(system) verifies post-hook system === [BASE_SYSTEM] (pass-by-reference, not a rebuild)

🚨 Confirmed Findings

None. Both reviewer-confirmed findings are false positives. Full reasoning follows.

[DROPPED] CRITICAL — Test helper expectStableArchitectSystem is a trivial tautology

  • Why dropped: The claim rests on a misread of the test helper's call site. invokeRegisteredArchitect at line ~175 does NOT rebuild system after the hook call. It passes const system = [BASE_SYSTEM] by reference to host.hooks['experimental.chat.system.transform']({ sessionID: SESSION_ID }, { system }). The hook mutates system in place. The return value { system } carries the post-mutation state. expectStableArchitectSystem(system) then asserts that the array the hook produced is exactly [BASE_SYSTEM]. If the hook incorrectly appended dynamic content, the assertion would fail. The test is structurally correct.

[DROPPED] HIGH — System array is reassigned after the hook call

  • Why dropped: Same false premise. The local const system = [BASE_SYSTEM] variable holds the post-mutation result because JavaScript passes the array reference, not a copy. output.system.length = 0; output.system.push(...kept) mutates the same object the test's system variable references. expect(system).toEqual([BASE_SYSTEM]) therefore tests the actual hook output. This is the intended pattern (AGENTS.md invariant 10: in-place mutation).

🔬 Blind-Spot Findings

None. The PR's mechanism is structurally sound:

  • Staging isolation: The request-local WeakMap (stagedArchitectGuidanceByMessages) cannot persist conversation text or cross sessions — it is cleared after the delivery step or on any exception.
  • Compaction marker scope: _architectCompactionPending is a Map<string, true> with a 500-entry cap and is deleted on session removal (src/index.ts:3653), so it cannot accumulate unboundedly.
  • Ledger consumption: advanceTurnGeneration runs in both the system hook (when it runs for non-architect) and the final context accounting step; the architect messages-stage ledger is separate from the system-stage ledger, preventing cross-surface attribution errors.
  • Role-filter integration: createRoleFilterSystemHook now reads input.agent as a primary source (src/context/role-filter.ts:253), matching the messagesTransformArchitectEnhancerDeliveryStep call which passes { sessionID, agent }. The fallback to getActiveAgentName is retained.
  • isSessionBoundArchitect shared predicate: Used in both the messages-stage architect enhancer and the system hook's early-return guard, guaranteeing exactly one delivery owner per invocation.

🧪 Test / Coverage Gaps

None found. Coverage is comprehensive:

  • AC1 (byte-stable history prefix): prompt-cache-prefix-stability-2759.test.ts AC1
  • AC2 (trailing user-role carrier): prompt-cache-prefix-stability-2759.test.ts AC2
  • AC3 (system surface stable for cache-capable): prompt-cache-prefix-stability-2759.test.ts AC3
  • AC4 (strict Qwen/Gemma collapse): prompt-cache-prefix-stability-2759.test.ts AC4 + system-render-boundary-registered.test.ts
  • AC5 (in-place mutation, no system-role carrier): prompt-cache-prefix-stability-2759.test.ts AC5
  • AC6 (enhancer disabled → command banner still delivered): prompt-cache-prefix-stability-2759.test.ts AC6
  • Compaction suppression: compaction-host-hook-2533.test.ts
  • Session-deletion marker cleanup: compaction-host-hook-2533.test.ts

📋 Shipped-vs-Claimed Gaps

  • Claim: "Zero message-surface system roles" — verified by system-render-boundary-registered.test.ts:143–153 which asserts messages.every((message) => message.info.role !== 'system').
  • Claim: "Strict model preservation" — verified by prompt-cache-prefix-stability-2759.test.ts AC4 which applies the strict classifier and checks system.length === 1 after collapse.

📝 Merge Recommendation

[APPROVE]

All six obligations are supported by the code. Both confirmed findings were refuted: the test assertions operate on the post-mutation reference, not a rebuilt array. The blind-spot pass found no structural gaps. The test suite comprehensively covers AC1–AC6, compaction suppression, session deletion cleanup, and the guidance-carrier partition invariant.

Check Result
No CRITICAL findings
No unresolved STEALTH_CHANGE
No UNSUPPORTED obligations
Test coverage adequate
No hardcoded secrets
All async errors handled
Input validation present
No broken agent role boundaries
Prompt format contracts intact
Lockfile consistent

🔁 Validation Provenance

Survived: 0 findings. Both reviewer-confirmed candidates were dropped as false positives (the tests verify post-mutation state via pass-by-reference, not trivial rebuilds).

Dropped (2):

  • CRITICAL system-enhancer-sanitization.test.ts:175expectStableArchitectSystem called on post-hook reference, not a rebuilt array; hook would mutate the local variable.
  • HIGH system-enhancer-sanitization.test.ts:172 — Same structural misunderstanding; test correctly checks the hook's actual output.

Blind-spot additions: 0. The PR's request-local staging, bounded compaction marker, ledger consumption ordering, and role-filter input.agent routing are all structurally sound.


🔒 Reviewed by a multi-stage local-first funnel (architect context pack → explorer candidates → critic challenge/author) for high recall with low false-positive noise. Findings are advisory — verify before acting.

@zaxbysauce

Copy link
Copy Markdown
Collaborator Author

🤖 Multi-Stage PR Review

Pipeline: MiniMax-M2.7-highspeed (orientation) (context pack) → MiniMax-M2.7-highspeed (explorer) (explore → candidates) → MiniMax-M2.7-highspeed (fallback arbiter) (challenge + blind-spot)
Commit reviewed: 8f606422c2dc


PR Reviewer — opencode-swarm

Phase 0 — Reconstruct Intent

From PR #2780 and linked issue #2759:

Problem: The architect's ~100K-token request prefix (tool schemas, agent prompt, skills) should hit provider prompt-cache on every call but does not. Per-step system-enhancer guidance rewrites system[1] and directive carriers are unshifted into the message list, moving the stable prefix and forcing re-tokenization. Measured impact: 61% of architect spend was uncached input.

Obligations (O-001 to O-005):

  • O-001 Move session-bound architect enhancer guidance from the cache-sensitive system tail into one trailing host-renderable user-role carrier
  • O-002 Preserve stable conversation prefixes across architect turns (byte-identical history prefix)
  • O-003 Retain strict Qwen/Gemma single-system rendering boundary
  • O-004 Compaction-aware one-shot suppression so live-turn guidance is not copied into compaction summaries
  • O-005 Maintain injection-budget accounting across the new surface routing

Phase 1 — Summarise Actual Behaviour

The diff implements a two-surface architecture for architect guidance:

  1. messagesTransformArchitectEnhancerStage (early in messages.transform): Stages the full architect enhancer against a request-local WeakMap keyed to the messages object. Runs before all other message consumers.

  2. messagesTransformArchitectEnhancerDeliveryStep (late in messages.transform, after all consumers): Retrieves staged guidance, passes it through the role-filter and command-rule hooks, joins into one string, and appends a fenced user-role guidance carrier via appendGuidanceCarrier.

  3. System hook (system-enhancer): For session-bound architect calls, returns early after capturing the model identity — skips the full enhancer and avoids polluting the cache-sensitive system tail. The command rule hook has a matching guard.

  4. moveGuidanceCarriersToEnd: Terminal partition at the very end of messages.transform, moving all guidance carriers to the request tail after the history.

  5. _architectCompactionPending map: One-shot suppression of the architect bridge on the immediate post-compaction turn.


Phase 2 — Compare Intended vs Actual

Obligation Status Evidence
O-001 SUPPORTED src/index.ts:3199–3261 — delivery step appends one architect-session carrier; src/hooks/system-guidance-carrier.ts:276appendGuidanceCarrier
O-002 SUPPORTED tests/integration/prompt-cache-prefix-stability-2759.test.ts AC1 — first.rendered.slice(0, 2) === second.rendered.slice(0, 2)
O-003 SUPPORTED src/index.ts:3080isSessionBoundArchitect shared by both surfaces; tests/integration/prompt-cache-prefix-stability-2759.test.ts AC4 — strict models collapse to one entry
O-004 SUPPORTED src/index.ts:3351–3359_architectCompactionPending consumed at architect stage entry; tests/unit/hooks/compaction-host-hook-2533.test.tssuppresses only the architect bridge on the immediate post-compaction transform
O-005 SUPPORTED src/hooks/final-context-accounting.tssurface: 'system' from ledger; src/services/injection-budget.ts:156guidance-carrier-fence producer

✅ / ⚠️ / ❌ Intended vs Actual

Obligation Status Evidence (file:line)
O-001 SUPPORTED src/index.ts:3199 — delivery step; src/hooks/system-guidance-carrier.ts:261appendGuidanceCarrier
O-002 SUPPORTED tests/integration/prompt-cache-prefix-stability-2759.test.ts:204 — AC1 prefix stability assertion
O-003 SUPPORTED src/index.ts:3080isSessionBoundArchitect; tests/integration/prompt-cache-prefix-stability-2759.test.ts:297 — AC4 strict model collapse
O-004 SUPPORTED src/index.ts:3351_architectCompactionPending; tests/unit/hooks/compaction-host-hook-2533.test.ts:167 — suppression test
O-005 SUPPORTED src/services/injection-budget.ts:156guidance-carrier-fence; src/hooks/final-context-accounting.ts:143 — ledger surface tokens

🚨 Confirmed Findings

None. The implementation is structurally sound across all surfaces.


🔬 Unverified but Plausible Risks

None that meet the structural-proven bar. The key architectural decisions are verifiable in the diff:

  • WeakMap isolation (src/index.ts:3160): request-local, object-keyed, cannot cross sessions or persist text — the concern about cross-request leakage is structurally eliminated.
  • isSessionBoundArchitect predicate (src/hooks/host-boundary.ts:90): fail-closed on missing sessionID; explicit agent parameter is tested in AC2-prefixed and AC5.
  • Fence token accounting (src/index.ts:3235–3242): guidance-carrier-fence producer and envelope reservation are additive, not double-counting — the sequence is: reserve at enhancer entry → decrement budget → record fence overhead at delivery → advance ledger. No structural gap.

🧪 Test / Coverage Gaps

  • Gap: None found. The 15 affected test files cover: prefix stability (AC1–AC6), strict model preservation, in-place mutation, disabled enhancer parity, compaction suppression, session-deletion cleanup, handoff security, decision-drift gating, turbo/full-auto banners, and system-render-boundary integration. The 195-test CI run is the functional proof.

📋 Shipped-vs-Claimed Gaps

  • Gap: None found. The PR invariant audit cross-references all 12 AGENTS.md invariants; every touched invariant has structural evidence in the diff.

🔍 PR Intent

Reconstructed obligation list (from PR text, issue, commits, changed tests, changed docs, changed interfaces):

  • O-001 Move session-bound architect enhancer guidance to trailing user-role carrier (not system tail)
  • O-002 Preserve byte-identical conversation prefix across architect turns for prompt-cache reuse
  • O-003 Retain strict Qwen/Gemma single-system rendering boundary
  • O-004 Compaction-aware one-shot suppression (live guidance must not enter compaction summaries)
  • O-005 Maintain unified injection-budget accounting across new surface routing

📦 Implementation Summary

The PR routes architect guidance through a messages.transform-local staging pipeline:

  • Early stage (messagesTransformArchitectEnhancerStage): Full enhancer runs against a WeakMap-keyed request-local object, before all other consumers.
  • Delivery stage (messagesTransformArchitectEnhancerDeliveryStep): Role-filtered and command-ruled staged output is joined and appended as one fenced architect-session user-role carrier.
  • System hook guard (isSessionBoundArchitect): The system-surface enhancer returns early for session-bound architects after capturing model identity — keeping the cache-sensitive system prefix untouched.
  • Terminal partition (moveGuidanceCarriersToEnd): All carriers moved to request tail after history, preserving stable prefix ordering.
  • Compaction suppression (_architectCompactionPending): One-shot marker consumed at architect stage entry.

📝 Merge Recommendation

[APPROVE]

The implementation correctly routes architect guidance to a trailing carrier, stabilises the system prefix, preserves the strict-model boundary, and suppresses guidance on compaction summaries. All five obligations are SUPPORTED. No structural defects were found in the diff.

Check Result
No CRITICAL findings
No unresolved STEALTH_CHANGE
No UNSUPPORTED obligations
Test coverage adequate
No hardcoded secrets
All async errors handled
Input validation present
No broken agent role boundaries
Prompt format contracts intact
Lockfile consistent

🔒 Reviewed by a multi-stage local-first funnel (architect context pack → explorer candidates → critic challenge/author) for high recall with low false-positive noise. Findings are advisory — verify before acting.

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.

Per-step system[1] rewrite and unshifted directive carriers defeat provider prompt caching for the architect

3 participants