Gate #4 triad (fable 0-critical, gemini clean) + sol agent-scope (cursor,
10 findings) dispositioned with base-vs-branch attribution:
Fixed (real, ours):
- G4-4 coop-checkpoint lost-trigger race: a quiescence trigger arriving while
the worker latch is held is memoized and replayed once after latch clear;
regression pins the exact interleaving.
- G4-5 SYSTEM.md overclaim: 'cannot be bypassed by any LLM' replaced with the
truthful deterministic-classification claim + the disclosed wrapper/
interpreter residual (matches CHECKLISTS item 21 and the code's own
docstrings).
- SC-7 git classifiers: remote gains read-only modes (bare/-v/show/get-url;
add/set-url/prune/... mutating — verb = first non-flag token, verified
against real git), tag -v/--verify reclassified read-only; network fence
kept for read-only remote.
- SC-10 reflog: no longer unconditionally read-only; expire/delete/drop
mutating with protected-runtime + external-lane pins.
- SC-8 compaction floor now counts protected old spans via the compactor's
own predicate — kills the recurring-futile-pass class the hysteresis was
built for; armed disclosure names the components honestly.
- SC-9 forced-acceptance bypass recorder: suppressed only by a canonical
host decision status, not by a status-less deferred agent stance;
end-to-end regression (pre-fix: bypass fully unrecorded).
- SC-4 owner-facing truth: Settings shows Auto for the unset surface-aware
light default (display-only; save path preserves the empty value).
- SC-6 vision/media parity: shared _read_file_parity_block applies read_file's
user-files/project-store/restricted-subagent guards in both consumers
(branch root-widening counterfactually admitted a credential-named PDF).
Rejected with evidence: G4-2 (oscillation — attacks the disclosed 600-char
bound its own G3-6 prescribed), G4-3 (repeat of G3-3 base-precedent
rejections), SC-2 (internal-only override by design; docs clarified — no
API surface on reviewer say-so).
Deferred as pre-existing base gaps (DEFERRED_ISSUES): SC-1 direct-Anthropic
settle-path cache undercount (~94% on cache-heavy calls; byte-identical at
base), SC-5 SSE FINAL_STATUSES/cancel_requested termination (byte-identical
at base).
Combined batch: 18 test files green incl. smoke gates; ruff -F clean.
Co-authored-by: Ouroboros <311266734+ouroboros-agent@users.noreply.github.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The submarine shape still ran the summarizer + full-transcript rewrite in 34 of
35 rounds (measured with the REAL compactor on the wave3 numbers: low mode, an
irreducible ~630K-char frame, an agent that keeps calling tools). The rearm
criterion was the COMPACTABLE region — which is exactly what a pass collapses,
so the pass's own output cleared the 1.2x growth bar on the very next tool
round. The shipped pin missed it because it stubbed the compactor to return the
transcript UNCHANGED, the one shape where the bar is hard to cross.
Judge utility on the FLOOR a pass could reach (frozen frame + the spans
_emergency_keep_recent must keep, summaries only add to it). While the floor is
over the trigger no pass can help, so region growth cannot rearm and only the
N-round window refires — which still bounds the transcript. A futile pass now
arms on the region it ACTUALLY HANDLED, not on the remainder it just collapsed.
Measured after: 3/35 rounds, 4 disclosures (was 34/35, 35 disclosures).
Also in this area, from the same adversarial wave:
- the emergency trigger's real magnitude is now stated in context_budget.py and
pinned per density/tool-envelope (max, density 1.7, 37K schema tokens fires at
~559K chars — 2.1x earlier than the 1.2M constant reads); the eagerness itself
is the owner's "necessity = total calibrated pressure" decision and is left
alone, but it can no longer move silently.
- the finalizer no longer claims the global prompt-cache TTL is "consumed HERE
and only here" while review_helpers.cached_prompt_blocks reads it too; a pin
derives the readers from the call sites and requires both docstrings to agree.
- cache_horizon_note documents its honest reachability (at the shipped 1h only
wait_tasks can emit it; wait_task sits exactly on 3600s, delegate_wait's 2100s
ceiling cannot reach it; at 5m all three do), pinned against the real clamps.
- a golden covers the per-tier cache-write split on the OpenRouter lane: the
harvest is passthrough-dependent, not structurally dead.
Co-authored-by: Ouroboros <311266734+ouroboros-agent@users.noreply.github.com>
Found while verifying the audit findings, in my own 02fecbc0. The arm that was
supposed to end the wave-3 "35/35 rounds fired" thrash did not engage in the
shape that produces it FIRST: a frozen frame already over the trigger while the
transcript still has under two tool rounds.
Two defects, one class:
- The compactor no-ops at `len(spans) <= keep_recent` and keep_recent floors at
1, so with 0-1 spans the pass was structurally incapable of helping — yet it
ran, writing a forensic checkpoint every round.
- The rearm test `region < armed * 1.2` is `0 < 0` for an empty compactable
region, i.e. FALSE, so the hysteresis popped itself and re-fired immediately.
Probed on the real function with the submarine's own numbers (low mode, ~630K
frame, no tool rounds): 5 of 5 rounds fired a no-op pass before, 0 of 5 after,
with exactly one disclosure.
- Under two spans: arm instead of running the pass (typed reason
`nothing_compactable`).
- Growth floor is `max(armed * GROWTH, armed + 1)` so an empty armed region
suppresses.
- Both arming paths share `_arm_compaction_hysteresis`, so the loud line and the
typed checkpoint event are identical whichever way a pass fails to earn its
cost — the suppression is never silent (P1).
Docs: ARCHITECTURE records both arming shapes and the empty-region floor.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The NECESSITY half of the emergency-compaction trigger claimed TOTAL calibrated
pressure but measured `messages` alone. Tool schemas are sent beside the
transcript on the wire — ~148K chars (~37K real tokens) on the submarine
traces — so the trigger fired a whole tool envelope late: ~12% past budget in
max, ~37% past it in low, exactly where the frame is already irreducible.
- context_fit: `tool_schema_tokens()` is now the ONE seam for the schema
segment; `projected_tokens_with_tools` and `estimate_context_prompt_tokens`
(which each hand-rolled the same json.dumps/chars-4) both read it, so the
compaction trigger cannot drift from the fit projections.
- loop: `_CompactionRoundContext` carries the round's LIVE schema list (the
same object `enable_tools` appends to), and total pressure = transcript +
schemas, calibrated by the main-loop density. The post-pass futility check
uses the SAME measure — otherwise a pass that never got the total under the
trigger would read as successful and refire next round, re-opening the
thrash the hysteresis exists to close. The armed checkpoint event now
discloses `tool_schema_tokens` so an irreducible frame is legible.
- UTILITY/rearm is unchanged: still the compactable region, same hysteresis.
Docs: ARCHITECTURE now states the necessity/utility split and that necessity
includes the schemas.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The submarine thrash class: once transcript+frame exceeded the trigger,
_run_round_compaction fired EVERY round — a light-model call plus a transcript
rewrite that collapsed the provider prompt cache to the static floor — because
the trigger counted the un-compactable frozen frame (wave3/low: 35/35 rounds,
the 400K-char LOW trigger sits below the irreducible low-mode frame; wave1:
24 passes with cached=338,944 streaks).
- NECESSITY (compact at all?) stays TOTAL pressure — the frame counts toward
the provider window (an immutable core overflowing the window must still
trigger) — but is now compared in CALIBRATED real tokens: the char budget's
documented token equivalent vs chars/4 x main_loop_token_density
(context_fit SSOT: neutral 1.0 cold, measured supersedes — deliberately NOT
resolve_token_density's review-pack cold-conservative value, which would
demote fresh installs; the v6.80->v6.81 oscillation). On a measured ~1.7x
Claude route the trigger now fires at its intended token budget instead of
~1.7x past it; cold stores behave byte-for-byte as before.
- UTILITY/rearm (can a pass help; when refire?) is the COMPACTABLE region only
(transcript beyond the frozen frame): a pass that could NOT get below the
trigger arms a hysteresis in accumulated_usage — no refire until the region
grows >=1.2x or 10 rounds pass (context_budget constants). One loud
emit_progress disclosure + a typed compaction_hysteresis_armed checkpoint
event on arming replace the per-round call/rewrite.
- The reactive provider-overflow one-shot low-retry net is untouched, as are
manual (pending) and routine compaction branches.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Motivated by benchmark forensics (terminal-bench/SWE-bench/GAIA): most
trial deaths were harness infrastructure, not agent inability. All three
sub-blocks are general-purpose robustness for normal users.
1a. Per-class same-model transient retry (loop_llm_call.py):
- Transient classes (finish_reason=null / empty-response shapes,
provider_transient 429/5xx/overloaded) retry the SAME model with a
larger budget: transient_retry_max() (OUROBOROS_TRANSIENT_RETRY_MAX,
SSOT default 6 in SETTINGS_DEFAULTS + apply_settings_to_env, floored
at the caller budget), exponential backoff capped 60s.
- Backoff sleeps are deadline-bounded (task_metadata.deadline_at threaded
as deadline_ts through the main loop, budget-limit and round-limit
wrap-up calls); stopping emits a durable llm_retry_deadline_exhausted
event from BOTH transient paths.
- Permanent classes (auth/quota/bad_request/request_too_large) fail fast
unchanged. NO cross-model fallback is introduced: single-model setups
(all slots one model, empty fallback) die only after the real budget,
and the failure text reports actual attempts used.
1b. Encrypted-reasoning strip-retry (llm.py):
- _is_openrouter_signature_error also matches "encrypted reasoning",
"encrypted content for item" (observed gpt-5 shape "...for item
rs_..."), "reasoning item", "reasoning_details" - reusing the existing
one-shot roundtrip-metadata strip-and-retry on the same model.
The allow_fallbacks pin is untouched.
1c. Compaction robustness (context_compaction.py + loop.py):
- Per-batch isolation: a failed batch leaves only its own rounds raw;
the old whole-pass try/except discarded every successful summary.
- Per-round degradation: a missing summary leaves that round raw instead
of the all-or-nothing completeness ValueError.
- Structured emit_round_summaries tool protocol (tool_choice=required,
reliable round_id keying) with text-protocol fallback for local light
models or prose answers; spend from failed batches is accounted
(_BatchSummaryError carries usage, including across fallback failures).
- Warning protection scans the first two non-empty lines (autocorrect
notes can prefix the marker); SHELL_EXIT_ERROR rounds are deliberately
compactable - trial-and-error history must compact, with the first
error line preserved by summarizer instruction.
- Emergency compaction adapts keep_recent to
min(50, max(6, spans//2), max(1, spans-1)) so oversized transcripts
with few huge rounds actually compact instead of no-opping.
Review of record: triad+scope rounds 1-4 via run_external_review.py;
round 4 blocked=False with zero criticals (scope fable-5 responded,
851,542 real tokens). Remaining advisory (param count on two
pre-existing over-limit signatures) is documented pre-existing debt;
context-object consolidation is out of block scope.
Carriers: VERSION, pyproject.toml, web/package.json, api_types.js
GATEWAY_CONTRACT_VERSION, README badge+history (oldest minor row
trimmed per P9 cap), ARCHITECTURE.md header + retry/compaction docs.