sage: merged B+C window plan draft 9 (sha256 523f20e03be8aa11), Mos's formal check closed with the W0 go (mos-0907); A1-A4 text fixes to draft 8 (mos-0906)
This commit is contained in:
@@ -0,0 +1,346 @@
|
||||
# Merged window B+C: re-pin to the tip after rows 175 and 176, bus 3h to 3i, as the tester
|
||||
|
||||
Sage, 2026-10-19 (draft 9, 2026-10-20T01:29Z, Mos's four text fixes A1-A4 to draft 8, mos-0906; draft 8, 2026-10-20T01:23Z, NEW and the tool blob after row 176 landed as 89af38a83; draft 7, 2026-10-20T00:55Z, its header said 01:05Z in error, Mos's read of snapshot.mjs 639fd28a, mos-0899; draft 6: Mos's early read mos-0888 of draft 1, Darkwing's operator read of draft 2, the P3 dry run finding on 8e888014d with Mos's agreement mos-0894, the whole-store snapshot for D3 with Mos's four checks mos-0896, and its sha 639fd28a), for mos-0870 under DECISIONS Q173, with Q174 (mos-0882) for
|
||||
tonight. This plan replaces Window B (`repin-ca15d73e9.md`), which never ran, and the "first window past
|
||||
c216f47db" section at its end. Window B's commit table, stop conditions and D3 rule carry over and are restated
|
||||
here so this file stands alone.
|
||||
|
||||
Status: for Mos's formal plan check. Rows 169, 175 and 176 have landed on origin `refactor`, 176 as NEW. It doesn't
|
||||
run until Mos has checked this file at NEW. Any change to this file or to the tool blob after the check means Mos
|
||||
checks again (mos-0849/0850).
|
||||
|
||||
## Who, and what nobody does
|
||||
|
||||
- Darkwing operates, as the tester. Mos verifies each step's output before the next step starts. Sage owns the
|
||||
plan and files the STATE report in Vikunja.
|
||||
- Jason has no step. Under Q173 agents may re-pin, migrate, roll back and restore this test system without him.
|
||||
Decision 96 is Mos's (mos-0716). Q173 lifts its conditions 1 to 3 for this business (Jason or Mos runs it, Jason
|
||||
present for `--migrate`, the `--events` wait) and keeps condition 4, no pruning, which this plan follows. The
|
||||
tool's "needs: Jason present for this run (decision 96 condition 2)" line on a `--migrate` plan only echoes
|
||||
(`stack-release.sh:763`) and isn't a gate (mos-0888 Q1).
|
||||
- Nobody runs anything as Jason: no `--by jason`, no human shell, no typing into a tmux pane or a human Console
|
||||
session. Every bus read and write in this plan carries `--tester`, which row 175 adds.
|
||||
- `bus.tester` stays as it is. It's Jason's switch. If it reads anything but `true`, the window stops before W0.
|
||||
- No pi. No role var and no `harness` entry names pi, and nobody maps CLAUDE_CODE_OAUTH_TOKEN into a pi variable
|
||||
(mos-0865 D2, P19 #383).
|
||||
- Nobody presses Save in the human Console, and `mosaic name` stays out of the window (mos-0641).
|
||||
- Who can reach the Console from outside doesn't change. The tunnel still forwards 7332 only, and P4 and W10
|
||||
check that. A change there is Jason's (Q173 exclusions).
|
||||
|
||||
## Names
|
||||
|
||||
- OLD, live: `5fa9cc8f2c66b52408b652b59c3070f7210b44d0`. Bus schema 3h. Window A's activation
|
||||
`20261019T214524Z-5fa9cc8f2c66`, plug-ins usage-source `["transcript"]` and channel `["cli","webui"]`.
|
||||
- NEW: `89af38a83afa22a8a4f0d368a0a4030ad15a0efa`, the origin `refactor` commit that lands row 176. `NEW=<sha>` is
|
||||
the bare sha (`console-check.sh` takes the sha, mos-0866 F3). Bus schema 3i. Commits after NEW on `refactor` are
|
||||
records only and don't move NEW.
|
||||
- REPO: the canonical checkout. Tool blob: `git rev-parse NEW:scripts/stack-release.sh` is
|
||||
`adcb68477c25822968ec9856add55a6a5f674355`. Row 176 changed it (98d29769e had 0b501ffbc247). P3 runs on that blob.
|
||||
`stack-release.sh:N` references in this file are at NEW unless a section says otherwise.
|
||||
- `COPIES`, `C_OLD`, `C_NEW` as in Window A, with `C_OLD` on OLD and `C_NEW` on NEW. `C_NEW` is
|
||||
`node $COPIES/$NEW/packages/cli/src/cli.mjs`. From row 175 on, `$COPIES/$NEW/scripts/mosaic` dispatches
|
||||
`plugins`, `name` and `names` to the CLI, so either form works for NEW.
|
||||
- `DATA`: the config's data root, `node -p 'require(process.env.HOME+"/.config/mosaic-dev/config.json").dataRoot'`,
|
||||
absolute. The store is `$DATA/bus/bus.sqlite`, as `stack-release.sh:1006` reads it.
|
||||
- `T=7333`, the tester port.
|
||||
- `WIN`: `agents/darkwing/work/window-merged-bc/`, where every transcript goes.
|
||||
|
||||
## What NEW carries over OLD
|
||||
|
||||
`git rev-list --count 5fa9cc8f2..NEW` is 143 (133 at 716ddcf1e). The path-limited log over `packages`, `scripts`,
|
||||
`roles`, `contracts` and `adapters` (tests left out) lists these 14 code commits, read again at NEW. Row 179 is
|
||||
docs only and listed for completeness.
|
||||
|
||||
| Row | Commit | Live effect |
|
||||
|---|---|---|
|
||||
| 126 | ca15d73e9 | A daily token quota, the `limit-check` module `daily-quota`. It stays off: nobody sets `plugins.limit-check` here. Schema 3h to 3i (`usage_records.account` loses its NULL check, `packages/bus/src/migrations/3h-3i.sql`). |
|
||||
| ledger | efb51169d | `packages/ledger` only, which Sage runs by hand from the checkout each Monday (row 7). No bus, Console or launch effect. |
|
||||
| 65 | c216f47db | A launch takes harness, model and thinking from the instance vars, and refuses until `plugins.harness` lists the harness. This is why the window has two phases. |
|
||||
| 170 | cb43dcb45 | A tester message to a role nobody holds refuses `tester-target-not-running`. |
|
||||
| 171 | 078518e4e | A thread project named like a business-file repo refuses `project-name-is-repo` unless `--repo` matches. |
|
||||
| 134 | 3a600cf5b, a85e573d4 | A role holding `organization.change` reads the organization revision itself with the `organization_revision` tool. |
|
||||
| 172 | be10e0c83 | Console: a Seen click during a Board read waits for the read. |
|
||||
| 64 | 9f0039711, 6b6567b8b | A managed session gets its role's skills as prompt text. The launcher refuses `skill-not-enabled` for a listed skill not in `<dataRoot>/skills-enabled`. W8 carries the skills. |
|
||||
| 166 | 4b738e2da | Tool only: activate refuses unreadable drop-ins and quoted unit values, rechecks the bus after a held read, and gates on the target copy. |
|
||||
| 169 | 264756a30 | Tool only: `activate --pm-after-harness`, `pm-on` and the pending pointer. |
|
||||
| 179 | 9e74925c2 | `docs/TOOLS.md` only. |
|
||||
| 175 | 98d29769e | Tester reads and the tester writes W1-W7, recorded as `tester`. `scripts/mosaic` dispatches `plugins`, `name` and `names`. |
|
||||
| 176 | 89af38a83 | The Console's tester listener on 127.0.0.1, `--tester-port`, and 7332 refusing `x-mosaic-tester`. `activate --tester-port N` writes the flag into the pointer and the unit. Its bus.js change (b0ffec0ce to 01c12b9e1bf2) is inside the decision 123 go (mos-0900). An activate and a pm-on in the same second refuse `capture-failed` (row 169's race, P19 391): wait a second and retry (mos-0902). |
|
||||
|
||||
`SCHEMA_VERSION` (`packages/bus/src/store.mjs:17`) is 3h at OLD and 3i at ca15d73e9, c216f47db and HEAD. There's
|
||||
one migration step.
|
||||
|
||||
## A dependency on row 176: the pointer's Console flags
|
||||
|
||||
This section explains the brief change, so its line numbers are at 716ddcf1e, before row 176. At NEW the same
|
||||
lines are :109, :812 (now `RUN_CONSOLE`), :952 and :609.
|
||||
|
||||
The Console unit's flags live in the pointer (`P_CONSOLE`, `scripts/stack-release.sh:101`). `activate`, `pm-on`
|
||||
and `rollback` all install the Console with the pointer's flags (:774, :914), and `flags_drift` (:601) refuses
|
||||
`unit-flags-drift` when the unit and the pointer differ. So adding `--tester-port 7333` by hand with
|
||||
`webui-service.sh install` would make the next run refuse, and nothing today writes a new flag into the pointer.
|
||||
A rollback is worse. It installs OLD's Console with the pointer's flags, and OLD's `serve` doesn't know
|
||||
`--tester-port`, so the Console wouldn't start and the run would end `rollback-failed` with both units down.
|
||||
|
||||
Sage added this to the row 176 brief before Rocko started (sage-1107 told Mos), and 89af38a83 lands it:
|
||||
|
||||
- `activate ... --tester-port N` adds or replaces `--tester-port N` in the Console flags it installs and writes
|
||||
to the pointer. It refuses `tester-port-target` before anything stops when the target copy's own Console
|
||||
CLI doesn't take the flag. The check reads the target copy, not REPO.
|
||||
- `activate` and `rollback` to a target whose Console doesn't take the flag drop `--tester-port` from the
|
||||
flags, and say so in `--plan` and in the steps log. `rollback` back to such a copy is the only place this
|
||||
happens in practice.
|
||||
- A re-pin or rollback between two copies that both take it keeps it. Test 11's rollback case becomes these
|
||||
two cases.
|
||||
|
||||
So the window adds the tester port on the activate itself (W5). The activate's store backup comes first, which
|
||||
is what the 176 brief's Gate section asks for.
|
||||
|
||||
## Backups (Q173: a backup before every change)
|
||||
|
||||
| Before | Backup | Taken by |
|
||||
|---|---|---|
|
||||
| W5 activate, which migrates | the store, `<dataRoot>/backups/stack/<activation id>` | `stack-release.sh` itself (`backup_store`, :329). W5 records the path and stamp |
|
||||
| W6 harness set | the business file, `cp -p` to `~/.config/mosaic-dev/businesses/mosaic-stack.json.pre-window-<stamp>` and its sha256 | Darkwing, in W0b. The organization writer's receipt also logs the old and new values |
|
||||
| W8 skill carry | `<dataRoot>/skills-enabled`, `tar -C <dataRoot> -cf $WIN/skills-enabled-<stamp>.tar skills-enabled` | Darkwing, in W0b |
|
||||
| W7 pm-on | the rollback set `pm-on` captures (:944; the activation's own capture is in `run_steps`, :784). It changes no store schema | `stack-release.sh` |
|
||||
|
||||
## Before the window (nothing stopped)
|
||||
|
||||
| # | Who | Step |
|
||||
|---|-----|------|
|
||||
| P0 | Mos | As Window A: two OK lines. |
|
||||
| P1 | Darkwing | The live file, read only, printing these values and nothing else: `vars["bus.tester"]` is `true`; `plugins` has no `harness` key; `launch.by` is `chief` and `roles.chief.vars.harness` is `claude-code`; no role's `vars.harness` or `vars["fallback.harness"]` is `pi`. Sage read them on 716ddcf1e before this draft: `bus.tester` true, kinds `usage-source` and `channel` only, `chief` and all six roles `claude-code`. Then `node $P/business-check.mjs` for OLD and, after W0, for NEW. Both LOAD_OK. A `harness` key here would make phase 1 refuse `pm-after-harness-set`. A chief without a `harness` var would make `pm-on` fail `no-route` (Darkwing's row 169 rehearsal, finding 3). |
|
||||
| P2 | Sage | `console-check.sh $NEW` against a stub Console of NEW on a scratch port, once without and once with `--tester-port` on a second scratch port. CONSOLE_PASS both times. |
|
||||
| P3 | Darkwing | The rehearsal, on the day's tool blob, on a scratch root seeded at OLD and 3h. Its business file has Window A's plug-ins, no `harness`, a chief with `harness` `claude-code`, `bus.tester` true, and the example file plus the plug-in keys (mos-0847). Run W3, W5, W6 and W7 on it with a scratch tester port, then the rollback path after the harness set (harness to null as the tester, `business-check` under OLD, `rollback --restore <id> --plan`, `rollback --restore <id> --events N` with N from the D3 snapshot). Before the restore it makes one write that adds an event after the stamp, so N is above 0. The real run without `--events` must refuse `post-backup-events` and the rerun with `--events N` must pass. The 8e888014d dry run had N = 0 and didn't test that case. Then confirm the pointer, the store schema and the Console flags are back on OLD with no `--tester-port`. The chief launch is emulated as in queue-169. Unlike that rehearsal, the harness set here is the real `plugins set --tester`, not a stand-in, so P3 is its first live test. Output in `$WIN/p3/`, with sha256 values Sage checks. |
|
||||
| P4 | Darkwing | The tunnel, read only: `systemctl --user show mosaic-preview-tunnel.service -p ExecStart -p DropInPaths`. ExecStart has exactly one `R:` spec, `R:0.0.0.0:7332:127.0.0.1:7332`, and DropInPaths is empty. Anything else stops the window. Sage read it before this draft: one spec, as above. |
|
||||
| P5 | Darkwing | `git show $NEW:roles/<r>.json` for coder, reviewer, cto and pm. The seven skills W8 carries are still the lists' union minus ms-communications: ms-unslop, ms-sdlc, ms-file-read, ms-file-write, ms-archify, ms-grill-me, ms-goal (checked at 716ddcf1e). If a list changed, W8 changes and Mos checks again. |
|
||||
|
||||
## The window
|
||||
|
||||
| # | Who | Step |
|
||||
|---|-----|------|
|
||||
| W0 | Darkwing | `cd $REPO && scripts/stack-copy.sh copy $NEW`. Note the full id. Then P1's `business-check` for NEW. |
|
||||
| W0b | Darkwing | The two backups in the table above, each with its sha256 in `$WIN/backups.txt`. |
|
||||
| W1 | Darkwing | The PM-idle check: `mosaic agents --business mosaic-stack --tester` (the chief must not be `working`) and `mosaic launches list`. OLD's broker takes `agents --tester` (it is in OLD's TESTER_VERBS). Record the start stamp with `date -u +%FT%TZ`. Then the before-snapshot S1 (below), `node $WIN/snapshot.mjs --store "$DATA/bus/bus.sqlite" --held`. Nobody talks to the chief until W9, so no turn writes a usage record before the gate (D3). |
|
||||
| W2 | Darkwing | `scripts/stack-release.sh status mosaic-stack`: pointer on OLD, schema 3h, no pending line, last line ok, unit flags match the pointer. |
|
||||
| W3 | Darkwing | `scripts/stack-release.sh activate $NEW mosaic-stack --pm-after-harness --migrate --tester-port 7333 --plan`. It must match P3 on: from OLD, to NEW, store schema 3h read from the store the running bus holds, target 3i, one step 3h to 3i, `--migrate` given, the commit count, and the Console flags with `--tester-port 7333` added. No `pm-after-harness-target`, `pm-after-harness-set`, `unknown-kind-for-target` or `tester-port-target` refusal. Any other difference stops the window here. |
|
||||
| W4 | Darkwing | The units, read only: `systemctl --user show [email protected] -p ExecStart -p WorkingDirectory -p DropInPaths -p Environment` and `systemctl --user show mosaic-webui.service -p ExecStart -p WorkingDirectory -p DropInPaths`. DropInPaths empty on both. Bus ExecStart has `--pm`. Both name the OLD copy. No `"`, `'` or `\` in the bus `Environment=` or either ExecStart (row 166's `unit-flags-drift`). |
|
||||
| W5 | Darkwing, on Mos's go | Phase 1: `scripts/stack-release.sh activate $NEW mosaic-stack --pm-after-harness --migrate --tester-port 7333`. Exit 0, final `result ok`, every gate check except `pm_launched`. Record the activation id and the backup path and stamp. Then `status`: pointer on NEW, `pm: false`, `pmPending: true`, schema 3i, Console flags with `--tester-port 7333`, and the pending line. The bus is live without its PM. |
|
||||
| W6 | Darkwing, after Mos verifies W5 | The harness set, as the tester: `$C_NEW plugins --business mosaic-stack --tester --json` for the revision, then `$C_NEW plugins set --file $WIN/harness.json --business mosaic-stack --tester` with `{"revision":"<that revision>","plugins":{"harness":["claude-code"]}}`. Read it again: `harness` is `["claude-code"]`, `usage-source` and `channel` unchanged. The organization receipt names actor `tester`. Then Mos runs `business-check` under NEW on the patched file: LOAD_OK. |
|
||||
| W7 | Darkwing, on Mos's go | Phase 2: `scripts/stack-release.sh pm-on mosaic-stack`. Exit 0: the chief launched and the pointer is `pm: true` with no `pmPending`. Exit 1 or 2: see the stop conditions. |
|
||||
| W8 | Darkwing, after Mos verifies W7 | The row 64 skill carry, from the pinned copy (`carry-past-row64.md`): `cd $COPIES/$NEW`, install and activate the seven, then `scripts/skill.sh list` shows eight under `enabled:` and ms-tools under `available:`. A STOP line is a stop condition. |
|
||||
| W9 | Darkwing | The checks and the turn below. |
|
||||
| W10 | Darkwing | The browser check below, then P4's tunnel read again. |
|
||||
| W11 | Darkwing, then Sage | The STATE report (below). Sage files it on P19 386 and 382 and closes 382 if W5 to W9 passed. |
|
||||
|
||||
### S1 and S2, the store snapshots
|
||||
|
||||
The before-reads can't go through the bus. OLD's broker doesn't take `--tester` on `usage`, `names` or
|
||||
`threads`, and row 175 only adds those on NEW. So S1 (in W1) and S2 (in W9) read the live store directly with
|
||||
Darkwing's `$WIN/snapshot.mjs` at 639fd28a, which Mos read (mos-0899). It reads every table in `sqlite_master`
|
||||
(type table, less `sqlite_*`). For each it prints the row count, the max `seq` and a sha256 of the rows, in `seq`
|
||||
order, or in column order for a table without `seq`. Every table hashes all its columns in name order except
|
||||
`usage_records`, which hashes the explicit list the 3h-3i copy carries (`3h-3i.sql:9`), so S1 under 3h and S2
|
||||
under 3i hash the same old rows. Only `usage_records` refuses `columns-changed`, when its column set differs from
|
||||
that list. It adds per-run input and output sums for `usage_records`, and `messages` and `message_threads` print
|
||||
counts only. It prints no message body, no instance, project or thread name, no credential and no file content.
|
||||
It reads no config, so `--store` takes the absolute store path.
|
||||
|
||||
`--held` is a plain `readOnly` open of the store the running bus holds, as `stack-release.sh` does, and refuses
|
||||
`store-not-held` if `-wal` or `-shm` is absent. `--stopped` opens it with `immutable=1` and refuses `store-unclean`
|
||||
if either is present. `--after` takes only the STAMP form with milliseconds (`2026-10-20T00:11:14.123Z`, `now_ms`
|
||||
at `stack-release.sh:44`). The count is a text compare, as the tool's own count at :298 is, so a timed table with
|
||||
any `at` in another form refuses `at-format` and names the table. `eventsAfter` is the query the tool runs for
|
||||
`--events`. S1 and S2 run against the live store with `--held`. The first version (909a11f65c42de1d, three
|
||||
tables, approved in mos-0892) is replaced.
|
||||
|
||||
Draft 5 changes the D3 side (sage-1123). Darkwing found that a tester `project.create` writes `projects` and a
|
||||
tester `message.send` writes `messages` and maybe `message_threads`, with no event, so the three-table stop
|
||||
misses them. The new `snapshot.mjs` reads the table list from `sqlite_master`, so a table added later can't slip
|
||||
by. It gives a `rowsAfter` count for every table with an `at` column. Each table without one is named in the
|
||||
output with its count against the backup's `bus.sqlite`, opened read-only. It still prints counts only, and
|
||||
`usage_records` keeps its explicit column list. Mos read all 235 lines and approved it at 639fd28a for S1, S2
|
||||
and D3 (mos-0899). Before each of S1, S2 and D3, Darkwing runs `sha256sum $WIN/snapshot.mjs` and refuses to run
|
||||
the snapshot on anything other than 639fd28a2674aaa03ce824e3394b4052f21cdef7d6fa49bae61a9927ed341e67.
|
||||
|
||||
The whole-store script is sha256 639fd28a2674aaa03ce824e3394b4052f21cdef7d6fa49bae61a9927ed341e67 (Darkwing,
|
||||
2026-10-20, snaptest run 5: 63 pass, 0 fail, records in `$WIN/snaptest/`, SHA256SUMS 10a4a5861e39f32e). Mos's
|
||||
four checks (mos-0896) and the tests for each:
|
||||
|
||||
- The backup opens with immutable=1 and readOnly, as `--stopped` does, and refuses `backup-unclean` when a `-wal`
|
||||
or `-shm` sits beside it. A test reads the backup five times and checks that files, sizes, mtimes, modes and
|
||||
sha256 values are unchanged. A missing or relative `--backup` refuses.
|
||||
- Counts only. `messages` and `message_threads` print rows, maxSeq, rowsAfter and counts against the backup,
|
||||
with no sha256 and no 64-hex value anywhere in their output.
|
||||
- `--after` must be the STAMP form with milliseconds (`now_ms`, `stack-release.sh:44`). With it, any `at` in a
|
||||
timed table that isn't in that form refuses `at-format`, naming the table and printing no value.
|
||||
- The table list is `type='table' AND name NOT LIKE 'sqlite\_%' ESCAPE '\'`, so `sqlite_sequence` is skipped
|
||||
and a table named like `sqlitex` is still listed. A table the backup lacks stops the window.
|
||||
|
||||
A mutant for each rule is caught by the named tests (17, 3, 1, 7 and 2 failures, `$WIN/snaptest/mut/`). The
|
||||
untimed tables are `message_threads`, `meta` and `task_comment_cursors`. Every bus table has `no_update`,
|
||||
`no_delete` and `no_replace` triggers, so an old row can't change in place without a schema change. The script
|
||||
still compares the rows at or below the backup's max seq as a backstop.
|
||||
|
||||
### W9 checks and the turn
|
||||
|
||||
```
|
||||
scripts/stack-release.sh status mosaic-stack # pointer on NEW, pm true, schema 3i, last line ok
|
||||
bash $P/console-check.sh $NEW # CONSOLE_PASS
|
||||
mosaic launches list # one running chief from this start
|
||||
mosaic agents --business mosaic-stack --tester # chief idle, pm not running
|
||||
mosaic talk chief "[mos test] re-pin $NEW: reply with one line, no staffing request" --tester
|
||||
$C_NEW plugins --business mosaic-stack --tester --json # harness, usage-source, channel; no limit-check
|
||||
$C_NEW names --business mosaic-stack --tester --json
|
||||
$C_NEW threads --business mosaic-stack --tester --json
|
||||
mosaic limits --business mosaic-stack --tester --json # exit 0
|
||||
mosaic usage --business mosaic-stack --tester --json # one new byRun entry
|
||||
node $WIN/snapshot.mjs --store "$DATA/bus/bus.sqlite" --held # S2, after the coder session ends
|
||||
```
|
||||
|
||||
Then one start of a role that lists skills (`carry-past-row64.md`, sage-1064 R4, mos-0863 D3): a coder session
|
||||
the tester starts with the task "List the skills in your prompt, then stop." The task makes no repo write, push,
|
||||
PR, issue or outward message (mos-0888 F2). Its bundle `manifest.json` lists the coder's four skills with their
|
||||
sha256 values. Darkwing records how the session ends: it exits by itself, or Darkwing stops it, with the stamp.
|
||||
S2 runs after it ends and shows its `usage_records` rows. A refusal here is a stop.
|
||||
|
||||
What passes:
|
||||
|
||||
- The 3i migration kept the rows: S2 has S1's `usage_records` rows unchanged, plus this start's chief run and
|
||||
the coder run. `instance_names` and threads are unchanged.
|
||||
- The transcript source works under 3i: one new `byRun` entry for the chief turn, input > 0, output > 0 and
|
||||
`unknownTurns` 0.
|
||||
- The tester reads answer. Their values agree with S2 where both report the same thing.
|
||||
- `byAccount` isn't compared with S1, since ca15d73e9 writes an account on new rows.
|
||||
|
||||
### W10 browser check, on the tester listener
|
||||
|
||||
On http://127.0.0.1:7333/ with the webui browser harness, from Darkwing's run:
|
||||
|
||||
1. The page shows the tester banner and the instance, routes and name editors only.
|
||||
2. The Board and Settings read. Settings shows Token limits with no daily quota entry.
|
||||
3. A request to 7332 with `x-mosaic-tester: 1` and a loopback Host gets 403.
|
||||
4. No write through the listener. The routes editor's write path is row 176's test 12 on a fixture, not a live
|
||||
change in this window.
|
||||
|
||||
Then P4 again: the tunnel's ExecStart still has the one `R:0.0.0.0:7332:127.0.0.1:7332` spec.
|
||||
|
||||
### W11 STATE report
|
||||
|
||||
Darkwing writes `$WIN/STATE.md`: the stamps, the activation ids for W5 and W7, the backup paths and sha256
|
||||
values, the pointer before and after, the unit ExecStart lines (no Environment values), S1 and S2, the W9 and
|
||||
W10 outputs, and any stop. Sage checks it against the transcripts, then posts a summary on P19 386 and 382 and
|
||||
on Gitea #1673 and #1674.
|
||||
|
||||
## Stop conditions
|
||||
|
||||
Before W5, any refusal or mismatch ends the window with nothing stopped.
|
||||
|
||||
- W5 exit 1: the run rolled back inside itself, restored the backup and started OLD. Report the log line and the
|
||||
failing check to Mos.
|
||||
- W5 exit 2, `rollback-failed`: both units stay stopped. Mos settles it from the rollback set the message names.
|
||||
- W6 fails: the pointer stays pending and the bus runs without its PM. Mos decides between fixing the set and
|
||||
the rollback from pending, which needs no harness undo.
|
||||
- W7 exit 1, `pm-on-failed`: the bus stays live without its PM and the pointer stays pending. Mos decides between
|
||||
fixing the `harness` entry and running `pm-on` again, or the rollback below. Exit 2, `pm-on-down`: both units
|
||||
are stopped, and Mos settles it.
|
||||
- W8, W9 or W10 failure after W7 passed: Mos decides between a fix forward and the rollback.
|
||||
- Two failures in one window: stop and report (mos-0823).
|
||||
|
||||
### The rollback, after W6
|
||||
|
||||
OLD refuses the unknown `harness` kind when it loads the file (ca15d73e9 `kinds.mjs:78`). So:
|
||||
|
||||
1. Darkwing sets `harness` to `null` as the tester with NEW's CLI, since OLD has no `plugins --tester` and
|
||||
tester-cli checks its own copy through argv[1]: `$C_NEW plugins --business mosaic-stack --tester --json` for the
|
||||
revision, then `$C_NEW plugins set --file $WIN/harness-null.json --business mosaic-stack --tester` with
|
||||
`{"revision":"<that revision>","plugins":{"harness":null}}`. Then a read again.
|
||||
2. Mos runs `business-check` under OLD. LOAD_OK.
|
||||
3. If W8 ran, its rollback: deactivate and uninstall the seven, and `list` shows ms-communications alone.
|
||||
4. The D3 counts below, then `rollback mosaic-stack --restore <W5 activation id> --plan`, then the real run
|
||||
with `--events N`, N from D3. The tool refuses `unknown-kind-for-target` by name until step 1 is done. With the
|
||||
row 176 change, `--plan` says it drops `--tester-port 7333`. `--plan` doesn't count the events after the
|
||||
backup: it exits at `stack-release.sh:854`, before the count at :866-875. A real run without `--events`, or
|
||||
with a count that no longer matches, refuses `post-backup-events` with the count before anything stops. That
|
||||
refusal is expected if the count moved after D3. Read it, take Mos's go again, and rerun with the new N.
|
||||
|
||||
From pending before W6, `rollback` installs OLD with `--pm` and gates `pm_launched`, with nothing else first.
|
||||
It still needs `--restore`, since the store is 3i.
|
||||
|
||||
### Before any `rollback --restore` (mos-0838 D3)
|
||||
|
||||
`--restore` counts only the `events` table after the backup stamp (`stack-release.sh:298`). `usage_records`
|
||||
(`usage.mjs:93`), `instance_names` (`broker.mjs:2237`), `projects`, `messages` and `message_threads` are written
|
||||
outside it, and a restore drops their rows written after the stamp from the live store. The post-attempt copy
|
||||
the run keeps still has them.
|
||||
|
||||
1. Darkwing runs `node $WIN/snapshot.mjs --store "$DATA/bus/bus.sqlite" --held --after "$(cat <backup>/STAMP)"
|
||||
--backup <backup>/bus/bus.sqlite`, where `<backup>` is `$DATA/backups/stack/<W5 activation id>`, with the
|
||||
snapshot.mjs sha Mos approved for D3, 639fd28a (mos-0899). Darkwing reports to Mos every table's rows after the backup
|
||||
stamp, the count difference against the backup for each table without an `at` column, and `eventsAfter`,
|
||||
which is the `--events N` value, plus `stopTables` and every table with `priorSame` or `same` false. STAMP is
|
||||
ISO with milliseconds, which `--after` takes. When the bus is stopped, after W5 exit 2 or W7 exit 2
|
||||
(`pm-on-down`), both units are down and `--held` refuses `store-not-held`, so D3 runs with `--stopped` in place
|
||||
of `--held`. A `store-unclean` refusal stops the window and goes to Mos.
|
||||
2. If `stopTables` is not empty, Darkwing stops before the restore, whatever `eventsAfter` says (mos-0899 A1).
|
||||
`stopTables` names every table other than `events` with rows after the stamp, a count difference, or a
|
||||
changed row at or below the backup's max seq. The last case has no row after the stamp and no count
|
||||
difference, so a check on those two alone would miss it (Darkwing's m5 mutant: `usage_records` with
|
||||
`priorSame` false). The tool won't refuse: a write that adds no event passes its guard. In the P3 dry run on 8e888014d, one
|
||||
`name --tester` after the stamp gave `instance_names` rowsAfter 1 and eventsAfter 0. The restore printed
|
||||
"0 event(s) were written after the backup" and dropped that row from the live store with no refusal. The row
|
||||
survived only in the post-attempt copy.
|
||||
3. Mos decides. Mos's go names the rows the restore drops, table by table. Under Q173 losing test-system data
|
||||
is allowed, so Jason isn't asked, but the counts go in the STATE report. Nobody opens or changes the
|
||||
post-attempt copy. The tool fix, counting these tables in the `--restore` guard, is a follow-up row Sage
|
||||
files after the window with its own brief and issue, tracked as Vikunja P19 390 (mos-0894). It isn't part of
|
||||
this window.
|
||||
4. A backstop: nobody makes a tester `project.create` or `message.send` between W5 and a rollback unless a
|
||||
window step needs it, so the stop in step 2 has as little to name as possible.
|
||||
5. Past W7 the stop always fires. A real PM launch writes `role_claims` and similar rows after the stamp
|
||||
(Darkwing, 2026-10-20). That is expected, not a fault: a rollback after W7 always needs Mos's go naming
|
||||
those rows. A rollback before W7 can pass step 2 with only `events` moved.
|
||||
|
||||
## Rollback copies
|
||||
|
||||
Keep 5fa9cc8f2, 8e7ea89a1, 52f35e7a0 and 3190ad762 (mos-0866). Don't touch 66ea40580. Nothing is pruned: the
|
||||
rollback sets, the backups and any post-attempt store stay.
|
||||
|
||||
## Questions for the plan check
|
||||
|
||||
Mos answered these in the early read of draft 1 (mos-0888):
|
||||
|
||||
- Q1, `--migrate` without Jason: yes. Conditions 1 to 3 of decision 96 are lifted, 4 stands (see "Who").
|
||||
- Q2, the row 176 brief change: approved. `pm-on` keeps the flag through `P_CONSOLE` (:914). Dewey's review
|
||||
covers how `tester-port-target` decides the target's Console takes the flag, and that it reads the target
|
||||
copy, not REPO.
|
||||
- Q3, S1 and S2 as a read-only snapshot: approved with F1 (the explicit column lists above).
|
||||
- Q4, the W9 coder start: approved under Q173 with F2 (the task above).
|
||||
- F3: W6 and W8 run after Mos verifies the step before, like W5 and W7.
|
||||
|
||||
Mos agreed the restore-guard handling in mos-0894: stop on any nonzero rowsAfter (widened to a non-empty
|
||||
`stopTables` in mos-0899), the tool fix as a row after
|
||||
the window (P19 390), and P3 on the 176 landing tests `--events N` with N above 0.
|
||||
|
||||
Mos approved the whole-store `snapshot.mjs` at 639fd28a for S1, S2 and D3 (mos-0899) and agreed D3 step 5
|
||||
with no allowlist.
|
||||
|
||||
Draft 8 puts NEW, the row 176 table line and the tool blob at NEW in this file. The P3 output sums from the run on
|
||||
NEW with `--events N` above 0 go in Darkwing's P3 transcript under `$WIN` and to Mos by message, not in this file,
|
||||
so this file's sha doesn't change when they arrive. The formal check covers this file's sha and those sums.
|
||||
|
||||
## What Sage ran for this plan
|
||||
|
||||
Read only, on 716ddcf1e, before 2026-10-19T23:59Z. Nothing live was changed.
|
||||
|
||||
- `git rev-list --count 5fa9cc8f2..HEAD` (133) and the path-limited log above.
|
||||
- `SCHEMA_VERSION` at 5fa9cc8f2, ca15d73e9, c216f47db and HEAD, and the one migration file.
|
||||
- `scripts/stack-release.sh` at HEAD: `parse_opts` (:60-80), `plugin_checks` (:264-277), `flags_drift`
|
||||
(:594-610), `run_steps`, `do_rollback` (:811-845), `do_pm_on` (:890-915), `backup_store` (:321).
|
||||
- The row 176 brief, the row 169 packet (`agents/darkwing/work/queue-169/BUILD.md`, findings 1-3) and
|
||||
`carry-past-row64.md`.
|
||||
- `roles/*.json` skill lists and `<dataRoot>/skills-enabled` (ms-communications alone).
|
||||
- The live business file's `vars["bus.tester"]`, plug-in kind names, `launch.by` and each role's `vars.harness`,
|
||||
printing those values only.
|
||||
- `systemctl --user show mosaic-preview-tunnel.service -p ExecStart`.
|
||||
Reference in New Issue
Block a user