docs: onboarding-wizard contract revision 6 (sol r5 residual F7 + N7 seed immutability)
ci/woodpecker/pr/ci Pipeline was successful

This commit is contained in:
fred
2026-08-26 21:08:33 -05:00
parent 0162443a38
commit b8b257e1ec
+70 -13
View File
@@ -88,6 +88,22 @@ different-scope collision, and the aborted-winner concurrency case
deviation (deferment) of the initial-user SSO option, not as its deviation (deferment) of the initial-user SSO option, not as its
satisfaction (N6). satisfaction (N6).
Revision 6 (sol re-review 4: residual F7, new N7): the seed parameter
becomes **immutable seed provenance**`bootstrap.seed-company-name`
is written exactly once by the finalize transaction and any later
write to it is refused, so a re-run's re-derived seed sequence is
byte-stable and replays cleanly against the §4.3 fence instead of
colliding with it; the current company name's canonical home is the
company row (renamed through the ordinary hierarchy command), and the
wizard renders the row, never the provenance value (N7). §6.3 gains
the changed-name re-run and rename-then-re-run witnesses plus the
immutability refusal probe, with a mutated-digest collision control
(N7). §6.7 adds the two missing envelope witnesses: the same raw key
under two different operations executes both independently
(pair-uniqueness, not global key-uniqueness), and a fresh
authorization refusal records no fence row so an authorized retry
executes afresh (F7).
Scope: the Gateway-backed product onboarding wizard. Out of scope: the Scope: the Gateway-backed product onboarding wizard. Out of scope: the
host-local install wizard (`mosaic wizard`, which drives host install and host-local install wizard (`mosaic wizard`, which drives host install and
gateway bootstrap and is not this artifact — audit REPORT.md layer 3); gateway bootstrap and is not this artifact — audit REPORT.md layer 3);
@@ -215,10 +231,21 @@ the named authority:
seed parameter, a disclosed drafting addition (§7.11) — committed seed parameter, a disclosed drafting addition (§7.11) — committed
by step 3's finalize command among the ordinary settings writes and by step 3's finalize command among the ordinary settings writes and
readable through the ordinary settings read surface. The company readable through the ordinary settings read surface. The company
name feeds step 4's company creation. On a first run this step name feeds step 4's company creation. **The seed parameter is
collects and validates only — the collected values are committed by immutable seed provenance:** it is written exactly once, by the
step 3's finalize command (§3.3). On a re-run (an authenticated admin exists) finalize transaction, and every later write to the key — through
it applies directly through the settings commands. any surface, any actor — is refused by the settings family (a
disclosed immutable-key rule, §7.11). It records what the seed
sequence was derived from, not what the company is currently
named: the current name's canonical home is the company row, and
renaming the seed company is the ordinary hierarchy rename
command against that row, never a settings edit. On a first run
this step collects and validates only — the collected values are
committed by step 3's finalize command (§3.3). On a re-run (an
authenticated admin exists) the system name and other settings
apply directly through the settings commands; the company-name
field renders the company row's current canonical name and
applies a change as the hierarchy rename.
2. **Component choices.** Mosaic Comms/Matrix vs external; Mosaic 2. **Component choices.** Mosaic Comms/Matrix vs external; Mosaic
SSO/Authentik vs external; Mosaic DB/PostgreSQL vs external; vector SSO/Authentik vs external; Mosaic DB/PostgreSQL vs external; vector
DB (D4). v1 records the choices as settings (first run: collected, DB (D4). v1 records the choices as settings (first run: collected,
@@ -293,10 +320,15 @@ the named authority:
the fixed example set (§4.3). A resumed run — including a fresh the fixed example set (§4.3). A resumed run — including a fresh
client holding none of the original run's transient state — client holding none of the original run's transient state —
reconstructs the same ordered sequence and the same deterministic reconstructs the same ordered sequence and the same deterministic
§4.3 keys from that canonical state alone. Once the first company §4.3 keys from that canonical state alone. Because the seed
exists the seed parameter is inert bookkeeping: the §4.3 fence, parameter is immutable (§3.1), the re-derived sequence is
not the parameter's presence or absence, is what prevents byte-stable across every re-run and resume: the same keys carry
re-seeding. the same payload digests, so already-committed mutations replay
(recorded outcomes) rather than collide, regardless of any
hierarchy rename performed since. The §4.3 fence, not the
parameter's presence or absence, is what prevents re-seeding; the
parameter is provenance the derivation reads, never a value any
later step may change.
The first company is created by the ordinary top-level company The first company is created by the ordinary top-level company
command under §5.2's eligibility policy, with the new admin as actor, command under §5.2's eligibility policy, with the new admin as actor,
naming the admin as initial `owner` in the same audited operation naming the admin as initial `owner` in the same audited operation
@@ -486,6 +518,18 @@ Binding on the implementing PRs:
**Canonical-state drift:** mutate state outside the wizard (a **Canonical-state drift:** mutate state outside the wizard (a
rename through the hierarchy command), then re-run — the wizard rename through the hierarchy command), then re-run — the wizard
renders the current canonical value, not a stored answer. renders the current canonical value, not a stored answer.
**Seed-provenance witnesses (§3.1, §3.4):** rename the seed
company through the hierarchy command, then re-run to completion —
the re-derived seed sequence carries the same keys and payload
digests as the first run (asserted digest equality), every seed
submission replays with the recorded outcome, zero new nodes are
created, and the company keeps its renamed name; a re-run
submitting a different company name renames the company row and
commits no settings write to the seed key; a direct post-epoch
settings write to `bootstrap.seed-company-name`, by any actor, is
refused; and a control run that force-mutates a seed payload
digest receives the §4.3 collision refusal, proving the fence
still discriminates.
**Second company:** a re-run creating a second company succeeds with **Second company:** a re-run creating a second company succeeds with
the running user as actor and names the creator as `owner` in the the running user as actor and names the creator as `owner` in the
same audited operation — asserted on the single audit event naming same audited operation — asserted on the single audit event naming
@@ -555,7 +599,16 @@ Binding on the implementing PRs:
submission received the winner's recorded outcome; and with the submission received the winner's recorded outcome; and with the
winner's transaction forced to abort, the waiting loser finds no winner's transaction forced to abort, the waiting loser finds no
fence row, executes, and commits exactly one mutation and one fence row, executes, and commits exactly one mutation and one
audit event. audit event. Two envelope-shape witnesses complete the §4.3
coverage: the same raw key submitted to two DIFFERENT operations
executes both independently, each committing its own mutation,
audit event, and fence row — proving uniqueness is the
(operation, key) pair, so a globally key-unique fence fails this
witness; and a fresh submission refused by authorization records
no fence row — the same actor, made eligible, retries the same
(operation, key, payload) and the command executes afresh,
distinguishing an authorization refusal from a pre-commit failure
and proving refusals record nothing.
8. **Actor-matrix witness (§5.2):** post-bootstrap top-level company 8. **Actor-matrix witness (§5.2):** post-bootstrap top-level company
creation succeeds for an ordinary authenticated non-admin user creation succeeds for an ordinary authenticated non-admin user
(positive), and is refused for an unauthenticated caller and for a (positive), and is refused for an unauthenticated caller and for a
@@ -644,10 +697,14 @@ contracts and are not additions:
initial-user field). The deviation narrows the PRD field for v1 initial-user field). The deviation narrows the PRD field for v1
and is severable. and is severable.
11. The **`bootstrap.seed-company-name`** settings key (§3.1) — the 11. The **`bootstrap.seed-company-name`** settings key (§3.1) — the
owning record of the §3.4 seed parameter: written by the finalize owning record of the §3.4 seed parameter: written exactly once by
transaction among the ordinary settings writes, read through the the finalize transaction among the ordinary settings writes, read
ordinary settings read surface, inert once the first company through the ordinary settings read surface, and **immutable
exists (§3.4). thereafter** — the settings family refuses every later write to
the key, from any surface and any actor. The key is seed
provenance for §3.4's derivation; the current company name lives
on the company row and changes only through the ordinary
hierarchy rename (§3.1, witnesses §6.3).
## Ruling request ## Ruling request