15 KiB
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.testerstays as it is. If it isn'ttrue, stop at P1. - No pi (P19 #383). No Save in the human Console, no
mosaic name. - Outside reach doesn't change. There's no
--ssoand 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 Mos's acceptance in mos-1015 (on sage-1359) already accepted losing browser access to 7333. DECISIONS has no Jason ruling on 7333 (mos-1214 item 2). - 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, pointerpm: true, activation20261020T220206Z-4429a104f6d6. The Console runs--port 7332 --public-host mosaic.woltje.com --auth-header X-authentik-username --allow-user jason.woltje --tester-port 7333, read fromstatusat 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/andSNAPare as inrepin-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-portwith no--tester-socketrefusestester-transport-migrationbefore anything stops. So--tester-socketgoes 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.sockmust fit 107 bytes, andconsole/must be absent or a directory with no symlink, owned by the instance's uid, with no group or other bits. A failure refusestester-socket-pathbefore the stop. P1 readsls -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. rehearsestarts NEW's Console with--tester-socketunder 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'sls -ld $DATA/consoleplus 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/configandGET /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 ... --testerstill 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_VERSIONis 3i at OLD and 3j at NEW (packages/bus/src/store.mjs:17). The only step ispackages/bus/src/migrations/3i-3j.sql(row 234, tableshostsandhost_grants). Nothing afterc771a36f4changes schema.sql or adds a step.--planmust saymigration: 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_sequenceandtask_comment_cursors. Each write tohostsorhost_grantsgoes with agrant.*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
--migratewrites, 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.allowedevents whose body.action or body.operation starts withgrant., or whose body hashostLineLeft. 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, 412 and 435 (J2, mos-1215), 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, answered (mos-1214 item 3)
- Q1: NEW stays
7247d80c7unless a landing fixes something this window needs. - Q2: mos-1211 item 2 rules the
--tester-port 7333to--tester-socketchange Q173 work. - Q3: Darkwing operates if free, and I check. Otherwise I operate.
- Q4: after a rollback, the tester listener stays off for the window's length, and the tester goes through
broker.sock. A same-copy re-activation of OLD with
--tester-port 7333goes to Mos only if a rollback holds past the window day.
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.