docs: row 116 brief round 2, land-work reads the bus database read-only (#1610)
Darkwing asked how land-work reads the decision. The Console's path is human-only (human-cli refuses agent environments, #225), so the conductor can't use it. land-work now opens bus.sqlite readOnly, runs SELECTs only and refuses bus-schema on a digest mismatch. The brief records what f71c73c9 holds: task_ref is null, the raise's target and approvalChoice give the branch and the merge option, and the work ref comes from the question. agents/sage/work/row116/live-rows.json holds the live rows for the replay fixtures. Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
@@ -60,10 +60,13 @@ and tell Sage. Don't add a verb.
|
||||
### What ships
|
||||
|
||||
1. `land-work <decision-id> [--base refactor] [--dry-run]`. It reads,
|
||||
and never writes, the decision and the verdict through the existing
|
||||
read-only path the Console and `mosaic` use. It never opens
|
||||
bus.sqlite for writing. It refuses with a named reason and exit 2
|
||||
unless all of these hold:
|
||||
and never writes, the decision and the verdict. It opens
|
||||
`<dataRoot>/bus/bus.sqlite` with `node:sqlite` `readOnly: true`, runs
|
||||
SELECTs only, and refuses `bus-schema` unless `schemaDigest(db)`
|
||||
equals `SCHEMA_SHA256` from `packages/bus/src/store.mjs` (imported,
|
||||
not copied). See "Read path" below for why it isn't the Console's
|
||||
path. It refuses with a named reason and exit 2 unless all of these
|
||||
hold:
|
||||
- the decision is resolved, by a human, with the option that means
|
||||
merge. The decision names one work ref (`work/vikunja-<p>-<t>`) and
|
||||
one target branch (exactly `refactor`; `next` and `main` always
|
||||
@@ -100,6 +103,49 @@ and tell Sage. Don't add a verb.
|
||||
8. The worktree, its `node_modules` link and any Docker network named
|
||||
for it are removed on every path, including refusals.
|
||||
|
||||
### Read path (Sage, 2026-10-14, after Darkwing's question)
|
||||
|
||||
Round 1 of this brief said to read through "the existing read-only path
|
||||
the Console and `mosaic` use". That path is human-only. `human-cli`
|
||||
refuses inside an agent environment and the broker checks the caller's
|
||||
ancestry (#225), so the conductor, which in practice is Sage's seat,
|
||||
can't use it. Asking a human to run `mosaic trail` before each landing,
|
||||
or to save the trail to files the tool trusts, would bring back the
|
||||
hand-routing this row removes.
|
||||
|
||||
So `land-work` reads the bus database directly, read-only, on the host.
|
||||
That's the same trust as the conductor's other host reads, and no
|
||||
session can reach the tool. No broker verb and no change under
|
||||
`packages/bus/src`. The schema digest check fails closed when the store
|
||||
changes, and the queries go in one module, so a schema change is one
|
||||
place to fix.
|
||||
|
||||
What f71c73c9 actually holds, read from the live database:
|
||||
|
||||
- `decisions`: `action` is `git.merge.protected`, `class` is `gated`,
|
||||
`route_to` is `human`, `task_ref` is null, `options` is
|
||||
`[{"key":"yes",...},{"key":"no",...}]`.
|
||||
- `decision_events`: one `resolved` by `jason`, `choice` `yes`, `via`
|
||||
`cli`.
|
||||
- The raise's `action.allowed` event (`operation` `decision.raise`)
|
||||
carries `target: "refactor"` and `approvalChoice: "yes"`, with
|
||||
`task_ref` null.
|
||||
|
||||
So the merge option is the raise's `approvalChoice`. The target branch
|
||||
is the raise's `target`. The work ref comes from the question text,
|
||||
which must name exactly one `work/vikunja-<p>-<t>` and no other work
|
||||
ref. The task is `vikunja:<p>/<t>` from that ref. If a later decision
|
||||
sets `task_ref`, it must agree with the ref from the question, or the
|
||||
tool refuses.
|
||||
|
||||
Tests build their fixture database through the real `Store` (and the
|
||||
broker where that's simpler), so the schema digest matches. The 19/265
|
||||
replay fixture copies the live rows: the decision, its event, the
|
||||
raise's event, and the task's `review.verdict` events (seq 368
|
||||
`changes` on 1b301831, seq 379 `approve` on 8ae5a149, id d3f97f9d).
|
||||
19/229 had no merge decision. Its replay uses a fixture decision of the
|
||||
same shape over verdict 1fbd1ed1 (`approve`, 010d30cbe).
|
||||
|
||||
### Not in this row
|
||||
|
||||
- Push, merge to `next` or `main`, re-pin or restart. Those stay
|
||||
|
||||
Reference in New Issue
Block a user