plans: brief for the host starting the landing run once a merge decision is approved (#1651)
Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
1 parent
917ef55e18
commit
bb0766826d
1 file changed
+104
@@ -0,0 +1,104 @@
|
||||
# Landing-run launch brief, 2026-10-18
|
||||
|
||||
A #314 follow-up from the row 149 review (Filbert, comment 28878 on
|
||||
#1643). Line numbers are at 4c1fee85a. Gitea #1651.
|
||||
|
||||
## The host starts the landing run once a merge decision is approved
|
||||
|
||||
### Problem
|
||||
|
||||
A non-thread instance never starts on its own. Only role.launch, pm's
|
||||
`launch` tool or `bus start <business> --pm` starts one
|
||||
(`packages/cli/src/launcher.mjs:1-36`). The thread tick
|
||||
(`launcher.mjs:358`, scheduled at `:561`) starts thread instances only.
|
||||
The launcher asks the broker `landHeld` once, at launch (`launcher.mjs:262`),
|
||||
and binds `land_work` and the git socket's land op only when it is true
|
||||
(`packages/bus/src/broker.mjs:951`). So the merge-gate run that raises a
|
||||
merge decision can't land it, and the approval comes back as a DECISION
|
||||
message (`broker.mjs:1590-1615`) that no launcher hears.
|
||||
|
||||
Row 149 closes the gap in the contracts: the technical arbiter tells the
|
||||
chief of staff, and the chief of staff launches merge-gate. That depends
|
||||
on two model turns, and after a restart (acceptance 314 step 7) on the
|
||||
chief of staff's next run reading a message sent before the restart.
|
||||
This row makes the host start the landing run itself.
|
||||
|
||||
### Owner and reviewer
|
||||
|
||||
- Owner: set when the row is briefed.
|
||||
- Reviewer: filbert.
|
||||
|
||||
### Files owned
|
||||
|
||||
- `packages/bus/src/broker.mjs`: a trusted read, `landHolders(business)`,
|
||||
the non-thread instances for which `landHeld` with `thread: null` is
|
||||
true, each with the id and resolution time of the decision that makes
|
||||
it true
|
||||
- `packages/bus/src/runtime.mjs`, `packages/bus/src/process.mjs`: the
|
||||
launch op `landHolders`, beside `threadsState` (`runtime.mjs:163`,
|
||||
`process.mjs:18`, `:36`)
|
||||
- `packages/cli/src/launcher.mjs`: the tick and its header comment
|
||||
- `packages/bus/tests/land.test.mjs`, `packages/cli/tests/launcher.test.mjs`
|
||||
- `packages/cli/README.md`, `docs/TOOLS.md`
|
||||
- `roles/merge-gate.md`, `roles/chief-of-staff.md`, `roles/cto.md`: only
|
||||
to say the host now starts the run. Row 149's steps stay as the
|
||||
fallback: cto tells the chief of staff, which ends the raising run if
|
||||
`launch` refuses `instance-running`, then launches
|
||||
- the packet `agents/<owner>/work/queue-<row>/`
|
||||
|
||||
### What ships
|
||||
|
||||
1. Each tick, after the thread pass, the host asks `landHolders`. For
|
||||
each holder that `launch.instances` lists and that isn't running, it
|
||||
starts the instance through `check()` and `start()` with
|
||||
`launchedBy` the business's human, as the thread pass does. The start
|
||||
refuses as any launch does.
|
||||
2. The raising run is usually still running. A runner stays in its
|
||||
`message.receive` loop after its turn, and only thread runs have an
|
||||
idle stop (`launcher.mjs:370-391`). A run that started before the
|
||||
decision's resolution has no `land_work`. The host stops it the way
|
||||
the idle stop does, SIGTERM to the runner after the start-time check
|
||||
(`launcher.mjs:388-390`), and logs `land-relaunch` with the run and
|
||||
the decision. It stops only between turns: a run with a turn in
|
||||
progress keeps going to a later tick, as `threadIdle` checks for a
|
||||
thread run, and the row adds that check for this run. The stop
|
||||
doesn't touch the decision. The next tick
|
||||
starts the instance. A run that started after the resolution already
|
||||
has `land_work`, and the host leaves it alone.
|
||||
3. One start per decision. The host keys starts on the decision id, as
|
||||
the thread pass keys them on the message and open
|
||||
(`launcher.mjs:396-400`). A run that ended without landing doesn't
|
||||
start again every tick. A refusal is logged once per code and isn't a
|
||||
start.
|
||||
4. A thread instance is never a holder. Thread runs keep today's rule.
|
||||
5. After a host restart, the first tick starts the holder, so step 7's
|
||||
landing comes from a new run of the same instance with the approval
|
||||
from before the restart.
|
||||
|
||||
Tests:
|
||||
|
||||
- `landHolders` lists an instance only while `landHeld` is true for it:
|
||||
not while open, declined, spent or gated, and not another role's.
|
||||
- The tick starts a listed holder once, gives it `land_work`, and starts
|
||||
nothing for an unlisted one or the same decision twice.
|
||||
- A holder whose run started before the resolution: the tick stops that
|
||||
run, logs `land-relaunch`, and the next tick starts it with
|
||||
`land_work`. A run started after the resolution is left running.
|
||||
- After the landing spends the decision, the tick starts nothing.
|
||||
- A host stopped and started with a held decision starts the holder on
|
||||
its first tick.
|
||||
|
||||
Mutants: one per behavior above, with the killing test in the packet.
|
||||
|
||||
### Out of scope
|
||||
|
||||
- The land op itself (row 137) and the contracts' two-run flow (row 149).
|
||||
- Thread instances that hold a merge decision.
|
||||
- A live smoke. Acceptance 314 steps 5 and 7 run after the re-pin, with
|
||||
Mos's go.
|
||||
|
||||
### Gate
|
||||
|
||||
Filbert approves on #1651, naming the candidate manifest digest. Sage
|
||||
reruns the full gate at the landing target, and it must be green. The
|
||||
bus is touched, so the live re-pin needs Mos's go.
|
||||
Reference in new issue
Block a user