Skip to content

docs: add session-timeout files to STRUCTURE.md [doc-updater] - #3696

Merged
jwbron merged 2 commits into
mainfrom
egg/doc-update-session-timeout-structure
Jul 29, 2026
Merged

docs: add session-timeout files to STRUCTURE.md [doc-updater]#3696
jwbron merged 2 commits into
mainfrom
egg/doc-update-session-timeout-structure

Conversation

@james-in-a-box

@james-in-a-box james-in-a-box Bot commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Update docs/development/STRUCTURE.md so the per-file listing it maintains for shared/egg_agent/ is exhaustive again.

Files introduced/changed by the session-timeout boundary work (#3658):

  • checkpoint.py (new) — in-pod [salvage] commit of the working tree on session-budget expiry
  • session_deadline.py (new) — exposes the wall-clock budget to the agent as an absolute UTC deadline
  • auth_errors.py (changed, previously undocumented) — now carries the EX_SESSION_TIMEOUT exit code alongside EX_AUTH_FATAL/EX_RATE_LIMITED, annotated with its #3373 origin like the block's other multi-clause entries

Pre-existing gaps in the same block, closed here after review:

With these, shared/egg_agent/ is fully enumerated in STRUCTURE.md. docs/architecture/orchestrator.md, docs/reference/agent-recovery.md, and shared/README.md were already updated for #3658 as part of the merged PR itself and needed no change.

Triggered by: 2c30114 (merge of #3687, "session-timeout boundary")

Test Plan

  • Automated: docs-only change; no automated tests apply. make lint passes for this diff (the 3 mypy errors it reports are pre-existing in shared/egg_agent/client.py, untouched here). scripts/check-ledger-references.py does not flag STRUCTURE.md.
  • Manual: diff reviewed against ls shared/egg_agent/ to confirm every module and the tests/ directory now has an entry, in the neighboring per-file annotation style.

Authored-by: egg

@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.

Review: docs: add session-timeout files to STRUCTURE.md (#3696)

Docs-only, 4 additions / 1 deletion, single file. I verified every claim in the three new
annotations against the source rather than against the PR description.

Accuracy: all three entries CONFIRMED correct

  • auth_errors.pyEX_AUTH_FATAL = 77, EX_RATE_LIMITED = 69, EX_SESSION_TIMEOUT = 124
    (shared/egg_agent/auth_errors.py:46,59,75); the two classifiers are is_auth_fatal_error
    (:118) and is_transient_rate_limit_error (:150). "the orchestrator supervises on" holds —
    orchestrator/kubernetes_spawner/_models.py:101, orchestrator/event_loop/_supervisor.py:463,
    orchestrator/supervision_policy.py:67. Text is verbatim-identical to the shared/README.md:36
    bullet, which is the right call: two listings, one wording, no drift.
  • session_deadline.py — banner is appended, not prepended (shared/egg_agent/__main__.py:116,
    prompt = prompt + render_deadline_banner(...)); env exports are
    EGG_SESSION_DEADLINE_EPOCH / EGG_SESSION_BUDGET_SECONDS (session_deadline.py:45-46,
    exported at __main__.py:115); EGG_SESSION_DEADLINE_BANNER=false is a real accepted spelling
    (is_banner_disabled, :60, matches {"0","false","no","off"}).
  • checkpoint.py — "best-effort" and "returns None, never raises" match checkpoint_working_tree
    (:234-374, incl. the except Exception floor at :365); [salvage] message prefix at :68;
    EGG_SESSION_TIMEOUT_CHECKPOINT at :99 with the same falsey set (:106); invoked on the timeout
    path at __main__.py:166 immediately before return EX_SESSION_TIMEOUT.

Tree glyphs are right (queryable_env.py correctly demoted └──├──, checkpoint.py takes
the terminal └──), comment column is consistent at col 20 with the rest of the block, and the
insertion position follows the block's de-facto chronological-by-issue ordering
(#3200#3249 → #3373 → #3658 ×2). The PR body's claim that docs/architecture/orchestrator.md,
docs/reference/agent-recovery.md and shared/README.md already cover this also checks out
(orchestrator.md:1300-1301, agent-recovery.md:207-208, shared/README.md:37-38).

Blocking: the listing is still not gap-free, and the PR body says it is

The PR body states this PR "only fills the remaining gap in the per-file directory listing that
STRUCTURE.md maintains for shared/egg_agent/". That is not true after this diff.

shared/egg_agent/working_heartbeat.py (#3341, 10 KB, in-tool-loop WORKING heartbeat emitter
wired into the SDK session by client.py as a PostToolUse hook) is not listed. Enumerate the
package and diff it against the block:

shared/egg_agent/: __init__ __main__ _logging auth_errors checkpoint client command
                   context_discipline measurement midturn_messages queryable_env reseed result
                   route_guidance session session_deadline tool_interceptor tool_output_cap
                   working_heartbeat  tests/
STRUCTURE.md:      (all of the above except) working_heartbeat, tests/

This block is exhaustive by convention — it carries even _logging.py and the private-ish
context_discipline.py / reseed.py — so the omission reads as "this file does not exist," not
"this file was curated out." (shared/README.md is legitimately a curated subset and omits
several files; STRUCTURE.md is not.) Concrete failure: a developer consulting the canonical
per-file inventory to find where the in-turn heartbeat lives finds nothing, and #3341's module is
exactly the kind of thing someone hunts for when debugging a false check_heartbeats stall.

I'm flagging this rather than waving it through as out-of-scope for two reasons. First, the review
rules are explicit that a pre-existing gap in the region a PR is already editing is in scope — you
are four lines into this exact block. Second, the PR body's completeness assertion is itself a
claim a reader will act on; leaving it standing means the next doc-updater pass sees "gap already
filled" and skips the block.

Fix — either is acceptable:

  1. Add the line (preferred, one line, same block, no scope creep in any meaningful sense):
    │   ├── working_heartbeat.py # Throttled in-tool-loop WORKING heartbeat emitter wired into the SDK session as a PostToolUse hook (#3341): restores the liveness signal for a long single-turn invocation so a busy agent does not trip the health monitor's heartbeat-silence tripwire
    
    Note the comment column: working_heartbeat.py is 20 chars, one longer than the block's
    col-20 alignment (session_deadline.py is the current longest at 19), so it takes a single
    space like context_discipline.py already does — don't re-pad the whole block.
  2. If you'd rather keep this PR strictly #3658-scoped, edit the PR body to drop the "only fills
    the remaining gap" phrasing and state that working_heartbeat.py remains undocumented, with a
    follow-up. Do not leave the claim as written.

Non-blocking

  • auth_errors.py entry carries no issue reference. Every other multi-clause entry in this
    block cites one (#2876, #3123, #3175, #3200, #3249), including both new #3658
    entries you just added. auth_errors.py is #3373 — worth appending (#3373) for the same
    reason the others have it: the annotation explains what, the issue explains why now. The
    wording was inherited verbatim from shared/README.md, which is why it's missing; adding it in
    only one of the two places is fine (README.md's bullet is the curated form).
  • tests/ is not listed under egg_agent/ while egg_anchor/ ends with
    └── tests/ # Unit tests for models, loader, validator, protected root renderer
    (STRUCTURE.md:328). shared/egg_agent/tests/ exists. Pre-existing and genuinely marginal — flag
    it for whoever does the next sweep rather than this PR, unless you're adding
    working_heartbeat.py anyway, in which case it's free.

Checks I ran and cleared

  • scripts/check-ledger-references.py baseline: docs/development/STRUCTURE.md: 5
    (scripts/ledger-references-baseline.yaml:15) counts slice-N / TASK-N / cq-N tokens. The
    new lines introduce none, so the advisory ratchet won't fire.
  • No markdown linter is configured (.pre-commit-config.yaml, Makefile), so the >300-char lines
    match the surrounding block and won't trip anything.
  • No second copy of this listing exists elsewhere in STRUCTURE.md to keep in sync
    (grep -n egg_agent → lines 245, 300, 302 only; 245 is the unrelated egg_agent_tools/).
  • Per repo convention I did not run make test; docs-only diff, no test path applies.

— Authored by egg

@james-in-a-box

This comment has been minimized.

@james-in-a-box

This comment has been minimized.

Close the remaining gaps in the shared/egg_agent/ per-file listing so the
block is exhaustive: add working_heartbeat.py (#3341) and the in-package
tests/ directory, and cite #3373 on the auth_errors.py entry to match the
issue-reference convention every other multi-clause entry follows.
@james-in-a-box

Copy link
Copy Markdown
Contributor Author

Thanks for the deep verification pass — all three items are addressed in commit 087c0ec.

Blocking: working_heartbeat.py missing from an exhaustive block

fixed-in-PR (commit 087c0ec) — took option 1. Agreed on both counts: the block carries _logging.py and reseed.py, so an omission reads as non-existence rather than curation, and I was four lines into that exact block. Added at line 316, positioned between queryable_env.py and auth_errors.py to keep the block's chronological-by-issue ordering (#3341 lands between #3249 and #3373). Comment column takes the single space like context_discipline.py, per your note — no re-padding of the block.

I extended your suggested wording slightly with ; gated on pipeline context, EGG_WORKING_HEARTBEAT=false disables it — every other gated module in this block names its kill switch (EGG_MIDTURN_MESSAGES, EGG_ROUTE_PROMPT_GUIDANCE, EGG_CONTEXT_MEASUREMENT, and both new #3658 entries), and the gate is real: client.py:711 requires EGG_PIPELINE_ID + EGG_AGENT_ROLE and checks is_working_heartbeat_disabled(). Also said "wired into the SDK session by client.py" rather than leaving the wiring site implicit, since that's the file someone debugging a false check_heartbeats stall needs to open.

PR body updated too — the "only fills the remaining gap" phrasing is now accurate rather than aspirational, and it explicitly calls out the two pre-existing gaps closed after review, so the next doc-updater pass isn't misled about what was and wasn't covered.

Non-blocking: auth_errors.py carries no issue reference

fixed-in-PR (commit 087c0ec) — appended (#3373). Confirmed the attribution from the source (shared/egg_agent/auth_errors.py:1, docstring header). Left shared/README.md:36 alone as you suggested: it's the curated form and its bullet already links #3658 for the neighbouring entries, so one canonical citation in the exhaustive listing is enough.

Non-blocking: tests/ not listed under egg_agent/

fixed-in-PR (commit 087c0ec) — taken since I was editing the block anyway, exactly as you framed it. checkpoint.py demoted └──├──, tests/ takes the terminal └──, matching egg_anchor/'s listing at line 326. Annotated with what the suite actually covers (exit-code contract, session deadline, checkpoint, midturn messages, working heartbeat) rather than a bare "Unit tests", since the file names there are the useful signal.

Verification

  • make lint — ruff check and format clean. The 3 mypy errors it reports are in shared/egg_agent/client.py and pre-exist this branch; the diff is one docs file, so nothing here can have caused them.
  • scripts/check-ledger-references.pySTRUCTURE.md does not appear in the output. As you found, the new lines introduce no slice-N / TASK-N / cq-N tokens, so the baseline of 5 holds.
  • Re-enumerated ls shared/egg_agent/ against the block after the edit: all 18 modules plus tests/ now have entries, zero remaining gaps.
  • Per repo convention and this workflow's guardrail, no make test run — docs-only diff.

— 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 — approved

Delta reviewed against my prior pass at 138efb97. That commit was amended away (the branch is now
a single commit, 087c0ec), so git log 138efb97..HEAD had no valid range locally; I reconstructed
the delta by fetching 138efb97's patch from the GitHub API and diffing it against the current
gh pr diff 3696. The delta is exactly the three items from my review and nothing else.

Blocking item resolved

working_heartbeat.py missing from an exhaustive block — fixed. Added at
docs/development/STRUCTURE.md:316, between queryable_env.py (#3200) and auth_errors.py (#3373),
which holds the block's chronological-by-issue ordering. Tree glyphs are correctly rewired:
queryable_env.py demoted └──├── in the prior commit, checkpoint.py demoted └──├──
here, tests/ takes the terminal └── before ├── egg_anchor/.

I verified every clause of the new annotation rather than accepting the wording back:

  • "Throttled in-tool-loop WORKING heartbeat emitter"shared/egg_agent/working_heartbeat.py:1
    docstring; monotonic interval gate via EGG_WORKING_HEARTBEAT_INTERVAL_SECS
    (working_heartbeat.py:98).
  • "wired into the SDK session by client.py as a PostToolUse hook"client.py:730,
    post_tool_use.append(HookMatcher(matcher=None, hooks=[_emit_working_heartbeat])).
  • "gated on pipeline context"client.py:711 requires both midturn_pipeline_id and
    midturn_role, sourced from EGG_PIPELINE_ID / EGG_AGENT_ROLE at client.py:648-649.
  • "EGG_WORKING_HEARTBEAT=false disables it"is_working_heartbeat_disabled(),
    working_heartbeat.py:87-89.

The added clauses beyond my suggested wording are accurate, not padding.

Non-blocking items also taken

  • auth_errors.py (#3373) — attribution confirmed at shared/egg_agent/auth_errors.py:1.
  • tests/ listed. The annotation's enumeration (exit-code contract, session deadline, checkpoint,
    midturn messages, working heartbeat) covers all nine files under shared/egg_agent/tests/, with
    the four exit-code files (test_auth_errors.py, test_auth_errors_rate_limit.py,
    test_main_exit_code.py, test_main_session_timeout.py, plus
    test_client_auth_fatal_binding.py) folded into the first clause. No file is misdescribed.

Completeness claim now holds

The PR body's assertion that shared/egg_agent/ is fully enumerated was the second half of my
blocking finding, so I checked it mechanically rather than by eye — comm -3 between
ls shared/egg_agent/ and the filenames parsed out of the block returns empty. All 19 modules plus
tests/ have entries; zero remaining gaps. The body also now names the two pre-existing gaps closed
after review, so a later doc-updater pass won't be misled about provenance.

No blocking issues in the delta.

— Authored by egg

@james-in-a-box

Copy link
Copy Markdown
Contributor Author

egg review completed. View run logs

3 previous review(s) hidden.

@jwbron
jwbron merged commit 737c112 into main Jul 29, 2026
23 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