plans: D1 brief carries decision 96's four conditions and records the claude pin and Console flags in the pointer (Mos mos-0716, Darkwing survey)

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
2026-10-18 10:44:59 -05:00
co-authored by Claude Opus 5.5
parent 23533625d4
commit d503552eab
+64 -23
View File
@@ -77,7 +77,12 @@ start has no gate that puts the old copy back.
1. A pointer and a log, the same shape as `release.sh`:
- `<dataRoot>/state/stack-active.json` holds `{ copy, business, pm,
schema, activation, at }`. It is written to a temp file and renamed.
claude, console, schema, activation, at }`. It is written to a temp
file and renamed. `claude` is the bus unit's `--claude` pin, and
`console` is the Console unit's flag list (`--port`, `--business`,
`--board`, `--send` and the public-host, auth-header and allow-user
set). `webui-service.sh` saves its flags nowhere else, so the
pointer is their record (Darkwing's survey, 2026-10-18).
- `<dataRoot>/state/stack-activation-log.jsonl` is append-only. Each
line has `at`, `op`, `from`, `to`, `backup`, `result` and, on a
refusal or a failed gate, `code`. `op` is one of `adopt`,
@@ -89,7 +94,10 @@ start has no gate that puts the old copy back.
passes and the bus unit's copy is the Console's and the wrapper's.
The live stack is already on one copy (52f35e7a0), so no mixed-setup
path is needed. A pointer that already exists refuses
`already-adopted`.
`already-adopted`. `adopt` reads `claude` and `console` from the
effective units with `systemctl --user show -p ExecStart -p
Environment`, the way `bus-service.sh status` reads `--pm`
(:200-209).
3. `activate ID BUSINESS [--pm]` moves the stack from the pointer's copy
to copy `ID`. It refuses, with a code, a log line and no change, when
any of these holds:
@@ -101,7 +109,11 @@ start has no gate that puts the old copy back.
- a bus drop-in overrides `ExecStart` or `WorkingDirectory`,
`drop-in-override`. It is named, and the operator removes it as in
TOOLS.md step 3;
- the target is already the pointer's copy, `already-active`.
- the target is already the pointer's copy, `already-active`;
- the effective units' `--pm`, `--claude` or Console flags differ from
the pointer's, `unit-flags-drift`. The difference is printed. A hand
edit between runs is never carried forward or reverted without
anyone seeing it; the operator settles it first.
4. The order inside `activate` is as follows. Each step is logged, and a
failure at any step goes to item 6.
1. Capture the rollback set under
@@ -116,7 +128,8 @@ start has no gate that puts the old copy back.
owner picks the read, for example a read-only SQLite open of the
version the store records, and the packet names it. If the version
is the new copy's `SCHEMA_VERSION`, there's no backup. If it's
older, back up the stopped store to
older and the run has no `--migrate`, refuse `migration-needs-flag`
through item 6. With `--migrate`, back up the stopped store to
`<dataRoot>/backups/stack/<activation>/` (`backup.sh`: 0700, sums,
a source and copy comparison, the stopped check again after the
copy), then run the new copy's `migrate-schema.mjs`. If it's newer
@@ -124,9 +137,10 @@ start has no gate that puts the old copy back.
`store-newer`. The stack is stopped by then, so the refusal goes
through item 6 and starts the old stack again.
4. Install the bus unit with `bus-service.sh install --copy ID`,
keeping `--pm` and the `--claude` pin the pointer recorded. Then
install the Console with `webui-service.sh install --copy ID`,
keeping its saved flags. Then switch the wrapper with
with exactly the `--pm` and `--claude` pin the pointer recorded.
Then install the Console with `webui-service.sh install --copy ID`
with exactly the pointer's `console` flags. Then switch the wrapper
with
`stack-copy.sh wrapper ID`.
5. Start the bus, then the Console.
5. The health gate runs after the start and passes only when all of
@@ -160,33 +174,56 @@ start has no gate that puts the old copy back.
`schema-differs` unless `--restore ACTIVATION` names the backup taken
when the store was migrated. With `--restore`, it prints the
post-attempt path it keeps and how many bus events were written after
the backup's stamp, then restores.
8. `status BUSINESS` prints the pointer, the last five log lines, the
the backup's stamp, then restores. If that count is above zero, it
refuses `post-backup-events` unless `--events N` repeats the printed
count.
8. `activate ID BUSINESS --plan` and `rollback BUSINESS --plan` print
the target, whether a migration or a restore is expected (from the
pointer's `schema` and the target copy's `SCHEMA_VERSION`, with no
store read) and the flags that would be installed. They change
nothing and write no log line, so the window knows beforehand
whether Jason must be present.
9. `status BUSINESS` prints the pointer, the last five log lines, the
live units' copies, the result of `stack-copy.sh check`, `bus status`
and the drift from `refactor`. It only reads.
9. Who runs it. `adopt`, `activate` and `rollback` stop and start the
live units, so they are run by Jason or Mos only, and each run is a
live step that needs Mos's go, as TOOLS.md says today. Decisions 94
and 102 still decide who starts the Console. `webui-service.sh`
keeps having no start or stop verb (:50). The release script is the
one path that stops and starts, and its header comment says who may
run it. `status` is open to every seat.
10. Who runs it. Decision 96 covers the script stopping and starting
the live units under four conditions (Mos, mos-0716), and the
header comment states all four:
- every run of `adopt`, `activate` or `rollback` happens on Mos's
go, and Jason or Mos runs it;
- a run that migrates the store, an `activate --migrate`, happens
with Jason present;
- a `rollback --restore` with events written after the backup waits
for Jason, which is why it needs `--events N`;
- the script never prunes backups, rollback sets, post-attempt
directories or copies.
Tests run with a stand-in `systemctl` on `PATH`, temporary
Decisions 94 and 102 still decide who starts the Console.
`webui-service.sh` keeps having no start or stop verb (:50). The
release script is the one path that stops and starts. `status` and
`--plan` are open to every seat.
Tests run with a stand-in `systemctl` and `systemd-analyze` on `PATH`
(`install_guard` also calls `systemd-analyze --user unit-paths`), temporary
`XDG_CONFIG_HOME` and `XDG_DATA_HOME`, a temporary data root, and fake
copies whose `scripts/mosaic` and Console are small stubs, as
`packages/cli/tests/stack-copy.test.mjs` and
`packages/webui/tests/service.test.mjs` do. The cases:
- `adopt` writes the pointer and one log line only when the check passes.
- `adopt` writes the pointer and one log line only when the check passes,
with `claude` and `console` read from the stand-in's `show` output.
A second `adopt` refuses.
- `activate` installs exactly the pointer's `--pm`, `--claude` and
Console flags, and a stand-in unit whose flags differ refuses
`unit-flags-drift` with no change.
- Each refusal in item 3 leaves the units, the wrapper, the pointer and
the store unchanged, and it writes one log line with its code.
- An `activate` with no schema change: the stand-in sees the stops, the
installs and the starts in that order. The pointer names the new
copy, and no backup directory exists.
- An `activate` with a schema change makes the backup before the
migration. A fixture migration that fails restores the backup and
- An `activate` with a schema change and no `--migrate` refuses
`migration-needs-flag` and starts the old stack. With `--migrate` it
makes the backup before the migration. A fixture migration that fails restores the backup and
starts the old stack. The post-attempt directory exists, and the
restored files match the backup's sums.
- Each check in item 5, failing on its own, rolls back. The pointer is
@@ -195,10 +232,14 @@ copies whose `scripts/mosaic` and Console are small stubs, as
- A failing rollback gate stops with `rollback-failed` and starts
nothing more.
- `rollback` finds the previous copy from the log, refuses
`schema-differs` without `--restore`, and restores with it.
`schema-differs` without `--restore`, and restores with it. With
post-backup events, `--restore` without a matching `--events N`
refuses `post-backup-events`.
- `--plan` reports the expected migration or restore and the flags, and
leaves the units, pointer, log and store unchanged.
- The store is never opened for writing outside `migrate-schema.mjs` and
the restore, and nothing under `backups/` or `bus.post-attempt-*` is
removed.
the restore, and nothing under `backups/`, `state/stack-rollback/`,
`bus.post-attempt-*` or the copies directory is removed.
Mutants: one per behavior above, with the killing test in the packet.