docs: onboarding-wizard contract revision 4 (sol re-review 2 residuals + N3/N4)
ci/woodpecker/pr/ci Pipeline was canceled

- F2: bootstrap-status closed two-field schema (epoch enum + pre-epoch-only
  mode), post-epoch mode-field absence witnessed, contract 6 \u00a72.2 amendment
  disclosed (\u00a77.9)
- F5/N4: contract 5 \u00a73.1 rank-6 mapping expansion disclosed naming the rows
  to amend (\u00a77.8); \u00a71.1 states which families are live vs amended
- F7: complete idempotency envelope \u2014 fence records operation/actor/scope/
  payload digest, re-authorized replay, collision refusal, no error replay,
  concurrent loser receives winner's recorded outcome; witnesses added
- N1/N3: post-epoch application phase replaced by a single bootstrap finalize
  command (one transaction: admin + epoch close + carried settings/registration/
  JIT/seed-parameter writes under the new admin); password-only v1 first admin
  (\u00a77.10); seed sequence derived from canonical state; \u00a76.11 uses the
  authentication-failure class
This commit is contained in:
fred
2026-08-26 20:21:55 -05:00
parent eb48d72f67
commit e58d0a5447
+244 -105
View File
@@ -48,6 +48,26 @@ better-auth ban, with no separate state (F9). Example-data seeding is
mandatory; the skippability policy is removed (PRD §6.4) (N2). All mandatory; the skippability policy is removed (PRD §6.4) (N2). All
drafting additions are consolidated in §7. drafting additions are consolidated in §7.
Revision 4 (sol re-review 2: residual F2/F5/F7/N1, new N3/N4): the
post-epoch application phase is replaced by a single **bootstrap
finalize command** — step 3 submits the first-admin fields and every
collected value (settings, registration mode, applicable JIT choices,
seed parameters) in one command on identity §3's bootstrap surface,
executed server-side in one transaction that creates the admin, closes
the epoch, and commits the carried values under the new admin's
authority; after it, every collected value is canonical state, so an
interrupted run resumes from canonical state alone (N1, N3). The v1
first admin is password-only; identity §3.6's SSO variant is not
composed by the v1 wizard (N1's SSO ordering). The bootstrap-status
response is a closed two-field schema (epoch state plus a
pre-epoch-only mode field), with the contract 6 §2.2 amendment
disclosed (F2). The idempotency envelope is completed: fence rows
record operation, actor, scope, and payload digest; replay is
re-authorized; changed-payload collision is refused; only committed
outcomes are recorded; the concurrent loser receives the winner's
recorded outcome (F7). §7 now names the contract 5 §3.1 rank-6
mapping rows the composition expansion amends (F5, N4).
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);
@@ -69,13 +89,17 @@ through the extensibility rule §2.4).
Gateway call issued from the wizard's web modules (or the equivalent Gateway call issued from the wizard's web modules (or the equivalent
scripted sequence), so contract 5 §6.1's outbound-call inventory, scripted sequence), so contract 5 §6.1's outbound-call inventory,
scoped to those modules, sees the wizard's complete operation set. scoped to those modules, sees the wizard's complete operation set.
The composed operations span six existing families, each already The composed operations span six existing families: the rank-1
within contract 5's mapping: the rank-1 hierarchy commands and the hierarchy commands and the rank-4 enrollment command (contract 5
rank-4 enrollment command (contract 5 §3.1 — built first), the §3.1 — built first), the settings command family (steps 12), the
settings command family (steps 12), the identity bootstrap and identity bootstrap and registration surface (step 3, including the
registration surface (step 3), the mode reads (contract 6 §2.2 §3.3 finalize command), the mode reads (contract 6 §2.2 post-epoch;
post-epoch; the §2.3 bootstrap-status field pre-epoch), and the the §2.3 bootstrap-status field pre-epoch), and the ordinary
ordinary content commands used for example seeding (step 4). content commands used for example seeding (step 4). Two of these
families (ranks 1 and 4) are in contract 5 §3.1's live rank-6
composition row; the other four are added by the disclosed §7.8
mapping amendment, without which their operations are unmapped and
blocked under contract 5 §5.
2. **The wizard introduces no new mutation surface.** Every state change 2. **The wizard introduces no new mutation surface.** Every state change
it performs is an existing command with its own contract: user and it performs is an existing command with its own contract: user and
epoch writes under the identity contract §3, hierarchy writes under epoch writes under the identity contract §3, hierarchy writes under
@@ -88,8 +112,10 @@ through the extensibility rule §2.4).
system's current configuration (read through the same commands) and system's current configuration (read through the same commands) and
applies deltas; the wizard does not keep an answer file whose contents applies deltas; the wizard does not keep an answer file whose contents
can drift from reality. Values a first run has collected but not yet can drift from reality. Values a first run has collected but not yet
applied (the §3.3 application rule) are transient run state, not a committed by the §3.3 finalize command are transient run state, not
persisted answer file. The wizard MAY persist run bookkeeping a persisted answer file; after finalize every collected value is
canonical state, and no transient value is needed to resume
(§4.4). The wizard MAY persist run bookkeeping
(started/completed timestamps); bookkeeping is a cache, never the (started/completed timestamps); bookkeeping is a cache, never the
source of truth for any decision. The §4.3 idempotency fence is source of truth for any decision. The §4.3 idempotency fence is
command-layer canonical state, not wizard bookkeeping — losing command-layer canonical state, not wizard bookkeeping — losing
@@ -118,9 +144,18 @@ through the extensibility rule §2.4).
unreachable there; the pre-epoch flow instead branches on the mode unreachable there; the pre-epoch flow instead branches on the mode
value reported by the **unauthenticated bootstrap-status response** value reported by the **unauthenticated bootstrap-status response**
of the bootstrap surface (identity §3), which evaluates the mode of the bootstrap surface (identity §3), which evaluates the mode
record server-side and discloses exactly one field beyond epoch record server-side. The bootstrap-status response is a **closed
state: the recorded mode value (drafting addition, §7). Post-epoch two-field schema**: `epoch` — one field whose value set is exactly
wizard runs read mode through contract 6 §2.2 unchanged. Changing the bootstrap epoch states identity §3 defines for
`bootstrap_state`, closed to that enumeration — and `mode` — the
recorded mode value, present **only while the epoch is open** and
absent from the response schema once the epoch has completed. No
other field exists in the response. The unauthenticated pre-epoch
mode disclosure is a disclosed amendment to contract 6 §2.2's
authenticated-read rule (§7.9); post-epoch, §2.2's
authenticated-only rule holds unchanged and the bootstrap-status
response carries no mode field. Post-epoch wizard runs read mode
through contract 6 §2.2 unchanged. Changing
mode later is conversion (contract 6), not a wizard re-run. In v1 a mode later is conversion (contract 6), not a wizard re-run. In v1 a
recorded mode of `enterprise` is refused at bootstrap (contract 6 recorded mode of `enterprise` is refused at bootstrap (contract 6
§5), so the wizard's Enterprise branch is unreachable in v1; a §5), so the wizard's Enterprise branch is unreachable in v1; a
@@ -140,46 +175,72 @@ the named authority:
1. **System and company name.** System name is a settings value; company 1. **System and company name.** System name is a settings value; company
name feeds step 4's company creation. On a first run this step name feeds step 4's company creation. On a first run this step
collects and validates only — application follows step 3's collects and validates only — the collected values are committed by
application rule below. On a re-run (an authenticated admin exists) step 3's finalize command (§3.3). On a re-run (an authenticated admin exists)
it applies directly through the settings commands. it applies directly through the settings commands.
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,
applied per step 3's application rule; re-run: applied directly) and committed by step 3's finalize command §3.3; re-run: applied
directly) and
configures what is installable in-product; component provisioning configures what is installable in-product; component provisioning
beyond that is host tooling, out of scope here. beyond that is host tooling, out of scope here.
3. **Initial user.** Email, password, and display name, or SSO (PRD §6 3. **Initial user and finalize.** Email, password, and display name
step list: "email/password/name/SSO"), per identity §3: the (PRD §6 step list: "email/password/name/SSO"), per identity §3: the
first-admin transition is atomic, one per bootstrap epoch, and the first-admin transition is atomic and one per bootstrap epoch. **The
SSO variant runs inside the bootstrap transaction (identity §3.6). v1 first admin is password-only.** A step-2 SSO choice cannot yield
The display-name source is bound per path: the password path uses a canonically configured provider before the epoch closes, so an
the submitted display name; the SSO variant uses the name claim SSO-authenticated first admin is not constructible in this flow;
mapped under identity §5's claim mapping. Canonical `users.name` the v1 wizard does not compose identity §3.6's SSO variant, and the
MUST equal that source value (witness §6.5); no field of the PRD's PRD step list's SSO option is satisfied post-epoch (providers
step list is dropped. The wizard also presents the applicable configured and JIT-enabled after finalize; identity §5 governs
every SSO-created account). This is a disclosed sequencing decision
(§7.10). The password path's canonical `users.name` MUST equal the
submitted display name; any SSO-created account's name is bound to
identity §5's mapped name claim (witness §6.5); no field of the
PRD's step list is dropped. The wizard also presents the applicable
mandatory choices — registration mode (identity §2.2) and, for each mandatory choices — registration mode (identity §2.2) and, for each
configured SSO provider, that provider's JIT enablement with its SSO provider canonically configured at finalize time, that
allowlist warning (identity §4.1, §4.3). The wizard MUST obtain an provider's JIT enablement with its allowlist warning (identity
explicit submission for each applicable mandatory choice and MUST §4.1, §4.3); a provider configured after finalize receives its JIT
refuse step completion while one is unsubmitted. This is a choice at configuration time under identity §4.1's default. The
presentation-and-submission obligation on wizard runs only: wizard MUST obtain an explicit submission for each applicable
identity's own defaults (registration `closed`, JIT off) continue to mandatory choice and MUST refuse finalize while one is unsubmitted.
govern everything a wizard run never touches, and this contract This is a presentation-and-submission obligation on wizard runs
creates no new stored-record obligation beyond those identity itself only: identity's own defaults (registration `closed`, JIT off)
defines. **Application rule (first runs):** immediately after the continue to govern everything a wizard run never touches, and this
epoch transition, authenticated as the newly created admin — the contract creates no new stored-record obligation beyond those
first-admin transition (identity §3) yields the account holding the identity itself defines. **Finalize rule (first runs):** step 3
RBAC §1.1 platform authority that system and component settings ends in a single **bootstrap finalize command** on identity §3's
writes require — the run applies the values collected in steps 12 bootstrap surface — a disclosed extension of that surface (§7.3) —
through the ordinary settings commands. Before the transition the carrying the first-admin fields and every collected value: the
run holds collected values only: no canonical settings write occurs step-1 system name, the step-1 company name (recorded as the §3.4
pre-epoch, and no pre-admin write authority exists or is invented seed parameter), the step-2 component choices, the
(disclosed sequencing addition, §7; witness §6.11). registration-mode submission, and the applicable JIT submissions.
4. **Initial hierarchy and seeding.** Runs strictly after step 3's epoch The command executes **in one transaction**: it creates the admin
transition, authenticated as the newly created admin. The bootstrap and closes the epoch exactly as identity §3 defines, then — with
writer (identity §3) creates only the first account and closes the the new admin existing inside the same transaction, holding the
epoch; it has no hierarchy authority and creates no hierarchy node. RBAC §1.1 platform authority those writes require — commits every
carried value through the ordinary settings and identity
configuration writes, each attributed in audit to the new admin.
Either the whole transaction commits or none of it exists (identity
§3.5's atomicity extends over the carried writes). Before finalize
the run holds collected values only: no canonical write of any kind
occurs pre-epoch, and no pre-admin write authority exists or is
invented (witness §6.11). After finalize, every collected value is
canonical state; no transient value is needed to resume (§4.4,
witness §6.7).
4. **Initial hierarchy and seeding.** Runs strictly after step 3's
finalize transaction, authenticated as the newly created admin. The
bootstrap writer (identity §3) creates only the first account,
closes the epoch, and commits the §3.3 carried values; it has no
hierarchy authority and creates no hierarchy node. The seed
sequence is derived entirely from canonical state: the seed
parameter the finalize command recorded (the company name) and the
fixed example set (§4.3). A resumed run — including a fresh client
holding none of the original run's transient state — reconstructs
the same ordered sequence and the same deterministic §4.3 keys from
that canonical state alone.
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
@@ -220,18 +281,45 @@ collects no sensitive category, so v1 ships no custody surface.
epoch. The at-most-once mechanism is an **idempotency key**, a epoch. The at-most-once mechanism is an **idempotency key**, a
disclosed drafting addition to contract 5's §4 command envelope disclosed drafting addition to contract 5's §4 command envelope
ratified with this contract (§7): a mutating command MAY carry a ratified with this contract (§7): a mutating command MAY carry a
caller-supplied idempotency key; the command layer records the key caller-supplied idempotency key. The complete envelope:
in a uniqueness-constrained fence table **in the same transaction** - **Fence row.** The command layer records, in a
as the mutation and its audit event, and a submission whose key is uniqueness-constrained fence table **in the same transaction**
already recorded executes nothing and returns the recorded outcome. as the mutation and its audit event: the key, the operation
identifier, the acting principal, the mutation's authorization
scope (the target company, or the platform scope for top-level
operations), a digest of the canonicalized request payload, and
a reference to the committed outcome. Fence uniqueness is the
pair (operation identifier, key).
- **Replay.** A submission whose (operation, key) pair is recorded
is first authorized exactly as a fresh submission would be — an
actor who is not authorized receives the authorization refusal,
never the recorded outcome. If authorization passes and the
recorded actor, scope, and payload digest all equal the
submission's, the command executes nothing and returns the
recorded outcome.
- **Collision.** A submission whose (operation, key) pair is
recorded but whose actor, scope, or payload digest differs is
refused with a single bounded conflict error (contract 5 §4.2);
it executes nothing and discloses nothing of the recorded
outcome.
- **No error replay.** The fence row commits only with its
mutation, so only committed outcomes are ever recorded. A failed
or refused submission records no fence row; a retry executes
afresh. There is no recorded-error state.
- **Concurrency.** Two submissions with the same (operation, key)
pair serialize on the fence's unique constraint: exactly one
executes. The loser waits for the winner's transaction to
resolve; if it committed, the loser is handled as a replay
(authorization first, then the recorded outcome, or the
collision refusal on mismatch); if it aborted, no fence row
exists and the loser executes. The loser never performs a second
mutation and is never left without a defined response.
The wizard submits deterministic keys derived from the bootstrap The wizard submits deterministic keys derived from the bootstrap
epoch and the seed role (e.g. epoch id + "seed-company") for every epoch and the seed role (e.g. epoch id + "seed-company") for every
seed mutation. Correlation ids (contract 5 §4.3) remain pure trace seed mutation. Correlation ids (contract 5 §4.3) remain pure trace
linkage and carry no idempotency semantics. Two concurrent resumed linkage and carry no idempotency semantics. Wizard bookkeeping of
runs serialize on the fence's unique constraint: exactly one seed node ids remains a cache
execution per key; the other submission receives the recorded
outcome or a single bounded conflict refusal, never a second
mutation. Wizard bookkeeping of seed node ids remains a cache
(§1.3): losing it cannot cause duplication, because the fence is (§1.3): losing it cannot cause duplication, because the fence is
canonical command-layer state. A re-run offers to create canonical command-layer state. A re-run offers to create
_additional_ hierarchy nodes (PRD: users can create N companies, N _additional_ hierarchy nodes (PRD: users can create N companies, N
@@ -240,18 +328,26 @@ collects no sensitive category, so v1 ships no custody surface.
likewise at-most-once per epoch; the example set is fixed and its likewise at-most-once per epoch; the example set is fixed and its
seeding is not skippable (PRD §6.4: a completed first run contains seeding is not skippable (PRD §6.4: a completed first run contains
the fixed example set). the fixed example set).
4. **Interrupted runs strand nothing.** The wizard is resumable at the 4. **Interrupted runs strand nothing.** The wizard is resumable at the
granularity of a single command: each mutation either commits through granularity of a single command: each mutation either commits
its command with its same-transaction audit event and fence row, or through its command with its same-transaction audit event and fence
leaves nothing (identity §3.5 for the bootstrap step). Step 4 is a row, or leaves nothing (identity §3.5, extended over the carried
sequence of individually atomic commands, not one transaction: an writes, for the §3.3 finalize command). A run interrupted before
interruption between them leaves a prefix of committed seed nodes, finalize has written nothing; its collected values are re-entered.
and the §4.3 fence makes the resumed run complete exactly the A run interrupted after finalize resumes from canonical state
remaining suffix — the run re-submits the full ordered seed sequence alone: every collected value was committed by the finalize
with the same deterministic keys, already-committed mutations return transaction, and the remaining work — the step 45 command
their recorded outcomes, and only the remainder executes, without sequence — is derivable from it (§3.4). Step 4 is a sequence of
duplication and without compensating rollback of completed commands. individually atomic commands, not one transaction: an interruption
There is no wizard-level transaction spanning steps. between them leaves a prefix of committed seed nodes, and the §4.3
fence makes the resumed run complete exactly the remaining suffix —
the run re-derives the full ordered seed sequence from canonical
state and re-submits it with the same deterministic keys,
already-committed mutations return their recorded outcomes, and
only the remainder executes, without duplication and without
compensating rollback of completed commands. There is no
wizard-level transaction spanning steps.
## 5. Seeding authority (resolves contract 2 review NEW-1) ## 5. Seeding authority (resolves contract 2 review NEW-1)
@@ -299,10 +395,12 @@ Binding on the implementing PRs:
2. **Mode witnesses:** the branch point exists — a pre-epoch flow 2. **Mode witnesses:** the branch point exists — a pre-epoch flow
resolves its step set from the bootstrap-status mode field (§2.3), resolves its step set from the bootstrap-status mode field (§2.3),
a post-epoch run from contract 6 §2.2's authenticated read; the a post-epoch run from contract 6 §2.2's authenticated read; the
bootstrap-status response discloses exactly one field beyond epoch bootstrap-status response matches §2.3's closed two-field schema
state (closed-field assertion on the response schema); post-epoch, exactly while the epoch is open, and after the epoch completes
an unauthenticated mode read is refused (contract 6 §2.2 holds contains the epoch field only — the mode field absent from the
unchanged); v1 with mode `standalone` yields the §3 step set; a response (closed-field assertion on the response schema in both
phases); post-epoch, an unauthenticated mode read through any
surface is refused (contract 6 §2.2, as amended by §7.9, holds); v1 with mode `standalone` yields the §3 step set; a
simulated unsupported or unreadable mode record yields one bounded simulated unsupported or unreadable mode record yields one bounded
precondition refusal (§2.3) and no partial flow; wizard sources precondition refusal (§2.3) and no partial flow; wizard sources
contain no mode write and no feature-state mode derivation. contain no mode write and no feature-state mode derivation.
@@ -339,10 +437,12 @@ Binding on the implementing PRs:
5. **Explicit-choice witness:** a run submitting explicit values 5. **Explicit-choice witness:** a run submitting explicit values
completes, and each canonical value equals the value the run completes, and each canonical value equals the value the run
submitted (asserted against the captured submissions, not by reading submitted (asserted against the captured submissions, not by reading
the canonical store twice); canonical `users.name` equals the path's the canonical store twice); canonical `users.name` equals the
declared source — the submitted display name for the password path, declared source — for the first admin (password path), the
the identity §5 mapped name claim for the SSO variant (asserted submitted display name; for an SSO-created account (a post-epoch
against the captured submission or captured assertion); a run with JIT-provisioned user), the identity §5 mapped name claim (each
asserted against the captured submission or captured assertion); a
run with
an applicable mandatory choice unsubmitted is refused at step 3 an applicable mandatory choice unsubmitted is refused at step 3
(§3.3); identity's defaults are asserted for a provider the run (§3.3); identity's defaults are asserted for a provider the run
never touched (registration `closed`, JIT off — identity §2.2, never touched (registration `closed`, JIT off — identity §2.2,
@@ -350,23 +450,35 @@ Binding on the implementing PRs:
6. **Gating-independence witness:** with any wizard-completion marker 6. **Gating-independence witness:** with any wizard-completion marker
deleted (§1.4), authorization and registration gating behave deleted (§1.4), authorization and registration gating behave
identically — proving no gate reads wizard state. identically — proving no gate reads wizard state.
7. **Interrupted-run witness:** inject failure after each internal 7. **Interrupted-run witness:** inject failure at each point of a
mutation of a run — after the bootstrap transaction, after each run — **inside the finalize transaction** (after admin creation but
individual seed command (company, estate, project, workspace, each before the carried writes commit: assert nothing exists — no
example item), and after the bookkeeping cache write — and for each account, the epoch still open, canonical settings untouched, no
injection point assert: no stranded partial outcome (every committed fence row, no audit event), after the committed finalize
command has its same-transaction audit event and fence row; nothing transaction, after each individual seed command (company, estate,
else exists), and a resumed run completes exactly the remaining project, workspace, each example item), and after the bookkeeping
mutations with no duplication (identity §8 covers the bootstrap cache write — and for each injection point assert: no stranded
step; §4.3–§4.4 define the fence the witness exercises). Deleting partial outcome (every committed command has its same-transaction
the bookkeeping cache between failure and resume MUST NOT change the audit event and fence row; nothing else exists), and a resumed run
outcome. **Idempotency-fence witnesses:** re-submitting a committed completes exactly the remaining mutations with no duplication
seed command with its same key executes nothing and returns the (identity §8 covers the epoch transition; §4.3–§4.4 define the
recorded outcome (asserted by mutation-count and audit-event-count fence the witness exercises). The resume after the committed
equality); two concurrent resumed runs executing the seed sequence finalize MUST be performed by a fresh client holding none of the
yield exactly one seed set — per key, exactly one mutation and one original run's transient state, deriving the remaining seed
audit event exist, and the losing submission received the recorded sequence from canonical state alone (§3.4). Deleting the
outcome or the single bounded conflict refusal. bookkeeping cache between failure and resume MUST NOT change the
outcome. **Idempotency-fence witnesses (§4.3):** re-submitting a
committed seed command with its same key, actor, and payload
executes nothing and returns the recorded outcome (asserted by
mutation-count and audit-event-count equality); the same key with a
changed payload digest is refused with the single bounded conflict
and executes nothing; a replay by an actor who has since lost
eligibility (identity §7.1 ban) receives the authorization refusal,
not the recorded outcome; a submission that failed before commit
leaves no fence row and its retry executes; two concurrent resumed
runs executing the seed sequence yield exactly one seed set — per
key, exactly one mutation and one audit event exist, and the losing
submission received the winner's recorded outcome.
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
@@ -383,13 +495,17 @@ Binding on the implementing PRs:
10. **Enrollment witness:** the enrollment step exists, invokes only the 10. **Enrollment witness:** the enrollment step exists, invokes only the
rank-4 family, and a run that skips it completes with zero rank-4 family, and a run that skips it completes with zero
enrollment-family mutations. enrollment-family mutations.
11. **Pre-epoch authority witness (§3.3 application rule):** during a 11. **Pre-epoch authority and finalize witness (§3.3):** during a
first run, before the epoch transition, canonical settings are first run, before finalize, canonical state is untouched
untouched (settings-state comparison against the pre-run capture), (settings-state comparison against the pre-run capture), and an
and an injected settings-write attempt from the unauthenticated injected settings-write attempt from the unauthenticated pre-epoch
pre-epoch flow is refused with contract 5 §4.2's authorization flow is refused with contract 5 §4.2's **authentication-failure
class; after step 3, the collected values are applied and each class** (the caller is unauthenticated, not an
application is attributable in audit to the new admin. authorized-but-refused actor); the finalize command commits the
admin, the epoch transition, and every carried value in one
transaction, each carried write attributable in audit to the new
admin; the §6.7 inside-finalize injection covers the atomicity
negative.
## 7. Drafting additions (PRD §12.1 disclosure) ## 7. Drafting additions (PRD §12.1 disclosure)
@@ -400,18 +516,41 @@ contracts and are not additions:
1. Enrollment-step skippability (§3.5) — the PRD step list does not 1. Enrollment-step skippability (§3.5) — the PRD step list does not
mark the step optional. mark the step optional.
2. The unauthenticated bootstrap-status mode disclosure — exactly one 2. The unauthenticated bootstrap-status mode disclosure — the closed
field (the recorded mode value), during the bootstrap epoch only two-field response schema (epoch state plus the recorded mode
(§2.3). value, the latter present during the bootstrap epoch only) (§2.3).
3. The collect-first, post-epoch application sequencing for steps 12 3. The **bootstrap finalize command** (§3.3) — an extension of
(§3.3 application rule). identity §3's bootstrap surface: one transaction carrying the
4. The idempotency-key field and its same-transaction uniqueness fence first-admin fields, the collected settings, registration-mode, and
(§4.3) — an addition to contract 5 §4's command envelope, proposed JIT values, and the §3.4 seed parameter, committing the carried
and ratified here, severable from the rest of this contract. writes under the new admin's authority with identity §3.5's
atomicity extended over them. Severable from the rest of this
contract.
4. The idempotency-key field and its same-transaction uniqueness
fence, with the §4.3 replay, collision, no-error-replay, and
concurrency rules — an addition to contract 5 §4's command
envelope, proposed and ratified here, severable from the rest of
this contract.
5. The presentation-and-submission obligation for applicable mandatory 5. The presentation-and-submission obligation for applicable mandatory
choices on wizard runs (§3.3). choices on wizard runs (§3.3).
6. The no-server-side-orchestrator architectural constraint (§1.1). 6. The no-server-side-orchestrator architectural constraint (§1.1).
7. The wizard-completion-marker presentational-only rule (§1.4). 7. The wizard-completion-marker presentational-only rule (§1.4).
8. The contract 5 §3.1 rank-6 mapping expansion (§1.1): the rank-6
composition row, which today names only the rank-1 hierarchy and
rank-4 enrollment families, is amended to name all six composed
families — adding the settings command family, the identity
bootstrap and registration surface (including the §3.3 finalize
command), the mode reads (contract 6 §2.2 and the §2.3
bootstrap-status field), and the ordinary content commands used for
example seeding — with one mapping row per newly named family.
Without this amendment those operations are unmapped and blocked
under contract 5 §5.
9. The contract 6 §2.2 amendment permitting the single unauthenticated
pre-epoch mode disclosure through the §2.3 bootstrap-status field;
post-epoch, §2.2's authenticated-only rule is unchanged.
10. The password-only v1 first admin (§3.3): identity §3.6's SSO
variant is not composed by the v1 wizard; the PRD step list's SSO
option is satisfied post-epoch.
## Ruling request ## Ruling request