diff --git a/docs/architecture/slice-dag.md b/docs/architecture/slice-dag.md index 5320909a2a..8b9a29592f 100644 --- a/docs/architecture/slice-dag.md +++ b/docs/architecture/slice-dag.md @@ -773,6 +773,22 @@ with no slices gets neither. A single-repo pipeline gets exactly one work branch and one context PR, byte-equivalent to the pre-multi-repo path. Context-PR bodies cross-reference their sibling context PRs in the pipeline. +For a multi-repo pipeline (`len(repos) > 1`), `kubernetes_spawner` asks the +gateway to materialize each repo's work branch on its own remote right after +the worktree is created (`create_worktrees(..., push_branches=True)`, wired +through the gateway's `_materialize_work_branch_on_remote`, #3393 slice-7): +the fresh worktree HEAD is pushed to +`refs/heads/{assigned_branch or work-branch}`. The push runs for every repo in +the list — including the primary, where it's a no-op the orchestrator's +existing push path already covered. It is best-effort, non-forced, and +idempotent: a branch already present on the remote — even one whose tip has +diverged — is treated as already materialized (a non-fast-forward rejection is +swallowed rather than force-pushed, so the primary's contract-init commit is +never clobbered). This guarantees a secondary repo's context/slice PR always +has a head branch to open against instead of soft-failing on a missing one. +Single-repo pipelines pass `push_branches=False` and stay byte-identical to +the pre-#3393 path. + ### Per-slice PR routing `GatewayClient.create_slice_pr` is repo-parameterized; the run loop passes each