Plan: docs/plans/2026-09-26-1209-feat-zone-link-plan.md (untracked, not yet committed).
17 units, 11 KTDs, R1-R19, AE1-AE17. Every unit is developed in its own git worktree and merged by a single integrator. No lane merges itself.
Four merge points, five lanes at the widest
MP1 - Foundations. 5 lanes start at once.
| Lane |
Units |
Depth |
| A |
U15 rename |
1 |
| B |
U1 ZoneParent |
1 |
| C |
U2 authority, then U4 CLI route |
2 |
| D |
U8 provider link declaration |
1 |
| E |
U17 link purpose, then U16 effect gate, then U13 Nix surface |
3 |
Lane E is the big win: the entire guest-mode track never touches the ZoneParent, provider, CLI or router work, so it runs three deep in parallel with everything else instead of waiting behind it.
MP2 - Reachability. 4 lanes: U3 | U5 | U9 | U12
MP3 - Carriage and shell. 3 lanes: U6 then U11 | U7 | U10
MP4 - Proof and landing. 1 lane: U14, then the PR opens.
Gates
| MP |
make check |
make test-unit |
make test-host-integration |
| MP1 |
required |
required |
required - U16 lifts a guest-mode restriction that existing checks may assert |
| MP2 |
required |
required |
- |
| MP3 |
required |
required |
- |
| MP4 |
required |
required |
required, including the new check |
make check runs after every individual lane merge, not just at the merge point, so a failure is attributed to the lane that caused it. make test-host-integration runs at MP1 and MP4 only, because those are the only two containing a change that can plausibly break an existing VM check.
Sanctioned same-file concurrency
Only three pairs share a file, and only in different hunks:
- U15 || U1 in role_binding.rs (rename vs bindable-subject list)
- U15 || U17 in zone_session.rs (endpoint role vs purpose value)
- U1 || U2 in resource_runtime_support.rs (subject uid vs provenance)
Anything beyond these three is a signal the lane split is wrong.
Generated artifacts still serialize the merge
make generate owns the resource-type registry, schemas, audit and surface catalogs, and generated Nix. Declaration-touching lanes merge one at a time with a regeneration between each. MP1 order: U15, U1, U8, U17, then lane C - U1's type must be in the registry before U8's parity gate runs against it.
No PR before MP4
Review runs over the accumulated diff at every merge point, so coverage is total by MP4 and an early finding costs one lane's rework rather than the branch's. The single PR opens only when make check and make test-host-integration pass on the full change and at least one round of review has covered the code in total.
Critical path is ~5 units deep against a width of 5. Open decisions remain in U16 (what a guest-mode host is trusted with), U17, U1 (ZoneParent uid), and U12 (foreign-rooted audit record).
Plan: docs/plans/2026-09-26-1209-feat-zone-link-plan.md (untracked, not yet committed).
17 units, 11 KTDs, R1-R19, AE1-AE17. Every unit is developed in its own git worktree and merged by a single integrator. No lane merges itself.
Four merge points, five lanes at the widest
MP1 - Foundations. 5 lanes start at once.
Lane E is the big win: the entire guest-mode track never touches the ZoneParent, provider, CLI or router work, so it runs three deep in parallel with everything else instead of waiting behind it.
MP2 - Reachability. 4 lanes: U3 | U5 | U9 | U12
MP3 - Carriage and shell. 3 lanes: U6 then U11 | U7 | U10
MP4 - Proof and landing. 1 lane: U14, then the PR opens.
Gates
make check runs after every individual lane merge, not just at the merge point, so a failure is attributed to the lane that caused it. make test-host-integration runs at MP1 and MP4 only, because those are the only two containing a change that can plausibly break an existing VM check.
Sanctioned same-file concurrency
Only three pairs share a file, and only in different hunks:
Anything beyond these three is a signal the lane split is wrong.
Generated artifacts still serialize the merge
make generate owns the resource-type registry, schemas, audit and surface catalogs, and generated Nix. Declaration-touching lanes merge one at a time with a regeneration between each. MP1 order: U15, U1, U8, U17, then lane C - U1's type must be in the registry before U8's parity gate runs against it.
No PR before MP4
Review runs over the accumulated diff at every merge point, so coverage is total by MP4 and an early finding costs one lane's rework rather than the branch's. The single PR opens only when make check and make test-host-integration pass on the full change and at least one round of review has covered the code in total.
Critical path is ~5 units deep against a width of 5. Open decisions remain in U16 (what a guest-mode host is trusted with), U17, U1 (ZoneParent uid), and U12 (foreign-rooted audit record).