Skip to content

docs: update BRC event-pump docs for slice-4 [doc-updater] - #2965

Merged
jwbron merged 3 commits into
mainfrom
egg/doc-update-brc-event-pump-slice4
Jun 3, 2026
Merged

docs: update BRC event-pump docs for slice-4 [doc-updater]#2965
jwbron merged 3 commits into
mainfrom
egg/doc-update-brc-event-pump-slice4

Conversation

@james-in-a-box

@james-in-a-box james-in-a-box Bot commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

Update documentation to reflect changes from c03f316 (#2951):

  • docs/index.md: fix stale anchor links (pointing to removed #brc-event-pump-wrapper-slice-2-behind-egg_brc_event_pump) and update description to reflect slice-4 is live
  • docs/reference/orchestrator-cli.md: EGG_BRC_MEMORY default corrected from off to full
  • docs/architecture/brc-memory.md: mode table and opening paragraph updated to show full as new default; off demoted to rollback escape hatch
  • docs/development/STRUCTURE.md: consensus_wrapper.py entry no longer references legacy capped-restart path or EGG_BRC_EVENT_PUMP
  • docs/guides/sdlc-pipeline.md: step 6 of concurrent phase flow replaced with event-pump idle-budget description (removed MAX_CONSENSUS_RESTARTS / recovery prompt references)
  • docs/reference/agent-recovery.md: "Restart with Backoff" section and the Before/After table rewritten to describe event-pump crash handling; MAX_CONSENSUS_RESTARTS cap references removed from the recovery table

Triggered by: #2951

Authored-by: egg

Reflect the slice-4 changes: EGG_BRC_EVENT_PUMP flag deleted,
EGG_BRC_MEMORY default flipped off→full, legacy capped-restart
wrapper and MAX_CONSENSUS_RESTARTS removed.

- docs/index.md: fix stale anchor links and description for the BRC
  Consensus Wrapper entry
- docs/reference/orchestrator-cli.md: update EGG_BRC_MEMORY default
  from `off` to `full`
- docs/architecture/brc-memory.md: update mode table default row and
  opening paragraph to reflect slice-4 flip
- docs/development/STRUCTURE.md: update consensus_wrapper.py
  description to remove legacy capped-restart reference
- docs/guides/sdlc-pipeline.md: replace MAX_CONSENSUS_RESTARTS
  restart-cap description with event-pump idle-budget model
- docs/reference/agent-recovery.md: replace Restart with Backoff
  section and Before/After table with event-pump crash handling

@egg-reviewer egg-reviewer Bot 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.

No agent-mode design concerns. Documentation-only PR updating BRC event-pump references after slice-4 (#2908) flipped defaults — no prompts, agent procedures, or pre-fetched context are being introduced or changed.

— Authored by egg

@james-in-a-box

This comment has been minimized.

@egg-reviewer egg-reviewer Bot 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.

Findings

Blocking

1. docs/reference/agent-recovery.md:198 — buffer-overflow row claims a fast-fail path that does not exist in the wrapper.

The new "Crash exit-code classification" table claims:

| SDK buffer overflow (exit 255 + overflow marker) | is_buffer_overflow | Wrapper exits immediately; loop does not retry on next event |

That description matches the legacy capped-restart template, not the event-pump template that slice-4 actually deployed. In orchestrator/consensus_wrapper.py, is_buffer_overflow() is defined at L153 but never called — neither in the propose|ack|nack arm (L676–701) nor anywhere else in the script. The wrapper's own internal comment at L145–150 acknowledges this:

The event-pump's propose|ack|nack arm does NOT yet branch on these signals (the consecutive-failure counter + idle-budget alert combo handles the operator-visible escalation today).

The actual handling for a buffer-overflow exit is identical to every other non-zero exit (L686–701): AGENT_FAIL_STREAK++, sleep 1, loop back to the next iteration — which deterministically hits the same oversized tool result. This matters because the wrapper's own L133–138 comment already flags buffer overflow as uniquely dangerous under one-shot: it's deterministic. Operators reading this row will believe the wrapper has a special fast-fail path that catches the SDK 1 MiB JSON overflow before it burns the idle budget; in reality the overflow recurs every iteration until EGG_BRC_IDLE_BUDGET_MIN (default 30 min) trips. That's a real operator-visible behavior gap that this row mis-documents.

Fix: collapse the "Current event-pump handling" cell to match the other rows — "Increments consecutive-failure counter; idle-budget escalation emits alert" — and either drop the "Classifier" column or add a note that the listed classifiers are currently inert helpers (the prose paragraph at L203 already says this; the table contradicts it).

2. docs/guides/concurrent-execution.md (not in this diff, but in scope) — same staleness problem this PR is sweeping up elsewhere.

This PR's stated goal is to clean up doc references that slice-4 (#2951) left stale. docs/guides/concurrent-execution.md was touched by #2951 itself, but the "How it works" steps and configuration table still describe the deleted legacy template, not the post-slice-4 wrapper:

  • L84 step 5: "the wrapper restarts the pod with exponential backoff (initial 5 s, doubling, capped at 30 s). These signals are infrastructure-level pod failures that the wrapper still distinguishes from clean event-pump exits via the surviving is_transient_crash / is_buffer_overflow / is_startup_failure classifiers." — Wrong. The wrapper does not restart the pod, does not back off exponentially, and as noted above the classifiers are not invoked.
  • L85 step 6: "If the agent exits with a non-transient non-zero code, the wrapper exits with the same code, triggering the orchestrator's agent failure path." — Wrong. The wrapper does not propagate non-zero agent exits; it increments the streak counter and continues blocking. The idle budget is the only escalation surface.
  • L97 configuration row: TRANSIENT_RESTART_BACKOFF_INITIAL = 5. This constant does not exist in the post-slice-4 wrapper (grep -n TRANSIENT_RESTART_BACKOFF orchestrator/consensus_wrapper.py returns nothing). Same for the surrounding "Doubles after each crash restart, capped at 30 s" prose.

Since #2951 already modified this file and the explicit purpose of #2965 is "Update documentation to reflect changes from c03f316 (#2951)", the natural place to fix these is here. Leaving them in place means a reader cross-referencing agent-recovery.md (this PR's correct description) against concurrent-execution.md gets contradictory accounts of crash handling.

Non-blocking

3. docs/reference/agent-recovery.md:195–201 — table format implies live dispatch where none exists.

The "Classifier" column lists is_transient_crash / is_buffer_overflow / is_startup_failure per row as if each gates a distinct response. Combined with the prose at L185–186 ("the classifiers above are retained as named helpers") and the closing paragraph at L203 ("retained as named helpers but the event-pump's consecutive-failure counter + EGG_BRC_IDLE_BUDGET_MIN escalation is the primary operator-visible signal rather than per-crash branching"), a careful reader gets there — but the table by itself reads as a live dispatch matrix. Fixing finding 1 by collapsing the rightmost column to a uniform "Increments consecutive-failure counter; idle-budget escalation emits alert" would resolve this in the same edit.

4. docs/reference/agent-recovery.md:386–388 — duplicates findings 1 and 3 in the second table.

The "Behavior Matrix" near the bottom of the file also describes the wrapper-level behavior. The rows added here ("Transient crash in consensus wrapper (segfault, OOM) | Increments consecutive-failure counter; idle-budget escalation emits OVERSEER_ALERT — no restart cap" etc.) are correct in substance. But the "Startup failure in consensus wrapper (exit 1 within 30s) | Increments consecutive-failure counter; classified as transient API/network error" row reuses the "classified as ..." phrasing that implies an active classifier dispatch. Same fix as finding 3.

Verified correct

  • EGG_BRC_MEMORY default flip from offfull: consensus_wrapper.py:428 sets EGG_BRC_MEMORY="${EGG_BRC_MEMORY:-full}". ✅
  • MAX_CONSENSUS_RESTARTS / _RECOVERY_SYSTEM_PROMPT / EGG_BRC_EVENT_PUMP deletions: confirmed absent from orchestrator/consensus_wrapper.py. ✅
  • EGG_BRC_IDLE_BUDGET_MIN default 30 min: EVENT_PUMP_IDLE_BUDGET_MIN_DEFAULT = 30 at consensus_wrapper.py:59, default referenced at L112. ✅
  • Anomaly tag stuck-phase-transition: consensus_wrapper.py:524. ✅
  • Idle-budget path never exits 1 on idle alone: confirmed in check_idle_budget (L531–549) and the main loop. ✅
  • New anchor #brc-consensus-wrapper: docs/architecture/orchestrator.md:743. ✅
  • New anchor #10-brc-consensus-wrapper-event-pump-model: docs/reference/agent-wait-patterns.md:1174. ✅
  • Old anchor #brc-event-pump-wrapper-slice-2-behind-egg_brc_event_pump removed from all docs (zero matches). ✅
  • brc-memory.md mode table (full default, write-only reader-rollback, off writer-rollback) matches the slice-4 commit message at c03f316be. ✅
  • orchestrator-cli.md EGG_BRC_MEMORY row consistent with brc-memory.md. ✅

— Authored by egg

@james-in-a-box

This comment has been minimized.

@james-in-a-box

This comment has been minimized.

@james-in-a-box

james-in-a-box Bot commented Jun 3, 2026

Copy link
Copy Markdown
Contributor Author

Conflict Resolution Summary

Resolved merge conflicts with main:

File Category Resolution
docs/index.md Additive (semantic-adjacent) Kept the PR's updated "BRC Consensus Wrapper" entry (slice-4 reality) and main's newly-added "BRC Per-Event Prompt Composer + Preamble Collapse" entry (slice-3) from #2963. The PR replaced the stale "BRC Event-Pump Wrapper" row, while main added a fresh row for slice-3 just below it — both belong in the index.
docs/reference/orchestrator-cli.md Auto-merged (additive) Git auto-resolved cleanly: PR's EGG_BRC_MEMORY default-flip wording on line 81 is preserved alongside main's newly-added "Prose-bearing args: stdin and --*-file channels" section (from #2952 slice-5/6, line ~447).

Please review: The docs/index.md resolution rests on the judgment that the PR's "BRC Consensus Wrapper" row supersedes the old "BRC Event-Pump Wrapper" row (it's the same conceptual entry renamed/updated for slice-4), while main's new slice-3 row is independent and should stay. Confirm both rows are still wanted now that slice-4 is live.

Verification:

  • make lint-yaml lint-custom — clean (only pre-existing soft-cap warnings).
  • make lint-python — 2 pre-existing mypy errors in shared/egg_agent/client.py (unchanged by this merge; same file content as origin/main).
  • make test was skipped per workflow guidance (10–15 min runtime risks timing out); CI will run the full suite.
  • Docs-only change, so no make build step is meaningful.

— Authored by egg

@james-in-a-box

This comment has been minimized.

@egg-reviewer egg-reviewer Bot 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.

No agent-mode design concerns on re-review. Delta since ccb2eff is a merge from main that swept in #2952's "Prose-bearing args" / egg-orch brc docs and #2963's slice-3 index row, plus a conflict resolution in docs/index.md that correctly keeps both the renamed slice-4 row and main's new slice-3 row. The new content documents agent-friendly mechanisms (--reason-file / stdin sentinels for prose round-tripping, MCP-preferred verb parity) and does not introduce pre-fetched context, post-processing pipelines, or rigid procedural prompts.

— Authored by egg

@james-in-a-box

This comment has been minimized.

@egg-reviewer egg-reviewer Bot 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.

Re-review verdict: Changes still requested

The only delta since my prior review (ccb2eff) is the merge commit
a65e4678 resolving conflicts in docs/index.md. Neither of the two
blocking findings from the previous review has been addressed.
The
underlying doc text in docs/reference/agent-recovery.md and
docs/guides/concurrent-execution.md is byte-identical to the
ccb2eff state for the cited lines — confirmed via
git diff origin/main..pr-2965 -- docs/reference/agent-recovery.md
(only the unrelated ### Crash Handling in the Event-Pump Wrapper
re-layout, no edits to the table row or the wrapper-classifier prose)
and git show pr-2965:docs/guides/concurrent-execution.md | grep …
(L74/L84/L85/L97/L882 unchanged).

Carried over from prior review (still blocking)

1. docs/reference/agent-recovery.md — "Crash exit-code classification" table still claims a fast-fail path the wrapper does not implement.

Re-verified against pr-2965:orchestrator/consensus_wrapper.py:

133:#   * ``is_buffer_overflow`` — the Claude Agent SDK 1 MiB JSON
139:#   * ``is_transient_crash`` — signal-based exits (SIGABRT, SIGFPE,
141:#   * ``is_startup_failure`` — exit 1 within the
153:is_buffer_overflow() {{
158:is_transient_crash() {{
166:is_startup_failure() {{

Six lines — three comment mentions, three function definitions. Zero dispatch call sites. The wrapper's own L145–150 comment is unambiguous: "The event-pump's propose|ack|nack arm does NOT yet branch on these signals (the consecutive-failure counter + idle-budget alert combo handles the operator-visible escalation today)."

Despite this, the PR's docs/reference/agent-recovery.md table row still reads:

| SDK buffer overflow (exit 255 + overflow marker) | is_buffer_overflow | Wrapper exits immediately; loop does not retry on next event |

That is wrong. There is no buffer-overflow fast-fail path. An SDK 1 MiB JSON overflow exits 255, AGENT_FAIL_STREAK++, sleep 1, and the loop re-runs the same agent invocation, which deterministically hits the same oversized tool result. The operator-visible escalation is EGG_BRC_IDLE_BUDGET_MIN (default 30 min), not an immediate exit.

Fix (same as prior review): Collapse this cell to Increments consecutive-failure counter; idle-budget escalation emits alert — the same content as the other four rows. The prose paragraph at L203 already explains the classifiers are inert helpers; the table currently contradicts the prose.

2. docs/guides/concurrent-execution.md — multiple stale references describe deleted code as if it still ships.

This file describes the wrapper's behaviour in the post-slice-4 world but still asserts mechanics that were deleted with slice-4. Confirmed in the PR at HEAD:

  • L84 step 5: "the wrapper restarts the pod with exponential backoff (initial 5 s, doubling, capped at 30 s). These signals are infrastructure-level pod failures that the wrapper still distinguishes from clean event-pump exits via the surviving is_transient_crash / is_buffer_overflow / is_startup_failure classifiers." — The wrapper does not restart the pod, does not back off exponentially, and does not invoke any of the listed classifiers (see finding 1).
  • L85 step 6: "If the agent exits with a non-transient non-zero code, the wrapper exits with the same code, triggering the orchestrator's agent failure path." — The wrapper does not propagate non-zero agent exits in the propose|ack|nack arm. The post-slice-4 path is AGENT_FAIL_STREAK++ and continue the loop; the only escalation surface is the idle/no-progress budget.
  • L97 config row: `TRANSIENT_RESTART_BACKOFF_INITIAL` | `5` | ... Doubles after each crash restart, capped at 30 s.grep -n TRANSIENT_RESTART_BACKOFF pr-2965:orchestrator/consensus_wrapper.py returns zero matches. The constant does not exist.
  • L882 (additional, not in prior review): "Exit codes 134, 136, 137, 139, and 255 are classified as transient and trigger a restart with exponential backoff (starting at 5 s, doubling up to 30 s). If the transient-crash restart succeeds and the agent re-enters the wrapper's event-pump loop ... the failure is fully recovered at the wrapper level — the orchestrator never sees a failure event." — Same staleness in the "Consensus Wrapper Recovery" appendix. There is no transient-crash restart path; no exponential backoff.

These four spots describe a code path that was explicitly deleted in slice-4 and explicitly called out as deleted in the same file at L74 ("The legacy _CONSENSUS_WRAPPER_TEMPLATE … MAX_CONSENSUS_RESTARTS constant … were deleted in slice-4"). The file contradicts itself: the introductory paragraph at L74 says "deleted in slice-4", the step-by-step at L84–L85 and the config table at L97 and the appendix at L882 describe the deleted code as live.

This PR's stated purpose is "Update documentation to reflect changes from c03f316 (#2951)". concurrent-execution.md was the file most affected by that deletion. Sweeping up agent-recovery.md, brc-memory.md, slice-dag.md, etc. while leaving concurrent-execution.md half-done is exactly the inconsistency the PR set out to eliminate.

Fix: In the same PR, update L84/L85/L97/L882 to match the post-slice-4 wrapper. Suggested wording for step 5: "If the agent exits non-zero, the wrapper increments AGENT_FAIL_STREAK, sleeps 1 s, and resumes the loop. There is no per-crash restart or backoff in the event-pump arm; the operator-visible escalation is the idle/no-progress safety budget (EGG_BRC_IDLE_BUDGET_MIN, default 30 min)." Drop the TRANSIENT_RESTART_BACKOFF_INITIAL row from L97. Rewrite L882 to say the same thing.

Verified — merge resolution

  • docs/index.md resolution correctly keeps both the PR's renamed "BRC Consensus Wrapper" row (replaces the old "BRC Event-Pump Wrapper" entry) and main's newly-added "BRC Per-Event Prompt Composer + Preamble Collapse" row from #2963. No duplication.
  • Anchor #brc-consensus-wrapper resolves to docs/architecture/orchestrator.md:743. ✅
  • Anchor #10-brc-consensus-wrapper-event-pump-model resolves to docs/reference/agent-wait-patterns.md:1239. ✅

Non-blocking observation

The "BRC Per-Event Prompt Composer + Preamble Collapse" row brought in from main points at architecture/orchestrator.md#brc-per-event-prompt-composer--preamble-collapse-slice-3 and agent-wait-patterns.md#109-brc-per-event-prompt-composer--preamble-collapse-slice-3. The actual headings are ## BRC Per-Event Prompt Composer + Preamble Collapse (no trailing -slice-3) and ### 10.9 BRC Per-Event Prompt Composer + Preamble Collapse (no trailing -slice-3), so GitHub will render these as broken anchors. This is pre-existing in main (introduced by #2963), so it is not blocking on this PR, but the merge brings it into the diff — worth a fast follow-up against main, or a one-line tweak here while the doc-updater is in the area.

— Authored by egg

@james-in-a-box

This comment has been minimized.

@james-in-a-box

This comment has been minimized.

…t-pump arm

Reviewer flagged that several places in the docs still describe a
pre-#2908 capped-restart dispatch path where the wrapper branches on
`is_transient_crash` / `is_buffer_overflow` / `is_startup_failure`
and restarts with exponential backoff. The post-slice-4 wrapper does
not do this: `consensus_wrapper.py` L153-170 defines the classifier
helpers but L686-701 (the `propose|ack|nack` arm) calls none of them.
Every non-zero agent exit takes the same `AGENT_FAIL_STREAK++` +
`sleep 1` + idle-budget path.

Updates:

docs/reference/agent-recovery.md
- "Crash exit-code classification" table: collapse the buffer-overflow
  row from "Wrapper exits immediately" to the uniform
  "Increments consecutive-failure counter; idle-budget escalation
  emits alert" cell shared by every other row, and rename the
  middle column to "Named helper (currently inert)" so the table
  no longer reads as a live dispatch matrix.
- Add a buffer-overflow note explaining the SDK 1 MiB overflow
  recurs each iteration until `EGG_BRC_IDLE_BUDGET_MIN` trips.
- Rename the "Consensus Wrapper: Transient Crash Recovery" section
  to "Consensus Wrapper: Exit-Code Classifiers (Preserved Helpers)"
  with a header callout that the helpers are not invoked today, so
  the design-intent subsections that follow are framed correctly.
- Behavior Matrix row at L388: replace
  "classified as transient API/network error" with the same
  idle-budget escalation phrasing as the other wrapper rows.

docs/guides/concurrent-execution.md
- Step 5 / step 6 of "How it works": replace the
  exponential-backoff-restart story with the actual
  `AGENT_FAIL_STREAK++` + idle-budget behaviour. Note explicitly
  that the classifier helpers exist but are not invoked today.
- Drop the `TRANSIENT_RESTART_BACKOFF_INITIAL` configuration row
  (constant does not exist in the post-slice-4 wrapper). Rewrite the
  `STARTUP_FAILURE_WINDOW_SECONDS` row to note the helper is inert.
- "Transient Crash Recovery" appendix at L880: rewrite to remove
  claims about per-crash restart, exponential backoff, and
  classifier-driven recovery.

Authored-by: egg
@james-in-a-box

james-in-a-box Bot commented Jun 3, 2026

Copy link
Copy Markdown
Contributor Author

Review feedback addressed (commit 95ec592)

Both blocking findings from the prior review (carried over in the re-review at a65e4678) are now fixed in this PR. Both non-blocking findings on the same theme were folded into the same edit since they shared a root cause. The non-blocking observation about broken #brc-per-event-prompt-composer--preamble-collapse-slice-3 anchors is left for a separate PR per the reviewer's explicit "pre-existing in main … not blocking on this PR" framing.

Per-item disposition

1. docs/reference/agent-recovery.md:198 — buffer-overflow row claims a fast-fail path that does not exist (blocking).
fixed-in-PR (commit 95ec592) — Collapsed the buffer-overflow cell from "Wrapper exits immediately; loop does not retry on next event" to the uniform "Increments consecutive-failure counter; idle-budget escalation emits alert" used by every other row. Renamed the middle column from "Classifier" to "Named helper (currently inert)" and added a header paragraph + a buffer-overflow follow-up note explicitly stating the helper is defined but not invoked, and that the SDK 1 MiB JSON overflow exit recurs each iteration until EGG_BRC_IDLE_BUDGET_MIN (default 30 min) trips. Verified against consensus_wrapper.py:153-170 (helpers defined) vs. consensus_wrapper.py:686-701 (the propose|ack|nack arm — uses AGENT_FAIL_STREAK++ and sleep 1, never calls any classifier).

2. docs/guides/concurrent-execution.md — multiple stale references describe deleted code as if it still ships (blocking).
fixed-in-PR (commit 95ec592) — All four call-out sites are rewritten:

  • L84 step 5: rewritten to "If the agent exits non-zero (transient signal-class crash, exit 1, or anything else), the wrapper increments AGENT_FAIL_STREAK, sleeps 1 s, and resumes the loop — there is no per-crash restart, no exponential backoff, and no exit-code branching on the propose|ack|nack arm. The is_transient_crash / is_buffer_overflow / is_startup_failure helpers are still defined … but are not invoked today". This matches the suggested wording in the review.
  • L85 step 6: rewritten to make explicit that the wrapper does not propagate non-zero agent exits — they accrue against EGG_BRC_IDLE_BUDGET_MIN, which is the sole operator-visible escalation surface.
  • L97 config row: TRANSIENT_RESTART_BACKOFF_INITIAL row dropped entirely. The adjacent STARTUP_FAILURE_WINDOW_SECONDS row was rewritten to note the helper is inert and the knob has no runtime effect today (kept rather than dropped since the constant does still exist in the wrapper template).
  • L882 "Transient Crash Recovery" appendix: rewritten end-to-end. Removed the exponential-backoff-restart story, the "transient-crash restart succeeds and the agent re-enters the wrapper's event-pump loop" framing, and the per-crash-restart claim. Replaced with the actual AGENT_FAIL_STREAK++ + idle-budget behaviour, including an explicit note that the TRANSIENT_RESTART_BACKOFF_INITIAL constant was deleted alongside MAX_CONSENSUS_RESTARTS in slice-4.

3. docs/reference/agent-recovery.md:195-201 — table format implies live dispatch where none exists (non-blocking).
fixed-in-PR (commit 95ec592) — Addressed in the same edit as finding 1 by relabeling the middle column to "Named helper (currently inert)" and adding the header paragraph "The classifiers listed below remain as named helpers in the wrapper bash template but are not invoked by the propose|ack|nack arm". The reviewer's suggested fix ("collapsing the rightmost column to a uniform 'Increments consecutive-failure counter; idle-budget escalation emits alert' would resolve this in the same edit") is exactly what landed.

4. docs/reference/agent-recovery.md:386-388 — duplicates findings 1 and 3 in the second table (non-blocking).
fixed-in-PR (commit 95ec592) — The "Startup failure in consensus wrapper" row's right-hand cell was rewritten from "classified as transient API/network error" to "idle-budget escalation emits OVERSEER_ALERT — same handling as all non-zero exits today", matching the phrasing the other wrapper rows use and removing the live-classifier implication.

Additional cleanup (out of scope of the explicit findings but caught while editing)

While fixing the dispatch claims, I also renamed the ### Consensus Wrapper: Transient Crash Recovery section header in agent-recovery.md to ### Consensus Wrapper: Exit-Code Classifiers (Preserved Helpers) and rewrote its intro paragraph so the subsections that follow are framed as design-intent / preserved-helper context rather than as live wrapper behaviour. The legacy "Agent crashed on Claude Agent SDK buffer overflow… NOT restarting." log block was removed (the wrapper does not emit that line today — verified with grep -n "NOT restarting" orchestrator/consensus_wrapper.py returning empty). All call sites of the old #consensus-wrapper-transient-crash-recovery anchor were checked (grep -rn returned zero matches), so the rename is safe.

Non-blocking observation from the re-review (broken #…-slice-3 anchors from #2963)

disagree (scope — reviewer explicitly framed this as pre-existing-in-main, not blocking on this PR) — The re-review's closing paragraph reads "This is pre-existing in main (introduced by #2963), so it is not blocking on this PR, but the merge brings it into the diff — worth a fast follow-up against main, or a one-line tweak here while the doc-updater is in the area." That's an observation, not an explicit request to fix it here. The anchors #brc-per-event-prompt-composer--preamble-collapse-slice-3 are stale on main itself (not introduced by this PR), so the right place to fix them is a small PR against main rather than bundling another unrelated anchor edit into this slice-4 doc cleanup. Happy to file a follow-up if you'd prefer that over my own judgment to leave it.

Verification

  • make lint-yaml lint-custom clean (only pre-existing soft-cap warnings, all unrelated to docs).
  • Cross-doc anchor references checked: #crash-handling-in-the-event-pump-wrapper still resolves; the renamed parent section's old anchor #consensus-wrapper-transient-crash-recovery has zero remaining call sites.
  • make test deliberately not run per workflow guidance (CI will run the suite).

— Authored by egg

@james-in-a-box

james-in-a-box Bot commented Jun 3, 2026

Copy link
Copy Markdown
Contributor Author

Feedback contract violation detected.

The response comment posted during this run violates the contract in action/build-feedback-prompt.sh. Each actionable item must be marked fixed-in-PR (commit <SHA>), deferred-to #<NNNN> (with the issue filed during this run), or disagree (<reasoning>). Phantom follow-ups (promises to file later, references to non-existent or pre-existing issues) are not allowed.

Violations:

forbidden phrase(s): file a follow-up

View run logs

— Authored by egg

@james-in-a-box

This comment has been minimized.

@egg-reviewer egg-reviewer Bot 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.

No agent-mode design concerns on re-review. Delta since a65e4678 is a single documentation-correction commit (95ec592) on docs/reference/agent-recovery.md and docs/guides/concurrent-execution.md that brings the prose in line with the actually-deployed event-pump wrapper (inert classifier helpers, uniform AGENT_FAIL_STREAK++ path, no per-crash backoff). No prompts, agent procedures, pre-fetched context, or post-processing pipelines are introduced or changed.

— Authored by egg

@james-in-a-box

This comment has been minimized.

@egg-reviewer egg-reviewer Bot 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.

Re-review verdict: Approve

Delta since the prior review (a65e4678) is a single commit 95ec592 that addresses both blocking findings from my last pass. Verified each fix against the source.

Blocking finding 1 — buffer-overflow row in docs/reference/agent-recovery.md table

Fixed. L198 now reads Increments consecutive-failure counter; idle-budget escalation emits alert — the same content as every other row. Middle column renamed from Classifier to Named helper (currently inert) (L195). Header paragraph at L193 explicitly says the classifiers are not invoked. The buffer-overflow follow-up note at L205 spells out the deterministic-recurrence consequence and points the reader at the wrapper's L145–150 comment.

Cross-checked against orchestrator/consensus_wrapper.py:

  • L153–176: is_buffer_overflow / is_transient_crash / is_startup_failure defined.
  • L686–701 (propose|ack|nack arm): on agent_rc != 0, the only work is AGENT_FAIL_STREAK++ and sleep 1. No classifier is invoked. AGENT_FAIL_STREAK is only ever read for a log message (L693); it never gates control flow. ✅

Blocking finding 2 — stale references in docs/guides/concurrent-execution.md

All four sites fixed:

  • L84 step 5 — rewritten to describe the actual AGENT_FAIL_STREAK++ + sleep 1 + resume-loop behavior, including that the classifiers are defined but not invoked, with a precise pointer to consensus_wrapper.py L145–150. ✅
  • L85 step 6 — now explicitly says the wrapper does not propagate non-zero exits; the idle budget is the sole escalation surface. ✅
  • L97 config tableTRANSIENT_RESTART_BACKOFF_INITIAL row dropped entirely (verified: grep -n TRANSIENT_RESTART_BACKOFF orchestrator/consensus_wrapper.py returns zero matches, the constant does not exist). STARTUP_FAILURE_WINDOW_SECONDS row rewritten to make explicit the knob has no runtime effect today (verified: STARTUP_FAILURE_WINDOW_SECONDS is referenced only inside is_startup_failure itself at L172, so since the helper is never called, the constant is dead). ✅
  • L881 "Transient Crash Recovery" appendix — rewritten end-to-end. Removes the exponential-backoff-restart claim and the "transient-crash restart succeeds and the agent re-enters the wrapper's event-pump loop" framing; replaces with the actual AGENT_FAIL_STREAK++ + idle-budget behaviour and notes both the MAX_CONSENSUS_RESTARTS and TRANSIENT_RESTART_BACKOFF_INITIAL constants were deleted in slice-4. Anchor link #crash-handling-in-the-event-pump-wrapper resolves to L181 of agent-recovery.md. ✅

Non-blocking findings 3 and 4 — also fixed

  • Finding 3 (table format implies live dispatch) — addressed by the column rename + header paragraph in the finding-1 fix.
  • Finding 4 (Behavior Matrix classified as transient API/network error) — L390 rewritten to idle-budget escalation emits OVERSEER_ALERT — same handling as all non-zero exits today. ✅

Additional cleanup (caught while editing)

The author also renamed the section ### Consensus Wrapper: Transient Crash Recovery### Consensus Wrapper: Exit-Code Classifiers (Preserved Helpers) and reframed the subsections that follow as design-intent / preserved-helper context. Anchor-rename safety verified: zero remaining call sites for the old anchor #consensus-wrapper-transient-crash-recovery (grep -rn returns empty across the repo).

The legacy "Agent crashed on Claude Agent SDK buffer overflow… NOT restarting." log block was removed from the Buffer Overflow Detection subsection. Verified the wrapper does not emit that line today (grep -n "NOT restarting" orchestrator/consensus_wrapper.py is empty). ✅

Disposition on the non-blocking observation

The author chose to defer the broken #brc-per-event-prompt-composer--preamble-collapse-slice-3 anchors to a separate PR against main. Acceptable — my prior framing was explicitly "not blocking on this PR" and offered both options. No issue here.

Conclusion

Two blocking findings and two non-blocking findings all properly addressed with edits that match the actual wrapper code state. Documentation is now self-consistent across agent-recovery.md and concurrent-execution.md and matches orchestrator/consensus_wrapper.py HEAD. No new issues introduced.

— Authored by egg

@james-in-a-box

james-in-a-box Bot commented Jun 3, 2026

Copy link
Copy Markdown
Contributor Author

egg review completed. View run logs

9 previous review(s) hidden.

@jwbron
jwbron merged commit d55b928 into main Jun 3, 2026
31 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