diff --git a/docs/plans/2026-10-20_activate-no-send.md b/docs/plans/2026-10-20_activate-no-send.md new file mode 100644 index 000000000..0444b774f --- /dev/null +++ b/docs/plans/2026-10-20_activate-no-send.md @@ -0,0 +1,72 @@ +# Brief: activate --no-send drops the Console's --send + +Sage, 2026-10-20, for Mos's ruling mos-0972 (Q175 interim, Vikunja #412). Owner Sage, reviewer Dewey, gate owner +Sage. Base: refactor 9ae8c73ac (row 163 landed). Line numbers are at that commit. + +This row builds the tool only. The live restart without `--send` is a separate step afterwards, a same-copy +activate under Q173 with a backup first and a STATE report after. No test here touches `~/.mosaic-dev`, the +live units or a slot file. Every test uses the stand-in `systemctl`, units, stores and data root that +`packages/cli/tests/stack-release.test.mjs` already builds. + +## Why + +Mos ruled that the Console runs without `--send` until Q175 phase 2, because with `--send` live any same-uid +process can forge `X-authentik-username` on 127.0.0.1:7332 and send as Jason (design section 8). On the pinned +stack, the Console flags live in the pointer (`~/.mosaic-dev/state/stack-active.json`): + +- `console_for_target` (scripts/stack-release.sh:658-687) carries the pointer's flags unchanged. Only + `--tester-port` and the row 187 proof pair can change. +- `check_target` (:247-249) lets an activate name the pointer's copy only for a proof-pair change. +- `adopt` refuses once a pointer exists (:822). +- A hand `webui-service.sh install` without `--send` makes `flags_drift` (:640-651) refuse + `unit-flags-drift` on every later activate, pm-on and rollback. + +So the tool can't drop `--send` today. This row adds that one path. + +## The change + +1. `activate ID BUSINESS --no-send` drops `--send` from `RUN_CONSOLE`, so `install_stack` leaves it out of the + Console unit and `write_pointer` leaves it out of the pointer. Only `activate` takes it. It combines with + `--tester-port`, the proof pair and `--no-proof`. +2. An activate with `--no-send` may name the pointer's copy when the pointer's Console flags hold `--send`. It + re-pins the live copy with only the Console flags changed, as row 187 does for the pair, including the + live-copy plan note and the backup of the stopped store. Without `--send` in the pointer, a same-copy + `--no-send` still refuses `already-active`. +3. The steps log records `drop --send; --no-send was given`, or `--no-send was given and the pointer holds no + --send, so there is nothing to drop`. +4. `--plan` prints one `send:` line for an activate or rollback: `send: dropped; --no-send was given`, + `send: off; --no-send was given and the pointer holds no --send`, `send: carried` when the pointer's + `--send` goes on unchanged, or `send: off`. +5. `rollback` and `pm-on` don't change: they carry the pointer's flags. So once `--no-send` has run, a rollback + to an earlier copy keeps send off. There is no flag to turn send back on. Q175 phase 2 changes the Console + flags in its own row. +6. `docs/TOOLS.md` "Pinned stack update" gets `--no-send` in the usage block and one sentence. + +## Tests (packages/cli/tests/stack-release.test.mjs) + +1. Seeded preview pointer with `--send` and `--tester-port 7333`: a same-copy `activate B acme --no-send` + passes. The pointer and the unit ExecStart lack `--send` and keep the preview flags and + `--tester-port 7333` in order. Status says `unit flags: match the pointer`. The steps log has the drop + line. The log line has from = to = B, and the stopped store was backed up. +2. A plain same-copy activate still refuses `already-active`. So does a same-copy `--no-send` once `--send` is + gone. +3. `--plan` prints the four `send:` lines in their cases, with the live-copy note on the same-copy run. +4. After `--no-send`, a rollback to the earlier copy and `pm-on` both leave `--send` out of the pointer and + the unit. +5. `--no-send` on `rollback`, `pm-on`, `status` or `adopt` is a usage error (exit 4). +6. `--no-send` with the proof pair, and with `--no-proof`, on a pointer holding both: each drops what it + names and keeps the rest. + +## Mutants (each must fail at least one test) + +- M1: the same-copy exception ignores `--no-send`. +- M2: the same-copy exception allows `--no-send` without `--send` in the pointer. +- M3: `--no-send` drops `--send` from the pointer but not from the unit (it writes the pointer from + `P_CONSOLE`). +- M4: rollback re-adds `--send`. +- M5: the arg parser accepts `--no-send` for rollback. + +## Gate + +Dewey approves the manifest. The cli suite and every `scripts/test-*.sh` are green on Sage's gate, and the +mutants are killed.