window plan: 10-24 re-pin draft 1, NEW 7247d80c7 with --tester-socket (mos-1145, mos-1211)

This commit is contained in:
jason.woltje committed 2026-10-21 16:15:48 -05:00
1 parent 829e5f8340
commit f7a77721a9
2 files changed
+259

No files matched your search

@@ -0,0 +1,90 @@
# 10-24 window, notes for draft 1
Sage, 2026-10-21T19:40Z. These are working notes, not a draft. Draft 1 is cut from them once NEW is fixed.
Draft 0 is `repin-1024-draft0.md`.
## Changes since draft 0
- **Phase 2 order (mos-1197 item 3).** Phase 2 now runs after this window's re-pin is verified, not on
10-23 before it, and Jason picks the hour. So this window's OLD is the live pin, not a phase 2 copy, and
draft 0's line 14-17 and Q2 are out of date.
- **Console flags.** They stay as they are: no `--sso` and no `--send`. `--send` goes on with `--sso` in the
phase 2 window (mos-1197 2a). P0 checks that the window's activate line carries neither flag.
- **NEW (mos-1161).** NEW is the latest code landing when draft 1 is cut. At 19:40Z that is e54e05463 (row
215). 194 hasn't landed, so P3 has no lifecycle step unless it lands with a full gate first.
- **Row 66 live check (Vikunja #454, DEFERRED 3b0aef995).** This is the first re-pin whose tree includes
2c38325ec. Add a step after the window is verified. One Claude Code managed session with a prompt that
draws a known tell, then record the operator note on the RESULT, the next-turn notice and the
`unslop.jsonl` counts. Backup first (Q173). Pi isn't run (#383).
## OLD, read 19:38Z from `stack-release.sh status mosaic-stack` (read only)
- Copy 4429a104f6d65ccf165f6c83b5d1dce3147dfde0, schema 3i, pm true, activation 20261020T220206Z-4429a104f6d6.
- Console flags: `--port 7332 --public-host mosaic.woltje.com --auth-header X-authentik-username
--allow-user jason.woltje --tester-port 7333`. P1 re-reads these on the day.
- Check pass, unit flags match the pointer, 123 commits of drift.
## Schema
`git diff --name-only 4429a104f origin/refactor` shows only `packages/bus/schema.sql` and
`migrations/3i-3j.sql` (row 234). Nothing since c771a36f4 adds a step, so the migration is still 3i to 3j.
Recheck this at the cut. Row 206 (3k-3l) hasn't landed.
## Rows NEW carries after c771a36f4 (first-parent, code paths)
| Row | Commit | Live effect to check |
|---|---|---|
| 240 | c515273db | Installer I4: root host check, pins, boot unit. This window doesn't run it. |
| 228 | 86249ac55 | ZAI_API_KEY joins the session env allowlist. The live config sets no ZAI key, so the env is unchanged. Check in P3. |
| 238 | d49b1f2bd | sso-config takes `--instance` on named instances. Default instance, `--sso` off, so there's no effect. |
| 212 | ee7b2f137 | New package packages/library. The live business has no library entry. |
| 195 | b65014647 | scripts/case1-accept.sh, root only. Not run. |
| 213 | 361ba2387 | Creative roles (roles/companion.*), persona file and block, launch-settings, bundle.mjs. Live roles are chief, pm, coder and reviewer. P3: the chief's and pm's bundles are unchanged apart from the new code path, and one pm reply. |
| 231 | 29ce1e360 | Library reader fixes. No live library. |
| 235 | b1fece6f0 | Machine grant row b: raise binding, executor, reconcile, revoke and sweep (broker, host-grant, credentials, runtime). The live business has no hosts. P3: bus start runs the grant reconcile and sweep, and they change nothing. Show the log lines. |
| 221 | 300766450 | Persona import script, with a count-only dry run. Not run. yaml 2.9 joins package-lock, so P3 runs npm ci on the copy. |
| 247 | 856c1826b | Persona import follow-up. Not run. |
| 245 | 6d5545d44 | case1-accept F9 follow-up. Not run. |
| 248 | 8a04f4aa4 | Test stubs only. |
| 249 | 9de5a57ab | broker: hostLineLeft on a grant whose install never returned. No grants live. The A22b look-alike count in draft 0 already covers `hostLineLeft`. |
| 197 | a36523713 | Test lane fixture. No live effect. |
| 66 | 2c38325ec | Managed sessions run the unslop check, runner.mjs, and stack-copy.sh COPY_PATHS adds tools/unslop-hook. P3 checks that the copy has tools/unslop-hook. The live check is above. |
| 243 | 6096b051b | Tests only. |
| 215 | e54e05463 | Library entry kind, consumer skips, M9, bare mirror, library.file and library.status. The live business has no library entry. M9 refuses any organization write that changes `projects`, so P3 checks that the chief's or pm's usual organization writes don't touch projects. |
| 250 | 1b6158ce2 | Conversation shim and K12 test. No live effect on its own. |
| 222 | 0b33f5e9d | Fetch-only library sync: library.sync bus verb, a 60 s timer per library entry with a sync user, the askpass helper, and stack-copy.sh COPY_PATHS. The live business has no library entry, so the timer starts nothing. P3: the copy has packages/library/bin/askpass with its mode, and bus start logs no `library:` line. |
| 196 | 7247d80c7 | Human boundary: SO_PEERCRED on the bus socket, the interpreter receipt in bus/peercred-starts.jsonl, and the Console's private tester socket in place of `--tester-port`. The section "If 196 lands before the cut" applies. P3: bus start writes a receipt line, and the Console starts with `--tester-socket`. |
Added 2026-10-21T20:30Z. NEW at this hour is 0b33f5e9d (row 222, landed 20:13Z), the latest code
landing. PRD 1.9 (f48725cfc) and 1.10 are doc and test changes, but `packages/tasks/requirements.json`
is in the copy, so `task.create` takes REQ-WEB-2 and REQ-INST-2 as ids after the re-pin. P3: requirements
returns 70 ids at 1.10. 196 r6 (527b9a1e6, on f48725cfc) is in its gate, so the section below may apply.
Added 2026-10-21T21:02Z. 196 landed at 7247d80c7 (20:57Z), and c3d88840c after it is doc-only. NEW at
this hour is 7247d80c7, so the section below applies.
## If 196 lands before the cut
196 retires the Console's `--tester-port` (webui cli.mjs:30, "activate explicitly with --tester-socket").
The live Console runs `--tester-port 7333`, so a NEW that carries 196 changes the Console's command line.
Draft 1 would then need:
- the activate line with `--tester-socket` and its path;
- the P2 unit diff showing only that change;
- a P3 rehearsal that starts the Console with it.
bus.tester stays Jason's. The tester path changes how the test client reaches the Console, but not who can
reach it from outside, so it stays Q173 work. I confirm that with Mos in draft 1. If 196 hasn't landed, NEW
leaves it out and none of this applies.
mos-1198 item 4: until row 253 (#1758, case2-unit.sh and case1-accept.sh to `--tester-socket`) lands, no
Case 1 or Case 2 host (.53, .54) takes a copy that carries 196. This window is dragon-lin only, so it isn't
blocked, but any .53 or .54 step that names NEW waits on 253.
Row 250 landed 1b6158ce2 at 19:42Z (conversation shim and K12 test). It has no live effect on its own, but
it is now the latest code landing if the cut were made today.
## Still open from draft 0
- The P-step evidence for rows 199, 210 and now 235 at bus start, from a P3 rehearsal run.
- Recount the restore-guard table list from NEW (T46).
- Q3 operator: Darkwing if free.
@@ -0,0 +1,169 @@
# 10-24 window: re-pin 4429a104f to 7247d80c7 (rows 190, 199, 210, 234 and on, row 196 last), with 3i-3j (draft 1)
Sage, 2026-10-21, draft 1, for mos-1145 under DECISIONS Q173. Mos checks this file at its commit before P0.
Any change to this file or to NEW after that check means Mos checks it again (mos-0849/0850). The step layout
follows `repin-4429a104f.md`. Where a step is unchanged, I name it and say what differs. Draft 0 is
`repin-1024-draft0.md`, and the working notes are in `repin-1024-draft1-prep.md`.
## Who, and what nobody does
- Q3 below names the operator: Darkwing if they're free, otherwise me. Mos verifies each step's output before
the next one, and runs `rehearse` (P3).
- Jason has no step. Q173 covers a re-pin of this test system with a migration, a backup first and a STATE
report after. Nothing is pruned.
- Nobody acts as Jason. No `--by jason`, no human shell or tmux pane, and every bus read and write carries
`--tester`. `bus.tester` stays as it is. If it isn't `true`, stop at P1.
- No pi (P19 #383). No Save in the human Console, no `mosaic name`.
- Outside reach doesn't change. There's no `--sso` and no `--send`. Both go on together in the Q175 phase 2
window, which runs after this window is verified, when Jason starts it (mos-1195, mos-1197). The proof pair
stays unset. The tunnel still forwards 7332 only (P4 and W10).
- One Console flag does change. Row 196 retires the tester's TCP port. The live Console runs
`--tester-port 7333`, and NEW refuses that flag. So W5 converts it explicitly with `--tester-socket`, and
the tester listener becomes the 0600 socket `$DATA/console/tester.sock`. Only 127.0.0.1 could reach port
7333, so nobody outside gains or loses reach. Mos ruled this Q173 work in mos-1211 item 2. The socket is
narrower than loopback TCP, and Jason's row 196 ruling (on sage-1359) already accepted losing browser
access to 7333.
- Under mos-1198, .53 and .54 take no copy carrying 196 until row 253 lands. This window is dragon-lin only.
## Names
- OLD, live: `4429a104f6d65ccf165f6c83b5d1dce3147dfde0`, schema 3i, pointer `pm: true`, activation
`20261020T220206Z-4429a104f6d6`. The Console runs `--port 7332 --public-host mosaic.woltje.com --auth-header
X-authentik-username --allow-user jason.woltje --tester-port 7333`, read from `status` at 19:38Z. P1
re-reads all of these on the day. I don't copy them from this file.
- NEW: `7247d80c7af7ffa70fc61557406bf491cdf3bfc7`, the row 196 landing, the latest code landing when this
draft was cut (mos-1161). It is 135 commits past OLD (`git rev-list --count 4429a104f..7247d80c7`). The commit
after it, c3d88840c, is doc-only and doesn't move NEW. If 244 or 251 land before P0, NEW stays here unless
Mos rules otherwise (Q1).
- 194 hasn't landed, so P3 has no lifecycle step (mos-1161).
- `REPO`, `P`, `WIN=agents/sage/work/window-repin-7247d80c7/` and `SNAP` are as in `repin-4429a104f.md`, with
the sha checks at P0 and before S1, S2 and any D3.
## What NEW carries over OLD
This is draft 0's table, rows 201 through 234 plus PRD 1.7 and 1.8, unchanged, together with these rows from
`git log --first-parent c771a36f4..7247d80c7`, limited to packages, scripts, roles, contracts, adapters,
skills, tools, migrations and the package files:
| Row | Commit | Live effect to check |
|---|---|---|
| 240 | c515273db | Installer I4: root host check, pins and the boot unit. This window doesn't run them. |
| 228 | 86249ac55 | ZAI_API_KEY joins the session env allowlist. The live config sets no ZAI key, so the env doesn't change. P3 checks this. |
| 238 | d49b1f2bd | sso-config takes `--instance`. Default instance with `--sso` off, so no effect. |
| 212 | ee7b2f137 | New package, packages/library. The live business has no library entry. |
| 195 | b65014647 | scripts/case1-accept.sh, root only. Not run. |
| 213 | 361ba2387 | Creative roles, persona file and block, launch-settings, bundle.mjs. P3 checks that the chief's and the pm's bundles are unchanged apart from the new code path, and gets one pm reply. |
| 231 | 29ce1e360 | Library reader fixes. No live library. |
| 235 | b1fece6f0 | Machine grant row b. The live business has no hosts. P3: bus start runs the grant reconcile and sweep, they change nothing, and the log lines are shown. |
| 221, 247 | 300766450, 856c1826b | Persona import script and follow-up. Not run. yaml 2.9 joins package-lock, and W0's npm ci covers it. |
| 245, 248, 249 | 6d5545d44, 8a04f4aa4, 9de5a57ab | case1-accept F9, test stubs, and `hostLineLeft` on a grant whose install never returned. No grants are live. The look-alike count below covers `hostLineLeft`. |
| 197 | a36523713 | Test lane fixture. No live effect. |
| 66 | 2c38325ec | Managed sessions run the unslop check. COPY_PATHS adds tools/unslop-hook, and P3 checks the copy has it. W12 is the live check. |
| 243 | 6096b051b | Tests only. |
| 215 | e54e05463 | Library entry kind, consumer skips, M9 and the bare mirror. M9 refuses an organization write that changes `projects`, so P3 checks that the chief's and the pm's usual organization writes don't touch it. |
| 250 | 1b6158ce2 | Conversation shim and K12 test. No live effect on its own. |
| 222 | 0b33f5e9d | library.sync verb, a 60 s timer per library entry, and the askpass helper in COPY_PATHS. No library entry, so the timer starts nothing. P3: the copy has `packages/library/bin/askpass` with its mode, and bus start logs no `library:` line. |
| PRD 1.9, 1.10 | f48725cfc, add0f1aae | `packages/tasks/requirements.json` is in the copy. W9: the pm's requirements read answers version 1.10 with 70 ids. |
| 196 | 7247d80c7 | The human boundary. See the next section. |
## Row 196 in this window
What the code does (`scripts/stack-release.sh:791-845`, `docs/TOOLS.md` "Console tester listener"):
- An inherited `--tester-port` with no `--tester-socket` refuses `tester-transport-migration` before anything
stops. So `--tester-socket` goes on W3 and W5, and the plan's drop line must read
`--tester-port 7333 (replaced by private Unix socket)`.
- Before the stop, activate checks the socket path: `$DATA/console/tester.sock` must fit 107 bytes, and
`console/` must be absent or a directory with no symlink, owned by the instance's uid, with no group or
other bits. A failure refuses `tester-socket-path` before the stop. P1 reads `ls -ld $DATA/console`
(expected absent).
- Activate preflights the pinned root-owned system Python, records its identity, and checks the bus's fresh
start receipt. Each bus start appends one line to `$DATA/bus/peercred-starts.jsonl`. P3's rehearsal must show
the preflight passing on dragon-lin, and W9 reads the one new receipt line.
- `rehearse` starts NEW's Console with `--tester-socket` under its scratch data root when the copy carries
the socket marker (`stack-release.sh:2153-2155`). It doesn't run activate's path check from line 815, so
that check first runs live at W3. P1's `ls -ld $DATA/console` plus the path length are its only preview.
If the rehearsal Console fails to start on the socket, P3 stops and the log goes to Mos.
- Direct browser access to the tester is gone, with Mos's acceptance in mos-1015. W10's browser check on
127.0.0.1:7333 becomes `node packages/cli/src/tester-http.mjs GET /api/config` and `GET /api/bus/agents`, run from
the NEW copy against the live data root. Each must answer 200 with the same tester flags OLD's 7333 gave.
`mosaic ... --tester` still uses broker.sock.
Rollback is where 196 matters most. Without `--sso`, rollback takes the Console flags from the pointer, and
after W5 the pointer carries `--tester-socket`. OLD's Console doesn't support the socket. So rollback to OLD
drops the tester listener, the plan prints `--tester-socket (tester disabled; no TCP fallback)`, and port 7333
doesn't come back. The test client then has no tester listener until a new activate. Q4 asks Mos how to
handle that.
## Schema and backups
- `SCHEMA_VERSION` is 3i at OLD and 3j at NEW (`packages/bus/src/store.mjs:17`). The only step is
`packages/bus/src/migrations/3i-3j.sql` (row 234, tables `hosts` and `host_grants`). Nothing after c771a36f4
changes schema.sql or adds a step. `--plan` must say `migration: 3i -> 3j`.
- Restore guard, recounted at NEW (T46, `packages/cli/tests/stack-release.test.mjs:913`). COUNTED is the
same 11 tables (`stack-release.sh:404`). The untimed list has six: `host_grants`, `hosts`, `meta`,
`message_threads`, `sqlite_sequence` and `task_comment_cursors`. Each write to `hosts` or `host_grants` goes
with a `grant.*` event, which is counted. A D3 snapshot still covers them, as draft 0 says.
- W5 takes the stopped store backup every activate takes (SHA256SUMS, SCHEMA 3i, STAMP) plus the rollback
set. Before `--migrate` writes, I check that SCHEMA reads 3i and record the backup's SHA256SUMS hash. W0b
copies the business file, as last time.
- Grant look-alikes (row 234 A22b, gizmoduck-0107): P3, and again just before W5, on the backup copy. Count the
`action.allowed` events whose body.action or body.operation starts with `grant.`, or whose body has
`hostLineLeft`. Expect 0. Any nonzero count stops the window until I've read those rows.
- Rollback after the migration isn't the plain rollback. OLD is 3i and the store is 3j, so going back needs
`--restore <W5 activation>`, which loses the events written after W5. Mos decides any restore past W5.
## Before the window (nothing stopped)
| # | Who | Step |
|---|-----|------|
| P0 | Mos | The `$P` sha check, and this file's commit. |
| P1 | Sage | `status`: pointer, activation, schema 3i, Console flags, unit flags match. The business file sha256 and `business-check.mjs` LOAD_OK for OLD now and NEW after W0. `ls -ld $DATA/console` (expected absent). `bus.tester` is `true`. |
| W0 | Sage | `scripts/stack-copy.sh copy $NEW` in a gap between gate runs. The package-lock diff is empty. The copy has `tools/unslop-hook` and `packages/library/bin/askpass`, with the mode NEW's tree gives it. |
| P2 | Sage | `console-check.sh $NEW` on a stub Console on a scratch port, once without and once with `--tester-socket` under a scratch data root. CONSOLE_PASS both. Render the Console unit for NEW from REPO's `webui-service.sh` and diff it against the live unit. The only difference allowed is `--tester-port 7333` becoming `--tester-socket`. Diff the bus unit too. It must match apart from the copy path. |
| P3 | Mos | `stack-release.sh rehearse $NEW mosaic-stack --backup <latest live activation> --port <scratch>` with `--migrate` on the backup copy. It must show the 3j step, row counts before and after, the interpreter preflight passing, a receipt line, the grant reconcile and sweep changing nothing, no `library:` line, no publish or land decision open (rows 241, 242), the look-alike count 0, and one pm reply. As in mos-1107, Mos also starts NEW's Console by hand with the pointer's flags, with `--tester-socket` in place of `--tester-port`, and reads healthz, `/api/config` and the two tester-http reads. |
| P4 | Sage | The tunnel read. |
| P5 | Sage | The four service scripts are held at NEW (`git diff --quiet $NEW HEAD --` on them, and empty porcelain). If 244 or 251 lands and touches one of them, P5 fails and the window waits for Mos. |
| P6 | Sage | The 7332 matrix (a)-(g) on OLD, saved as `$WIN/matrix-old.txt`, plus the two tester reads on 7333 with curl, for W10 to compare against. |
## The window
| # | Who | Step |
|---|-----|------|
| W0b | Sage | The business file copy. |
| W1 | Sage | Idle check, the start stamp from `date -u`, then S1 with `$SNAP --held`. Open pm tasks from row 42: pm finishes or parks them before W5, or I record which piece crosses the window. |
| W2 | Sage | `status`: pointer on OLD, `pm: true`, 3i, unit flags match. |
| W3 | Sage | `stack-release.sh activate $NEW mosaic-stack --pm --migrate --tester-socket --plan`. It must show OLD to NEW, `migration: 3i -> 3j`, the backup line, the drop line for `--tester-port 7333`, and a Console line with OLD's other flags exactly: no `--send`, no `--sso`, no proof pair. Any other difference stops here. |
| W4 | Sage | The unit reads, as in the 177-185 plan. |
| W5 | Sage, on Mos's go | The same command without `--plan`. Exit 0, `result ok`, and every gate check passes, `pm_launched` included. Record the activation id, the backup path, STAMP and the backup SHA256SUMS sha256. Then `status`. |
| W9 | Sage, after Mos verifies W5 | The 177-185 W9 list, plus: the webui journal since the W5 stamp (with `UTC`) has no `Sign-in:` line; `/proc/<Console pid>/cwd` names the NEW copy; `$DATA/console/tester.sock` is 0600 in a 0700 `console/`; `peercred-starts.jsonl` gained one line for this start; the bus journal has the grant reconcile and sweep lines and no `library:` line; the pm's requirements read gives 1.10 with 70 ids. |
| W10 | Sage | The matrix again, as `$WIN/matrix-new.txt`, identical to `matrix-old.txt` apart from the lines the pin changes, each one named. The two tester reads through `tester-http.mjs` match P6's. Port 7333 has no listener (`ss -ltn`). Then P4 again. A write without a signed-in session must still be refused. That's Console POST through the main port, with no session. This is the check mos-1195 asks for before phase 2 is done, so I run it here too, as a baseline. |
| W11 | Sage | STATE report in `$WIN/STATE.md`, posted on P19 386 and 412 and on the J2 task, whose id I confirm by title before P0, and on the Gitea issues for 190, 199, 210, 234 and 196. |
| W12 | Sage, after W11 | Row 66's live check (Vikunja #454). One Claude Code managed session with a prompt that draws a known tell, then the operator note on the RESULT, the next-turn notice and the `unslop.jsonl` counts. Backup first (Q173). Pi isn't run (#383). |
## Stop conditions and rollback
The same as the 177-185 plan. Two failures in one window: stop and report (mos-0823).
Rollback before W5 writes is `rollback --plan`, then the real run. After the migration it needs `--restore
<W5 activation>`, with Mos deciding. Both drop the tester listener (see Row 196 above). Keep every copy.
Prune nothing.
## Questions for the plan check
- Q1: NEW is 7247d80c7. If 244 or 251 lands before P0, I recommend keeping NEW, so this check stays valid,
unless one fixes something this window needs.
- Q2: settled. mos-1211 item 2 rules the `--tester-port 7333` to `--tester-socket` change Q173 work.
- Q3: Darkwing operates if free, and I check. Otherwise I operate.
- Q4: after a rollback the tester listener is off. I recommend accepting that for the window's length, then
reading the tester through broker.sock until a fixed NEW goes on. The alternative is `activate 4429a104f
--tester-port 7333` as a same-copy re-pin of OLD, which restores 7333 but is a second activation.
## What Sage ran for this plan
Read only, 2026-10-21 between 20:40Z and 21:20Z: the path-limited first-parent log c771a36f4..7247d80c7,
`git rev-list --count`, `SCHEMA_VERSION` at both ends, `git diff --name-only` on the schema and migrations,
`stack-release.sh` lines 40-47, 125-158, 404, 791-845, 886-919 and 2140-2157, T46 in
`stack-release.test.mjs:913`, `packages/cli/src/tester-http.mjs`, and TOOLS.md:1274-1310 on the tester
listener. Nothing ran against
live. OLD's values come from the 19:38Z `status` read, and P1 reads them again.