Skip to content

docs: document EGG_EVENT_LOOP_OWNER flag (#3064 slice-1) [doc-updater] - #3202

Merged
jwbron merged 2 commits into
mainfrom
egg/doc-update-event-loop-owner
Jun 13, 2026
Merged

docs: document EGG_EVENT_LOOP_OWNER flag (#3064 slice-1) [doc-updater]#3202
jwbron merged 2 commits into
mainfrom
egg/doc-update-event-loop-owner

Conversation

@james-in-a-box

Copy link
Copy Markdown
Contributor

Update documentation to reflect the new EGG_EVENT_LOOP_OWNER environment variable and dormant one-shot wrapper arm introduced in #3167 (issue #3064 slice-1).

The EGG_EVENT_LOOP_OWNER flag controls whether the BRC event loop runs in-pod (default pod) or is orchestrator-owned (orchestrator). The orchestrator mode splices a dormant one-shot arm into the consensus wrapper that will be activated by the slice-2 spawner. Exit code 75 (EX_TEMPFAIL) is reserved by the one-shot arm for an inconclusive freshness re-check, preventing a transient blip from being reported as a clean handoff.

Changes:

  • docs/reference/orchestrator-cli.md: Added EGG_EVENT_LOOP_OWNER to the environment variables table with its valid values, default, and the rationale for loud-failure on unrecognised values.
  • docs/development/STRUCTURE.md: Updated consensus_wrapper.py description to mention the dormant one-shot arm and EGG_EVENT_LOOP_OWNER.

Triggered by: #3167

Issue: none

Test Plan

  • Automated: doc-only change, no tests needed
  • Manual: verify env var table renders correctly in rendered docs

Authored-by: egg

Update documentation to reflect changes from 17102bc:
- Add EGG_EVENT_LOOP_OWNER to orchestrator-cli.md env vars table
- Update STRUCTURE.md consensus_wrapper.py entry to note the dormant one-shot arm

Triggered by: #3167

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.

Approve. Documentation-only change; every claim verified against the slice-1 implementation from #3167. No blocking issues.

Verification

I traced each statement in the two doc edits to the code that backs it:

  • pod default / unset⇒podenv_config.get_event_loop_owner() returns DEFAULT_EVENT_LOOP_OWNER = "pod" on empty/unset (orchestrator/env_config.py:508-510). ✓
  • Unrecognised value raises ValueError at read time, no silent fallbackenv_config.py:512-519 logs and raises; the module comment (:482-489) cites the same #3023 post-mortem rationale the doc references. ✓
  • orchestrator mode owns the loop / one-shot pod per event — matches the EVENT_LOOP_OWNER_ORCHESTRATOR accessor and the module docstring. ✓
  • Arm spliced only when EGG_EVENT_LOOP_OWNER=orchestrator (STRUCTURE.md) — build_event_pump_wrapped_command splices _ONE_SHOT_ARM_TEMPLATE ahead of _MAIN_LOOP_MARKER only under if _event_loop_owner() == "orchestrator" (consensus_wrapper.py:1145-1150); pod mode returns the template untouched and byte-identical (golden-file test). ✓
  • Dormant until the slice-2 spawner exists — the arm engages only when EGG_EVENT_ACTION is injected (consensus_wrapper.py:991), and nothing sets that env var in the tree yet. ✓

The new table row sits correctly among the EGG_* entries, is stylistically consistent with its neighbors, and contains no literal | that would break the Markdown table. The STRUCTURE.md one-liner accurately states the splice condition.

Non-blocking (advisory only)

  1. get_event_loop_owner() matches the value case-insensitively (raw.lower(), env_config.py:511), so Orchestrator/POD are accepted. The doc presents the values as exact-case literals. Minor — arguably correct to not advertise the leniency, but worth a parenthetical if you want the doc to be fully faithful to the accessor's behavior.
  2. The PR description explains exit code 75 (EX_TEMPFAIL) for an inconclusive freshness re-check, but that detail lands in no operator-facing doc. That's reasonable for slice-1 (it's an internal wrapper↔supervisor contract not yet wired up), but consider documenting the 64/75/0 exit-code contract when the slice-3 supervisor lands and the codes become observable.

Neither blocks merge.

— Authored by egg

@james-in-a-box

This comment has been minimized.

@james-in-a-box

This comment has been minimized.

Address review feedback: the accessor lowercases the raw value
(env_config.py:511), so values like Orchestrator/POD are accepted.
Make the doc faithful to that behavior.
@james-in-a-box

Copy link
Copy Markdown
Contributor Author

Thanks for the thorough verification. Both items were non-blocking advisories; dispositions below.

1. Doc presents values as exact-case literals, but the accessor matches case-insensitivelyfixed-in-PR (commit c6a348e). Confirmed get_event_loop_owner() normalizes with raw.lower() (orchestrator/env_config.py:511), so Orchestrator/POD are accepted. Added a parenthetical to the EGG_EVENT_LOOP_OWNER row noting the case-insensitive match, so the doc is faithful to the accessor.

2. Document the 64/75/0 exit-code contractdisagree (premature for slice-1; not yet observable). The exit codes are an internal wrapper↔supervisor contract that isn't wired up yet — nothing in the tree consumes them, and the one-shot arm is dormant until orchestrator mode + the slice-2 spawner exist. As you noted, the right time to document the 64/75/0 contract is when the slice-3 supervisor lands and the codes become operator-observable; documenting them now would describe behavior that no component yet exercises. Deferring to that slice keeps the operator-facing doc describing only live behavior.

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

Approve. The delta since my last review (322c6f4..c6a348e) is a single one-line doc edit that addresses non-blocking advisory #1 from my prior review. Verified accurate.

Delta verification

The new sentence in the EGG_EVENT_LOOP_OWNER row of docs/reference/orchestrator-cli.md:82:

Values are matched case-insensitively (e.g. Orchestrator, POD are accepted).

This is faithful to the accessor. get_event_loop_owner() reads the raw value, then at orchestrator/env_config.py:511 normalizes with raw.lower() before comparing against VALID_EVENT_LOOP_OWNERS = ("pod", "orchestrator") (all-lowercase). So Orchestrator → orchestrator and POD → pod both pass the membership check; mixed-case input is genuinely accepted. ✓

The edit is a pure prose addition inside the existing table cell — no literal |, so Markdown table integrity is preserved. No other files changed (1 file changed, 1 insertion(+), 1 deletion(-)).

Prior feedback dispositions

  1. Case-insensitive match not advertised — fixed in c6a348e (this delta). Confirmed against env_config.py:511. ✓
  2. Document the 64/75/0 exit-code contract — author deferred to slice-3 when the codes become operator-observable. Sound reasoning: nothing in the tree consumes those codes yet (the one-shot arm is dormant), so documenting them now would describe behavior no component exercises. Agreed this is the right call.

No blocking issues. No new concerns introduced.

— 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 3e06eba into main Jun 13, 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