docs: onboarding wizard contract (S2 contract 3) #1437
@@ -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
|
||||
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
|
||||
host-local install wizard (`mosaic wizard`, which drives host install and
|
||||
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
|
||||
scripted sequence), so contract 5 §6.1's outbound-call inventory,
|
||||
scoped to those modules, sees the wizard's complete operation set.
|
||||
The composed operations span six existing families, each already
|
||||
within contract 5's mapping: the rank-1 hierarchy commands and the
|
||||
rank-4 enrollment command (contract 5 §3.1 — built first), the
|
||||
settings command family (steps 1–2), the identity bootstrap and
|
||||
registration surface (step 3), the mode reads (contract 6 §2.2
|
||||
post-epoch; the §2.3 bootstrap-status field pre-epoch), and the
|
||||
ordinary content commands used for example seeding (step 4).
|
||||
The composed operations span six existing families: the rank-1
|
||||
hierarchy commands and the rank-4 enrollment command (contract 5
|
||||
§3.1 — built first), the settings command family (steps 1–2), the
|
||||
identity bootstrap and registration surface (step 3, including the
|
||||
§3.3 finalize command), the mode reads (contract 6 §2.2 post-epoch;
|
||||
the §2.3 bootstrap-status field pre-epoch), and the ordinary
|
||||
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
|
||||
it performs is an existing command with its own contract: user and
|
||||
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
|
||||
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
|
||||
applied (the §3.3 application rule) are transient run state, not a
|
||||
persisted answer file. The wizard MAY persist run bookkeeping
|
||||
committed by the §3.3 finalize command are transient run state, not
|
||||
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
|
||||
source of truth for any decision. The §4.3 idempotency fence is
|
||||
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
|
||||
value reported by the **unauthenticated bootstrap-status response**
|
||||
of the bootstrap surface (identity §3), which evaluates the mode
|
||||
record server-side and discloses exactly one field beyond epoch
|
||||
state: the recorded mode value (drafting addition, §7). Post-epoch
|
||||
wizard runs read mode through contract 6 §2.2 unchanged. Changing
|
||||
record server-side. The bootstrap-status response is a **closed
|
||||
two-field schema**: `epoch` — one field whose value set is exactly
|
||||
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
|
||||
recorded mode of `enterprise` is refused at bootstrap (contract 6
|
||||
§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
|
||||
name feeds step 4's company creation. On a first run this step
|
||||
collects and validates only — application follows step 3's
|
||||
application rule below. On a re-run (an authenticated admin exists)
|
||||
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)
|
||||
it applies directly through the settings commands.
|
||||
2. **Component choices.** Mosaic Comms/Matrix vs external; Mosaic
|
||||
SSO/Authentik vs external; Mosaic DB/PostgreSQL vs external; vector
|
||||
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
|
||||
beyond that is host tooling, out of scope here.
|
||||
3. **Initial user.** Email, password, and display name, or SSO (PRD §6
|
||||
step list: "email/password/name/SSO"), per identity §3: the
|
||||
first-admin transition is atomic, one per bootstrap epoch, and the
|
||||
SSO variant runs inside the bootstrap transaction (identity §3.6).
|
||||
The display-name source is bound per path: the password path uses
|
||||
the submitted display name; the SSO variant uses the name claim
|
||||
mapped under identity §5's claim mapping. Canonical `users.name`
|
||||
MUST equal that source value (witness §6.5); no field of the PRD's
|
||||
step list is dropped. The wizard also presents the applicable
|
||||
3. **Initial user and finalize.** Email, password, and display name
|
||||
(PRD §6 step list: "email/password/name/SSO"), per identity §3: the
|
||||
first-admin transition is atomic and one per bootstrap epoch. **The
|
||||
v1 first admin is password-only.** A step-2 SSO choice cannot yield
|
||||
a canonically configured provider before the epoch closes, so an
|
||||
SSO-authenticated first admin is not constructible in this flow;
|
||||
the v1 wizard does not compose identity §3.6's SSO variant, and the
|
||||
PRD step list's SSO option is satisfied post-epoch (providers
|
||||
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
|
||||
configured SSO provider, that provider's JIT enablement with its
|
||||
allowlist warning (identity §4.1, §4.3). The wizard MUST obtain an
|
||||
explicit submission for each applicable mandatory choice and MUST
|
||||
refuse step completion while one is unsubmitted. This is a
|
||||
presentation-and-submission obligation on wizard runs only:
|
||||
identity's own defaults (registration `closed`, JIT off) continue to
|
||||
govern everything a wizard run never touches, and this contract
|
||||
creates no new stored-record obligation beyond those identity itself
|
||||
defines. **Application rule (first runs):** immediately after the
|
||||
epoch transition, authenticated as the newly created admin — the
|
||||
first-admin transition (identity §3) yields the account holding the
|
||||
RBAC §1.1 platform authority that system and component settings
|
||||
writes require — the run applies the values collected in steps 1–2
|
||||
through the ordinary settings commands. Before the transition the
|
||||
run holds collected values only: no canonical settings write occurs
|
||||
pre-epoch, and no pre-admin write authority exists or is invented
|
||||
(disclosed sequencing addition, §7; witness §6.11).
|
||||
4. **Initial hierarchy and seeding.** Runs strictly after step 3's epoch
|
||||
transition, authenticated as the newly created admin. The bootstrap
|
||||
writer (identity §3) creates only the first account and closes the
|
||||
epoch; it has no hierarchy authority and creates no hierarchy node.
|
||||
SSO provider canonically configured at finalize time, that
|
||||
provider's JIT enablement with its allowlist warning (identity
|
||||
§4.1, §4.3); a provider configured after finalize receives its JIT
|
||||
choice at configuration time under identity §4.1's default. The
|
||||
wizard MUST obtain an explicit submission for each applicable
|
||||
mandatory choice and MUST refuse finalize while one is unsubmitted.
|
||||
This is a presentation-and-submission obligation on wizard runs
|
||||
only: identity's own defaults (registration `closed`, JIT off)
|
||||
continue to govern everything a wizard run never touches, and this
|
||||
contract creates no new stored-record obligation beyond those
|
||||
identity itself defines. **Finalize rule (first runs):** step 3
|
||||
ends in a single **bootstrap finalize command** on identity §3's
|
||||
bootstrap surface — a disclosed extension of that surface (§7.3) —
|
||||
carrying the first-admin fields and every collected value: the
|
||||
step-1 system name, the step-1 company name (recorded as the §3.4
|
||||
seed parameter), the step-2 component choices, the
|
||||
registration-mode submission, and the applicable JIT submissions.
|
||||
The command executes **in one transaction**: it creates the admin
|
||||
and closes the epoch exactly as identity §3 defines, then — with
|
||||
the new admin existing inside the same transaction, holding the
|
||||
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
|
||||
command under §5.2's eligibility policy, with the new admin as actor,
|
||||
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
|
||||
disclosed drafting addition to contract 5's §4 command envelope
|
||||
ratified with this contract (§7): a mutating command MAY carry a
|
||||
caller-supplied idempotency key; the command layer records the key
|
||||
in a uniqueness-constrained fence table **in the same transaction**
|
||||
as the mutation and its audit event, and a submission whose key is
|
||||
already recorded executes nothing and returns the recorded outcome.
|
||||
caller-supplied idempotency key. The complete envelope:
|
||||
- **Fence row.** The command layer records, in a
|
||||
uniqueness-constrained fence table **in the same transaction**
|
||||
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
|
||||
epoch and the seed role (e.g. epoch id + "seed-company") for every
|
||||
seed mutation. Correlation ids (contract 5 §4.3) remain pure trace
|
||||
linkage and carry no idempotency semantics. Two concurrent resumed
|
||||
runs serialize on the fence's unique constraint: exactly one
|
||||
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
|
||||
linkage and carry no idempotency semantics. Wizard bookkeeping of
|
||||
seed node ids remains a cache
|
||||
(§1.3): losing it cannot cause duplication, because the fence is
|
||||
canonical command-layer state. A re-run offers to create
|
||||
_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
|
||||
seeding is not skippable (PRD §6.4: a completed first run contains
|
||||
the fixed example set).
|
||||
|
||||
4. **Interrupted runs strand nothing.** The wizard is resumable at the
|
||||
granularity of a single command: each mutation either commits through
|
||||
its command with its same-transaction audit event and fence row, or
|
||||
leaves nothing (identity §3.5 for the bootstrap step). Step 4 is a
|
||||
sequence of individually atomic commands, not one transaction: an
|
||||
interruption 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-submits the full ordered seed sequence
|
||||
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.
|
||||
granularity of a single command: each mutation either commits
|
||||
through its command with its same-transaction audit event and fence
|
||||
row, or leaves nothing (identity §3.5, extended over the carried
|
||||
writes, for the §3.3 finalize command). A run interrupted before
|
||||
finalize has written nothing; its collected values are re-entered.
|
||||
A run interrupted after finalize resumes from canonical state
|
||||
alone: every collected value was committed by the finalize
|
||||
transaction, and the remaining work — the step 4–5 command
|
||||
sequence — is derivable from it (§3.4). Step 4 is a sequence of
|
||||
individually atomic commands, not one transaction: an interruption
|
||||
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)
|
||||
|
||||
@@ -299,10 +395,12 @@ Binding on the implementing PRs:
|
||||
2. **Mode witnesses:** the branch point exists — a pre-epoch flow
|
||||
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
|
||||
bootstrap-status response discloses exactly one field beyond epoch
|
||||
state (closed-field assertion on the response schema); post-epoch,
|
||||
an unauthenticated mode read is refused (contract 6 §2.2 holds
|
||||
unchanged); v1 with mode `standalone` yields the §3 step set; a
|
||||
bootstrap-status response matches §2.3's closed two-field schema
|
||||
exactly while the epoch is open, and after the epoch completes
|
||||
contains the epoch field only — the mode field absent from the
|
||||
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
|
||||
precondition refusal (§2.3) and no partial flow; wizard sources
|
||||
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
|
||||
completes, and each canonical value equals the value the run
|
||||
submitted (asserted against the captured submissions, not by reading
|
||||
the canonical store twice); canonical `users.name` equals the path's
|
||||
declared source — the submitted display name for the password path,
|
||||
the identity §5 mapped name claim for the SSO variant (asserted
|
||||
against the captured submission or captured assertion); a run with
|
||||
the canonical store twice); canonical `users.name` equals the
|
||||
declared source — for the first admin (password path), the
|
||||
submitted display name; for an SSO-created account (a post-epoch
|
||||
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
|
||||
(§3.3); identity's defaults are asserted for a provider the run
|
||||
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
|
||||
deleted (§1.4), authorization and registration gating behave
|
||||
identically — proving no gate reads wizard state.
|
||||
7. **Interrupted-run witness:** inject failure after each internal
|
||||
mutation of a run — after the bootstrap transaction, after each
|
||||
individual seed command (company, estate, project, workspace, each
|
||||
example item), and after the bookkeeping cache write — and for each
|
||||
injection point assert: no stranded partial outcome (every committed
|
||||
command has its same-transaction audit event and fence row; nothing
|
||||
else exists), and a resumed run completes exactly the remaining
|
||||
mutations with no duplication (identity §8 covers the bootstrap
|
||||
step; §4.3–§4.4 define the fence the witness exercises). Deleting
|
||||
the bookkeeping cache between failure and resume MUST NOT change the
|
||||
outcome. **Idempotency-fence witnesses:** re-submitting a committed
|
||||
seed command with its same key executes nothing and returns the
|
||||
recorded outcome (asserted by mutation-count and audit-event-count
|
||||
equality); 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 recorded
|
||||
outcome or the single bounded conflict refusal.
|
||||
7. **Interrupted-run witness:** inject failure at each point of a
|
||||
run — **inside the finalize transaction** (after admin creation but
|
||||
before the carried writes commit: assert nothing exists — no
|
||||
account, the epoch still open, canonical settings untouched, no
|
||||
fence row, no audit event), after the committed finalize
|
||||
transaction, after each individual seed command (company, estate,
|
||||
project, workspace, each example item), and after the bookkeeping
|
||||
cache write — and for each injection point assert: no stranded
|
||||
partial outcome (every committed command has its same-transaction
|
||||
audit event and fence row; nothing else exists), and a resumed run
|
||||
completes exactly the remaining mutations with no duplication
|
||||
(identity §8 covers the epoch transition; §4.3–§4.4 define the
|
||||
fence the witness exercises). The resume after the committed
|
||||
finalize MUST be performed by a fresh client holding none of the
|
||||
original run's transient state, deriving the remaining seed
|
||||
sequence from canonical state alone (§3.4). Deleting the
|
||||
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
|
||||
creation succeeds for an ordinary authenticated non-admin user
|
||||
(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
|
||||
rank-4 family, and a run that skips it completes with zero
|
||||
enrollment-family mutations.
|
||||
11. **Pre-epoch authority witness (§3.3 application rule):** during a
|
||||
first run, before the epoch transition, canonical settings are
|
||||
untouched (settings-state comparison against the pre-run capture),
|
||||
and an injected settings-write attempt from the unauthenticated
|
||||
pre-epoch flow is refused with contract 5 §4.2's authorization
|
||||
class; after step 3, the collected values are applied and each
|
||||
application is attributable in audit to the new admin.
|
||||
11. **Pre-epoch authority and finalize witness (§3.3):** during a
|
||||
first run, before finalize, canonical state is untouched
|
||||
(settings-state comparison against the pre-run capture), and an
|
||||
injected settings-write attempt from the unauthenticated pre-epoch
|
||||
flow is refused with contract 5 §4.2's **authentication-failure
|
||||
class** (the caller is unauthenticated, not an
|
||||
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)
|
||||
|
||||
@@ -400,18 +516,41 @@ contracts and are not additions:
|
||||
|
||||
1. Enrollment-step skippability (§3.5) — the PRD step list does not
|
||||
mark the step optional.
|
||||
2. The unauthenticated bootstrap-status mode disclosure — exactly one
|
||||
field (the recorded mode value), during the bootstrap epoch only
|
||||
(§2.3).
|
||||
3. The collect-first, post-epoch application sequencing for steps 1–2
|
||||
(§3.3 application rule).
|
||||
4. The idempotency-key field and its same-transaction uniqueness fence
|
||||
(§4.3) — an addition to contract 5 §4's command envelope, proposed
|
||||
and ratified here, severable from the rest of this contract.
|
||||
2. The unauthenticated bootstrap-status mode disclosure — the closed
|
||||
two-field response schema (epoch state plus the recorded mode
|
||||
value, the latter present during the bootstrap epoch only) (§2.3).
|
||||
3. The **bootstrap finalize command** (§3.3) — an extension of
|
||||
identity §3's bootstrap surface: one transaction carrying the
|
||||
first-admin fields, the collected settings, registration-mode, and
|
||||
JIT values, and the §3.4 seed parameter, committing the carried
|
||||
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
|
||||
choices on wizard runs (§3.3).
|
||||
6. The no-server-side-orchestrator architectural constraint (§1.1).
|
||||
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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user