PoC specification review¶
Specification review for ginsys/bronzeward#20. It reads the three milestone-02 contracts against design §18.1 and §18.2, §13.7 and the feasibility evidence review, traces each required property to evidence, contract clause and acceptance scenario, checks the contracts against each other, lists the owner-review choices with a recommendation for each, maps every carried gap to an issue or to later work, and gives the refinement text for ginsys/bronzeward#21 to ginsys/bronzeward#31. It decides nothing: the owner or designated reviewer accepts the specification (criterion 5), and the refinement labels come off only when the issues carry the refined text.
Read at main aa58272 (2026-09-27), with the
acceptance plan and the E3 disposition wording of §8 landing in the
same change as this report.
1. Question¶
Is the PoC specification consistent, traceable and implementable for the selected profile? Put narrowly: for each property design §18.2 requires, does a contract clause specify it, does evidence support it, and does a scenario of the acceptance plan show it; where two contracts meet, do they say the same thing; and what does each implementation issue need before its refinement label comes off?
2. What binds every conclusion¶
Carried forward from the feasibility evidence review (FR §2) and from the issue:
- Upgrade/LifecycleClient execution testing is deferred and design experiment E3 has not passed. PoC compatibility is not full-E3 completion (§8).
- The fixture limits bind every conclusion: exact-copy leak scanning, one Talos version, containers without reboot, upgrade, reset, installer or disk behaviour, one control plane and one worker (fixtures report §7).
- A contract clause is a specification, not evidence. "Specified" below never means "shown"; only an executed acceptance scenario turns a specified property into an evidenced one, and only within the fixture limits.
- Licence selection (S04) is independent and does not block this review.
No row below is a production claim.
3. Sources¶
| Key | Source | Read at |
|---|---|---|
| C | compilation contract (ginsys/bronzeward#17) | aa58272 |
| PA | persistence and API contract (ginsys/bronzeward#18) | aa58272 |
| ER | execution and recovery contract (ginsys/bronzeward#19) | aa58272 |
| AP | acceptance plan (ginsys/bronzeward#20) | this change |
| FR | feasibility evidence review (ginsys/bronzeward#12) | aa58272 |
| Design | design document | aa58272 |
The E-reports (Fx, E1, SR, SP, E3, DB, DS, PC, RC, KL, OM) keep the keys, issues and pins of
FR §3; FR §3.1 establishes that every
fixture-based capture carries the same fixtures/versions.env blob, which is unchanged at aa58272.
Line numbers in §6 are at aa58272. The repairs of §7 moved some of those lines; the section cited
with each stays the reference.
4. Properties¶
One row per property the PoC must have, drawn from the numbered §18.2 items and its closing paragraph, the §13.7 policy items, and FR's SP rows (FR §4) where they bear on the PoC.
| ID | Property | Design | FR |
|---|---|---|---|
| PR01 | Import reads the live configuration without mutating it | §18.2 item 1 | SP01 |
| PR02 | Extraction precedes every durable write on import and drift adoption, across success, rejection, crash and restart; protected staging has a recovery owner | §18.1 E1; §18.2 item 1 | SP02, SP03 |
| PR03 | Schema-based detection assessed without a completeness claim; marking load-bearing | §18.1 E1 | SP04 |
| PR04 | Exact encrypted baseline | §18.2 item 1 | SP05 |
| PR05 | Composition with references reaches native merge parity, no custom merge semantics | §18.2 item 2 | SP06 |
| PR06 | Named validation stages; materialized validation | §18.2 item 2 | SP07 |
| PR07 | Sensitivity provenance; redaction not solely by value matching | §18.2 item 3 | SP08 |
| PR08 | Exact dependency records, effective and reproduction | §18.2 item 3 | SP09 |
| PR09 | Stale-revision writes rejected | §18.2 item 2 | SP12 |
| PR10 | Publication atomic and idempotent | §18.2 item 3 | SP13 |
| PR11 | Immutable encrypted per-machine artifacts | §18.2 item 3 | SP32 |
| PR12 | Publication, checks or a retained verdict alone cannot dispatch |
§18.2 item 3 | SP14, SP25 |
| PR13 | Dependency classification and alerts; unknown never pass or lost | §18.2 closing (§7.8) | SP25, SP26 |
| PR14 | Minimal authenticated API; authorization scoped by capability | §18.2 item 4 and closing; §13.7 items 1–2 | SP30 |
| PR15 | Plan bound to the exact artifact and assignment; one approval; self-approval recorded | §18.2 item 4; §13.7 item 3 | SP17 |
| PR16 | Approval and identity revocation reach what §13.7 item 4 states | §13.7 item 4 | SP17 |
| PR17 | Unique durable intent; ownership loss fenced; A-after-B overwrite prevented at the fence: a stale owner commits and attempts nothing after a newer one | §18.1 E4 | SP15, SP18, SP19 |
| PR18 | Direct dispatch by the E4 mechanism, verification, separate desired/applied/observed | §18.2 item 5 | SP10, SP21 |
| PR19 | A node whose observed identity differs from the plan's is refused before any send | §18.2 items 4–5 ("exact ... assignment") | none |
| PR20 | Drift detected; freeze, sanitized adoption and approved revert | §18.2 item 6 | SP22 |
| PR21 | Interrupted RPCs and reconnects end safe or explicitly unresolved | §18.2 item 7 | SP20 |
| PR22 | A bound on when an abandoned request can no longer land | §18.2 item 7 | FR §9 item 3 |
| PR23 | Restoration recovered through explicit recovery mode; conflicting work stopped | §18.2 item 7; §13.7 item 5; §14.6 | SP23 |
| PR24 | Usable operation timeline | §18.2 closing | SP30 |
| PR25 | Selected database/provider behaviour, including migrations | §18.2 closing (§7.7); §18.1 E4 | SP16, SP24, SP28 |
| PR26 | Upgrade/LifecycleClient transition | §18.1 E3 | SP11 |
| PR27 | The E6 existing-cluster vertical slice | §18.1 E6 | SP31 |
Not a PoC property: enrolment, reset/reuse, bootstrap, upgrades, remote transports and managed-cluster etcd recovery (§18.2 exclusions; AP §8).
5. Matrix¶
Status codes:
- evidenced: FR grades the property P for the tested mechanism, and a contract clause specifies that mechanism.
- specified-not-evidenced: a contract clause (or, for PR13, a decided design policy) specifies it; evidence is partial or absent; the named scenario is what would show it.
- gap: no clause specifies it, or the clause substitutes an operator decision for the missing property. §10 assigns each.
| ID | Evidence (FR grade) | Clause | Scenario | Status |
|---|---|---|---|---|
| PR01 | E1 (P) | C §2.3; ER §6.3 | S1 | evidenced |
| PR02 | E1 (p); pipeline interruption never measured (C §15) | C §2.3, §3 | S1, S5 | specified-not-evidenced |
| PR03 | E1, SP (p) | C §2.1, §2.4 | S1 | specified-not-evidenced |
| PR04 | E1 (P) | C §2.3 step 8 | S1 | evidenced |
| PR05 | SR (P at the SR boundary); machinery parity inferred (FR §8 C4) | C §5, §6, §10.1 | S2 | specified-not-evidenced: the selected machinery path is the C §10.1 condition |
| PR06 | SR (P), E3 (p) | C §7 | S2 | specified-not-evidenced |
| PR07 | SP (P), E1 (p) | C §8 | S2, S8 | specified-not-evidenced |
| PR08 | SP (P), SR (p) | C §9 | S2 | specified-not-evidenced |
| PR09 | DB (P) | PA §4 | S2 | evidenced |
| PR10 | DB (P) | PA §6, §7 | S2 | evidenced |
| PR11 | PC (p) | C §11; PA §3, §6.2 | S2 | specified-not-evidenced |
| PR12 | PC, RC (p) | ER §2; C §11; PA §6.2 | S2, S3 step 1 | specified-not-evidenced |
| PR13 | RC (P), PC (P) cells; overall p | design §7.6, §7.8, §15.3; PA §3 (DependencyStatus); C §6 step 3 | S2 | specified-not-evidenced; no contract section owns the monitor (§10) |
| PR14 | none (G) | PA §9, §10 | S0, S3 | specified-not-evidenced |
| PR15 | DS (p) | ER §2; PA §8.1, §10.5 | S3 | specified-not-evidenced |
| PR16 | DS rows 002–005 for approvals (p); identity revocation unmeasured | ER §3.2, §3.3, §8.5; PA §10.4 | S3, S7 | specified-not-evidenced; approval half evidenced |
| PR17 | DB (P), DS (P, p) | ER §3.2, §3.4; PA §5.1 | S4, S6.1 | evidenced for the fence, by the P grades; a request already sent can still land after a newer operation, detected as drift, not prevented (§7 A; PR22's gap) |
| PR18 | DS, E3 (p) | ER §1, §3.5, §4 | S4 | specified-not-evidenced: the machinery client is the ER §3.5 condition |
| PR19 | none | ER §2, §3.2 comparison 3, §7.4 (choice §10.26); PA §7.3 | S4, S7 | specified-not-evidenced: no investigation read the SMBIOS UUID or membership through Talos |
| PR20 | none (G) | ER §6; C §2.3 | S5 | specified-not-evidenced |
| PR21 | DB (P), DS (p) | ER §5 | S6.1 | specified-not-evidenced |
| PR22 | DS: late landings in three of six partitions (FR §7) | ER §5.2: an operator decision after a settle floor, not a bound | S6.2 | gap |
| PR23 | DB (N), KL (p), DS (G) | ER §7; PA §12; C §3.5 | S7 | specified-not-evidenced; the epoch answering the N finding is inferred (DB §9) |
| PR24 | none (G) | ER §4.1; PA §8.3 | S8 | specified-not-evidenced |
| PR25 | PC (P), DB (p) | PA §5, §11 | S0 to S8 | specified-not-evidenced |
| PR26 | none (G) | none: deferred | none (AP §8) | gap, beyond the PoC (§8) |
| PR27 | none (G) | AP | the integrated run | specified-not-evidenced |
27 properties: evidenced 5 (PR01, PR04, PR09, PR10, PR17), specified-not-evidenced 20, gap 2 (PR22, PR26); PR19 was a gap until the owner's gap G decision (§10). Every §18.2 item and closing-paragraph requirement has at least one scenario (AP §7).
6. Cross-contract consistency¶
Checked where two contracts state the same fact. Paths are under docs/spec/, lines at aa58272.
Items 1, 2, 4, 6 and 7 are repaired by
ginsys/bronzeward#56, which lands before this
report; item 3 was a gap (§10), closed by the owner's gap G decision (ER choice §10.26); item 5 needs no change, and PA's request in it is declined (below).
Inconsistent or open at aa58272:
- Configuration-digest hand-off called open, but landed.
persistence-api.md:104-110(PA §1.1 item 2) says the compilation hand-off of the plaintext and baseline configuration digests is open "until that amendment lands";compilation.md:159-166(§2.3 step 8) andcompilation.md:971-973(§11) carry both. PA's gap bulletpersistence-api.md:2059-2061is stale for the same reason. - What the recovery start serves before entry.
execution-recovery.md:1129-1135(ER §7.2) says the recovery-start controller serves observation, the recovery API, drafts, ingestion, compilation and publication, without distinguishing before and after entry;persistence-api.md:1616-1625(PA §12.2) serves only liveness and entry until entry commits, andpersistence-api.md:1935(PA §14) refuses every other request. PA is stricter and is what AP S7 tests; ER needs the same before-entry limit. ER §7.2 also allowed the normal restart only after the first released scope, PA §12.2 after entry; the repair aligns both (§7). - Pre-send identity check.
persistence-api.md:869-873(PA §7.3) records that no contract refuses a node whose observed identity differs from the plan's before the first send; inexecution-recovery.md:163-167(ER §2) machine identity is a postcondition, not a precondition, so ER §3.2 comparison 3 does not check it. Property PR19; a gap (§10), closed by the owner's gap G decision: ER §2 now binds identity as a precondition (choice §10.26). - Ingestion role wording.
execution-recovery.md:953-955(ER §6.3) gives the ingestion toauthor;persistence-api.md:1431-1436(PA §10.3) requiresauthorheld by a human. ER cites PA's rule, so the effect agrees; the word "human" is missing. - "Self-approval undetermined".
execution-recovery.md:223-225(ER §2) keeps it as a guard;persistence-api.md:143-146(PA §1.2 item 9) says it never arises, because every automation identity names a responsible human. Consistent in effect; PA asked ER to state that it never arises. Declined: ER already says the record is persistence's and requires a responsible human, and a guard that never fires costs nothing while it keeps a missing record from reading as "not self-approval". No gap follows. - The generation-path component.
compilation.md:146-150(C §2.3 step 6) requires a component the database does not issue without naming it; PA §17.8 names it (claim id plus a random value id) and says it "Needs a line in compilation §2.3 step 6". - Parallel-revision note.
persistence-api.md:42-44says ER "is being revised in parallel"; ER has landed.
Consistent (checked, no action): PA §1.2 item 8 and ER §7.1 (execution-recovery.md:1097-1100)
on reissued identifiers; ER §7.5's publication row (execution-recovery.md:1277) and PA §12.2's
assignment-change exception (persistence-api.md:1683-1688), which applies ER's own assignment
rule; and the choice pairs in §9.
7. Carried findings¶
The findings carried into this review on ginsys/bronzeward#20: two from the final head of the first execution-recovery pull request (A, B), the post-round findings of the persistence (J–N) and execution-recovery (C–I) pull requests, and six review threads declined there. Each was re-verified against aa58272; the repairs are ginsys/bronzeward#56.
| ID | Finding | Disposition |
|---|---|---|
| A | ER §4: an attempt already sent when its executor dies can land after a newer operation | Addressed as disclosed: ER §5.2 states the residual, a late landing is detected as drift, not prevented; ER §9.3 gap 2 and PR22 carry the missing bound |
| B | ER §7: a reconnecting executor passes comparison 1 on a restored approval before entry | Addressed as an operator step: ER §7.2 requires every controller stopped until entry commits, which Bronzeward neither enforces nor detects (choice ER §10.18); an enforced fence would be a new mechanism |
| C | ER §7.2 served drafts, ingestion and publication before entry; PA §12.2 serves only liveness and entry | Fixed: ER §7.2 and choice §10.18 now match PA |
| D | ER §6.3: the adoption record compared no machine identity | Fixed: the adopt plan binds the identity and requirement 4.4 compares it |
| E | ER §4: a first contradicting completion read fails the operation before the verification deadline | Fixed by owner decision (2026-09-27): a bound health check has a convergence window up to the verification deadline; identity, assignment revision and digest fail at once (ER §4, choice §10.25) |
| F | ER §4: an operation with no attempt could complete after a takeover | Fixed: an apply-config operation needs a recorded attempt to complete or fail |
| G | ER §7.3: any successful restoration read makes a scope ready |
Fixed by owner decision (2026-09-27): the read's SMBIOS UUID and cluster membership must match the machine record, as before every send (PR19); a mismatch leaves the scope blocked (ER §3.2, §7.3 step 6, §7.4, choice §10.26) |
| H | ER §7.3: a restored operation ends cancelled though an attempt may have been sent after the snapshot |
Fixed as wording: cancelled after a restore refers to the restored journal and is never proof that nothing was sent |
| I | ER §3.3: unresolved and cancelled read as simultaneous |
Fixed: a sequence |
| J | PA: a service identity's token reissued after a restore before its revocation is re-recorded | Fixed: deniedSubjects names service identities too, the operator adds the subject before the revocation is recorded (F9), and the tool issues no token to a listed identity |
| K | PA T11: leaving recovery mode and inventory both read installation state FOR SHARE |
Fixed: leaving takes it FOR UPDATE |
| L | PA §8.2, T8, T9: jobs failed without a terminal event | Fixed: every move of a job to a terminal state appends its terminal event |
| M | PA §7.2: a refused ingestion retried under a new key after rotation ingests again | Fixed as disclosure: the cost is stated in PA §7.1 and §14 |
| N | PA §10.5: a refused draft entry that persists a claim wrote no act | Fixed: it writes the act |
| Threads | Epoch representation, adoption Desired binding, pre-commitment states, first-baseline adoption plan |
Addressed by the execution-recovery text as landed |
| Threads | Desired selection on the machine timeline; drift reads after an assignment change |
Refuted: ER §4.1 excludes Desired selection from the machine-scope facts; drift compares with Applied, which an assignment change does not move |
The fresh review of the repairs raised one further point: under recovery start no job worker runs
(PA §12.2), and ER §7.2 allowed the normal restart only once the first scope was released while
PA §12.2 allows it once entry has committed, so a publication clearing a blocked scope could not
run. ginsys/bronzeward#56 aligns ER §7.2 with PA: the restart may follow entry.
The reviews of ginsys/bronzeward#56 itself led to further repairs in the same change: an
apply-config operation needs a recorded attempt to fail as well as to complete; the recovery
start accepts publication, which completes after the normal restart; a cancelled unattempted
operation's drift opens at the first observation after release, or at scope marking after a
restore; entry (T9) locks the publish and ingest operations it fails; and a machine inventoried
after entry starts pre-restore unaccounted.
8. E3 disposition¶
Disposition. The Upgrade/LifecycleClient transition tests that
E3 §6.3
deferred are deferred to the machine-lifecycle phase. They are now a named acceptance item of
design §18.3
and part of the
§18.5 proof:
on VMs or hardware, an upgrade through MachineService.Upgrade and through
LifecycleClient.Upgrade, the version gate that chooses between them, an upgrade across the v1.13
boundary, a later configuration contract applied after an upgrade, reboot-mode apply and the
upstream upgrade windows. The fixtures report names Talos in QEMU as the tool, rejected for Phase 0
because its provisioner needs root
(fixtures report §2).
What the PoC claims. E3's report is PoC compatibility evidence: render, validation and
apply-config compatibility at the node's running contract minor (C §10.2). It is not full E3; a
search of the repository outside the research reports for E3 and deferral wording found no claim
that E3 passed. The PoC does not upgrade Talos (§18.2 exclusions; AP §8), so the
deferral removes nothing the PoC needs.
Design wording reconciled in the same change: the §18.1 E3 row keeps its definition and adds the
disposition; §18.3 gains the upgrade-transition item; §18.5 states that neither the lifecycle
phase nor E3 can be complete before that item passes; §6.5's compatibility paragraph names the
phase;
CONTRIBUTING.md states the disposition instead of deferring it to this review. The §13.7 item 4
parenthetical calling ER "landed but not yet accepted" was removed as stale.
9. Owner-review choices¶
All 80 choices the contracts put to the owner: C §16 (26), ER §10 (26), PA §17 (28). The default recommendation is accept as specified. FLAG marks a choice where the reviewer recommends the owner decide explicitly; each is expanded below the table.
| ID | Subject | Recommendation |
|---|---|---|
| C16.1 | Ingestion and compiler as two identities | accept as specified |
| C16.2 | RFC 6901 addressing with doc[n] |
accept as specified |
| C16.3 | Create-only cas=0 generations at paths of their own |
accept as specified |
| C16.4 | Baseline under its own key, decryptable by no runtime identity | accept as specified |
| C16.5 | Transient staging by default; separate staging key | accept as specified |
| C16.6 | Absolute expiry beside the lease | accept as specified |
| C16.7 | Owner-only lease extension; takeover only on request after lapse | accept as specified |
| C16.8 | Abandonment evaluated at read time, written by a sweep | accept as specified |
| C16.9 | Claims from an earlier epoch abandoned | accept as specified |
| C16.10 | HMAC under a provider-held key for value digests | accept as specified |
| C16.11 | Substring search kept beside value comparison | accept as specified |
| C16.12 | Every secret scoped to one cluster | accept as specified |
| C16.13 | A new name for every extracted value | accept as specified |
| C16.14 | Declarations name the exact version | accept as specified |
| C16.15 | Tag syntax !bwref <name> |
accept as specified |
| C16.16 | Kinds string, integer, boolean, mapping; lists refused | accept as specified |
| C16.17 | Declarations beside the fragment; encoding enum |
accept as specified |
| C16.18 | SR's re-serialization rules for embedded documents | accept as specified |
| C16.19 | Reserved text !bwref refused in any string |
accept as specified |
| C16.20 | Import base stands in for §6.7's generation resources | accept as specified |
| C16.21 | An exact literal copy of a resolved value refuses publication | accept as specified |
| C16.22 | SP's stand-in format and token syntax | accept as specified |
| C16.23 | Withhold verbatim messages from boolean-input steps | accept as specified |
| C16.24 | Go machinery renderer in process, conditional on a parity re-run | FLAG F2, decided |
| C16.25 | Compile only the node's running contract minor | accept as specified |
| C16.26 | Unkeyed configuration digest of baselines and artifacts | FLAG F1, decided |
| ER10.1 | Ignore is not a PoC drift policy | accept as specified; the role question stays open beyond the PoC |
| ER10.2 | Configuration digest is SHA-256 over the normalized read-back | FLAG F1, decided |
| ER10.3 | Operation created by the dispatch commitment | accept as specified |
| ER10.4 | Self-approval marked for any contained revision and a token's human | accept as specified |
| ER10.5 | Rollout limit fixed at one | accept as specified |
| ER10.6 | Identity revocation refuses every later attempt, retries included | FLAG F6, decided |
| ER10.7 | Takeover at start and on request only; no timer | accept as specified |
| ER10.8 | Machinery Talos client in process, conditional on DS re-runs | FLAG F2, decided |
| ER10.9 | Route bound in the plan; the worker's own endpoint only (owner, F3) | FLAG F3, decided |
| ER10.10 | Retry after full accounting only with attempts, approval and gate | accept as specified |
| ER10.11 | Accounting by recovery-admin after a 30 s settle floor |
FLAG F8, decided |
| ER10.12 | Drift detection does not freeze by itself | accept as specified |
| ER10.13 | Adoption as a plan with operation adopt |
accept as specified |
| ER10.14 | author performs the ingestion feeding an adoption |
FLAG F4, decided |
| ER10.15 | Adoption record compares with the baseline's digest | accept as specified |
| ER10.16 | A revert's approval recorded as approving an unseen overwrite | accept as specified |
| ER10.17 | Recovery epoch a never-reissued random identifier | accept as specified |
| ER10.18 | Recovery start keeps gates closed; entry by the API act | accept as specified |
| ER10.19 | Every scope pre-restore unaccounted at entry | accept as specified |
| ER10.20 | Scope blocked on apply dependencies, not regeneration |
accept as specified |
| ER10.21 | Recovery mode enforced per scope | accept as specified |
| ER10.22 | Leaving recovery mode needs every scope released | accept as specified |
| ER10.23 | An ordinary plan cannot overwrite undetected drift | accept as specified |
| ER10.24 | Every plan binds Desired; commitment refuses once it changed |
FLAG F10, decided |
| ER10.25 | Health-check convergence window up to the verification deadline | owner decision on gap E (§7, §10), decided |
| ER10.26 | Machine identity (SMBIOS UUID, cluster membership) a precondition before any send and before ready |
owner decision on gap G with PR19 (§7, §10), decided |
| PA17.1 | Random application identifiers; mch machine ID |
accept as specified |
| PA17.2 | ETags carry a random token beside the revision | accept as specified |
| PA17.3 | Immutability enforced by database triggers | accept as specified |
| PA17.4 | Publication checks every input head and import base | accept as specified |
| PA17.5 | Import base is the Applied release's; no separate head | accept as specified |
| PA17.6 | Publication selects the release as Desired | FLAG F7, decided |
| PA17.7 | No provider I/O inside a transaction; fixed lock order | accept as specified |
| PA17.8 | Generation paths carry claim id and random value id; orphans reported | accept as specified; C §2.3 step 6 now states the component (§6 item 6) |
| PA17.9 | Idempotency key on every mutating request, kept, epoch-bound | accept as specified |
| PA17.10 | Release natural key is the draft revision | accept as specified |
| PA17.11 | Operation created by the dispatch commitment | accept as specified |
| PA17.12 | Job states; lapsed publish reclaimed; ingest never re-run |
accept as specified |
| PA17.13 | Recovery mode per scope | accept as specified |
| PA17.14 | Problem documents, v1 policy, pagination, SSE |
accept as specified |
| PA17.15 | Adoption approval is a plan with operation: adopt |
accept as specified |
| PA17.16 | OIDC tokens verified per request, 15-minute maximum | accept as specified |
| PA17.17 | One automation token per identity, 30/90-day expiry | accept as specified |
| PA17.18 | Every automation identity names a responsible human | accept as specified |
| PA17.19 | Identity revocation permanent; deny list survives restore | FLAG F6, decided |
| PA17.20 | Several qualifying roles: first in the route's order | accept as specified |
| PA17.21 | Both unsettled self-approval cases marked | accept as specified |
| PA17.22 | Ingestion and inventory need a human author |
FLAG F4, decided |
| PA17.23 | Losing a role does not invalidate approvals | FLAG F5, decided |
| PA17.24 | Migrations by explicit command, service stopped; no downgrade | accept as specified |
| PA17.25 | Epoch a random 128-bit identity, no counter | accept as specified |
| PA17.26 | Recovery-start flag; entry once per start by the API act | accept as specified |
| PA17.27 | Automation tokens from an earlier epoch refused | accept as specified |
| PA17.28 | Drafts and releases per cluster; library fragments shared | accept as specified |
Flags.
- F1: unkeyed configuration digest (C16.26, ER10.2). Both contracts say it is not the most conservative option: a whole-configuration SHA-256 is a guessing oracle when the only unknown parts are low-entropy secrets, and PA §16 and C §15 carry it as unassessed. The alternative, a keyed digest under the C §4.1 HMAC key, costs a provider call per observation and rests on an HMAC primitive no investigation exercised. Recommendation: accept for the PoC, with the residual recorded in the acceptance evidence; revisit before any production use. Owner decision (2026-09-27): accepted; a Talos configuration also holds the cluster's generated key material, which a guess would need, and a configuration without it stays an unassessed residual in ginsys/bronzeward#30's limits.
- F2: machinery in process (C16.24, ER10.8). The renderer and the Talos client both leave what
was measured (subprocess
talosctl), to keep plaintext in one process; the deciding reason is inferred. Both are conditional on re-runs (SR/SP matrices through the compiler, DS rows through the client), which AP S2 and S4 carry as preconditions. Recommendation: accept, and treat a failed re-run as selecting the subprocess fallback, not as a contract change. Owner decision (2026-09-27): in process; a failed re-run selects that component's subprocess fallback within its implementation issue, with the fallback's channel scanned (C §15). - F3: both routes allowed (ER10.9). Chosen for route flexibility. Every late landing DS observed came through the control plane's proxy, and PR22 has no bound. The alternative, the worker's own endpoint only, has one row of evidence. Recommendation: the worker route only until AP S6.2 records a proxy distribution, since that removes the observed late-landing path from the PoC's dispatch. Owner decision (2026-09-27): the worker's own endpoint only; ER §3.5 and choice §10.9 now say so, a proxied-route plan is refused at creation, and AP S6.2 measures the proxy outside the dispatch path.
- F4: ingestion role (ER10.14, PA17.22). Interim, pending the question design §13.7 leaves open.
A human
authoringests; automation cannot. Recommendation: decide the question on ginsys/bronzeward#14 before ginsys/bronzeward#22 starts; the interim is safe to accept if not. Owner decision (2026-09-27): the interim is final; a humanauthoringests, automation does not, and design §13.7 no longer lists the question as open. - F5: role loss (PA17.23). Interim, pending §13.7's open question. Approvals survive loss of the
approverrole; only an identity revocation (item 4) reaches them. The alternative needs a directory lookup or session state. Recommendation: accept the interim for the PoC, stated in ginsys/bronzeward#30's limits, and record the owner's answer on ginsys/bronzeward#14. Owner decision (2026-09-27): accepted for the PoC; the operator revokes the approval or the identity when someone loses the role, ginsys/bronzeward#30's limits say so, and design §13.7 no longer lists the question as open. - F6: identity revocation scope (PA17.19, ER10.6). Both go beyond §13.7 item 4 without contradicting it: revocation is permanent, refuses authentication, and refuses retries of an already-used approval. A mistaken revocation locks the person out until given a new identity. Recommendation: accept, and have the owner confirm the lockout consequence explicitly. Owner decision (2026-09-27): accepted, lockout confirmed; a mistaken revocation is corrected by issuing a new subject, and ginsys/bronzeward#30's limits say so.
- F7: Desired at publication (PA17.6). Design §12.6's "select the latest applicable approved
release" points to selection at approval. Selecting at publication is what AP S2 tests ("the
release is
Desiredfor the worker, with no plan"). Recommendation: the owner confirms; if accepted, design §12.6 needs matching wording so the contract does not silently override it. Owner decision (2026-09-27): selection at publication; design §12.6 now says so, and approval gates only the plan that applies it. - F8: settle floor (ER10.11). Accounting a lost response is a
recovery-admindecision after at least 30 s, a choice not a bound (FR §9 item 3). Recommendation: accept for the PoC; AP S6.2's measurement is the input for any change. Owner decision (2026-09-27): accepted, 30 s; F3 keeps the proxy, the only path seen landing late, out of dispatch. - F9: deny-list order (PA17.19, ER §7.3 step 2). The operator adds a revoked subject to
deniedSubjectsbefore the revocation is recorded; nothing enforces it. A missed entry, then a restore to an earlier backup, then a token reissue before re-recording revives the identity. Enforcing it would make an urgent revocation wait for a configuration rollout. Owner decision (2026-09-27, on ginsys/bronzeward#56): keep the operator step, not enforced; the residual stays disclosed. - F10:
Desiredbinding (ER10.24). Raised by review after F7: with selection at publication, a plan approved before a later publication still passed every commitment comparison and could apply a release the machine no longer desires; only adopt plans boundDesired. The alternative keeps the approved plan valid until commitment or expiry. Owner decision (2026-09-27): bindDesiredon every plan; anapply-configplan is created only for the currentDesired, commitment refuses once it changed (ER §2, §3.2 comparison 2), and AP S3 carries the publication-between-approval-and-commitment control.
Pairs checked. Each pair states the same rule: C16.26 and ER10.2 (digest); C16.24 and ER10.8 (in-process machinery, separate conditions); C16.9, ER §7.2 item 5 and PA §12.2 (earlier-epoch claims abandoned); ER10.3 and PA17.11 (operation at commitment); ER10.4 and PA17.18, PA17.21 (self-approval; §6 item 5); ER10.13 and PA17.15 (adopt plan); ER10.14 and PA17.22 (ingestion role; §6 item 4); ER10.17 and PA17.25 (random epoch); ER10.18 and PA17.26 (recovery start and entry; §6 item 2 on what is served before entry); ER10.21, ER10.22 and PA17.13 (per-scope recovery mode and exit); ER10.6 and PA17.19 (identity revocation). C16.7 and ER10.7 apply the same no-timer takeover rule to different objects (claims, operations). ER10.23 has no PA counterpart and needs none; ER10.24 builds on PA17.6 (selection at publication) and PA T4/T6 defer to it.
10. Gaps¶
Every gap the contracts and FR carry, with its owner. "Beyond the PoC" means it stays open after ginsys/bronzeward#31 and is stated in ginsys/bronzeward#30's limits.
FR §9 (FR §9):
| Gap | Where it goes |
|---|---|
| 1. Drift freeze, sanitized adoption, approved revert; E6 | ginsys/bronzeward#27 (AP S5); ginsys/bronzeward#31 |
| 2. Upgrade/LifecycleClient transition | beyond the PoC: design §18.3 item (§8) |
| 3. Late-landing bound | ginsys/bronzeward#28 (AP S6.2); if no bound results, beyond the PoC, accounting staying an operator decision |
| 4. Recovery mode after restoration | ginsys/bronzeward#29 (AP S7) |
| 5. Authenticated API, scoped authorization, timeline | ginsys/bronzeward#21 (S0), ginsys/bronzeward#25 (S3), ginsys/bronzeward#26 and ginsys/bronzeward#31 (S8) |
| 6. SQLite dispatch; MySQL/MariaDB | beyond the PoC: profile is PostgreSQL |
| Narrower: machinery parity; migrations; plan expiry, observation age, attempt bound | ginsys/bronzeward#23; ginsys/bronzeward#21; ginsys/bronzeward#25, ginsys/bronzeward#26, ginsys/bronzeward#28 |
Narrower: exact-copy scanning; age combinations g1/g2/g1 and g2/g1/g2; Transit soft_deleted; crash-to-sealed |
beyond the PoC |
ER §9.3 (ER §9.3):
items 1 to 4 are AP S5, S6.2, S7 and S8 (ginsys/bronzeward#27, #28, #29, #26). Plan expiry and
cancellation, the assignment-change refusal and identity revocation go to ginsys/bronzeward#25;
observation age, InvalidArgument for a validation error and the machinery client to
ginsys/bronzeward#26; the attempt bound and takeover at start to ginsys/bronzeward#28; observation
ordering under a concurrent accounting transaction, which ER §9.2 requires, to
ginsys/bronzeward#28; comparison 6 to ginsys/bronzeward#27 and
ginsys/bronzeward#29. Beyond the PoC: other response classes, the two age combinations, a new OpenBao cluster, token expiry
across a restore. The two specification gaps (no decommission act for a machine never observed
again; completion consulting only recorded observations) stay open beyond the PoC, with their
residuals stated in ER §9.3, unless the owner asks for a rule first.
PA §16 (PA §16): authentication, same-key concurrency and migrations to ginsys/bronzeward#21; restore epoch and recovery-entry quiescence to ginsys/bronzeward#29; orphan listing to ginsys/bronzeward#22; unkeyed digests to F1; the cross-contract bullet was stale and is removed (§6 item 1). Beyond the PoC: undetected restore (design §14.6 accepts it), online migration and downgrade, serializable isolation, ciphertext determinism.
C §15 (C §15): pipeline interruption, the HMAC primitive, claim contention, staging-key, baseline-key and HMAC policies, and addressing to ginsys/bronzeward#22; machinery composition parity, the fidelity and paired-diff controls, messages and the plaintext boundary to ginsys/bronzeward#23; whole-configuration digests to F1. Beyond the PoC: detector precision, digest key rotation, clock skew, generated-configuration ingestion, kinds not run, tracer limits, embedded formatting, exact-copy leak detection and metal-mode validation.
Found by this review (PR19, PR13), or carried in for an owner decision (§7 E and G, both decided):
- PR19, pre-send identity, with G. ER §2 had machine identity as a postcondition only, so ER
§3.2 comparison 3 did not check it, and any successful restoration read made a scope
ready(§7 G). Owner decision (2026-09-27): the node's SMBIOS UUID and cluster membership must match the machine record before any send and beforeready; a mismatch leaves the scopeblocked(ER §2, §3.2 comparison 3, §7.3 step 6, §7.4, choice §10.26). Reading either through the Talos API is unevidenced, including what the Docker fixture's nodes report; ginsys/bronzeward#26 and ginsys/bronzeward#29 carry the checks (AP §7.1). A machine whose node now reports another identity staysblocked, which joins ER §9.3's decommissioning gap. - E, the verification deadline. Whether a first contradicting completion read may fail an operation before its deadline, or the deadline is a convergence window, and for which postconditions (§7 E). Owner decision (2026-09-27): a window for a bound health check only, written into ER §4 (choice §10.25); ginsys/bronzeward#26 carries the check (AP §7.1).
- PR13, the dependency monitor. No contract section owns the classification procedure, alert
timing or least-privilege metadata access; design §7.6, §7.8 and §15.3 set the policy, and RC
§6.4 is evidence, not a contract. A specification section for the monitor must land before
ginsys/bronzeward#24 loses
status/needs-refinement.
11. Refinement mapping¶
Each block can be lifted verbatim into its issue. Paths are repository paths; "AP" is
docs/spec/acceptance-plan.md. A block's checks are a summary; its Required verification line
is the complete list: every row of AP §7.1 that names the issue, including the items marked
check that no scenario runs. When the block is lifted, those rows are copied under it verbatim,
and the row count stated in the line must match.
ginsys/bronzeward#21, runnable foundation.
- Contracts: persistence-api.md §2, §5, §9, §10, §11; §14 rows for authentication and migration.
- Acceptance: AP S0 steps 1–5 and its negative controls; AP §2 fixture additions (instances A and B
as injector targets, the instance-to-node link fault, disposable OIDC issuer, automation token
tool, OpenBao seal and unseal actions, deployment settings).
- Required verification: the 4 AP §7.1 rows naming #21, among them the in-flight idempotency key
and the concurrent rotation and rotation-revocation races (check).
- Checks: concurrent migrate runs with the advisory-lock control; startup refusal on schema or
checksum mismatch; every token defect 401, except a revoked or deployment-denied subject,
403 identity-revoked (PA §9.4); each design §13.7 row that role alone decides through
the API, the others mapped to S1–S7; no
dispatch, token or role route (404); same-key idempotency with the key-lock control.
- Carries: authentication is untested by any investigation (PA §16).
ginsys/bronzeward#22, adoption.
- Contracts: compilation.md §2, §3, §4, §13; persistence-api.md §3.2, §5.1, §6.4;
execution-recovery.md §6.3 (existing-cluster handover).
- Acceptance: AP S1.
- Required verification: the 6 AP §7.1 rows naming #22, among them the claim eligibility re-check
and two inventory requests for one SMBIOS UUID (check).
- Checks: pre/post digest and resource version unchanged; scan of every surface with its positive
control on success, each refusal and each pipeline step 0–8 interruption under both staging modes;
takeover of a held and of a resumed claim only after lease lapse; lease extension refused to
a non-owner, to an older generation and after lapse; orphans listed, none deleted; automation refused on ingestion;
executor cannot decrypt the baseline.
- Carries: pipeline interruption unmeasured; HMAC primitive unexercised; JSON Pointer addressing
untested (C §15). Owner choice F4 decided: a human author ingests.
ginsys/bronzeward#23, edit and publish.
- Contracts: compilation.md §5–§11; persistence-api.md §4, §6, §7.
- Acceptance: AP S2 steps 1–5 and negative controls.
- Required verification: the 8 AP §7.1 rows naming #23, among them the compiler process's scans
over publications killed at each point before COMMIT (check).
- Checks: SR and SP matrices through the compiler's own path (the C §10.1 condition, before relying
on the machinery); a profile revision selected through the assignment, recorded on the release
and in provenance; ETag 412 on fragment and profile; 409 stale-input with the FOR SHARE
control; literal copy and reserved text refused; fidelity check fires on an injected change;
immutable rows refuse writes; idempotent replay and 422 on reuse; publication creates its
publish operation and no plan or apply-config operation; the draft-update ingestion's
success, refusal and every-step interruption matrix with scans (C §15).
- Carries: machinery parity inferred; paired-diff control loose; messages withheld (C §15). Owner
choice F7 decided: Desired at publication.
ginsys/bronzeward#24, retention checks.
- Contracts: design §7.6, §7.8 and §15.3 (the decided PoC policy); persistence-api.md §3
(DependencyStatus), §6.3; compilation.md §6 step 3, §9. No contract section owns the monitor.
- Gap to close first: the monitor's specification section (§10, PR13): classification procedure,
alert timing and metadata-only access.
- Acceptance: AP S2 step 6 and its soft-delete, destroy and partition controls; AP S7 variants.
- Required verification: the 1 AP §7.1 row naming #24, the refusals of its own clauses.
- Checks: retained, blocked, lost, unknown per RC's evidence; a 404 stays unknown; a
retained dependency turning unreadable alerts at once; persistent unknown re-alerts after 15
minutes; the monitor reads metadata only; publication pinning a non-retained version refused;
a retained verdict never admits dispatch (use-time check stays ER §3.1).
- Carries: Transit soft_deleted and the same-second window (RC §7).
ginsys/bronzeward#25, plan and approve.
- Contracts: execution-recovery.md §2, §3.2 comparisons 1–2, §3.3, §8.1, §8.5;
persistence-api.md §8.1, §10.3–§10.5.
- Acceptance: AP S3.
- Required verification: the 9 AP §7.1 rows naming #25, among them identity revocation racing
commitment with the lock control and its T5c timeline entries (check), and a publication
racing a commitment (check, ER choice §10.24).
- Checks: plan binds every ER §2 value; one approval, automation and non-approvers 403; both
self-approval marks; assignment change refuses commitment; a plan for a release that is not
Desired refused, and a publication after plan creation refuses commitment but not a
committed operation's attempt (F10); an approval surviving role loss (F5); expiry; plan
cancellation before
commitment and after it with no attempt (ER §9.2); approval revocation before and
after commitment with the DS row 003 lock control; identity revocation before and after
commitment; publication alone dispatches nothing.
- Carries: identity revocation unmeasured. F5 decided (role loss not acted on); F6 decided
(permanent revocation).
ginsys/bronzeward#26, safe apply.
- Contracts: execution-recovery.md §1, §3.1–§3.5, §4, §5.1, §8; persistence-api.md §8.3.
- Acceptance: AP S4; AP S8 for the timeline, with ginsys/bronzeward#30 and ginsys/bronzeward#31.
- Required verification: the 10 AP §7.1 rows naming #26, among them machine revisions in commit
order under concurrent writers (check), the health-check convergence window (check,
gap E) and the pre-send identity comparison (check, gap G with PR19).
- Checks: DS rows 001–023 through the implementation with controls 006, 008 and 011 (ER §9.2),
which include the ER §3.5 condition's rows 001–005, 012–017 and 022 through its client; digest equals the artifact's after completion; evidence, commitment and attempt
precede the request; Desired, Applied, Observed served separately; sealed OpenBao, stale
observation, second plan (scope-index control), frozen scope, a proxied-route plan (F3), a node
with another identity and InvalidArgument each refused.
- Gap G with PR19 decided: the node's SMBIOS UUID and cluster membership are compared with the
machine record before any send (ER §3.2 comparison 3, choice §10.26); reading them through the
Talos API, including in the Docker fixture, is unevidenced and this issue shows it. Gap E
decided: a bound health check has a convergence window up to the verification deadline, the
other postconditions none (ER §4, choice §10.25). Owner choices F2 and F3 decided.
ginsys/bronzeward#27, drift.
- Contracts: execution-recovery.md §6, §8.6; compilation.md §2.3 (drift adoption);
persistence-api.md §9.2.
- Acceptance: AP S5 (ER §9.3 closing run 1).
- Required verification: the 4 AP §7.1 rows naming #27, among them the drift-adoption ingestion
matrix and the adoption read's ordering (check).
- Checks: detection opens a record without freezing; freeze by any listed role, unfreeze by
approver only; sanitized adoption with the E1 scan on success, rejection and interruption;
adoption record refused on each stale input; revert refused on re-drift and closed returned on
a manual return; an ordinary plan refused while a record is open; the baseline-reproduction
measurement recorded.
ginsys/bronzeward#28, interrupted execution.
- Contracts: execution-recovery.md §3.4, §4, §5, §8.2–§8.4; persistence-api.md §5.1.
- Acceptance: AP S6.1 and S6.2 (ER §9.3 closing run 2).
- Required verification: the 6 AP §7.1 rows naming #28, among them the attempt bound exhausted
after a lost response, an out-of-band completion that does not complete an operation, and a
takeover that keeps unresolved and refuses a terminal operation (check).
- Checks: each ER §5.3 interruption point ends as its table says; stale owner refused in the
attempt UPDATE with the DS row 008 control; lost response held unresolved until a
recovery-admin decision after the settle floor; newer plan refused (DS row 011 control); retry
only under ER §5's conditions; observation ordering under a concurrent accounting transaction
(ER §4.1, §9.2); the late-landing distribution recorded whichever way it falls.
- Carries: no bound unless S6.2 produces one. Owner choice F8 decided: a 30 s floor.
ginsys/bronzeward#29, restoration.
- Contracts: execution-recovery.md §7, §8.7; persistence-api.md §12, §13.6;
compilation.md §3.5.
- Acceptance: AP S7, its nominal run (quiesced, in the integrated run) and its closing run with a
missed stale instance (ER §9.3 item 3), including its Transit-key and older-OpenBao variants.
- Required verification: the 7 AP §7.1 rows naming #29, among them leaving recovery mode racing an
inventory request, a reissue refused for a denied service identity, and a scope left blocked
by a restoration read with another identity (check).
- Checks: recovery start answers only liveness and entry before entry; entry mints an epoch, marks
every scope, takes over non-terminal operations, abandons claims; the missed stale instance's
attempt refused by the epoch term, and its job claim, takeover, ingestion start and commitment of
a new-epoch plan on a released scope by the process-epoch comparison, each with its control
(PA §16); restored operation never retried; per-scope
refusals; exit only when every scope is released; the no-entry restart residual shown.
- Depends on the §6 item 2 repair (what the recovery start serves).
- Gap G decided: a restoration read makes a scope ready only when its SMBIOS UUID and
cluster membership match the machine record, and a mismatch leaves it blocked (ER §7.3 step 6,
§7.4, choice §10.26).
ginsys/bronzeward#30, package and document. - Acceptance: AP S8 step 1's walkthrough; AP §8 and §9 as the documented limits. - Required verification: no AP §7.1 row names #30. - Checks: a reviewer runs the walkthrough from a fresh checkout and disposable environment, including interruption and restoration; limits list the profile and versions, the gaps §10 marks beyond the PoC, that losing a role leaves approvals valid until the approval or identity is revoked (F5), that a mistaken identity revocation is corrected only by a new subject (F6), that the unkeyed whole-configuration digest is an unassessed guessing oracle for a configuration without generated key material (F1), and that E3 is not complete.
ginsys/bronzeward#31, E6 acceptance.
- Contract: the acceptance plan, docs/spec/acceptance-plan.md, as accepted under
ginsys/bronzeward#20.
- Required verification: the 1 AP §7.1 row naming #31, the complete existing-cluster E6 slice.
- Checks: one integrated run of S0–S5, S7's nominal run and S8 from a fresh bin/up (AP §2); S6, negatives
and matrices separately;
common evidence per AP §2; the coverage tables of AP §7 and §7.1 answered row by row, each
required-verification item with a retained result; no production claim.
12. Acceptance criteria¶
| Criterion of ginsys/bronzeward#20 | Where | State |
|---|---|---|
| 1. Trace properties to evidence and contracts; resolve inconsistencies and required gaps | §4–§6, §10 | Traced. §6 items 1, 2, 4, 6 and 7 and §7 C, D, F and H–N are repaired by ginsys/bronzeward#56, and §7 E by this change (ER §4, choice §10.25); the rest are disclosed, need no change or are gaps assigned in §10 |
| 2. E3 disposition and design wording; no full-E3 claim | §8; design §18.1, §18.3, §18.5; CONTRIBUTING.md |
Recorded here and in the design |
| 3. Refine every P issue before removing its label | §11 | Text ready; the issues are not yet edited and keep their labels |
| 4. Approve an integrated acceptance plan | AP | Plan landed; approval is the owner's |
| 5. Owner or designated reviewer acceptance, without S04 | not this report | Pending: the owner records acceptance on ginsys/bronzeward#20 |
13. Limits¶
- This review reads the contracts and reports; it runs nothing. A status is as strong as the evidence FR graded and no stronger.
- Cross-contract checking covered the points where two contracts name the same fact, rule or choice; clauses stated in one contract only were read for the properties in §4, not audited line by line.
- The property list is this review's reading of §18.1, §18.2 and §13.7; a property those sections imply but do not state is not covered.
- Line numbers are at aa58272 and move with the parallel repair.
14. Hand-off¶
- ginsys/bronzeward#20: the owner's acceptance (criterion 5) and approval of the acceptance plan (criterion 4); every flagged choice, F1 to F10, and gaps E and G are decided (§9, §10).
- ginsys/bronzeward#56, the spec repair: §6 items 1, 2, 4, 6 and 7, and §7 C, D, F and H–N; §7 E is fixed by this change instead (ER §4, choice §10.25).
- ginsys/bronzeward#14: a note that the role-loss question (F5) and the ingestion role (F4) were decided on ginsys/bronzeward#20.
- ginsys/bronzeward#21 to ginsys/bronzeward#31: the §11 text with the AP §7.1 rows its Required
verification line counts, then removal of
status/needs-refinementonce each issue carries it and no open decision it depends on remains. Gap G with PR19 (the restoration read and the pre-send identity check) is decided and in the contracts of ginsys/bronzeward#26 and ginsys/bronzeward#29; ginsys/bronzeward#24 keeps the label until the dependency monitor has a specification section (§10, PR13). - Later lifecycle work: the upgrade-transition item of design §18.3 (§8).