docs: document cross-repo merge gate [doc-updater] - #3451
Conversation
This comment has been minimized.
This comment has been minimized.
…conflict in docs/architecture/slice-dag.md main's #3437 added a broader '## Per-slice repo (multi-repo pipelines)' section whose '### Cross-repo merge-sequencing hold (two-tier)' subsection overlaps this PR's standalone '## Cross-repo merge-sequencing gate' section. Kept main's better-integrated section and folded in this PR's unique details (gateway routes POST /api/v1/gh/pr/merge_state and /pr/ready, Gateway README link, EGG_ORCH_CROSS_REPO_MERGE_GATE_MAX_ATTEMPTS attempt bound, the [hold:beyond-merge-state] marker, and the two operator-selectable HITL options). Repointed the Configuration-knobs table link to the surviving anchor.
Conflict Resolution SummaryResolved merge conflicts with
Only one file conflicted. The PR's other edits (
|
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
No agent-mode design concerns.
This is a documentation-only change, and the design it documents aligns well with agent-mode principles: the cross-repo merge gate enforces sequencing through gateway routes (/api/v1/gh/pr/merge_state, /api/v1/gh/pr/ready) and routes its failure terminals through the HITL decision queue — sidecar/infrastructure enforcement rather than prompt-level instructions. No pre-fetching, human-facing structured output, post-processing pipelines, or pinned model identifiers are introduced.
— Authored by egg
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
Autofix tracking{"Lint/Python": 1, "Lint/Custom Checks": 1, "Test/Unit Tests": 1} |
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
Review: docs for cross-repo merge gate (#3393 slice-5)
Documentation-only PR (5 files, +41/-12). I verified every technical claim against the source it describes — orchestrator/cross_repo_merge_gate.py, orchestrator/env_config.py, orchestrator/routes/pipelines.py, and gateway/gateway.py. Everything is accurate.
Verified accurate
EGG_ORCH_CROSS_REPO_MERGE_GATE_MAX_ATTEMPTSdefault 240 / "~2h at 30s cadence" — matchesDEFAULT_CROSS_REPO_MERGE_GATE_MAX_ATTEMPTS = 240(env_config.py:287) andDEFAULT_STACKED_PR_RECONCILER_INTERVAL_SECONDS = 30.0; 240 × 30s = 7200s = 2h. ✓- "rides the stacked-PR reconciler cadence" — confirmed:
_poll_cross_repo_merge_gateis driven inside_start_stacked_pr_reconcileron the shared tick (routes/pipelines.py:18824-19004), no new scheduler. ✓ - Merge detection keys off
mergedAt/state, not head-SHA —_is_merged(cross_repo_merge_gate.py) checksmerged_at/mergedAt/merged/state == MERGED; the gateway route requests--json state,mergedAt(gateway.py:4581). ✓ - Two Tier-A failure terminals (CLOSED-not-merged, attempt-bound timeout) —
_poll_one_gateregistersclosed_unmergedvia_is_closed_unmerged, andtimeoutwhenprog.attempts > max_attempts. ✓ - Tier-B opt-in via
[hold:beyond-merge-state]marker ingoalor a task description — matchesBEYOND_MERGE_STATE_MARKERandclassify_hold_kind, which scansgoalthen eachtask.description. ✓ - HITL decision offers two options — release (marks ready) / keep-held (terminal, stays draft) — matches
_CROSS_REPO_HOLD_RELEASE_OPTION_*/_CROSS_REPO_HOLD_KEEP_OPTION_*and theRELEASE/KEEPhandling in_poll_one_gateand_cross_repo_hold_resolution(routes/pipelines.py:12778-12845). The fail-safe (ambiguous resolution → KEEP, never auto-ready) is real. ✓ - Gateway routes —
POST /api/v1/gh/pr/merge_state(read{state, mergedAt}) andPOST /api/v1/gh/pr/ready(draft→ready, wrapsgh pr ready) both exist atgateway.py:4535/4631, both decorated@require_launcher_auth, both taking{repo, pr_number}. The documentedAuth: Bearer {launcher_secret}(vs. thePolicy:line on session-auth routes) is the correct distinction — these are control-plane/orchestrator-only. ✓ STRUCTURE.mdmodule entry —orchestrator/cross_repo_merge_gate.pyexists and the one-line description matches its docstring. ✓- Anchor links —
#cross-repo-merge-sequencing-hold-two-tierresolves to the### Cross-repo merge-sequencing hold (two-tier)heading (slice-dag.md:795); cross-file links to gateway README and orchestrator-cli/slice-dag are valid. ✓
Non-blocking (optional)
gateway/README.md: the two new routes sit inside the "GitHub Operations" block amongPolicy:-annotated session-auth routes. TheAuth:-line + "Orchestrator-only" wording already disambiguates, but if you want them visually grouped with the other launcher-auth control-plane routes (e.g.find_open_pr/list_open_prs), consider co-locating them. Cosmetic only.
No blocking issues. Docs faithfully describe the implemented behavior.
— Authored by egg
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
No agent-mode design concerns (re-review).
Since my prior review at 9cbed6d, the delta is a merge with main (reconciling the overlapping slice-dag.md cross-repo-hold section) plus automated formatting reflows across config/, gateway/, and orchestrator/. None of it touches agent-mode surface:
- The documented cross-repo merge gate still enforces sequencing through gateway routes (
/api/v1/gh/pr/merge_state,/api/v1/gh/pr/ready, orchestrator/launcher-auth only) and routes both failure terminals and the Tier-B opt-in hold through the HITL decision queue — sidecar/control-plane enforcement rather than prompt-level instructions. - No pre-fetching, human-facing structured output, post-processing pipelines, rigid procedures, prompt-level security, direct Anthropic API calls, or pinned model identifiers introduced in the delta.
The earlier non-blocking suggestion (co-locating the two new launcher-auth gateway routes with the other control-plane routes in the README) was cosmetic and doesn't affect agent-mode alignment.
— Authored by egg
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
No agent-mode design concerns (re-review).
Since my prior review at beb459df, the delta is lint/autofix commits plus a file-size allowlist entry for orchestrator/models.py (#3450). None of it touches the agent-mode surface.
The documented design remains well-aligned:
- The cross-repo merge gate enforces sequencing through gateway routes (
/api/v1/gh/pr/merge_state,/api/v1/gh/pr/ready) that are launcher-auth / orchestrator-only control-plane — sidecar enforcement, not prompt-level instructions. - Both Tier-A failure terminals (CLOSED-not-merged, attempt-bound timeout) and the Tier-B opt-in hold route through the HITL decision queue with a single release path.
- No pre-fetching, human-facing structured output, post-processing pipelines, rigid procedures, prompt-level security, direct Anthropic API calls, or pinned model identifiers in the delta.
Note (outside agent-mode scope, deferring to the base review bot / CI): the branch appears stale relative to main — the diff reverts several of main's line-length reformats and, in gateway/gateway.py and orchestrator/routes/pipelines.py, re-introduces except ValueError, TypeError: (invalid Python 3 syntax). That's a correctness issue for the base bot, not an agent-mode concern, but worth a rebase on main before merge.
— Authored by egg
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
Re-review at 8c896170 (delta since 9cbed6d)
The only new commit since my approving review is 8c896170 "Fix checks: allowlist orchestrator/models.py". I re-reviewed its full delta. No blocking issues — but two things need correcting for the record, and one PR-hygiene item is worth fixing before merge.
The delta breaks down as
scripts/file-size-allowlist.yaml— addsorchestrator/models.py: {issue: "3450"}. This is the commit's stated purpose (unblocks the file-size check thatmodels.pytrips onmain). Legitimate.- Formatting-only churn across
config/repo_config.py,gateway/gateway.py,gateway/tests/test_repo_visibility.py,orchestrator/mcp_tools/_submit.py,orchestrator/routes/pipelines.py,orchestrator/tests/test_kubernetes_spawner.py— line-length reflows, implicit-string-concat collapses, andexcept (A, B):→except A, B:.
Correcting the record on the "invalid Python 3 syntax" concern
A prior agent-mode note flagged except ValueError, TypeError: (in gateway.py and pipelines.py) as "invalid Python 3 syntax" and recommended a rebase. That is a false positive. This repo sets requires-python = ">=3.14" / target-version = "py314" (pyproject.toml), and Python 3.14 (PEP 758) permits unparenthesized multiple exception types. I confirmed:
ast.parseaccepts it and produces an AST byte-identical to the parenthesized form (ExceptHandler(type=Tuple(...))).- Runtime catches both types.
So these are semantically identical, not syntax errors.
The churn is ruff-canonical — CI will pass, and main is the stale one
I verified with the pinned toolchain (ruff>=0.15.12,<0.16; system ruff 0.15.20):
ruff format --checkreports all four changed production files "already formatted" at this PR head.- The
mainversions ofrepo_config.py,gateway.py, andpipelines.pyall report "Would reformat".
So the PR is advancing these files to canonical ruff format, not reverting main's. The format check on this PR's changed files will pass. I also confirmed the three collapsed implicit-string-concats produce byte-identical strings (no dropped/added spaces), and every other hunk is pure whitespace/wrapping. Net semantic change of the churn: zero.
Docs (this PR's actual purpose) — unchanged and still accurate
No docs/* or gateway/README.md file changed in this delta, so my prior verification stands: env-var default 240, both gateway routes (/api/v1/gh/pr/merge_state, /api/v1/gh/pr/ready), and the cross_repo_merge_gate.py module all match source.
Non-blocking — fix before merge
The PR description is now inaccurate. It states "documentation-only change, no code paths affected" and "Automated: none — documentation-only change, no code paths affected." The PR in fact modifies four production files (config/repo_config.py, gateway/gateway.py, orchestrator/mcp_tools/_submit.py, orchestrator/routes/pipelines.py) plus two test files and the file-size allowlist. The changes are provably inert (format-only + a CI allowlist entry), so the risk is nil and I'm not blocking — but the merger is being told there's no code to look at when there is. Please either:
- update the description/test-plan to note the ruff-format collateral + the
#3450allowlist entry, or - split the unrelated formatting churn and the allowlist entry out of a docs PR.
Approving: the delta is merge-safe and CI-clean; the docs are accurate.
— Authored by egg
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
Feedback dispositionThanks for the thorough re-reviews. All reviews are approving; the two non-blocking items:
— Authored by egg |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
- Rename local var context_title -> secondary_pr_title in _maybe_open_secondary_context_prs (it reads contract.pr.title, not the removed PRMetadata.context_title field; the grep test flagged the name). - Allow-list shared/egg_contracts/tests/test_models.py in TestNoSurvivingReadSites: its migration test constructs a legacy payload with the removed keys to assert they are stripped on load.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
Conflict Resolution SummaryNo action needed — this branch is already conflict-free and up to date with Investigation:
The earlier conflicts were already resolved by the existing merge commit on this branch ( The No merge commit was created and nothing was pushed, since the working tree and branch are unchanged. — Authored by egg |
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
No agent-mode design concerns (re-review).
Since my prior review at 8c896170, the PR-authored delta is limited to two CI-check fixes plus a merge with main:
orchestrator/routes/pipelines.py: local variable renamecontext_title→secondary_pr_titlein_open_secondary_context_prs(it readscontract.pr.title, not the removedPRMetadata.context_titlefield — the rename satisfies the surviving-field grep test).tests/shared/egg_contracts/test_pr_metadata.py: allow-listsshared/egg_contracts/tests/test_models.pyinTestNoSurvivingReadSitesbecause that migration test intentionally constructs a legacy payload with the removed keys to assert they're stripped on load.
Neither touches the agent-mode surface. The documented design remains well-aligned: the cross-repo merge gate enforces sequencing through gateway routes (/api/v1/gh/pr/merge_state, /api/v1/gh/pr/ready, launcher-auth / orchestrator-only control-plane) and routes both failure terminals and the Tier-B opt-in hold through the HITL decision queue — sidecar/control-plane enforcement rather than prompt-level instructions. No pre-fetching, human-facing structured output, post-processing pipelines, rigid procedures, prompt-level security, direct Anthropic API calls, or pinned model identifiers in the delta.
— Authored by egg
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
Re-review at cbaaceca (delta since 8c896170)
The only new commit since my prior review is the merge cbaaceca "Merge main into doc-update-cross-repo-merge-gate; dedupe overlapping CI fixes". I re-reviewed the full delta and re-verified every technical claim against source. No blocking issues.
The merge resolved my prior non-blocking concern
At 8c896170 I flagged that the PR carried non-doc collateral (ruff-format churn across config/repo_config.py, gateway/gateway.py, orchestrator/mcp_tools/_submit.py, orchestrator/routes/pipelines.py, two test files, plus the orchestrator/models.py file-size-allowlist entry) while the description claimed "documentation-only". This merge dedupes all of it — those files are now byte-identical to main and no longer appear in the PR-vs-main diff. The PR is now genuinely close to docs-only.
Current PR content vs main (9daf5cb) — 6 files, clean
Verified via compare/9daf5cb...cbaaceca (ahead 6, behind 0):
docs/architecture/slice-dag.md(+22/-12) — the reconciled two-tier sectiondocs/architecture/orchestrator.md,docs/reference/orchestrator-cli.md,docs/development/STRUCTURE.md,gateway/README.md— the env-var / route / module doc rowstests/shared/egg_contracts/test_pr_metadata.py(+4/-4) — inert: relocates the existingshared/egg_contracts/tests/test_models.pyentry withinALLOWED_PATHSand rewords its comment. The tuple is consumed as an order-independent substring membership set (any(allowed in path for allowed in self.ALLOWED_PATHS), line 615) and the entry appears exactly once, so behavior is unchanged.
Technical claims re-verified against source (all accurate)
EGG_ORCH_CROSS_REPO_MERGE_GATE_MAX_ATTEMPTSdefault 240 (env_config.py:287); reconciler cadence 30.0s (env_config.py:282); 240 × 30s = 7200s = ~2h ✓- Gateway routes
POST /api/v1/gh/pr/merge_state(gateway.py:4535) andPOST /api/v1/gh/pr/ready(gateway.py:4631), both@require_launcher_auth— matches the documentedAuth: Bearer {launcher_secret}/ "Orchestrator-only" wording ✓ mark_pr_ready(repo, pr_number)verb exists (gateway_client/_pr.py:727, wrapsgh pr ready) ✓- Tier-B opt-in via
[hold:beyond-merge-state]marker scanned ingoalthen eachtask.description(cross_repo_merge_gate.py:59,161-164) ✓ - Two HITL options: "Release the hold and mark the PR ready" / "Keep the PR held for manual handling" (
routes/pipelines.py:12783-12785); keep-held is terminal / stays draft ✓ orchestrator/cross_repo_merge_gate.pyexists;STRUCTURE.mdone-liner matches the module docstring ✓- Anchor
#cross-repo-merge-sequencing-hold-two-tierresolves to### Cross-repo merge-sequencing hold (two-tier)(slice-dag.md:795); the config-knobs-table link (slice-dag.md:923) points to the same surviving anchor ✓ - Reconciled
slice-dag.mdsection reads coherently — no conflict markers, no duplicated prose, main's better-integrated multi-repo framing preserved with this PR's route/env-var/marker details folded in ✓
Non-blocking
The test_pr_metadata.py reorder is unrelated collateral pulled in by the merge's conflict resolution. It's provably inert, so I'm not blocking — but strictly it's still a non-doc change in a docs PR. Fine to leave; noting for the record.
Approving: the delta is merge-safe, the docs faithfully describe the implemented behavior, and my earlier collateral concern is resolved.
— Authored by egg
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
Feedback dispositionAll formal reviews are approving (agent-mode-design: approve; review bot: approve-with-suggestions). Addressing the outstanding non-blocking items, and correcting the PR description now that the
— Authored by egg |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
…conflicts in slice-dag.md, STRUCTURE.md, test_pr_metadata.py
Conflict Resolution SummaryResolved merge conflicts with
Verification:
Please review: The Configuration-knobs table row ordering in — Authored by egg |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
No agent-mode design concerns (re-review).
Since my prior review at cbaaceca, the only PR-authored commit is the merge 28b3afe "Merge origin/main into egg/doc-update-cross-repo-merge-gate". Its conflict resolution is confined to three files and is additive/cosmetic:
docs/architecture/slice-dag.md— both sides append rows to the Configuration-knobs table; kept theEGG_ORCH_CROSS_REPO_MERGE_GATE_MAX_ATTEMPTSrow followed by main'sEGG_SLICE_GREEN_GATE*rows. No conflict markers, no duplicated prose.docs/development/STRUCTURE.md— additive module-tree entry (cross_repo_merge_gate.pyalongside main'sslice_green_gate.py).tests/shared/egg_contracts/test_pr_metadata.py— comment-only resolution on an existingALLOWED_PATHSentry; provably inert (order-independent membership set, entry present exactly once).
None of these touch the agent-mode surface. The documented design remains well-aligned with agent-mode principles: the cross-repo merge gate enforces sequencing through gateway routes (/api/v1/gh/pr/merge_state, /api/v1/gh/pr/ready — launcher-auth, orchestrator-only control plane) and routes both Tier-A failure terminals and the Tier-B [hold:beyond-merge-state] opt-in through the HITL decision queue. That's sidecar/control-plane enforcement rather than prompt-level instruction — the right pattern.
No pre-fetching, human-facing structured output, post-processing pipelines, rigid procedures, prompt-level security, direct Anthropic API calls, or hardcoded model identifiers in the delta.
— Authored by egg
|
egg conflict resolution completed. View run logs |
|
egg agent-mode-design completed. View run logs 24 previous review(s) hidden. |
There was a problem hiding this comment.
Re-review: docs for cross-repo merge gate (#3393 slice-5)
My prior review commit (cbaaceca) was rewritten off the branch, so I re-verified the full current diff against origin/main from scratch. Net diff is now genuinely docs-only — 5 files, +41/−12 (docs/architecture/orchestrator.md, docs/architecture/slice-dag.md, docs/development/STRUCTURE.md, docs/reference/orchestrator-cli.md, gateway/README.md). The earlier ruff-format churn, the except (A,B):→except A,B: rewrites, and the models.py allowlist entry are all gone from the diff — the merge with main deduped them (those files are byte-identical to main). The prior "invalid Python 3 syntax" and "PR-description-claims-docs-only-but-carries-code" concerns are therefore both moot: there is no code in this diff.
Every technical claim re-verified against source
EGG_ORCH_CROSS_REPO_MERGE_GATE_MAX_ATTEMPTSdefault240—DEFAULT_CROSS_REPO_MERGE_GATE_MAX_ATTEMPTS = 240(env_config.py:287, read at:400). ✓- "~2h at the default 30s reconciler cadence" —
DEFAULT_STACKED_PR_RECONCILER_INTERVAL_SECONDS = 30.0(env_config.py:282); 240 × 30s = 7200s = 2h. ✓ - Gateway routes —
POST /api/v1/gh/pr/merge_state(gateway.py:4535) andPOST /api/v1/gh/pr/ready(gateway.py:4631), both@require_launcher_authand self-documented "orchestrator-only." The doc'sAuth: Bearer {launcher_secret}line is the correct distinction. ✓ - merge_state returns
{state, mergedAt}— route requests--json state,mergedAtand returnsstate/mergedAtfrom the parsed payload. ✓ - Merge detection keys off
mergedAt/state, not head-SHA — matches the route surface and the doc's squash/rebase rationale. ✓ mark_pr_readywrapsgh pr ready—gateway.py:4634docstring: "wrapgh pr ready(#3393)", fixed narrow argv. ✓[hold:beyond-merge-state]Tier-B marker ingoalor a task description —BEYOND_MERGE_STATE_MARKER = "[hold:beyond-merge-state]"(cross_repo_merge_gate.py:59);classify_hold_kindscansgoalthen eachtask.description(:161-164). ✓- Two HITL options (release → ready / keep → stays draft) —
_CROSS_REPO_HOLD_RELEASE_OPTION_*/_CROSS_REPO_HOLD_KEEP_OPTION_*(routes/pipelines.py:12811-12814), release marks ready, keep leaves it draft (:12951-12958). ✓ STRUCTURE.mdmodule entry —orchestrator/cross_repo_merge_gate.pyexists; the one-line description matches its purpose. ✓- Anchor link — the config-knobs row (
slice-dag.md:970) links#cross-repo-merge-sequencing-hold-two-tier, which resolves to### Cross-repo merge-sequencing hold (two-tier)(slice-dag.md:817). Cross-file link../../gateway/README.mdfromdocs/architecture/resolves correctly. ✓ - No conflict markers in any of the 5 merged files. ✓
Non-blocking
- PR description slightly over-discloses. The "Non-doc collateral" section still lists
tests/shared/egg_contracts/test_pr_metadata.py (+4/-4)as "the single remaining non-doc file," but that file is now byte-identical tomainand does not appear in this PR's diff. Harmless — this is over-disclosure, not under-disclosure — but the section could be trimmed to say the diff is purely docs. Not blocking.
No blocking issues. The docs faithfully describe the implemented behavior, and the diff is merge-safe and CI-clean.
— Authored by egg
|
egg review completed. View run logs 24 previous review(s) hidden. |
| egg is addressing review feedback... |
Feedback dispositionAll formal reviews are approving (agent-mode-design: approve; review bot: approve-with-suggestions). The diff is now genuinely docs-only — 5 files (
— Authored by egg |
|
egg feedback addressed. View run logs 24 previous review(s) hidden. |
Update documentation to reflect the cross-repo merge-sequencing gate added in
#3393 slice-5 (
orchestrator/cross_repo_merge_gate.py, two new gatewayroutes, and a new env var):
docs/architecture/slice-dag.md— folds the cross-repo merge-gate details(orchestrator-only gateway routes, the
EGG_ORCH_CROSS_REPO_MERGE_GATE_MAX_ATTEMPTSknob, the
[hold:beyond-merge-state]Tier-B marker, and the release/keep-heldHITL options) into main's
### Cross-repo merge-sequencing hold (two-tier)subsection, and repoints the Configuration-knobs table row to the surviving anchor.
docs/reference/orchestrator-cli.mdanddocs/architecture/orchestrator.md— add
EGG_ORCH_CROSS_REPO_MERGE_GATE_MAX_ATTEMPTSto the env-var tables.docs/development/STRUCTURE.md— list the neworchestrator/cross_repo_merge_gate.pymodule.gateway/README.md— document the two new orchestrator-only routes,POST /api/v1/gh/pr/merge_stateandPOST /api/v1/gh/pr/ready.Triggered by: 4eaa3ce (merge of #3430, egg/issue-3393/slice-5)
Scope: docs-only
The diff is purely documentation — 5 files (
docs/architecture/orchestrator.md,docs/architecture/slice-dag.md,docs/development/STRUCTURE.md,docs/reference/orchestrator-cli.md,gateway/README.md), no code pathsaffected.
The ruff-format churn, the
orchestrator/models.pyfile-size-allowlist entry,and the
tests/shared/egg_contracts/test_pr_metadata.pyallowlist reorder thatthis branch briefly carried through earlier
mainmerges have all since beendeduped — every one of those files is now byte-identical to
mainand nolonger appears in this PR's diff.
Test Plan
HEAD.
(
gateway/gateway.py,orchestrator/cross_repo_merge_gate.py,orchestrator/env_config.py,orchestrator/routes/pipelines.py) to confirmaccuracy.
Authored-by: egg