Repository navigation
Auto-compacted fleet root reports success without the recipe terminal reason #5272
Description
Fix target and integration order — mandatory routing
Repository: TalonT-Org/AutoSkillit.
Fix PR base branch: develop, currently 381afb4e59cc23acf4ca9ace7a7644b75e6e7b14.
Scope: fleet orchestrator runtime on the Claude Code backend: the result contract, and what the root still knows after automatic compaction. Every product file involved already exists on develop.
Open the remediation PR against develop, not impl-issue-5233-20261008-implementation. The E2E check that exposed this (check_implementation_envelope, scripts/e2e/e2e_harness.py:342-346 on the #5255 branch) is correct and must stay strict; do not change it. Once merged, the owner of parent PR #5255 integrates the develop commit and reruns commissioning, the same order as #5270.
Defect
A fleet-dispatched Claude Code root receives the recipe once, at startup. When the session auto-compacts, that content is gone, including the terminal done step's instruction, and nothing re-delivers it. The root then finishes by improvising and emits a success result block with no reason. The fleet layer accepts that block as dispatch_status: "success" with an empty reason.
Evidence
Run 38431354139, attempt 1 at 93457f16ecc30249799c02084c20f41d9cd88455, Claude Code 2.1.280, model MiniMax-M3. Artifact e2e-implementation-38431354139-1.
out/envelope.json:kind: "completed",success: true,dispatch_status: "success",reason: "",l3_parse_source: "stdout".l3_payloadcarriessuccessplus PR, CI and audit fields, and has noreasonkey.out/result.jsonlistsfleet run: implementation terminal reason is missing. Its other failure is the lifecycle one tracked in Unfiltered SDK stops enter E2E native-session coverage accounting #5271.- The reason is defined only in the recipe's terminal step:
src/autoskillit/recipes/implementation.yaml:3172-3176(done:Example sentinel: {"success": true, "reason": "implementation_complete"}). - Root transcript
out/transcripts/-workspace-sandbox/123756d6-70db-4319-a2a1-226e765d3d30.jsonl:- Records 141 and 148: the root receives that text in
get_recipe_sectionresults (orchestration_rulesandcontent). - Record 382:
compact_boundary, triggerauto,preTokens194567,postTokens2221. - The string
implementation_completeappears in records 141, 142, 148 and 149 only. It is not in the compaction summary (record 385) or in any later record. - All 15
get_recipe_sectioncalls come before the boundary (records 128 to 365). None follows it. - The compaction summary keeps the result wrapper format and a failure example that has a reason. It does not keep the success contract.
- After the boundary the root rebuilds routing by grepping the installed recipe YAML through
run_cmd(for example records 1268 to 1330). At record 1334 it decides by itself to skiprelease_issue_success. No later record contains thedonestep's text. Record 1342 is the final block.
- Records 141 and 148: the root receives that text in
out/fleet-run.stderr.txthas a warning at 17:07:57Z:completion_marker_in_separate_message, recoveryrebuilding result from assistant_messages.- Earlier run 38170521660, attempt 1: the root also auto-compacted (
preTokens166958), and its envelope endedsuccess: false,reason: "fleet_l3_no_result_block". That envelope and transcript are retained on the Add seeded sandbox implementation E2E validation #5255 branch undertests/infra/fixtures/e2e_sessions/run_38170521660_attempt_1/.
Existing product context
src/autoskillit/hooks/guards/auto_compact_guard.pydenies automatic compaction "before it can replace session history", but returns without acting unlessAUTOSKILLIT_AGENT_BACKENDiscodex(Isolate AutoSkillit Codex runtime config and block automatic compaction #4271; the Codex form of this defect was Codex Sous-Chef Recipe Context Loss via Auto-Compaction #3938). The Claude Code backend has no equivalent protection.src/autoskillit/fleet/_prompts.py:117showsreasonin the result block and:333lists generic reasons. The recipe-specific reason exists only in the recipe's stop-step message.
Required behaviour
Owner decision, 2026-10-13: a fleet root must not auto-compact.
- Block automatic compaction for a fleet root on the Claude Code backend, as is already done for Codex. Claude Code's hook documentation lists
PreCompactas able to block compaction. - Where a backend cannot block it, the dispatch must detect that the root compacted and fail explicitly. It must not continue on a compacted context.
- Reaching the point where compaction would be needed, or the model's maximum window, is itself a fault. Report it as an explicit failure with its own reason. A fleet root is not expected to get there in a normal run; Fleet root is never delivered the verify step digest and exhausts its context #5273 covers why this one did.
- A dispatch must not report success with an empty reason when the recipe's terminal step declares one.
- Codex: the existing guard already denies automatic compaction. Per the owner, Codex windows now exceed 200K, so confirm the guard and the maximum-window path still behave, and record any Codex-specific handling that turns out to be needed.
- Keep the E2E acceptance check strict. Do not infer or default the reason in the harness.
- Add focused regressions: a fleet root on Claude Code cannot auto-compact, and a success block that lacks
reasonis rejected. Runpre-commit run --all-filesand the configuredtask test-local-gate.
Not established
- The causal link from compaction to the omitted reason rests on this one run. No successful run without compaction is retained for comparison.
- Both observed roots ran MiniMax-M3 through Claude Code 2.1.280. Behaviour on other models or versions is unknown.
Related tickets
- Fleet root is never delivered the verify step digest and exhausts its context #5273: why this root reached the compaction point at all. It was never delivered the
verifystep digest and spent its context searching for it. - E2E fleet sessions run at a 200K context window despite the harness's 1M setup #5274: E2E fleet sessions run at a 200K window although the harness is set up for 1M. Claude Code's own result output reports
claude-sonnet-5: contextWindow 200000. With compaction blocked, a 200K window turns a compaction into a hard stop near 200k tokens.
Coordination
Tickets from the #5255 commissioning runs: #5270, #5272, #5273 and #5274 (all base develop) and #5271 (stacked on the #5255 branch). They are independent and can be worked in parallel. One interaction: once compaction is blocked here, a commissioning run no longer exercises #5271's capture matcher through a compacting root, so #5271 rests on its own tests.
Activity