plans: brief for row 187, activate carries the row 178 proof pair (mos-0928 Part B A0, #1685)
This commit is contained in:
@@ -0,0 +1,99 @@
|
||||
# Brief: activate carries the row 178 proof pair
|
||||
|
||||
Sage, 2026-10-20, step A0 of mos-0928 Part B (`agents/sage/work/window-plan/repin-rows-177-185.md`
|
||||
§ Part B). Gitea #1685. Owner Darkwing, reviewer Filbert, gate owner Sage. Starts after row 186, which touches the same
|
||||
script. Base: the refactor head once row 186 lands. Line numbers are at 1d7fd75e2.
|
||||
|
||||
This row builds the tool only. Turning the proof on for the live Console is Part B, which waits for Jason
|
||||
(J1-J6 on P19 385) and is not part of this row. Nothing here runs against `~/.mosaic-dev`, the live units
|
||||
or the slot file. Every test uses the stand-in `systemctl`, units, stores and data root that
|
||||
`packages/cli/tests/stack-release.test.mjs` already builds, with a proof file the test writes itself.
|
||||
|
||||
## Why
|
||||
|
||||
Row 178 gave the Console `--proof-header NAME --proof-file PATH` (`packages/webui/src/serve.mjs`
|
||||
`proofOptions`, :217). On the pinned stack the Console flags live in the pointer. `flags_drift` (:627)
|
||||
refuses `unit-flags-drift` when the unit differs, and `console_for_target` (:645) carries the pointer's
|
||||
flags unchanged. So a hand `webui-service.sh install` with the pair would make every later `activate`,
|
||||
`pm-on` and `rollback` refuse. `activate --tester-port N` is the only path that writes a new Console flag
|
||||
into the pointer today. Part B's B3 needs the same path for the pair.
|
||||
|
||||
Part B's rollback also needs a way to turn the proof off. A plain `rollback` goes to the log's previous
|
||||
distinct copy (`from_log previous`, :907). Today that is 89af38a83, which predates row 178, so the
|
||||
rollback would drop the proof only by also dropping rows 177-185. An activate of the live copy without
|
||||
the pair is the narrow way back, and today an activate carries the pair unchanged. So this row adds
|
||||
`--no-proof` too.
|
||||
|
||||
## The change
|
||||
|
||||
1. `activate ID BUSINESS --proof-header NAME --proof-file PATH` writes the pair into `RUN_CONSOLE`, so
|
||||
`install_stack` puts it in the Console unit and `write_pointer` puts it in the pointer, the same way
|
||||
`--tester-port` does (:659-668). It replaces any pair the pointer already holds. Both flags or
|
||||
neither; one alone is a usage error. Only `activate` takes them.
|
||||
2. `activate ... --no-proof` drops any pair from `RUN_CONSOLE` and says so in the steps log, the way
|
||||
`DROP_TESTER` does. With no pair in the pointer it is a no-op that says so. It can't go with the pair
|
||||
flags (usage).
|
||||
3. Before anything stops, the run refuses (exit 3, through `check_refuse` so `--plan` lists them) when:
|
||||
- `proof-target`: the target copy's `packages/webui/src/cli.mjs` doesn't take `--proof-header`.
|
||||
- `proof-needs-preview`: the Console flags the run would install lack any of `--public-host`,
|
||||
`--auth-header` or `--allow-user`, which `proofOptions` needs.
|
||||
- `proof-header-invalid`: the lowercased name doesn't match `^[a-z0-9][a-z0-9-]{0,63}$`, or is `host`,
|
||||
`origin`, `x-mosaic-tester` or the lowercased `--auth-header` value. These are `proofOptions`'
|
||||
own rules (serve.mjs :203, :220-222).
|
||||
- `proof-file-invalid`: the path isn't absolute, holds a character outside `[A-Za-z0-9/._+-]` (the
|
||||
unit argv can't quote, :166), is a symlink, isn't a regular file, isn't mode 600 or 400, or isn't
|
||||
owned by the uid the script runs as (the Console unit's uid today; J2 changes that and gets its own
|
||||
row).
|
||||
4. The script never reads the proof file's contents. It checks the file with `stat` only. The value
|
||||
never appears in the pointer, the log, the steps log, the plan output or any refusal text.
|
||||
5. A `rollback` to a copy whose Console doesn't take `--proof-header` drops the pair and says so, as
|
||||
`DROP_TESTER` does for `--tester-port`, since a rollback is the way back and must not refuse on it.
|
||||
An activate to such a copy with a pair in the pointer refuses `proof-target` unless `--no-proof` is
|
||||
given, so an activate never turns the proof off unless the operator asked. Unlike `--tester-port`,
|
||||
the proof decides who can reach the Console. The plan prints the drop line. A copy that takes the
|
||||
pair carries it unchanged, as today.
|
||||
6. `--plan` prints one `proof:` line for an activate or rollback: `proof: on, header NAME, file PATH` for
|
||||
a new pair, `proof: carried, header NAME` when the pointer's pair goes on unchanged, `proof: dropped;
|
||||
...` with the reason, or `proof: off`.
|
||||
7. `pm-on` is unchanged. It already writes the pointer's Console flags back as they are (:1008).
|
||||
8. `docs/TOOLS.md` "Pinned stack update" gets the two flags in the usage block and one paragraph on the
|
||||
pair, `--no-proof` and the drop.
|
||||
|
||||
## Tests
|
||||
|
||||
1. Activate with the pair: the pointer's `console` and the Console unit's argv end with
|
||||
`--proof-header NAME --proof-file PATH`, after the preview flags and with `--tester-port` kept.
|
||||
2. Activate of the live copy with the pair (Part B's B3 shape) passes and writes the pair.
|
||||
3. A later activate without pair flags carries the pair; `pm-on` keeps it.
|
||||
4. `--no-proof` drops it from the pointer and the unit, and the steps log says so. With no pair it says so
|
||||
and passes.
|
||||
5. Each refusal in change 3 exits 3 with no unit start or stop, and `--plan` lists it with any other
|
||||
refusals.
|
||||
6. Usage errors: one of the pair alone, `--no-proof` with the pair, either flag on `rollback` or `pm-on`.
|
||||
7. Rollback to a copy without proof support drops the pair and says so. Rollback to one with it carries
|
||||
the pair. Activate to a copy without support, with a pair in the pointer, refuses `proof-target`
|
||||
without `--no-proof` and passes with it.
|
||||
8. The value never leaks: the test's proof file holds a sentinel line, and no file under the test's state
|
||||
or data root, and no stdout or stderr of any run, holds it.
|
||||
9. `--plan` prints the `proof:` line for each case and writes nothing.
|
||||
|
||||
Mutants, each killed by some gate test (mos-0862):
|
||||
|
||||
- the run reads the proof file (any `cat` or `node` read of PATH)
|
||||
- a target without proof support keeps the pair on rollback
|
||||
- an activate to a target without proof support drops the pair without `--no-proof`
|
||||
- `--no-proof` leaves the pair in the pointer but not the unit (drift)
|
||||
- the mode check accepts 644
|
||||
|
||||
## Gate
|
||||
|
||||
Filbert approves the candidate manifest. Cli suite and every `scripts/test-*.sh` green on Sage's gate, run
|
||||
from a git worktree of the candidate. Touched files: `scripts/stack-release.sh`,
|
||||
`packages/cli/tests/stack-release.test.mjs`, `docs/TOOLS.md`, and the packet. Anything else gets named in
|
||||
BUILD.md with the reason. No change to `packages/webui`.
|
||||
|
||||
## Out of scope
|
||||
|
||||
Running Part B or any step of it, writing the slot file (A1), the uid separation (J2), the k3s middleware
|
||||
(J3, J4), and any change to the Console's proof rules. Going live needs a re-pin window that Mos checks
|
||||
(A2), after Jason's go on Part B.
|
||||
Reference in New Issue
Block a user