diff --git a/docs/06-risk-register.md b/docs/06-risk-register.md index 6694982..ef394d8 100644 --- a/docs/06-risk-register.md +++ b/docs/06-risk-register.md @@ -21,6 +21,7 @@ | R20 | Foundation donation may require transferring assets or marks the project intends to keep | Med | Med | Proposal drafting (122) | Unverified: the requirement is asserted from an announcement, not from the charter text. Read the charter, then decide what is offered and what is retained. Legal review before any proposal leaves the tree | 122 | | R21 | The tree carries IP that is not this project's to publish | Med | High | Any design in Trinity that reproduces a third party's protected mechanism | Trinity's receipt and policy design is its own. Policy identifiers stay out of `signed_payload` until legal review clears them; 024's field set is reviewed before that slice starts | 024, 120, 122 | | R21 | **Answered 2026-09-24 for the receipt field set, which was the open half.** Slice 024 proposed the `signed_payload` field set for review and built "the default until cleared"; nothing cleared it until now, and slice 120's AC3 could not be met while that was true. Two questions, both now answered from published standards rather than from instinct. **Does the field set reproduce a third party's protected mechanism?** No, because it contains no mechanism anyone owns: `prev_hash` with `seq` is a forward-integrity hash chain (Bellare and Yee 1997; Schneier and Kelsey 1998), `key_id` is COSE `kid`, `scheme` occupies COSE `alg`'s role, `at` is RFC 3339, `subject` is in-toto's Statement subject, `chain_scope` is Certificate Transparency's per-log scoping, `fingerprint` is an RFC 8785 canonical-digest commitment and `decision` is XACML's PDP outcome. IETF **RFC 9943** (Standards Track, June 2026) standardises this whole object class as COSE_Sign1 Signed Statements and Receipts, which settles it: an open standard for the thing means the mechanism is nobody's to protect. **May policy identifiers enter `signed_payload`?** No, and the existing placement in unsigned `meta` is confirmed rather than merely tolerated. SLSA's attestation model separates `externalParameters` (untrusted, MUST be included and verified downstream) from `internalParameters` (platform-set, trusted, OPTIONAL, not verified downstream); a policy identifier is the second kind. Field-tier minimisation (arXiv 2608.25474) gives the governing property: the ledger commits to a canonical digest of the full parameters computed *before* minimisation, so "reclassifying a field changes what is disclosed without invalidating a historical entry, reopening a hash, or altering what an offline verifier checks" - Trinity already holds that commitment as the fingerprint, and moving policy identifiers into the signed bytes would convert a revisable disclosure decision into an immutable one for no gain, since a downstream verifier cannot evaluate Trinity's policy anyway and `decision.basis` already names the layer that decided inside the signed bytes. The original hazard also holds: if policy identifiers ever come from the external authority plane, embedding another party's namespace in immutable signed bytes is exactly what this row warns about, and in `meta` a namespace change is a metadata change rather than a scheme bump. **The rule, so this is not re-litigated:** the signed payload carries the commitment and the decision facts; anything platform-set, revisable or another party's namespace goes in `meta`. The row above stands for everything other than the receipt field set | Low (was Med: the named open question is closed) | High | The lift condition slice 024 named, met | docs/06-risk-register.md R21; slice 120 AC3 | 024, 120 | +| R21 | **Amended 2026-09-26, appended on the owner's instruction after slice 026.** Chain-integrity fields generated by this node (`seq`, `prev_hash`, `clock`) are commitments. They stay in the signed payload so a merge cannot be reordered by rewriting unsigned `meta`. "Platform-set" in the original sentence means revisable transport and operator annotations, not the values that make two chains one. | Low | High | The lift condition slice 024 named, met | docs/06-risk-register.md R21; slice 026 NOTES | 024, 026, 120 | | R22 | Single maintainer; Growth needs two unaffiliated production users and commits from two orgs | High | Med | 6-month Sandbox checkpoint | Sandbox tolerates it; GOVERNANCE.md documents intent to grow; recruit co-maintainers via the Elixir community once public | 120, 122 | | R22 | Partly mitigated 2026-09-23: two further maintainers, Zach Mead and Mike Hostetler, joined with review, merge, tag and release rights (`MAINTAINERS.md`; `GOVERNANCE.md` "Continuity"). **What that closes is availability**, which is what the OpenSSF criterion `access_continuity` asks for: the project can accept a change and publish a release without any one person. **What it does not close is knowledge or independence.** Every commit in the tree to date has one author, so a "bus factor" of two or more in the sense the criteria mean it (the number who would have to disappear before the work stalls for lack of competent personnel) is being established rather than claimed, and the badge answer says so; and organisation administration, the domain and the security mailbox still rest with the author alone, which `GOVERNANCE.md` names as the first thing a reader should ask about. Lift condition, checkable by a stranger: reviews and merged changes from a maintainer other than the author in the git history, and the administrative access documented as recoverable. The row above stands as written | Med | Med | The lift condition above, unmet | GOVERNANCE.md "Continuity"; MAINTAINERS.md | 120, 122 | | R24 | A native NIF in the desktop bundle: `mdex_native` (the markdown renderer's Rust core, added at 013) is the first, and slice 001 proved the packaging chain with a pure-BEAM release | Med | Med | The `package` workflow fails on one of its three operating systems after 013, or 100's cross-target build finds no artifact for a target | `rustler_precompiled` ships artifacts for every target the chain builds for (013 NOTES.md, measured against the checksum file); the `package` run on 013's `mix.lock` change is the first proof on three runners; lift condition: that run green on all three, cited in 013's PROOF.md; a fallback is `MDEX_NATIVE_BUILD=1` with the pinned Rust toolchain already in the tree | 013, 100 |