diff --git a/docs/design/covered_earnings_correction.md b/docs/design/covered_earnings_correction.md index 1eba7ff6..743e9065 100644 --- a/docs/design/covered_earnings_correction.md +++ b/docs/design/covered_earnings_correction.md @@ -56302,3 +56302,1668 @@ member: R04 bytes are derivable, but R05, Q5, G17, authority, and production cannot pass. The missing-reason campaign remains outside this amendment as A20/revision 22, and active routing is `A20_SUCCESSOR_PROGRAM_STOP` with no alias.** + +## 34. AMENDMENT SECTION — Amendment 20: dual-authority covered-earnings correction + +### 34.1 Status, immutable prefix, evidence boundary, defects, and scope + +This section is the prospective Amendment 20 and therefore proposes design +revision 22 under §30.2.1. Its immutable, now-operative revision-21 prefix is +the complete design through §33: exactly 4,025,587 bytes, raw SHA-256 +`38139b8ddd24ef7be09e8f149960e8e0b6e39699d84f3783827eff6c294a9ae9`, +Git blob `1eba7ff6366bad1999de36c9f7261ad6939ad86a`, and mode `100644`. +The prefix interval is `[0, 4,025,587)`. Every prefix byte survives; no +historical wording, artifact, closure, or registry value is edited by this +amendment. + +The controlling consolidated campaign charter is the repository-external +evidence record `e8-ops/sol-ce-a20-charter.md`, exactly 27,368 bytes with raw +SHA-256 +`5ecd4092f3fc62ef894866a1a5b505d6dba7bb04cde1360ff7134d7d8e927717`. +The adversarial law-gap report is +`e8-ops/sol-ce-law-gap-sweep-r21-2026-08-16.md`, exactly 11,805 bytes with raw +SHA-256 +`39887de99d75a395e97b04f33b4c5264a6828f56c9321cfe248b4ba11a7e5846`. +Those records prove scope and discovered defects but are NONAUTHORITY for any +source meaning, missingness, purpose, alias, binding, or field attachment. +Their machine-local parent path is deliberately not enacted. + +The sweep confirmed nine seams: terminal-A19 fixtures, A19-only active-pin +selection, the unbound R06 223-node result, 46 singleton-token collisions, +the lifecycle-definition timing conflict, the A19/A12 construction-order +conflict, the receipt/operativity gap, two silently changed frozen Q5 shapes, +and the interpreter-token conflict. It also identified nine prospective +seams. Sections 34.2–34.11 cure every structural seam. Sections 34.5.2 and +34.3.3 enact the two unresolved factual matters as mandatory evidence probes; +neither is represented as a proved cure. + +This is one two-arm successor law. The missing-reason and purpose-authority +arms share physical source infrastructure but never share semantic admission, +claims, digests, or acceptance. There is no planned A21. A split to A21 is +lawful only after the charter's kill/recharter event and may not preserve a +claim that A20 is the complete production cure. + +The A4 evidence freeze has not occurred. Consequently +`amendment20_evidence_freeze_status` is exactly +`not_instantiated_a4_required_before_ratify`, the two expected semantic-domain +identities and every compiled successor identity are absent, and +`amendment20_ratification_ready` is false. Absence is a closed drafting status, +not a wildcard or zero digest. Before either referee may ratify, a later exact +prospective edit must replace that status with `pass_a4_exact_freeze`, set +ratification readiness true, and pin every nonempty identity required below. +`pass_a4_exact_freeze` means the dual-review freeze and exact identity process +passed; it does not mean either semantic arm, R04, or a downstream gate passed. +The freeze may bind an exact permanent-failure outcome. Until it occurs, all +A20 authority selection, R04 passage, R05, dispatch, lifecycle instantiation, +and production are forbidden. + +The exact `amendment20_evidence_freeze` object has +`schema_version`, `amendment20_evidence_freeze_status`, +`missing_reason_authority_status`, `purpose_authority_status`, +`prompt_field_semantic_binding_status`, `expected_identity_bindings`, and +`amendment20_ratification_ready`. Its schema is +`a20_evidence_freeze.v1`. The current four statuses after the schema are, +respectively, +`not_instantiated_a4_required_before_ratify`, JSON null, JSON null, and JSON +null; `expected_identity_bindings` has every §34.2–§34.7 required name with a +null value; readiness is false. At A4, the freeze status may become only +`pass_a4_exact_freeze`; each arm status becomes either `pass` or its exact +`fail_permanent_*_residue` identifier; and every identity value becomes a +nonempty exact identity object. Readiness becomes true if and only if those +shape, freeze, and identity conditions hold. It does not require any arm +status to be `pass`. Missing keys, an unknown status, a zero/empty identity, +or readiness true before the exact freeze aborts. + +#### 34.1.1 Chartered campaign stages, dates, and kill rules + +The two evidence arms run in parallel but exit independently through this +exact stage order: + +~~~text +E0 banked evidence reauthentication +E1 shared physical-source closure and separate domain projections +E2 compilers, representation bridges, and measured pilots +A1 concentrated queues +A2 recurring remainder +A3 occurrence-local residue with capacity kills +A4 dual-review reconciliation and exact identity freeze +C20 ratification and revision-22 activation +X1 authoritative settlement with missing dispatch disabled +X2 complete normal R04 and R05 +historical R06 replay and first-add +fresh reconstruction +Q5 +slot, inventory, G17-C01, and V-B6 +sealed publication chain +~~~ + +Bulk adjudication retains `rounds(L, q) = ceil(2L / (3q))`, where `q` is +observed independently reviewed logical decisions per lane-day, not an +assumed throughput. The charter's conditional forecast, as of 2026-08-15, +is p50 2026-11-09 and p80 2027-01-22. Those dates are planning metadata, not +authority, promises, activation deadlines, or permission to weaken a gate. +They must be recomputed if measured throughput, available lanes, evidence +yield, source response, or an A21 kill/recharter event changes an assumption. + +The closed kill rules survive: reject any source that fails provenance, +bytes, release, access, licensing, storage, or locator checks; kill a missing +rule without a disjoint exact predicate and exception complement; kill a +purpose rule that proves only navigation, universe, proximity, heading, or +subject matter; split every nonuniform family; forbid lexical translation of +legacy purposes, circular attachment, reviewer-created meaning, and +cross-arm semantics; and stop for any uncovered identity, duplicate, +overlap, conflict, source drift, reconstruction disagreement, or partial +emission. If the missing arm exceeds the chartered residue/capacity limits or +the purpose complement remains near the unscalable prompt-local tail, seek +official machine-readable clarification rather than manufacturing authority. +Any R04 or downstream failure remains permanent fail-closed residue until a +separately scoped lawful cure passes. + +#### 34.1.2 Status-dependent A4 identity union and nonemission shadows + +For the final A4 freeze, §34.1's unconditional statement that every identity +value is nonempty is superseded by this closed status-dependent union. The +current drafting object has exactly 21 expected identity-binding names: the +previous 18 names followed by, in order, +`missing_reason_failure_shadow_identity`, +`purpose_failure_shadow_identity`, and +`prompt_field_semantic_failure_shadow_identity`; all 21 values remain JSON +null while the freeze status is +`not_instantiated_a4_required_before_ratify`. The nine common identities are +`physical_source_identity`, `evidence_statement_identity`, +`missing_reason_source_domain_identity`, `purpose_source_domain_identity`, +`a20_successor_source_binding_identity`, `r04_q5_shape_identity`, +`r06_six_module_identity`, `r06_collected_node_id_identity`, and +`dormant_lifecycle_definition_identity`. Every ratification-ready outcome +requires all nine to be nonempty pass identities. + +The remaining identities form these exact three unions: + +| Status member | `pass` identities | Permanent-failure status and sole required shadow | +|---|---|---| +| `missing_reason_authority_status` | `missing_reason_rule_set_identity`, `missing_reason_successor_relation_identity`, `missing_representation_bridge_identity` | `fail_permanent_missing_reason_authority_residue`; `missing_reason_failure_shadow_identity` | +| `purpose_authority_status` | `purpose_rule_set_identity`, `purpose_authority_mapping_identity` | `fail_permanent_purpose_authority_residue`; `purpose_failure_shadow_identity` | +| `prompt_field_semantic_binding_status` | `prompt_field_evidence_identity`, `prompt_field_candidate_set_identity`, `zero_candidate_positive_group_identity`, `semantic_binding_identity` | `fail_permanent_prompt_field_or_semantic_binding_residue`; `prompt_field_semantic_failure_shadow_identity` | + +For `pass`, every identity named in that row is nonempty and the row's shadow +is null. For the exact permanent-failure status, every pass identity named in +that row is null and the one shadow is nonempty. Thus a shadow proves why a +forbidden relation is absent; it is not that relation, a partial successor, +authority, a zero digest, or a wildcard. No other null/non-null combination is +ratification-ready. + +Every ordinary common pass identity has exactly `identity_name`, `row_count`, +`ordered_keyset_sha256`, `row_domain_sha256`, and `status`. Every arm pass +identity inserts exact `arm_status_member` and `arm_status` after +`identity_name`. Counts are positive JSON integers excluding booleans; both +digests are nonzero 64-character lowercase hex; `identity_name` exact-equals +its binding key; `status` is `pass`; and an arm identity's two status members +exact-equal its controlling freeze member and `pass` value. + +The `a20_successor_source_binding_identity` instead has exactly +`identity_name`, `row_count`, `ordered_keyset_sha256`, +`row_domain_sha256`, `arm_status_bindings`, +`active_identity_bindings_sha256`, and `status`, under the same positive-count, +nonzero-digest, exact-name, and pass-status rules. `arm_status_bindings` is the +exact three-member status mapping in the table's order. +`active_identity_bindings_sha256` is SHA-256 of terminal-LF §29.4.1 canonical +JSON of an object with exactly `arm_status_bindings` and +`expected_identity_bindings`; the latter contains the other 20 binding values +under their exact names and excludes only +`a20_successor_source_binding_identity`, preventing a self-digest cycle. + +Each failure shadow has schema `a20_failure_shadow_identity.v1` and exactly: + +~~~text +schema_version +identity_name +arm_status_member +arm_status +shadow_row_count +shadow_ordered_keyset_sha256 +shadow_row_domain_sha256 +complement_identity +forbidden_output_identity_names +forbidden_output_paths +nonemission_evidence +status +~~~ + +Its identity name, status member, arm status, and status exact-cross-bind the +selected table row. `forbidden_output_identity_names` is exactly that row's +displayed pass-identity array. The shadow rows are, in that same order, one +exact object `{"emitted":false,"identity_name":}` per forbidden output. +`shadow_row_count` is the array length; +`shadow_ordered_keyset_sha256` hashes the terminal-LF canonical name array; +and `shadow_row_domain_sha256` hashes the terminal-LF canonical shadow-row +array. `forbidden_output_paths` is the same-length array obtained, without a +caller choice, by mapping each displayed identity name in order to +`docs/analysis/amendment_20_ratification/evidence_freeze/.json`. +Every mapped path is repository-relative, canonical, traversal-free, and +unique. A caller-selected, missing, additional, reordered, or noncanonical +path aborts. + +`complement_identity` has schema +`a20_nonemission_complement_identity.v1` and exactly `schema_version`, +`complement_of_identity_names`, `row_count`, `ordered_keyset_sha256`, +`row_domain_sha256`, and `status`. It exact-copies the forbidden name array, +count, two rederived digests, and permanent-failure status. A missing, empty, +zero, forged, reordered, or differently statused complement aborts. + +The shadow's `nonemission_evidence` has exactly: + +~~~text +execution_commit +execution_tree_oid +repository_manifest_rows_before +repository_manifest_sha256_before +repository_manifest_rows_after +repository_manifest_sha256_after +repository_clean_before +repository_clean_after +forbidden_outputs_absent_after_execution +~~~ + +The commit and tree are nonzero 40-character lowercase hex and must resolve, +with replacement objects disabled and inherited `GIT_*` controls removed, to +an exact commit object and an exact tree object in the repository object +store. Resolving `^{tree}` must return exactly +`execution_tree_oid`; current `HEAD` equality is not required during later +historical validation. + +Each manifest-row member is a complete §29.4.1 canonical array of every +nonignored tracked or untracked repository path in unsigned UTF-8 path order. +Every row has exactly `path`, `mode`, `git_blob`, `byte_size`, and +`raw_sha256`. The validator recursively enumerates the authenticated execution +tree, reads each blob from the object store, and independently reconstructs +every tracked row with exact mode, blob, byte count, and raw digest. In the +validator's isolated verification checkout it also rereads all working bytes, +requires every tracked row and the index to exact-match the authenticated +tree, enumerates and rereads every nonignored untracked path, and requires +exact porcelain status—including intent-to-add—to be empty. Historical +validation must materialize that exact verification checkout; current `HEAD` +identity is not substituted for the authenticated execution commit. Missing, +extra, duplicate, reordered, malformed, unreadable, noncanonical, +unsupported-mode, tree-disagreeing, staged, modified, deleted, or +intent-to-add rows abort. + +The validator independently reconstructs and deep-compares both supplied +arrays, rederives each 64-character manifest SHA-256 from its terminal-LF +canonical array, and requires the arrays and digests to exact-equal before and +after. It derives clean state from the authenticated complete path domain and +derives forbidden-output absence by requiring every fixed +`forbidden_output_paths` member to be absent from the authenticated +after-manifest. `repository_clean_before`, `repository_clean_after`, and +`forbidden_outputs_absent_after_execution` must exact-equal those derived +facts. + +This complete-manifest evidence alternative makes no OS read-only, network, +or captured-stream assertion: `repository_read_only`, `network_disabled`, +`captured_streams`, and any other extra assertion fail the exact evidence +keyset. Equality proves unchanged repository state, not an OS sandbox policy. +No lifecycle boolean, including a true clean or absence assertion, is accepted +as self-attestation or as a substitute for the verified Git objects and +complete manifests. A different evidence alternative may claim read-only, +network, or stream confinement only when it carries an equivalently +independently verifiable execution artifact that proves those claims. Those +verified facts plus the exact complement prove durable repository +nonemission. + +For the successor composite only, §34.2.3's exact field list is extended as +follows: immediately after `purpose_source_domain_identity`, insert the three +status members in the table's order; immediately after +`r04_q5_shape_identity`, insert the three shadow identities in the table's +order and then `active_identity_bindings_sha256`. Each pass-output or shadow +field follows the same status-dependent null/non-null rule, and the digest +exact-equals the freeze identity's cross-binding digest. The composite +therefore binds the selected statuses, emitted identities, and complements +without treating a nonemission proof as emitted output. + +Ratification readiness is true if and only if the exact freeze status, all +three allowed arm statuses, every schema/key/count/digest/status check, every +pass-versus-shadow exclusivity rule, all three status cross-bindings, and the +successor-binding digest pass. A status flip without the corresponding +identity-union change, an arbitrary truthy mapping, a forged shadow, or a +missing complement aborts. + +### 34.2 Limb I — shared source infrastructure and separate authority domains + +#### 34.2.1 Physical-document and statement registries + +The A20 physical source envelope has exactly two ordered relations: +`a20_physical_source_rows` and `a20_evidence_statement_rows`. A physical row +has exactly these members in this order: + +~~~text +evidence_source_id +upstream_capture_or_registry_identity +document_role +release_or_wave +representation +official_url +canonical_local_path +storage_identity +byte_size +raw_sha256 +access_disposition +licensing_disposition +statement_locator_ids +extraction_tool_identity +recovered_source_provenance +~~~ + +The path is repository-relative, canonical, traversal-free, and contains no +machine-local absolute prefix. A source identity, storage identity, and path +are unique. `byte_size` is a positive JSON integer excluding booleans. Every +hash is lowercase exact-length hex over complete bytes. Official URL, access, +licensing, release, role, representation, recovery provenance, and extraction +tool identity are explicit; none may be inferred from a current URL or latest +edition. + +Each statement row has exactly: + +~~~text +evidence_statement_id +evidence_source_id +page_or_section_locator +utf8_byte_start +utf8_byte_end +exact_statement_raw_sha256 +extraction_tool_identity +recovery_provenance_id +~~~ + +The half-open span must slice the authenticated source bytes and reproduce the +statement digest. Locator IDs, statement IDs, and complete preimages are +unique. OCR or recovered bytes remain distinguishable and must bind the +original source, recovery method, and exact recovered representation. A +paraphrase, unavailable text, unregistered source, alias, drift, malformed +span, or substituted edition supplies no authority. + +#### 34.2.2 Two closed semantic projections + +Construct exactly two domain projections, in this fixed order: + +~~~text +missing_reason_source_domain +purpose_source_domain +~~~ + +Each projection has exactly `domain_id`, `domain_version`, +`included_source_rows`, `included_source_count`, +`included_source_keyset_sha256`, `included_source_domain_sha256`, +`excluded_source_rows`, `excluded_source_count`, +`excluded_source_keyset_sha256`, `excluded_source_domain_sha256`, +`admitted_statement_rows`, `statement_count`, `statement_keyset_sha256`, +`statement_domain_sha256`, and `status`. Every exclusion row binds one +physical source ID and one closed exclusion disposition. Inclusion and +exclusion form a complete, disjoint projection of the physical source +envelope; their counts sum to its count. The two domains independently +authenticate every foreign key and independently derive every count, ordered +keyset digest, and complete row-domain digest. Shared physical bytes do not +imply shared admission. Missingness cannot entail purpose; purpose cannot +entail missingness. A mixed semantic payload or a shared accepted semantic +digest aborts both projections. + +At A4, the final law must pin each complete projection's version, inclusion +and exclusion counts, ordered keyset digests, row-domain digests, statement +identities, and exact `pass` status. The current draft fixes those expected +values as absent and therefore nonpassing. The fixed A11 47-source domain, +the 81-document questionnaire domain, and A19's historical 257+22=279 build +input envelope retain their exact identities and members. No A20 row enters, +renames, widens, or reinterprets those historical relations. + +#### 34.2.3 Successor composite binding and dual reconstruction + +The separate `a20_successor_source_binding` has exactly +`historical_a19_build_input_identity`, `physical_source_identity`, +`evidence_statement_identity`, `missing_reason_source_domain_identity`, +`purpose_source_domain_identity`, `missing_reason_rule_set_identity`, +`missing_reason_successor_relation_identity`, +`missing_representation_bridge_identity`, `purpose_rule_set_identity`, +`purpose_authority_mapping_identity`, `prompt_field_evidence_identity`, +`prompt_field_candidate_set_identity`, +`zero_candidate_positive_group_identity`, `semantic_binding_identity`, +`r04_q5_shape_identity`, `canonicalization`, and `status`. Each identity +is an exact count/keyset/domain-digest object, not a candidate-supplied +summary. Both independent R04 reconstructors authenticate the immutable +historical 279-row identity and separately reconstruct every A20 relation +before reading candidate rows or status. They must deep-equal one another in +count, order, keyset, complete row bytes, and digest. The purpose and +missing-reason acceptance gates remain distinct even when a physical document +appears in both projections. + +### 34.3 Limb II — complete missing-reason authority + +#### 34.3.1 Authority rules and exact occurrence compiler + +Every `missing_reason_authority_rules` row has exactly: + +~~~text +authority_rule_id +registered_evidence_source_ids +registered_statement_ids +rule_kind +exact_scope_predicate +explicit_exclusions +strict_boolean_disposition +projected_occurrence_count +projected_occurrence_keyset_sha256 +overlap_conflict_complement_results +~~~ + +Every evidence foreign key resolves only inside the admitted +`missing_reason_source_domain`. Corroborating statements remain within one +rule. Two rules that agree on one occurrence are still duplicate authority; +disagreement is conflict. Conflict has precedence over incomplete coverage. +Each projection is exact, nonzero, disjoint, and exception-complete. A broad +modal, lexical, frequency, sibling, wave, representation, ordinary-value, +nearest-rule, priority, majority, or candidate default has zero authority. + +The compiler preserves each formerly unresolved literal's complete §25.3.1 +12-position identity, in order: schema tag, global member position, +source-document position, source-row position, entry position, source +document ID, codebook field-row ID, complete ordered nonempty locator-ID +array, entry reference, entry kind, exact source value/range lexeme, and exact +nonempty source meaning. It produces exactly one strict JSON Boolean claim +for each of the 524,538 formerly unresolved literal occurrences. Missing, +extra, duplicate, overlap, conflict, malformed identity, invalid Boolean, or +uncovered complement aborts the complete relation. + +Both independent compilers derive the same exact 524,538 count, ordered +occurrence-keyset bytes and digest, complete compiled-row bytes and digest, +rule projections, overlap/conflict complements, and disposition counts. +Staging is transactional. On any failure, the successor relation is not +emitted, no partial rule is selectable, and every staged byte is discarded. + +#### 34.3.2 Least-risk reason construction and composition + +Only after both reconstructions and every preflight pass may the successor +compose with the inherited 52 source-authorized literals and 37,283 numeric +structural-null ranges. Unless an admitted official source enacts a richer +taxonomy, `missing == true` receives the opaque exact-occurrence +`psid-source-missing-reason:` identity derived from the complete §25.3.1 +identity; `missing == false` receives JSON null; numeric ranges remain JSON +null. These values assert no semantic missing-reason class. + +The historical A11 relation, expected abort, A18 R06 record, 52 identities, +524,538 blocker count, and 37,283 structural-null count remain byte exact. +A20 uses a separately versioned settlement entry point and relation. It does +not rewrite history or interpret the old abort as success. + +#### 34.3.3 Mandatory `MD=` representation bridge probe + +Before any rule based on the provisional `MD=` convention is admitted, +construct `missing_representation_bridge_rows`. Each row binds an exact +historical source/document/locator/wave/field/release coordinate to an exact +current registered document/raw-field/release coordinate, the admitted +official-equivalence statement IDs, the two exact representations, and one +closed bridge disposition. The mapping and complement must be unique, +complete, independently reconstructed, and bound by counts, ordered keyset +digest, complete row-domain digest, and disposition census. + +The 54,898 direct-field ceiling, 71,635 gross source-era ceiling, and 59,424 +diagnostic shadow are distinct NONAUTHORITY observations. They are never +averaged, equated, or promoted. The current 54,898-versus-59,424 difference +and 87 zero projections are unresolved. Until the exact bridge accounts for +both the difference and all zero projections, the `U24`/`E2-93MD` family +contributes zero accepted claims and the missing arm remains nonpassing. + +### 34.4 Limb III — complete purpose authority + +#### 34.4.1 Purpose rules and successor rows + +The completed purpose ontology is the inherited 35-purpose vocabulary in its +exact inherited order followed by `source_underdetermined`. That final arm is +the enacted §34.4.2 source-backed ontology projection; it means a reconciled +adjudication ruling proves that authenticated sources do not determine any +nonempty inherited-purpose subset. It is not `no_applicable_purpose`, a +determined negative, and silence or ontology inconvenience cannot create it. +Each +`purpose_authority_rules` row has exactly: + +~~~text +purpose_authority_source_id +rule_kind +registered_evidence_statement_ids +exact_prompt_scope_predicate +explicit_exclusions +explicit_official_purposes +projected_prompt_count +projected_prompt_keyset_sha256 +~~~ + +Every purpose array is nonempty, stable-unique, and in inherited purpose +order. Exact text can organize a review queue but cannot establish meaning. +Navigation, universe, proximity, heading, subject matter, or reviewer +agreement does not entail a purpose. Nonuniform families are killed and +split to narrower source-backed scopes; no priority or majority rule exists. +The 13 legacy literals are never lexically translated. + +The compiler emits one `purpose_authority_mapping_rows` member for every +prompt with exactly: + +~~~text +source_prompt_occurrence_id +authority_basis +purpose_authority_source_id +evidence_statement_ids +explicit_official_purposes +purpose_mapping_disposition +reconciled_adjudication_ruling_id +~~~ + +For a determined row, `reconciled_adjudication_ruling_id` is JSON null. For a +`source_underdetermined` row it is the nonempty exact ruling identity and the +row carries the same authenticated source, statement, locator, byte, and +nonemission-provenance checks as a determined row. A missing, unauthenticated, +or non-reconciled ruling aborts; reviewer agreement is not a ruling. + +This schema does not overload A19's `source_classification_row_id`. Every one +of A19's 818 `complete_official_mapping` rows must be expressly re-ratified +or re-grounded in admitted official evidence; manual origin is not +grandfathered, and any source conflict reopens the row. + +#### 34.4.2 Totality, alternatives, and atomic gate + +Under the completed ontology, the prompt denominator and both disposition +counts are exact A4 freeze-slots. The A4 freeze binds each slot to a positive +JSON integer excluding booleans, requires the two disposition counts to sum +exactly to the frozen prompt denominator, and requires this exact disposition +object: + +~~~text +complete_official_mapping: +source_underdetermined: +U: 0 +~~~ + +`U` is the number of prompts having no lawful disposition under that completed +ontology. Every prompt must resolve either to a determined nonempty inherited- +purpose array or to `source_underdetermined`; the relation is total. Acceptance +also requires exact prompt coverage; zero gap, extra, duplicate, zero-match, +overlap, or conflict; exact completed-ontology rule projections; two +independent reconstructions; and equal count, keyset, row bytes, row-domain +digest, frozen disposition census, and ruling identities. `U == 0` is +necessary but not sufficient for R04. Failure emits no partial successor row +or authority. + +Pre-reconciliation exact-row agreement is a reviewer-process alert, not an +authority gate. The reconciled outcomes gate authority. The adjudication +evidence measured exact-row agreement at 85.90%, macro per-prompt Jaccard at +90.17%, and found that 61% of row mismatches shared at least one literal. +Macro per-prompt Jaccard at or above 90% therefore survives only as a +calibration diagnostic; it cannot select, create, or replace a disposition. + +This draft enacts the source-backed ontology-projection alternative and, in +the same exact draft, changes the selector, `O_P`, expansion, joins, +projections, and mutations. It does not enact the occurrence-kind/denominator +correction or the separately tagged source-proved `no_applicable_purpose` +alternative. + +### 34.5 Limb IV — acyclic prompt-field evidence and semantic binding + +#### 34.5.1 Pre-`O_P` prompt-field relation and the 46 collisions + +Before `O_P`, construct `prompt_field_evidence_rows` solely from +authenticated prompt and field bytes. Each row has exactly: + +~~~text +prompt_field_evidence_id +source_prompt_occurrence_id +interview_wave +questionnaire_span +prompt_source_locator_ids +field_source_document_id +field_source_row_id +field_source_member +raw_field_id +attachment_basis +official_alias_statement_ids +attachment_disposition +candidate_raw_field_ids +~~~ + +`questionnaire_span` has exactly `utf8_byte_start` and `utf8_byte_end`. +They are JSON integers excluding booleans and identify the minimal half-open +UTF-8 byte interval `[start,end)` of the exact identifier-token match in the +authenticated prompt source bytes, with +`0 <= start < end <= len(prompt_source_utf8_bytes)`. Thus repeated literal +tokens in one prompt retain distinct coordinates without enlarging the source +domain. + +`prompt_field_evidence_id` is literal +`psid-prompt-field-evidence:` plus SHA-256 of terminal-LF canonical JSON of +the remaining 12 members in displayed order. Evidence rows follow complete +prompt source position, interview wave, source-prompt occurrence ID, +questionnaire-span start then end, direct branch before question-token +branch, and field reconstruction document/row/member order. Emitting an exact +duplicate row aborts. Coordinate-distinct spans must produce distinct row +bodies; collapsing them to one body aborts. + +Worked 1976 `V4632` example: prompt position 1,843 contains two exact `V4632` +token matches. The first row carries the minimal byte interval of the first +five-byte ASCII token and the second carries the disjoint minimal byte +interval of the second five-byte token. Each interval is derived directly +from the same authenticated prompt bytes. Across each of the three canonical field-source +rows, the two spans therefore remain distinct; omitting, widening, equating, +or deduplicating those coordinates aborts. The identical rule applies to the +two `V4991` spans at position 1,938. + +Allowed positive bases are an exact source identifier or an expressly +admitted official alias. Every candidate remains materialized in +`candidate_raw_field_ids`. Zero or multiple candidates fail unless a +source-backed accepted resolution, admitted alias, or denominator correction +uniquely resolves the complete candidate set. Exact direct-ID appearance is +not blanket precedence over a conflicting question token. The inherited +post-`O_P` positive-field join cannot establish this relation. + +`attachment_disposition` is exactly +`accepted_exact_source_identifier`, +`accepted_expressly_admitted_official_alias`, or `unresolved_multiple`. +The first two are lawful only when the complete candidate set has exactly one +source-authorized survivor under the named basis. Every row in an unresolved +multiple uses the third disposition; no one member is silently selected. +Zero-candidate prompts have no fabricated evidence row and are instead +carried by the complete candidate-set and grouping relations in §34.5.2. + +The historical collision census is exactly the 46 same-coordinate leading- +question-token conflicts among the 818 complete-official prompt rows. The +relation must disposition every member of that domain before normal R04 can +pass. Separately, the prompt-level stable-unique complete candidate union over +those 818 rows has 49 multiples. Its three additional ordinary, +nonoverlapping evidence rows are 1974 `[V3585,V3586]`, 1985 +`[V11649,V11648]`, and 1985 `[V11616,V11676]`; they are not collision-census +members. Separately again, `multiple_candidates` over the full 21,971-prompt +denominator is 2,349. These evidence-dependent counts remain A4 freeze-slots: +the numbers identify observed domains and do not instantiate freeze authority. + +The mandatory 1985 C68 regression +is prompt occurrence +`psid-questionnaire-occurrence:4cd66190a898d568dd20c27140f44f1dff53d229f664f537722624d00c9b4b67`: +printed `V11804` is direct evidence, while token `C68.` produces both +`V11804` and `V11805`. It remains an unresolved multiple unless admitted +source authority supplies the exact A20 resolution; direct-ID priority, +stable-first choice, or omission is forbidden. + +#### 34.5.2 Mandatory zero-candidate grouping probe + +Reconstruct a candidate-set row for every prompt in the A4-frozen denominator, +including exact +zero-, one-, and multiple-candidate counts, ordered keyset and row-domain +digests. Every zero candidate maps through the eventual `O_P` and positive +rows. `zero_candidate_positive_group_rows` groups the complete reference +union by `positive_occurrence_id` and records the exact prompt complement. +Both reconstructors must agree. + +Each `prompt_field_candidate_set_rows` member has exactly +`prompt_field_candidate_set_id`, `source_prompt_occurrence_id`, +`interview_wave`, `candidate_prompt_field_evidence_ids`, +`candidate_raw_field_ids`, `candidate_count`, and `candidate_disposition`. +For each prompt, before the independent §34.5.1 evidence-row sort, the +candidate projection stream concatenates all direct-branch evidence events +in questionnaire-span then field-reconstruction order and then all +question-token-branch events in the same within-branch order; +`candidate_prompt_field_evidence_ids` and `candidate_raw_field_ids` are +respectively the complete stable-unique `prompt_field_evidence_id` and +scalar `raw_field_id` projections of that one stream. Count is a JSON +integer excluding booleans and equals the raw-field array length. Disposition is exactly `zero_candidates`, +`one_candidate`, or `multiple_candidates` iff count is respectively zero, +one, or greater than one. The ID is literal +`psid-prompt-field-candidate-set:` plus SHA-256 of terminal-LF canonical JSON +of the remaining six members in displayed order. Rows follow complete prompt +source order; IDs and prompt IDs are unique. + +Each `zero_candidate_positive_group_rows` member has exactly +`zero_candidate_positive_group_id`, `positive_occurrence_id`, +`zero_candidate_source_prompt_occurrence_ids`, +`all_source_prompt_occurrence_ids`, `complete_reference_union_ids`, +`empty_reference_union`, and `group_disposition`. There is one row for every +eventual positive occurrence containing at least one zero-candidate prompt. +The prompt arrays are complete positive-row projections in source order; the +reference union is the complete stable-unique inherited reference-ID +projection. `empty_reference_union` is strict Boolean equality to zero union +length. Disposition is exactly `complete_nonempty_reference_union` when false +or `fail_empty_reference_union` when true. The ID is literal +`psid-zero-candidate-positive-group:` plus SHA-256 of terminal-LF canonical +JSON of the remaining six members in displayed order. Rows follow positive- +occurrence order; IDs and positive IDs are unique. Each relation's count, +ordered ID-array keyset digest, complete row-domain digest, and exact +disposition census are independently reconstructed. + +The sweep's 15,428 zero-candidate claim and the later diagnostic compiler's +14,450 count are NONAUTHORITY and disagree. A4 must reproduce and explain +the difference rather than select either number. Acceptance requires zero +eventual positive group with an empty reference union and exactly one +accepted pre-`O_P` attachment for every codebook-supported purpose rule. A +required zero, an all-zero positive group, or any unresolved multiple stops +before R04 and R05 absent an admitted alias or denominator correction. + +#### 34.5.3 Semantic bindings and post-`O_P` joins + +The normal arm reuses, without renaming or duplicating, the inherited +`near_match_source_annotation_rows` seven-key row schema, source-occurrence +schema, `semantic_bindings` array schema, annotation-ID equation, complete- +locator-union order, count/keyset/domain equations, and cross-use law. The A20 +`semantic_binding_identity` must deep-equal that exact relation's count, +ordered keyset digest, and row-domain digest; there is no separate +`semantic_binding_rows` serialization or alternate authority path. + +That inherited relation retains complete source-atom cover over every questionnaire +occurrence and field-stream locator and the exact five coordinates `role`, +`job_slot_id`, `questionnaire_component_slot_id`, `slot_kind`, and +`field_purpose`. Binding sets are complete, jointly supported, and +subsumption-maximal. Disposition is exactly `semantically_bound`, +`no_supported_predicate_dimension`, or `unresolved_semantic_binding`, with +zero unresolved rows. Both reconstructions build the relation before +candidate rows are read and agree on count, keyset, complete row bytes, +domain digest, cross-use, and maximality. + +After `O_P`, retain `occurrence_raw_field_reference_rows`, +`positive_field_join_rows`, nonempty reference and raw-field projections, +unique same-wave attachment, purpose expansion, and reverse covers. The +selector domain, `O_P` order, purpose expansion, post-`O_P` joins, reverse +covers, and rule projections all use the completed 36-arm order. The new arm +flows through exact-token joins with the same exactness as every inherited +purpose; a silent union or conflation is forbidden under §19.3.3. The +known `Family`, `Dl7.`/`D17.`, and A19 `D2.` ambiguity witnesses are mandatory +regressions. Only official evidence plus an exact admitted alias, denominator +correction, or revised law can resolve them; normalization, similarity, +inventory selection, or omission cannot. + +### 34.6 Limb V — selector, R04 order, Q5 shapes, and failure scopes + +#### 34.6.1 Exact construction and gate order + +The exact active order is: + +~~~text +authenticate fixed historical denominators and both A20 source domains +construct and seal missing rules, purpose rules, and successor source binding +compile complete purpose mapping, prompt-field, and semantic evidence inputs +compute completed-ontology purpose U and all independent acceptance results +select failure or normal member +normal only: construct H and purpose-independent source-only O_H +normal only: require O_H before O_P +normal only: construct O_P, semantic bindings, post-O_P joins, reverse covers, + purpose expansion, D0 -> search/proofs -> D1, and every R04 gate +normal only: R05 strict certificate and dual normal-member reconstruction +~~~ + +This supersedes predecessor precedence and full-build-on-failure only. +The selector and `O_P` consume the completed 36-arm order, and all purpose +expansion, joins, reverse covers, and rule projections preserve its exact +tokens. `O_H` remains source-only and precedes `O_P`; the pre-`O_P` field relation +does not depend on a post-`O_P` join. Purpose totality alone never passes R04. +Any unresolved source, purpose, attachment, semantic binding, `H`, `O_H`, +reverse-cover, expansion, join, or other inherited normal conjunct stops +before R05. + +#### 34.6.2 Read, evaluation, and serialization scopes + +For failure selection, both reconstructors must authenticate, read, and +construct `questionnaire_occurrence_rows` solely to derive the fixed prompt +denominator, purpose rows, candidate sets, and selector inputs. Those reads +are permitted and required. On a selected failure member, the rows and all +pass-only arrays remain forbidden from serialization into the historical +877-byte A19 failure member or from masquerading as evaluated Q5 output. +Thus `permitted_selector_input_reads` and +`forbidden_selected_failure_member_serialization` are separate closed sets; +the unqualified §33.8 combined prohibition is superseded. + +The exact historical A19 failure member and identity remain byte exact. An +A20 evidence failure uses its separately tagged diagnostic status and emits +no Q5 member, R05 certificate, authority, or production object. + +#### 34.6.3 Frozen-shape composition + +Section 20.4.2 is superseded only for A19's already enacted per-era +`purpose_mapping_rows` insertion; A19's +`hierarchy_preproof_domain_sha256` search-key replacement; and the following +closed A20 additions. In `source_document_manifest`, immediately after +`source_document_domain_sha256`, insert exactly, in order: + +~~~text +a20_successor_source_binding_identity +missing_reason_source_domain_identity +purpose_source_domain_identity +missing_reason_rule_set_identity +purpose_rule_set_identity +prompt_field_evidence_identity +semantic_binding_identity +~~~ + +In the A20 normal effective authority header, replace A19's four active +`purpose_mapping_row_count`, `purpose_mapping_keyset_sha256`, +`purpose_mapping_domain_sha256`, and `purpose_mapping_disposition_counts` +members with the first four successor members below, then insert the remaining +members before inherited `positive_occurrence_row_count`, exactly in order: + +~~~text +purpose_authority_mapping_row_count +purpose_authority_mapping_keyset_sha256 +purpose_authority_mapping_domain_sha256 +purpose_authority_mapping_disposition_counts +prompt_field_evidence_row_count +prompt_field_evidence_keyset_sha256 +prompt_field_evidence_domain_sha256 +prompt_field_evidence_disposition_counts +prompt_field_candidate_set_row_count +prompt_field_candidate_set_keyset_sha256 +prompt_field_candidate_set_domain_sha256 +prompt_field_candidate_set_disposition_counts +zero_candidate_positive_group_row_count +zero_candidate_positive_group_keyset_sha256 +zero_candidate_positive_group_domain_sha256 +zero_candidate_positive_group_empty_union_count +~~~ + +Each A20 normal `era_rows` member replaces A19's adjacent +`hierarchy_rows`, `purpose_mapping_rows`, `positive_occurrence_rows` triple +with exactly this ordered sequence: + +~~~text +hierarchy_rows +purpose_authority_mapping_rows +prompt_field_evidence_rows +prompt_field_candidate_set_rows +zero_candidate_positive_group_rows +positive_occurrence_rows +~~~ + +Both expected and actual G17-C01 projections carry those exact source- +manifest, header, and era shapes. Direct era-order concatenation independently +reproduces every displayed row count, ordered keyset digest, complete row- +domain digest, and disposition census. No failure arm serializes any member +in these three addition lists. A19's 21,971-row relation remains immutable +historical audit evidence but is absent and nonconsumable on the A20 normal +Q5 path; it cannot feed `O_P`, a join, a purpose disposition, or a successor +digest. Every successor row, including the former 818 complete rows, derives +only from §34.4 authority. The inherited `near_match_source_annotation_rows` +remains at its inherited position and exact shape; the source-manifest +`semantic_binding_identity` is only an independent deep-equality binding to +that one relation, not a new era array. + +All other §20.4.2 top-level, source-manifest, era, occurrence, positive, +hierarchy, absence-proof, canonical-order, self-zero, and join shapes remain +exact. A20 preserves A19's acyclic +`D0 -> search_implementation -> A_h -> final rows -> D1` construction. No +fixed-point, placeholder, old D1 search member, or copied digest is lawful. + +### 34.7 Limb VI — historical R06 authentication and dormant lifecycle law + +#### 34.7.1 Six-module collection binding and interpreter + +The exact six historical R06 test paths and authenticated identities are: + +| Path | Git blob | Bytes | Raw SHA-256 | +|---|---|---:|---| +| `tests/data/test_psid_codebook_extraction_validation.py` | `7b2f33af3ff6a4e389a944e349aa222f6ca41519` | 13,718 | `7af8a2847b4428fa7376598cc48333d008f225389eee461f3edae58ca624ff67` | +| `tests/data/test_psid_missing_reason_authority_artifact.py` | `c8863f4a6a5e915666f0cce2cac4817e73839e9f` | 18,129 | `4f425c776ddba30f3b861812cdcbd0abef5b10ae0f41608bcaa6d456c9cdcd85` | +| `tests/data/test_psid_missing_reason_authority_unit.py` | `499aa397f75e1d2f62e7c91a929f9ecdcf71a478` | 18,252 | `5e9b7cc33fd560ce5c472c6ac146f07a6b7b238003c6e96f715e417679149cda` | +| `tests/estimates/test_birth_evidence_artifact.py` | `d4e838a1123d4e07c6f472ff64cfd6c11462f4a8` | 25,883 | `70acf9c2f36f9f88a7e5e2c8c7b5825427d6a44cf1926b0a6c0c7cf4bbb7d5d5` | +| `tests/test_rebuild_amendment11_missing_reason_authority.py` | `632357933ea37c982d18402d249b74147cd80823` | 22,828 | `eedbab9e3ba3eaad19f08d36472b2fbc53cc5dc62b417a3600d5cb4360368dcb` | +| `tests/test_replay_amendment11_no_movement.py` | `cc4c1c6d65c89ad97feb0b4f04e6c5d2ecd2405f` | 19,309 | `0875ac524e0cd2e7f3cb6e601026b0d2db5b459c6f426fe5182ac08ebaef9ec1` | + +Each listed tree entry has mode `100644`. + +The selector starts with the executing validator process's current +`sys.executable`, then exact `-m`, `pytest`, and the six paths in displayed +order. `PYTHONPATH` remains exactly `src:.`; inherited `GIT_*` variables are +removed. No machine-local interpreter path is enacted. The ordered module +path-array digest remains +`a5099c464482c5b652e31e5dfa958703a4ae4c75c1dc1e4caa03cb2aef408063`. + +The distinct preflight collection command starts with that same dynamic +interpreter and exact `-m`, `pytest`, `--collect-only`, and `-q` tokens, +followed by the same six paths in displayed order. It uses the same working +directory and environment law, removes ambient `PYTEST_ADDOPTS`, and emits no +authority. + +Before replay, collect exact node IDs from those authenticated bytes. The +terminal-LF canonical ordered 223-node-ID array is 28,268 bytes with raw +SHA-256 +`09071bf4d9a9a5ee8b9ccc4d8d5c0bd91705c04d3c7c99d6ef155dfdc0dfdf05`. +Its first and last IDs are respectively +`tests/data/test_psid_codebook_extraction_validation.py::test_exact_nested_derivation_schemas_accept_generated_shapes[_text_derivation]` +and +`tests/test_replay_amendment11_no_movement.py::test_reason_mutation_changes_field_source_identity_but_not_terminal`. +Because each collected row is the unique node ID scalar, this array is both +the ordered keyset and complete collected-row domain; the named size and +digest bind both. `expected_collected`, `collected`, and `passed` derive from +its exact length and remain 223. Only this exact binding explains the +historical integer 223. File or +collection drift aborts before replay rather than changing that recorded +result. Every historical R06 process result, test result, and JSON byte +remains exact. + +The implementation entry point +`_validate_amendment20_r06_collection_binding` rereads and authenticates all +six working-tree and `HEAD` file identities, invokes this exact collection +command with the executing `sys.executable`, removes inherited `GIT_*` +variables, and reconstructs the complete node-ID array, byte size, digest, +and endpoints. Static constants or a reported integer without that execution +do not satisfy the gate. + +#### 34.7.2 Dormant definitions and ancestry DAG + +Section 34 may ratify complete dormant successor definitions before tier-2 +certification. This expressly supersedes §26.10.3 and DC-71 solely as to the +timing of definitions. A dormant definition is law text and schema only: it +creates no artifact, instance, selected relation, first-add, dispatch, +authority, or output. A20 evidence relations may be admitted and settled +before R06 only while missing-reason dispatch is disabled. The false members +of §32.4.4 remain exact facts about the historical R06/A11 replay's own +production/lifecycle emissions; they do not forbid authenticated A20 source +manifests, rules, candidate relations, or dormant schema definitions. + +Every lifecycle envelope has exactly `lifecycle_stage_id`, `schema_id`, +`predecessor_stage_ids`, `input_identity_ids`, `output_identity_id`, +`first_add_index`, `selection_enabled`, and `status`. Schema IDs and stage IDs +are fixed in §34.11. Status is exactly `dormant_definition`, +`blocked_predecessor`, `pass`, or `fail_atomic_nonemission`. An output identity +is absent until execution derives and first-adds it; it is never a zero hash. +Failure leaves the stage and every descendant uninstantiated. + +The dormant definition relation has exactly these 26 rows and values. The +displayed row order and `first_add_index` are normative: + +| `first_add_index` | `lifecycle_stage_id` | `schema_id` | Exact predecessor stage IDs | Exact input-identity binding roles | +|---:|---|---|---|---| +| 1 | `A20_SOURCE_RELATIONS_SETTLED_DISPATCH_DISABLED` | `a20_source_settlement.v1` | `REVISION22_REGISTRY_REPIN` | `revision22_registry_repin_identity`, `a20_successor_source_binding_identity`, `dormant_lifecycle_definition_identity` | +| 2 | `A20_NORMAL_R04_REQUIRED` | `a20_normal_r04.v1` | `A20_SOURCE_RELATIONS_SETTLED_DISPATCH_DISABLED` | `a20_source_settlement_identity`, `historical_a19_build_input_identity` | +| 3 | `A20_R05_REQUIRED` | `a20_r05_certificate.v1` | `A20_NORMAL_R04_REQUIRED` | `a20_normal_r04_identity` | +| 4 | `A20_HISTORICAL_R06_REQUIRED` | `a20_historical_r06_binding.v1` | `A20_R05_REQUIRED` | `a20_r05_certificate_identity`, `r06_six_module_identity`, `r06_collected_node_id_identity`, `historical_a11_replay_identity` | +| 5 | `A20_MISSING_REASON_SUCCESSOR_ACTIVE` | `a20_missing_reason_successor_relation.v1` | `A20_HISTORICAL_R06_REQUIRED` | `a20_historical_r06_identity`, `missing_reason_successor_relation_identity` | +| 6 | `A20_CLASSIFIER_REBUILD_REQUIRED` | `a20_classifier_rebuild.v1` | `A20_MISSING_REASON_SUCCESSOR_ACTIVE` | `a20_active_missing_reason_identity`, `historical_classifier_input_identity` | +| 7 | `A20_TERMINAL_MOVEMENT_REQUIRED` | `a20_terminal_movement.v1` | `A20_CLASSIFIER_REBUILD_REQUIRED` | `a20_classifier_rebuild_identity` | +| 8 | `A20_ASSIGNMENT_REBUILD_REQUIRED` | `a20_assignment_rebuild.v1` | `A20_TERMINAL_MOVEMENT_REQUIRED` | `a20_terminal_movement_identity` | +| 9 | `A20_LOGICAL_RANGE_REBUILD_REQUIRED` | `a20_logical_range_rebuild.v1` | `A20_ASSIGNMENT_REBUILD_REQUIRED` | `a20_assignment_rebuild_identity` | +| 10 | `A20_STORAGE_POPULATION_REBUILD_REQUIRED` | `a20_storage_population_rebuild.v1` | `A20_LOGICAL_RANGE_REBUILD_REQUIRED` | `a20_logical_range_rebuild_identity` | +| 11 | `A20_CONSTRUCTIBILITY_REQUIRED` | `a20_constructibility.v1` | `A20_STORAGE_POPULATION_REBUILD_REQUIRED` | `a20_storage_population_rebuild_identity` | +| 12 | `A20_FULL_RELATION_IDENTITY_REQUIRED` | `a20_full_relation_identity.v1` | `A20_CONSTRUCTIBILITY_REQUIRED` | `a20_constructibility_identity` | +| 13 | `A20_COMPARATOR_REQUIRED` | `a20_comparator_census.v1` | `A20_FULL_RELATION_IDENTITY_REQUIRED` | `a20_full_relation_identity` | +| 14 | `A20_Q5_REQUIRED` | `a20_q5.v1` | `A20_COMPARATOR_REQUIRED` | `a20_comparator_census_identity` | +| 15 | `A20_SLOT_REBUILD_REQUIRED` | `a20_slot_rebuild.v1` | `A20_Q5_REQUIRED` | `a20_q5_identity` | +| 16 | `A20_INVENTORY_REBUILD_REQUIRED` | `a20_inventory_rebuild.v1` | `A20_SLOT_REBUILD_REQUIRED` | `a20_slot_rebuild_identity` | +| 17 | `A20_G17_C01_REBUILD_REQUIRED` | `a20_g17_c01_rebuild.v1` | `A20_INVENTORY_REBUILD_REQUIRED` | `a20_inventory_rebuild_identity` | +| 18 | `A20_VB6_REQUIRED` | `a20_vb6_successor.v1` | `A20_G17_C01_REBUILD_REQUIRED` | `a20_g17_c01_rebuild_identity` | +| 19 | `A20_SUCCESSOR_BUNDLES_REQUIRED` | `a20_successor_bundles.v1` | `A20_VB6_REQUIRED` | `a20_vb6_identity` | +| 20 | `A20_MIGRATIONS_REQUIRED` | `a20_migrations.v1` | `A20_SUCCESSOR_BUNDLES_REQUIRED` | `a20_successor_bundles_identity` | +| 21 | `A20_CAPTURE_REQUIRED` | `a20_capture.v1` | `A20_MIGRATIONS_REQUIRED` | `a20_migrations_identity` | +| 22 | `A20_RECEIPT_REQUIRED` | `a20_receipt.v1` | `A20_CAPTURE_REQUIRED` | `a20_capture_identity` | +| 23 | `A20_REGISTRATION_REQUIRED` | `a20_registration.v1` | `A20_RECEIPT_REQUIRED` | `a20_receipt_identity` | +| 24 | `A20_SEALED_RUN_REQUIRED` | `a20_sealed_run.v1` | `A20_REGISTRATION_REQUIRED` | `a20_registration_identity` | +| 25 | `A20_WALL_LEDGER_REQUIRED` | `a20_wall_ledger.v1` | `A20_SEALED_RUN_REQUIRED` | `a20_sealed_run_identity` | +| 26 | `A20_PUBLICATION_REQUIRED` | `a20_publication.v1` | `A20_WALL_LEDGER_REQUIRED` | `a20_wall_ledger_identity` | + +The row-22 `a20_receipt.v1` object is the downstream successor-publication +and applicability receipt inherited from the covered-earnings artifact chain. +It is not, does not contain, and cannot substitute for the external +ratification receipt whose schema is `executed_transition_state.v2` in +§34.8. + +The last column contains closed binding-role names, not literal future output +IDs. At execution, `revision22_registry_repin_identity` exact-equals the real +repin output. For every later row, the first role exact-equals the actual +`output_identity_id` first-added by its sole displayed predecessor; the +remaining roles exact-equal the separately authenticated named historical or +settlement identity. The instantiated `input_identity_ids` array contains +those resolved IDs in displayed role order. A role-name substitution, +unresolved value, stale payload identity in place of the predecessor output, +or unequal predecessor/output/input edge aborts before the row is evaluated. + +In every dormant row `output_identity_id` is JSON null, +`selection_enabled` is false, and status is `dormant_definition`. At +execution, `output_identity_id` becomes literal `a20-lifecycle-output:` plus +SHA-256 of terminal-LF canonical JSON of `[lifecycle_stage_id, schema_id, +predecessor_stage_ids, input_identity_ids, exact_output_payload_identity]`. +The transition to `pass` and its first-add are atomic. Only row 5 changes +`selection_enabled` to true on passage; every other passing row retains false. +A missing or nonpassing predecessor yields `blocked_predecessor` with null +output and false selection. Any other failure yields +`fail_atomic_nonemission`, null output, false selection, and no descendant +instantiation. + +The prefix's historical `A20_SUCCESSOR_PROGRAM_STOP` remains active while A20 +is unratified. Upon a real revision-22 repin, the A20-governed deep copy of the +historical R06 lifecycle replaces only `next_required_state` with +`A20_SOURCE_RELATIONS_SETTLED_DISPATCH_DISABLED`. Passage of row 26 replaces +it with `A20_SUCCESSOR_LIFECYCLE_COMPLETE`. Neither state is an A21 alias or +permission for an unchartered amendment. + +The only ancestry/order is: + +~~~text +revision-22 repin + -> admitted and independently settled A20 source relations, dispatch disabled + -> complete normal R04 + -> R05 strict certificate first-add + -> exact historical R06 expected-abort rerun and first-add + -> accepted missing-reason successor selection and dispatch enablement + -> fresh 89,599-field classifier + -> terminal movement + -> assignments, logical ranges, and storage populations + -> constructibility and new full-relation identity + -> fresh comparator census + -> Q5 admission and first-add + -> slot, inventory, full G17-C01, and V-B6 + -> successor bundles, migrations, capture, receipt, registration, + sealed run, wall/ledger, and publication +~~~ + +Historical classifier, movement, storage, constructibility, comparator, Q5, +inventory, and V-B6 facts cannot be copied; zero movement cannot be assumed. +Each stage authenticates every predecessor identity, uses its versioned +schema, commits atomically, and first-adds in displayed order. The actual +objects are post-operative execution outputs; this amendment emits none. + +### 34.8 Limb VII — exact ratification, receipt, and scratch-state law + +#### 34.8.1 Qualifying affirmative verdict grammar + +Prospectively for Amendment 20 and every later activation-affecting +amendment, §28.2.1 condition 1 is satisfied only by two qualifying affirmative +verdicts. A qualifying verdict incorporates §§31.3.1–31.3.3 and §30.2.4; the +receipt is not a fifth operativity condition. Both referees independently +verify and attest the same external executed-transition receipt before +emitting their verdicts. + +Verdict bytes are strict UTF-8 with no BOM, NUL, or CR, LF separators, and +exactly one terminal LF. They have exactly these eight lines in order: + +~~~text +# RATIFY +attested_design_byte_size: +attested_design_raw_sha256: <64 lowercase hex> +attested_design_blob_oid: <40 lowercase hex> +executed_transition_receipt_byte_size: +executed_transition_receipt_raw_sha256: <64 lowercase hex> +executed_transition_receipt_schema: executed_transition_state.v2 +--- +~~~ + +`` is either canonical ungrouped `[1-9][0-9]*` or canonical comma +grouping `[1-9][0-9]{0,2}(,[0-9]{3})+`; both parse to and must equal the exact +positive integer. Leading zeroes, spaces, underscores, malformed groups, +space grouping, incidental substrings, repeated labels, narrative bytes, or +another line fail. The two verdict files are distinct closure artifacts but +attest one exact candidate triple and one exact receipt pair. +The receipt's Git-resolved `candidate_commit_identity` design tree entry is +mode `100644`, and its complete design byte size, raw SHA-256, and Git blob +must equal that verdict candidate triple, the closure's candidate triple, and +the design bytes carried at the terminal registry's `ratification_commit`. +The terminal registry's design binding raw SHA-256 must equal that same triple, +and its ratification commit must equal the real closure's operator-integration +commit. Neither equality makes scratch candidate commit `C` equal to that later +real commit; only their mode-`100644` design byte/blob/SHA identity is +cross-bound. A receipt for a different internally valid candidate is not +composable. + +The preceding current-terminal-registry cross-binding applies if and only if +Amendment 20 is the terminal closure, necessarily at revision 22. At revision +23 or later, Amendment 20 is historical: its receipt candidate design still +exact-equals the A20 closure and both verdicts, and the receipt's internal +revision-22 canonical registry binding remains authenticated, but the later +current terminal registry's design commit and SHA are not compared with A20's +historical commit or SHA. Instead, §30.2.3 controls: independently authenticate +the A20 closure's own operator-integration commit, sole parent, mode-`100644` +tree entry, complete design bytes, byte count, raw SHA-256, Git blob OID, and +A20 semantic projection. The later current registry authenticates its complete +closure-binding domain and its own terminal design. It does not rewrite the +historical A20 design identity. + +The A20 receipt is the separate tracked file +`docs/analysis/amendment_20_ratification/executed_transition_receipt_v2.json` +with mode `100644`. It is outside candidate `C`, outside scratch `S`, and not +a verdict artifact. Its strict-canonical JSON bytes are created only after the +scratch executions complete and before either real verdict; the later real +artifact sequence first-adds the fixed path no later than closure creation. +On the real history its unique first-add is an ancestor of or equal to the A20 +closure path's unique first-add. Candidate `C` and the later lawful +single-parent operator integration need not have the same commit identity and +need not be ancestor-related: a squash or cherry-pick may carry the identical +design blob as §§28.3.2 and 28.4 permit. The receipt chronology therefore does +not require `C` to be an ancestor of its first-add, and it must not make +unreachable scratch `S` an ancestor of production history. +The public loader reads that fixed path through the ordinary +replacement-ref-immune working-tree/`HEAD` verifier, validates the complete +v2 object under §34.8.2, and requires both verdicts' receipt byte size and raw +SHA-256 to equal those reread bytes. Absence, an untracked or nonregular file, +tree/worktree disagreement, another path, noncanonical bytes, or an identity +mismatch aborts. A later activation-affecting amendment inherits the same +`docs/analysis/amendment__ratification/executed_transition_receipt_v2.json` +path rule unless its own exact law supersedes the receipt schema. +Path inheritance alone does not invent a later amendment's candidate/scratch +topology: the A20 implementation must reject `N > 20` until that amendment's +own exact projection supplies and pins the generalized receipt transition. + +This exact grammar supersedes §30.2.3's loose “contains” rule and repairs the +nonexistent §31.5 “A16 ratification demonstration” map anchor. The public +§30.2.4 path validates A20's semantic projection, qualifying verdicts, and +receipt attestation before returning a closure domain. + +That supersession is limited to verdict-byte grammar. It does not supersede +§30.2.3's terminal-versus-historical design selector or permit a historical +A20 receipt to bind a later terminal registry design. + +#### 34.8.2 Exact scratch-only transition + +The §31.3 same-state demonstration uses an isolated scratch descendant, never +the production registry. Candidate commit `C` contains the final design and +pinned implementation and records its actual sole parent. Scratch commit `S` +is a strict child of `C` and changes only two +`SIMULATED_NONAUTHORITY` verdict artifacts, one synthetic closure, the mutable +scratch registry binding. The +scratch registry is revision 22 with ordered closure domain +`(13,14,15,16,17,18,19,20)` and design bytes exactly from `C`. + +Pre-receipt stand-ins use this distinct exact seven-line grammar: + +~~~text +# RATIFY +attested_design_byte_size: +attested_design_raw_sha256: <64 lowercase hex> +attested_design_blob_oid: <40 lowercase hex> +executed_transition_receipt_status: pending_same_state_execution +simulation_context: amendment20_same_state_nonauthority_v1 +--- +~~~ + +They are accepted only after the public-entrypoint-verifiable +`_validate_amendment20_scratch_transition_context` predicate passes; they are +never qualifying §28 verdicts. That predicate has no caller flag, environment +switch, mock, private entrypoint, or verification bypass. It reads Git and the +ordinary registry snapshot and requires all of these exact facts: + +~~~text +HEAD is scratch commit S and has sole parent C +C is the exact final candidate commit and its design/pinned files match §34.9 +HEAD is detached; no Git ref contains S; and no refs/replace ref exists +the scratch worktree and index are clean at S +S changes exactly the four ordered paths below and no candidate byte +the scratch registry declares SIMULATED_STATE_AUTHORITY = NONAUTHORITY +the scratch registry declares SIMULATION_CONTEXT = amendment20_same_state_nonauthority_v1 +the scratch registry otherwise exact-binds revision 22 and closures 13..20 +the synthetic A20 closure binds the two exact stand-ins and candidate design C +each stand-in passes the distinct seven-line grammar +~~~ + +When and only when the terminal revision-22 closure supplies these two +stand-ins, the unmodified public entrypoint invokes that predicate itself +before accepting either artifact and before returning its closure domain. A +predicate failure is final; the loader does not fall back from malformed real +verdict bytes to a caller-selected scratch mode. On the later real closure, +the stand-in grammar is forbidden and the loader instead requires the fixed +external receipt path and both exact qualifying verdicts in §34.8.1. + +The exact allowed changed-path order is: + +~~~text +docs/analysis/amendment_20_ratification/sol-ce-amend20-sim-r1-verdict.md +docs/analysis/amendment_20_ratification/sol-ce-amend20-sim-r2-verdict.md +docs/analysis/amendment_20_ratification/closure_v1.json +scripts/covered_earnings_correction_registry.py +~~~ + +That terminal-LF canonical path array is exactly 260 bytes with raw SHA-256 +`5a7912498c4d959fef337f2a1d1cf85a2f254fa29d825d365ccf4fe214ad48a7`. + +Candidate C's production registry predecessor is fixed and unchanged: path +`scripts/covered_earnings_correction_registry.py`, mode `100644`, 55,473 +bytes, Git blob `92a24e3af4358f75cbead00f223837a68c2f9da8`, and raw SHA-256 +`bd60336e3e388e5ef12f3f204b9bb08938c27be4db57f9e6fca6582aed7efb16`. +The scratch validator rederives that complete identity from C before it may +normalize any S assignment. Thus C cannot hide a duplicate, nonliteral, +augmented, deleted, or otherwise mutating binding operation outside the exact +production-registry bytes. + +The detached/unreachable conditions are checked from Git itself: `git +symbolic-ref -q HEAD` must fail, `git for-each-ref --contains S` must return +the empty byte string over all refs, and `refs/replace/*` must be absent. A +ref, tag, replacement, merge, descendant, or other currently observable +ref-reachable state containing `S` makes this adapter reject at validation +time. The adapter makes no unobservable claim about deleted refs or a push to +another repository; the receipt's exact C/S identities remain NONAUTHORITY +and nonreusable outside the one validated state. +The two scratch-only registry constants are forbidden in a production +registry. A stand-in in an ordinary registry, a self-declared context without +the exact C→S topology and detached-unreachable state, wrong parent/tree/path +set, dirty index or worktree, real-verdict parser, alternate filename, or +extra changed byte aborts. The unmodified public oracle and complete pinned +battery run against that one state. The resulting external +receipt uses schema `executed_transition_state.v2`. It retains §31.3.3's exact +six-key top level and the inherited `public_oracle`, +`full_pinned_battery`, closure-identity, and test-identity keysets. Its +`simulated_state_manifest` replaces the v1 seven-key shape with exactly: + +~~~text +schema_version +simulated_state_authority +candidate_commit_identity +scratch_transition +terminal_revision +canonical_registry_binding +ordered_closure_identities +full_pinned_battery_test_identity +~~~ + +For A20, the inherited `full_pinned_battery.exact_command` member is the exact +portable string: + +~~~text +executing_process_sys.executable -m pytest -q tests/test_validate_amendment13_execution_law.py +~~~ + +Its first token is a closed selector: the ceremony resolves it to that +executing validator process's current `sys.executable` before invocation, but +no host-specific absolute path is serialized. A later verifier checks the +selector string and authenticated test identity, not equality to the +verifier's own interpreter pathname. + +`schema_version` is `executed_transition_state.v2`; authority is +`NONAUTHORITY`. `candidate_commit_identity` has exactly `commit`, `tree`, and +`sole_parent`. Those values exact-equal Git-resolved `C`, `C^{tree}`, and +`C^`; `C` must have exactly that one parent. `scratch_transition` has exactly +`commit`, `tree`, `sole_parent`, `changed_paths`, and +`changed_path_domain_sha256`. Its first three values exact-equal Git-resolved +`S`, `S^{tree}`, and `C`; `S` must have exactly that one parent. Every commit, +tree, and parent is 40 lowercase hex. Both independent referees recompute +those objects and equalities from the repository rather than trusting receipt +text. `changed_paths` is the exact ordered domain of two simulated +verdicts, one synthetic closure, and one scratch registry binding—no receipt, +candidate, implementation, source, or unrelated path enters it—and its +terminal-LF canonical array digest must equal the named digest. The existing +`candidate_or_scratch_HEAD` value is thereby superseded by these two explicit +objects. Every other §31.3.3 type, canonicalization, state-identity equation, +public result, complete test census, and zero-nonpassing rule survives. + +Receipt result booleans are not self-authenticating. The receipt validator +rereads all four changed paths from Git at `S`: it strict-parses the synthetic +A20 closure, authenticates and seven-line-parses both stand-ins against that +closure and candidate triple, and literal-parses the scratch registry's exact +revision, candidate identity, closure bindings, authority, and simulation +context without executing caller-selected code. After removing only the six +ordinary binding assignments from C's registry AST and those same six plus +the two scratch-only assignments from S's registry AST, the complete +attribute-free AST dumps must be identical. Each removed name is a unique +top-level literal assignment; C has no scratch-only assignment. Thus the +ordinary `design_binding()` implementation and all other executable behavior +are unchanged. Those registry values must exact-equal the receipt manifest's +canonical registry binding and C design identity. A self-consistent receipt +whose S tree carries another closure, +stand-in, or registry binding aborts even when both recorded execution booleans +are true. + +Real referees verify that receipt and emit the exact §34.8.1 verdicts. A +stand-in is tagged NONAUTHORITY, nonmergeable, +noncopyable, nonreusable, and cannot enter the real closure. + +The later real sequence remains: final candidate, same-state receipt, two +real verdicts, lawful sole-parent operator integration, A20 closure creation, +and real revision-22 registry repin. This draft changes no registry byte. + +### 34.9 Implementation pins, semantic projection, activation, and routing + +#### 34.9.1 Active implementation pins and fixpoint + +The Amendment-20-governed active identity is exactly mode `100644` and these +three path/blob/byte/hash rows: + +| Path | Git blob | Bytes | Raw SHA-256 | +|---|---|---:|---| +| `scripts/validate_amendment13_execution_law.py` | `5a8f318b8ea24b3ca22c71e874eae22ba9f4fa3e` | 666,439 | `2e1f07f849743f09a0cb6ec07033b1b379e5b62696c7451ed45bbe2e306e9f90` | +| `tests/test_validate_amendment13_execution_law.py` | `b91f8a193589f11ad1de9a2cf294e24e7d01996a` | 185,950 | `0447d19588bf9a4a929844e2be1bf28e5127f48c2becb12625c2cde08c22a458` | +| `scripts/build_amendment13_tier2_repairs.py` | `8e7550ff71cd43f3acd39b7fd1779b6e3a223581` | 111,145 | `2ff0ff39d7ca316fb78c1beb8164300991ea194e803795e642b544bd78b5ef1b` | + +The semantic projection requires the exact 4,025,587-byte revision-21 prefix, +one Amendment-20 boundary, UTF-8, and one terminal LF. It strict-parses the +complete §34.12 manifest and hashes the entire normalized A20 suffix. Exactly +ten captures may be normalized: mode plus each of the three rows' blob OID, +decimal byte count, and raw SHA-256. Each remains separately Git- and +byte-authenticated. No evidence identity, readiness value, manifest member, +verdict grammar, supersession, routing value, or other prose byte is +normalized. + +The final fixed point is: freeze prose/manifest; compute the normalized §34 +digest; set the validator constant; format code/tests; derive the exact three +implementation rows; replace only the ten captures; and prove the normalized +digest unchanged. Any other change invalidates the semantic digest and pins. + +#### 34.9.2 Exact route and production boundary + +The current production registry remains exact revision 21, terminal +Amendment 19, ordered closure domain `(13,14,15,16,17,18,19)`, and closure +count `7 = 21 - 14`. Its ordinary loader must reject the unratified A20 suffix. +Only the exact §34.8 scratch copy may bind revision 22 before real activation. + +For prospective validation, exact revision-21 constants and the A20 boundary +select A20 pins before A19 pins. A terminal Amendment 20 validates the exact +A19 prefix and complete A20 projection. Every later amendment first validates +the inherited A20 projection. An arbitrary A20 suffix, A19-only fallback, +wrong terminal heading, second A20 boundary, non-pin semantic change, pending +A4 freeze presented as ready, or alternate active route aborts. Historical +A19 validation uses only the exact revision-21 prefix and its own pin table. + +Amendment 20 is activation-affecting. Its exact proposed transition is +terminal Amendment 20, revision 22, ordered closure domain +`(13,14,15,16,17,18,19,20)`, and closure count `8 = 22 - 14`. One final +same-state public-oracle execution and the complete final pinned battery must +have zero failed, skipped, deselected, xfailed, or xpassed tests. Activation +requires the exact receipt, qualifying dual verdicts, operator integration, +closure, and later real registry repin. This draft performs none of them. + +### 34.10 Exact mutation inventory and inherited censuses + +The separate Amendment-20 mutation inventory is exactly: + +~~~text +shared_source_domain_or_statement_locator_forged +missing_reason_rule_or_exact_cover_forged +purpose_authority_or_totality_forged +prompt_field_or_semantic_binding_forged +r04_order_source_binding_or_q5_shape_forged +r06_collection_or_lifecycle_order_forged +receipt_verdict_or_scratch_transition_forged +amendment20_terminal_pin_or_suffix_route_forged +evidence_freeze_identity_shadow_or_status_forged +failure_shadow_nonemission_provenance_forged +determined_as_source_underdetermined_without_ruling_forged +source_underdetermined_as_no_applicable_purpose_forged +source_underdetermined_a4_census_binding_forged +completed_ontology_new_arm_omitted +coordinate_distinct_questionnaire_spans_collapsed_to_one_body_forged +~~~ + +Its terminal-LF canonical name array is 738 bytes with raw SHA-256 +`eab546538a26abac04f559b73646bbca9d240832ae9d9ee82c6295a1462d0e2b`. +A name is appended only after every implemented attack in that group reaches +and fails its intended contract gate. At this evidence-incomplete draft stage, +the exact attacks are closed-manifest removal or mutation of source-domain, +statement-span, missing exact-cover/Boolean/bridge, purpose 818/U/totality, +C68/46/candidate-partition/zero-group/semantic, build-order/Q5/279, +R06 interpreter/file/count/lifecycle, receipt-schema/path, and +terminal/revision/routing members; strict verdict CRLF mutation; live +reauthentication of the six files and 223 collected nodes; and rejection of +stand-ins in the ordinary attached production worktree. The focused receipt +tests separately rederive C/S, the synthetic closure, both stand-ins, and the +scratch registry and reject a function-only registry forgery. These attacks +do not claim that absent A4 evidence rows or the future same-state scratch +commit have already been instantiated. The final pinned battery must add and +pass row-level, rule-overlap, complete-46, zero-group omission, receipt +absence/mismatch, and valid-scratch reuse attacks against those frozen objects +before either qualifying verdict; manifest-only rejection cannot substitute +for that later evidence/runtime coverage. + +The ninth group first accepts exact synthetic controls for all-pass and for +each of the three independent permanent-failure statuses, using one real +temporary Git repository whose exact commit, tree, blob, manifest rows, and +manifest digest are reconstructed from its object store. It then rejects a +forged failure-shadow digest, a missing complement, a status flip that retains +the prior union of pass identities and shadow, and replacement of all identity +values by arbitrary truthy mappings. Each of those four attacks continues to +reach and fail its prior status-dependent freeze gate rather than relying on +whole-manifest inequality. + +The tenth group starts from that accepted real scratch provenance, substitutes +nonexistent execution commit and tree object IDs plus arbitrary equal manifest +hashes, retains the complete manifest arrays and the derived clean/absence +assertions, and recomputes the outer successor-binding digest. It must reach +raw Git object authentication and fail because the commit does not resolve. +An unkeyed outer digest, equal caller-provided hashes, or true booleans never +authenticate the forged provenance. + +The final four groups separately reject a determined row rewritten as +`source_underdetermined` without its reconciled ruling, conflation of +`source_underdetermined` into `no_applicable_purpose`, disagreement between +the underdetermined census and its A4 freeze-slot binding, and a completed- +ontology disposition object missing the new arm. Each reaches and fails the +purpose-authority contract rather than relying on whole-manifest inequality. +The fifteenth group collapses two coordinate-distinct questionnaire spans to +one evidence body and must fail the prompt-field contract. + +The runner first executes and authenticates these five separate inherited +censuses, without relabeling their total as an A20 census: + +| Inventory | Count | Raw SHA-256 | +|---|---:|---| +| inherited complete certificate | 100 | `fe2efd7b96c24b7cbd3c6ce350d44906eb5a88b8b35ee77565c1b133cbf1f3e3` | +| Amendment 16 | 7 | `1e00099f636c1a727839ebc298b965cd0981e0ad8f23189367ba7dbd0eddb871` | +| Amendment 17 | 3 | `b19ebcbf47278d63e12bd8021334a88910895bdfe48caf2d49c6bbe3014417e6` | +| Amendment 18 | 3 | `1bf9f6d30461d003cab597a405cb5cc9855273372ed3e7e5b36b1627eaa11108` | +| Amendment 19 | 3 | `002aa021325c18e311cc778562ad0e937468a90c378db0740290fcf617929101` | + +Only after the inherited `100 + 7 + 3 + 3 + 3 = 116` attacks pass does the +runner execute the fifteen A20 attacks. Drift, omission, reordering, wrong-gate +rejection, type coercion, or census inflation aborts. + +### 34.11 Complete supersession, preservation, and new identifiers + +The complete supersession and preservation disposition is: + +| Earlier normative anchor | Amendment-20 disposition | +|---|---| +| §19.3.3 purpose classification, prompt consumption, singleton token/group attachment, `source_document_manifest` and `era_rows` shapes, `near_match_source_annotation_rows`/semantic bindings, and post-`O_P` joins | Superseded for the A20 successor by admitted purpose rules, complete A4-frozen-denominator re-grounding over the completed ontology, pre-`O_P` evidence, source-backed resolution rows that materialize every candidate, and only §34.6.3's exact manifest/era replacements. All 46 collisions require dispositions; there is no direct-ID priority. The inherited seven-key near-match row is reused as the sole semantic-binding serialization and deep-equals the A20 identity. Its five-coordinate binding, nonempty exact-token joins, ambiguity abort absent accepted evidence, reverse covers, and source-only limits survive. | +| §20.4.2 frozen Q5 shapes; §§33.2.2 and 33.3.2; the corresponding §33.7 shape rows | Superseded only by A19's per-era purpose rows and preproof search-key change and §34.6.3's exhaustive A20 header/per-era additions. Every other frozen shape, ordering, self-zero, and join rule survives. | +| §§19.4.2, 26.6.1, and 26.10.1 expected/actual G17-C01, effective-header, Q5, inventory, and slot projections | On the A20 normal arm, both expected and actual projections carry every exact §34.6.3 header and per-era addition and direct-concatenation identity. Failure arms emit none of those pass-only projections. Every unnamed member and order survives. | +| §§25.2–25.4 historical missing-reason census and settlement | Historical 47-source audit, 12-position identities, 52 authorized literals, 524,538 unresolved blocker, 37,283 numeric nulls, abort, and nonemission remain exact. A20 adds a separately versioned, transactionally selected successor relation. | +| §§25.5 and 25.10.1–25.10.2 blocker, no-movement, and later-successor stop; §§32.4.4, 32.7–32.8, and 33.4 active `A20_SUCCESSOR_PROGRAM_STOP` | Historical expected abort, no-movement conclusions, and stop literal survive while A20 is unratified and through R06. Real revision-22 repin changes active `next_required_state` to row 1; only after settled source relations, normal R04, R05, and exact historical R06 may row 5 select the successor and enable dispatch. No earlier conclusion is rewritten. | +| §25.6.6 exact selector and §§32.4.2–32.4.3 R06 input/test result; the deficient §32.7 row | Superseded only for command position zero by executing-process `sys.executable` and completed by the six exact file identities and 223-node array identity. `PYTHONPATH`, module order, sanitized environment, and historical result survive. | +| §§25.9–25.10 lifecycle families, §26.10.3, and DC-71 | Superseded solely to allow §34's dormant definitions before certification. After revision-22 activation, rows 1–4 may instantiate and first-add only in their exact source-settlement→R04→R05→historical-R06 order. No successor selection, dispatch, or row-5-through-row-26 instance, first-add, authority, or output exists before that order completes. Other lifecycle ancestry and nonemission rules survive. | +| §26.6.3, §26.10.1, §33.2.2–§33.2.3, and the first §33.7 construction-order row | Superseded only in precedence and failure-arm nonexecution by §34.6.1. Source-only `O_H` still precedes `O_P` on the normal arm; no purpose failure arm evaluates the full normal build. | +| §26.11.2 complete R04/R05/R06 gate | Preserved and strengthened by separate source-domain authentication, prompt-field evidence, semantic binding, post-`O_P` joins, and dual reconstruction. Purpose `U == 0` alone is never passing. | +| §§28.2.1 and 28.4 verdict/operator/closure order | Composed prospectively: condition 1 requires two qualifying §34.8.1 verdicts that attest the same verified §31.3 receipt. Scratch stand-ins are NONAUTHORITY and cannot satisfy the real sequence. The other three iff conditions and real sole-parent sequence survive. | +| §§29.4.4–29.4.5 source-member identity and independent reconstruction | Composed with the separate A20 successor binding. Both reconstructors preserve the historical 279 envelope and independently authenticate both A20 semantic domains and every successor relation. | +| §29.4.1 canonicalization and identity equations | Fully preserved for every A20 relation: ASCII JSON, sorted keys, compact separators, no nonfinite value, and one terminal LF. Displayed schema-member order remains normative independently of sorted canonical bytes. | +| §§30.2.3–30.2.4 verdict checking and public atomic operativity | Superseded prospectively by the closed UTF-8/LF/decimal/receipt grammar and A20 projection check before the public oracle returns. Historical closure bytes remain valid under historical law. | +| §30.2.2 exact five-key registry context and caller-context prohibition | Preserved for every ordinary production invocation. Candidate C retains the exact pinned revision-21 production-registry bytes. The public-entrypoint scratch adapter may additionally read only the two exact scratch registry constants `SIMULATED_STATE_AUTHORITY` and `SIMULATION_CONTEXT` after the Git-derived detached/unreachable predicate passes; they are absent and forbidden in production, are not caller input, and cannot widen the ordinary five-key context. S's nonbinding AST must otherwise equal C's exactly. | +| §30.2.1 amendment/revision arithmetic | Preserved and applied: Amendment 20 proposes revision 22, terminal closure 20, and eight closures because `8 = 22 - 14`. | +| §§31.3.1–31.3.3 same-state demonstration and the §31.5 nonexistent “A16 ratification demonstration” map row | Composed with §§28.2.1 and 30.2.4 by §34.8. Receipt verification is part of a qualifying affirmative verdict, not a fifth operativity condition. The six-key receipt top level survives; its v1 manifest is superseded only by the exact v2 candidate/scratch topology, the portable executing-process command selector, independent synthetic-closure/stand-in/registry rederivation, and the distinct pending stand-in that resolves pre-verdict chronology. | +| §§32.2.1–32.2.2 and §33.8 authenticated 257+22=279 build-input envelope | Preserved byte-for-byte. A20 sources enter only the separately authenticated successor composite and never widen or rename the historical envelope. | +| §32.4.4 false R06 lifecycle booleans | Preserved as exact facts about the historical R06/A11 execution's production and lifecycle outputs. They do not prohibit pre-R06 evidence relations while dispatch-disabled or dormant law definitions. | +| §§30.4.1, 31.2.2, 32.5.1, and 33.5.1 active implementation rows and narrow pre-ratification review | Historical pin tables remain exact. After final freeze, only the A20 three-row table becomes the active prospective-validation selector; publisher isolation, working-tree/HEAD/Git checks, narrow review, and the three-path domain survive. | +| §§33.2.2–33.2.3 purpose rows and selected A19 failure member | A19's relation survives only as immutable historical audit evidence and is absent/nonconsumable on the A20 normal Q5 path; its exact 877-byte historical failure member also survives. A20 replaces active mapping and selection only after every row in the A4-frozen prompt denominator has a lawful completed-ontology disposition and every R04 conjunct passes; A20 evidence failures use separate diagnostic statuses. | +| §33.3.2 D0/search/proof/D1 construction | Preserved exactly and composed after the A20 normal selector. No A20 relation may recreate the digest cycle. | +| §33.4 obsolete campaign pin and A20 out-of-scope label | Superseded as prospective scope by the exact consolidated charter pin in §34.1. Historical A19 routing remains evidence of its then-deferred program. | +| §§33.5.2–33.5.3 A19 projection, routing, and activation | Historical A19 validation uses the exact revision-21 prefix. Active prospective routing adds exact A20 terminal/inherited validation and the revision-22 same-state obligation. | +| §33.6 mutation inventory and inherited census | Preserved as three A19 names after the earlier 113 attacks. A20 runs the five inherited censuses separately, then its own fifteen-name inventory. | +| The four §33.7 rows concerning construction order, raw-field ambiguity, Q5 shape, and R04 reconstruction | Superseded or composed exactly as the first, second, sixth, seventh, and ninth rows of this table; no unlisted A19 semantic change is implied. | +| §33.8 `questionnaire_occurrence_rows` combined evaluation/serialization prohibition | Superseded by two scopes: authenticated read/construction is required for the selector, while serialization into the failure member and treatment as pass-only output remain forbidden. The 877-byte member survives. | +| §33.9 terminal A19 prospective effect | Preserved as historical drafting law and superseded only as the terminal prospective section by §34.13 after A19's external activation. | +| §§20.3, 21.3–21.5, 22.2–22.5, 23.2–23.5, and 24.2–24.6 downstream algorithms | Preserved as algorithms but every A20-affected classifier, movement, assignment, range, storage, constructibility, full identity, and comparator fact is freshly recomputed; no historical result is copied. | +| §§19.6–19.8, 20.7–20.8, 21.8–21.9, 22.8–22.9, 23.8–23.9, 24.9–24.10, and 25.9–25.10 artifact families | Composed with §34.7's versioned lifecycle envelope, exact DAG, atomic gates, and first-add order. Historical artifact bytes and predecessor versions survive. | +| §§27.3–27.6 repair overlays and six seals; §28.2.2 closure schema/history; §29.4.7 raw 100-census attestation | Fully preserved. A20 neither changes their bytes nor treats their conclusions as authority for either new semantic arm. | + +No predecessor byte is deleted. Any prior requirement not expressly changed +in the table remains exact. A new relation never silently waives an inherited +normal gate. A failure member's omission is lawful only where §34 expressly +forbids evaluation or serialization. + +The exact new schema identifiers are: + +~~~text +amendment_20_dual_authority_successor_law.v1 +executed_transition_state.v2 +a20_evidence_freeze.v1 +a20_failure_shadow_identity.v1 +a20_nonemission_complement_identity.v1 +a20_physical_source_registry.v1 +a20_evidence_statement_registry.v1 +a20_missing_reason_source_domain.v1 +a20_purpose_source_domain.v1 +a20_successor_source_binding.v1 +a20_missing_reason_authority_rules.v1 +a20_missing_reason_successor_relation.v1 +a20_missing_representation_bridge.v1 +a20_purpose_authority_rules.v1 +a20_purpose_authority_mapping.v1 +a20_prompt_field_evidence.v1 +a20_prompt_field_candidate_sets.v1 +a20_zero_candidate_positive_groups.v1 +a20_source_settlement.v1 +a20_normal_r04.v1 +a20_r05_certificate.v1 +a20_historical_r06_binding.v1 +a20_classifier_rebuild.v1 +a20_terminal_movement.v1 +a20_assignment_rebuild.v1 +a20_logical_range_rebuild.v1 +a20_storage_population_rebuild.v1 +a20_constructibility.v1 +a20_full_relation_identity.v1 +a20_comparator_census.v1 +a20_q5.v1 +a20_slot_rebuild.v1 +a20_inventory_rebuild.v1 +a20_g17_c01_rebuild.v1 +a20_vb6_successor.v1 +a20_successor_bundles.v1 +a20_migrations.v1 +a20_capture.v1 +a20_receipt.v1 +a20_registration.v1 +a20_sealed_run.v1 +a20_wall_ledger.v1 +a20_publication.v1 +~~~ + +The exact new status, lifecycle, and authority identifiers are: + +~~~text +not_instantiated_a4_required_before_ratify +pass_a4_exact_freeze +fail_permanent_missing_reason_authority_residue +fail_permanent_purpose_authority_residue +fail_permanent_prompt_field_or_semantic_binding_residue +dormant_definition +blocked_predecessor +fail_atomic_nonemission +accepted_exact_source_identifier +accepted_expressly_admitted_official_alias +unresolved_multiple +zero_candidates +one_candidate +multiple_candidates +complete_nonempty_reference_union +fail_empty_reference_union +SIMULATED_NONAUTHORITY +pending_same_state_execution +amendment20_same_state_nonauthority_v1 +REVISION22_REGISTRY_REPIN +A20_SOURCE_RELATIONS_SETTLED_DISPATCH_DISABLED +A20_NORMAL_R04_REQUIRED +A20_R05_REQUIRED +A20_HISTORICAL_R06_REQUIRED +A20_MISSING_REASON_SUCCESSOR_ACTIVE +A20_CLASSIFIER_REBUILD_REQUIRED +A20_TERMINAL_MOVEMENT_REQUIRED +A20_ASSIGNMENT_REBUILD_REQUIRED +A20_LOGICAL_RANGE_REBUILD_REQUIRED +A20_STORAGE_POPULATION_REBUILD_REQUIRED +A20_CONSTRUCTIBILITY_REQUIRED +A20_FULL_RELATION_IDENTITY_REQUIRED +A20_COMPARATOR_REQUIRED +A20_Q5_REQUIRED +A20_SLOT_REBUILD_REQUIRED +A20_INVENTORY_REBUILD_REQUIRED +A20_G17_C01_REBUILD_REQUIRED +A20_VB6_REQUIRED +A20_SUCCESSOR_BUNDLES_REQUIRED +A20_MIGRATIONS_REQUIRED +A20_CAPTURE_REQUIRED +A20_RECEIPT_REQUIRED +A20_REGISTRATION_REQUIRED +A20_SEALED_RUN_REQUIRED +A20_WALL_LEDGER_REQUIRED +A20_PUBLICATION_REQUIRED +A20_SUCCESSOR_LIFECYCLE_COMPLETE +~~~ + +The exact new Q5, evidence-freeze, and scratch member identifiers are: + +~~~text +amendment20_evidence_freeze +amendment20_evidence_freeze_status +missing_reason_authority_status +purpose_authority_status +prompt_field_semantic_binding_status +expected_identity_bindings +amendment20_ratification_ready +missing_reason_failure_shadow_identity +purpose_failure_shadow_identity +prompt_field_semantic_failure_shadow_identity +arm_status_bindings +active_identity_bindings_sha256 +arm_status_member +arm_status +shadow_row_count +shadow_ordered_keyset_sha256 +shadow_row_domain_sha256 +complement_identity +complement_of_identity_names +forbidden_output_identity_names +forbidden_output_paths +nonemission_evidence +repository_manifest_rows_before +repository_manifest_rows_after +forbidden_outputs_absent_after_execution +a20_successor_source_binding_identity +missing_reason_source_domain_identity +purpose_source_domain_identity +missing_reason_rule_set_identity +purpose_rule_set_identity +prompt_field_evidence_identity +semantic_binding_identity +purpose_authority_mapping_row_count +purpose_authority_mapping_keyset_sha256 +purpose_authority_mapping_domain_sha256 +purpose_authority_mapping_disposition_counts +prompt_field_evidence_row_count +prompt_field_evidence_keyset_sha256 +prompt_field_evidence_domain_sha256 +prompt_field_evidence_disposition_counts +prompt_field_candidate_set_row_count +prompt_field_candidate_set_keyset_sha256 +prompt_field_candidate_set_domain_sha256 +prompt_field_candidate_set_disposition_counts +zero_candidate_positive_group_row_count +zero_candidate_positive_group_keyset_sha256 +zero_candidate_positive_group_domain_sha256 +zero_candidate_positive_group_empty_union_count +purpose_authority_mapping_rows +prompt_field_evidence_rows +prompt_field_candidate_set_rows +zero_candidate_positive_group_rows +SIMULATED_STATE_AUTHORITY +SIMULATION_CONTEXT +candidate_commit_identity +scratch_transition +changed_paths +changed_path_domain_sha256 +~~~ + +The exact new identity prefixes are: + +~~~text +psid-prompt-field-evidence: +psid-prompt-field-candidate-set: +psid-zero-candidate-positive-group: +a20-lifecycle-output: +~~~ + +The exact new Python identifiers are: + +~~~text +_validate_amendment20_draft_design +_validate_amendment20_ratification_design +_validate_inherited_amendment20_ratification_design +_validate_amendment20_evidence_freeze +_canonical_amendment20_repository_path +_read_amendment20_worktree_file +_reconstruct_amendment20_repository_manifest +_validate_amendment20_nonemission_evidence +_parse_amendment20_implementation_pins +_parse_amendment20_projection +run_amendment20_contract_mutation_tests +validate_amendment20_qualifying_verdict +_validate_amendment20_scratch_transition_context +_amendment20_registry_behavior_ast +_parse_amendment20_scratch_registry_binding +_validate_amendment20_transition_receipt +_validate_amendment20_r06_collection_binding +~~~ + +Each displayed inventory is ordered, unique, and closed for its stated kind; +the schema, status/disposition/lifecycle/authority, member, prefix, and Python +kinds are disjoint. The inherited `near_match_source_annotation_rows` schema +and its identifiers are deliberately not renamed or recounted. + +### 34.12 Exact machine projection + +The exact Amendment-20 normative manifest is this one-line terminal-LF canonical JSON value: + +~~~text +{"activation_transition":{"activation_affecting":true,"activation_requires_operator_integration_closure_and_registry_repin":true,"all_nonpassing_counts":0,"closure_count":8,"closure_count_subtrahend":14,"full_pinned_battery_collected":220,"full_pinned_battery_exact_command":"executing_process_sys.executable -m pytest -q tests/test_validate_amendment13_execution_law.py","full_pinned_battery_required":true,"ordered_closure_domain":[13,14,15,16,17,18,19,20],"production_registry_changed_by_draft":false,"public_entrypoint":"validate_ratification_operativity","receipt_inside_candidate_bytes":false,"same_state_required":true,"terminal_amendment":20,"terminal_revision":22},"amendment20_evidence_freeze":{"amendment20_evidence_freeze_status":"not_instantiated_a4_required_before_ratify","amendment20_ratification_ready":false,"expected_identity_bindings":{"a20_successor_source_binding_identity":null,"dormant_lifecycle_definition_identity":null,"evidence_statement_identity":null,"missing_reason_failure_shadow_identity":null,"missing_reason_rule_set_identity":null,"missing_reason_source_domain_identity":null,"missing_reason_successor_relation_identity":null,"missing_representation_bridge_identity":null,"physical_source_identity":null,"prompt_field_candidate_set_identity":null,"prompt_field_evidence_identity":null,"prompt_field_semantic_failure_shadow_identity":null,"purpose_authority_mapping_identity":null,"purpose_failure_shadow_identity":null,"purpose_rule_set_identity":null,"purpose_source_domain_identity":null,"r04_q5_shape_identity":null,"r06_collected_node_id_identity":null,"r06_six_module_identity":null,"semantic_binding_identity":null,"zero_candidate_positive_group_identity":null},"missing_reason_authority_status":null,"prompt_field_semantic_binding_status":null,"purpose_authority_status":null,"schema_version":"a20_evidence_freeze.v1"},"canonicalization":"python-json-sort-keys-compact-ascii-no-nan-lf-v1","controlling_external_records":[{"authority":"NONAUTHORITY","byte_size":27368,"logical_path":"e8-ops/sol-ce-a20-charter.md","raw_sha256":"5ecd4092f3fc62ef894866a1a5b505d6dba7bb04cde1360ff7134d7d8e927717"},{"authority":"NONAUTHORITY","byte_size":11805,"logical_path":"e8-ops/sol-ce-law-gap-sweep-r21-2026-08-16.md","raw_sha256":"39887de99d75a395e97b04f33b4c5264a6828f56c9321cfe248b4ba11a7e5846"}],"evidence_campaign":{"conditional_p50":"2026-11-09","conditional_p80":"2027-01-22","dates_are_nonauthority_conditional_planning_metadata":true,"fail_closed_kill_categories":["source_admission","missing_rule_scope","purpose_entailment","family_equivalence","legacy_vocabulary","circular_attachment","prompt_field_ambiguity","reviewer_origin","cross_arm_contamination","missing_convention_arm_capacity","missing_ledger_capacity","purpose_ledger_capacity","acceptance_exact_cover_and_reconstruction","complete_R04","downstream_reconstruction_and_publication"],"forecast_as_of":"2026-08-15","permanent_residue_remains_fail_closed":true,"q_definition":"observed_independently_reviewed_logical_decisions_per_lane_day","rounds_formula":"ceil(2L/(3q))","stage_order":["E0_banked_evidence_reauthentication","E1_shared_source_closure_and_separate_domain_projections","E2_compilers_representation_bridges_and_measured_pilots","A1_concentrated_queues","A2_recurring_remainder","A3_occurrence_local_residue_with_capacity_kills","A4_dual_review_reconciliation_and_exact_identity_freeze","C20_ratification_and_revision_22_activation","X1_authoritative_settlement_missing_dispatch_disabled","X2_complete_normal_R04_and_R05","historical_R06_replay_and_first_add","fresh_reconstruction","Q5","slot_inventory_G17_C01_and_V_B6","sealed_publication_chain"]},"evidence_freeze_contract":{"absent_identity_is_not_zero_digest_or_wildcard":true,"authority_selection_permitted":false,"final_arm_status_domains":{"missing_reason_authority_status":["pass","fail_permanent_missing_reason_authority_residue"],"prompt_field_semantic_binding_status":["pass","fail_permanent_prompt_field_or_semantic_binding_residue"],"purpose_authority_status":["pass","fail_permanent_purpose_authority_residue"]},"final_required_evidence_freeze_status":"pass_a4_exact_freeze","identity_contract":{"arm_identity_contracts":{"missing_reason_authority_status":{"failure_shadow_identity_name":"missing_reason_failure_shadow_identity","failure_status":"fail_permanent_missing_reason_authority_residue","forbidden_output_paths":["docs/analysis/amendment_20_ratification/evidence_freeze/missing_reason_rule_set_identity.json","docs/analysis/amendment_20_ratification/evidence_freeze/missing_reason_successor_relation_identity.json","docs/analysis/amendment_20_ratification/evidence_freeze/missing_representation_bridge_identity.json"],"pass_identity_names":["missing_reason_rule_set_identity","missing_reason_successor_relation_identity","missing_representation_bridge_identity"],"pass_status":"pass"},"prompt_field_semantic_binding_status":{"failure_shadow_identity_name":"prompt_field_semantic_failure_shadow_identity","failure_status":"fail_permanent_prompt_field_or_semantic_binding_residue","forbidden_output_paths":["docs/analysis/amendment_20_ratification/evidence_freeze/prompt_field_evidence_identity.json","docs/analysis/amendment_20_ratification/evidence_freeze/prompt_field_candidate_set_identity.json","docs/analysis/amendment_20_ratification/evidence_freeze/zero_candidate_positive_group_identity.json","docs/analysis/amendment_20_ratification/evidence_freeze/semantic_binding_identity.json"],"pass_identity_names":["prompt_field_evidence_identity","prompt_field_candidate_set_identity","zero_candidate_positive_group_identity","semantic_binding_identity"],"pass_status":"pass"},"purpose_authority_status":{"failure_shadow_identity_name":"purpose_failure_shadow_identity","failure_status":"fail_permanent_purpose_authority_residue","forbidden_output_paths":["docs/analysis/amendment_20_ratification/evidence_freeze/purpose_rule_set_identity.json","docs/analysis/amendment_20_ratification/evidence_freeze/purpose_authority_mapping_identity.json"],"pass_identity_names":["purpose_rule_set_identity","purpose_authority_mapping_identity"],"pass_status":"pass"}},"arm_pass_identity_keys":["identity_name","arm_status_member","arm_status","row_count","ordered_keyset_sha256","row_domain_sha256","status"],"common_identity_names":["physical_source_identity","evidence_statement_identity","missing_reason_source_domain_identity","purpose_source_domain_identity","a20_successor_source_binding_identity","r04_q5_shape_identity","r06_six_module_identity","r06_collected_node_id_identity","dormant_lifecycle_definition_identity"],"failure_nonemission_evidence_keys":["execution_commit","execution_tree_oid","repository_manifest_rows_before","repository_manifest_sha256_before","repository_manifest_rows_after","repository_manifest_sha256_after","repository_clean_before","repository_clean_after","forbidden_outputs_absent_after_execution"],"failure_shadow_identity_keys":["schema_version","identity_name","arm_status_member","arm_status","shadow_row_count","shadow_ordered_keyset_sha256","shadow_row_domain_sha256","complement_identity","forbidden_output_identity_names","forbidden_output_paths","nonemission_evidence","status"],"failure_shadow_paths_are_exact_arm_contract_paths":true,"failure_shadow_rows_are_exact_forbidden_output_complement":true,"lifecycle_booleans_are_not_accepted_as_self_attestation":true,"nonemission_complement_identity_keys":["schema_version","complement_of_identity_names","row_count","ordered_keyset_sha256","row_domain_sha256","status"],"pass_identity_keys":["identity_name","row_count","ordered_keyset_sha256","row_domain_sha256","status"],"repository_manifest_row_keys":["path","mode","git_blob","byte_size","raw_sha256"],"successor_binding_digest_excludes_self":true,"successor_binding_identity_keys":["identity_name","row_count","ordered_keyset_sha256","row_domain_sha256","arm_status_bindings","active_identity_bindings_sha256","status"],"successor_binding_identity_name":"a20_successor_source_binding_identity"},"object":{"amendment20_evidence_freeze_status":"not_instantiated_a4_required_before_ratify","amendment20_ratification_ready":false,"expected_identity_bindings":{"a20_successor_source_binding_identity":null,"dormant_lifecycle_definition_identity":null,"evidence_statement_identity":null,"missing_reason_failure_shadow_identity":null,"missing_reason_rule_set_identity":null,"missing_reason_source_domain_identity":null,"missing_reason_successor_relation_identity":null,"missing_representation_bridge_identity":null,"physical_source_identity":null,"prompt_field_candidate_set_identity":null,"prompt_field_evidence_identity":null,"prompt_field_semantic_failure_shadow_identity":null,"purpose_authority_mapping_identity":null,"purpose_failure_shadow_identity":null,"purpose_rule_set_identity":null,"purpose_source_domain_identity":null,"r04_q5_shape_identity":null,"r06_collected_node_id_identity":null,"r06_six_module_identity":null,"semantic_binding_identity":null,"zero_candidate_positive_group_identity":null},"missing_reason_authority_status":null,"prompt_field_semantic_binding_status":null,"purpose_authority_status":null,"schema_version":"a20_evidence_freeze.v1"},"r04_or_later_permitted":false,"ratification_readiness_iff_freeze_shape_statuses_and_identities":true,"semantic_arm_pass_required_for_ratification":false},"inherited_mutation_censuses":[{"count":100,"inventory":"inherited_complete_certificate","raw_sha256":"fe2efd7b96c24b7cbd3c6ce350d44906eb5a88b8b35ee77565c1b133cbf1f3e3"},{"count":7,"inventory":"amendment16","raw_sha256":"1e00099f636c1a727839ebc298b965cd0981e0ad8f23189367ba7dbd0eddb871"},{"count":3,"inventory":"amendment17","raw_sha256":"b19ebcbf47278d63e12bd8021334a88910895bdfe48caf2d49c6bbe3014417e6"},{"count":3,"inventory":"amendment18","raw_sha256":"1bf9f6d30461d003cab597a405cb5cc9855273372ed3e7e5b36b1627eaa11108"},{"count":3,"inventory":"amendment19","raw_sha256":"002aa021325c18e311cc778562ad0e937468a90c378db0740290fcf617929101"}],"missing_reason_authority":{"agreeing_duplicate_rules_abort":true,"authority_rule_row_keys":["authority_rule_id","registered_evidence_source_ids","registered_statement_ids","rule_kind","exact_scope_predicate","explicit_exclusions","strict_boolean_disposition","projected_occurrence_count","projected_occurrence_keyset_sha256","overlap_conflict_complement_results"],"candidate_defaults_forbidden":true,"claim_type":"strict_json_boolean_excluding_integer_coercion","conflict_precedes_incomplete_coverage":true,"formerly_unresolved_literal_occurrence_count":524538,"historical_a11_and_a18_results_preserved":true,"independent_compiler_count":2,"inherited_source_authorized_literal_count":52,"missing_false_reason":null,"missing_true_reason_id_prefix":"psid-source-missing-reason:","numeric_range_reason":null,"numeric_structural_null_range_count":37283,"occurrence_identity_position_order":["schema_tag","global_member_position","source_document_position","source_row_position","entry_position","source_document_id","codebook_field_row_id","ordered_nonempty_locator_id_array","entry_reference","entry_kind","exact_source_value_or_range_lexeme","exact_nonempty_source_meaning"],"projection_requirements":["exact","nonzero","disjoint","collectively_exhaustive","exception_complete"],"representation_bridge_probe":{"accepted_bridge_identity":null,"bridge_required_before_acceptance":true,"diagnostic_shadow_observation":59424,"direct_field_ceiling_observation":54898,"gross_source_era_ceiling_observation":71635,"observations_are_nonauthority":true,"relation":"missing_representation_bridge_rows","u24_e2_93md_claims_accepted":0,"zero_projection_observation":87},"transactional_atomic_nonemission":true},"mutation_domain_byte_size":738,"mutation_domain_sha256":"eab546538a26abac04f559b73646bbca9d240832ae9d9ee82c6295a1462d0e2b","mutation_inventory":["shared_source_domain_or_statement_locator_forged","missing_reason_rule_or_exact_cover_forged","purpose_authority_or_totality_forged","prompt_field_or_semantic_binding_forged","r04_order_source_binding_or_q5_shape_forged","r06_collection_or_lifecycle_order_forged","receipt_verdict_or_scratch_transition_forged","amendment20_terminal_pin_or_suffix_route_forged","evidence_freeze_identity_shadow_or_status_forged","failure_shadow_nonemission_provenance_forged","determined_as_source_underdetermined_without_ruling_forged","source_underdetermined_as_no_applicable_purpose_forged","source_underdetermined_a4_census_binding_forged","completed_ontology_new_arm_omitted","coordinate_distinct_questionnaire_spans_collapsed_to_one_body_forged"],"new_identifiers":{"identity_prefix":["psid-prompt-field-evidence:","psid-prompt-field-candidate-set:","psid-zero-candidate-positive-group:","a20-lifecycle-output:"],"member":["amendment20_evidence_freeze","amendment20_evidence_freeze_status","missing_reason_authority_status","purpose_authority_status","prompt_field_semantic_binding_status","expected_identity_bindings","amendment20_ratification_ready","missing_reason_failure_shadow_identity","purpose_failure_shadow_identity","prompt_field_semantic_failure_shadow_identity","arm_status_bindings","active_identity_bindings_sha256","arm_status_member","arm_status","shadow_row_count","shadow_ordered_keyset_sha256","shadow_row_domain_sha256","complement_identity","complement_of_identity_names","forbidden_output_identity_names","forbidden_output_paths","nonemission_evidence","repository_manifest_rows_before","repository_manifest_rows_after","forbidden_outputs_absent_after_execution","a20_successor_source_binding_identity","missing_reason_source_domain_identity","purpose_source_domain_identity","missing_reason_rule_set_identity","purpose_rule_set_identity","prompt_field_evidence_identity","semantic_binding_identity","purpose_authority_mapping_row_count","purpose_authority_mapping_keyset_sha256","purpose_authority_mapping_domain_sha256","purpose_authority_mapping_disposition_counts","prompt_field_evidence_row_count","prompt_field_evidence_keyset_sha256","prompt_field_evidence_domain_sha256","prompt_field_evidence_disposition_counts","prompt_field_candidate_set_row_count","prompt_field_candidate_set_keyset_sha256","prompt_field_candidate_set_domain_sha256","prompt_field_candidate_set_disposition_counts","zero_candidate_positive_group_row_count","zero_candidate_positive_group_keyset_sha256","zero_candidate_positive_group_domain_sha256","zero_candidate_positive_group_empty_union_count","purpose_authority_mapping_rows","prompt_field_evidence_rows","prompt_field_candidate_set_rows","zero_candidate_positive_group_rows","SIMULATED_STATE_AUTHORITY","SIMULATION_CONTEXT","candidate_commit_identity","scratch_transition","changed_paths","changed_path_domain_sha256"],"python":["_validate_amendment20_draft_design","_validate_amendment20_ratification_design","_validate_inherited_amendment20_ratification_design","_validate_amendment20_evidence_freeze","_canonical_amendment20_repository_path","_read_amendment20_worktree_file","_reconstruct_amendment20_repository_manifest","_validate_amendment20_nonemission_evidence","_parse_amendment20_implementation_pins","_parse_amendment20_projection","run_amendment20_contract_mutation_tests","validate_amendment20_qualifying_verdict","_validate_amendment20_scratch_transition_context","_amendment20_registry_behavior_ast","_parse_amendment20_scratch_registry_binding","_validate_amendment20_transition_receipt","_validate_amendment20_r06_collection_binding"],"schema":["amendment_20_dual_authority_successor_law.v1","executed_transition_state.v2","a20_evidence_freeze.v1","a20_failure_shadow_identity.v1","a20_nonemission_complement_identity.v1","a20_physical_source_registry.v1","a20_evidence_statement_registry.v1","a20_missing_reason_source_domain.v1","a20_purpose_source_domain.v1","a20_successor_source_binding.v1","a20_missing_reason_authority_rules.v1","a20_missing_reason_successor_relation.v1","a20_missing_representation_bridge.v1","a20_purpose_authority_rules.v1","a20_purpose_authority_mapping.v1","a20_prompt_field_evidence.v1","a20_prompt_field_candidate_sets.v1","a20_zero_candidate_positive_groups.v1","a20_source_settlement.v1","a20_normal_r04.v1","a20_r05_certificate.v1","a20_historical_r06_binding.v1","a20_classifier_rebuild.v1","a20_terminal_movement.v1","a20_assignment_rebuild.v1","a20_logical_range_rebuild.v1","a20_storage_population_rebuild.v1","a20_constructibility.v1","a20_full_relation_identity.v1","a20_comparator_census.v1","a20_q5.v1","a20_slot_rebuild.v1","a20_inventory_rebuild.v1","a20_g17_c01_rebuild.v1","a20_vb6_successor.v1","a20_successor_bundles.v1","a20_migrations.v1","a20_capture.v1","a20_receipt.v1","a20_registration.v1","a20_sealed_run.v1","a20_wall_ledger.v1","a20_publication.v1"],"status_lifecycle_authority":["not_instantiated_a4_required_before_ratify","pass_a4_exact_freeze","fail_permanent_missing_reason_authority_residue","fail_permanent_purpose_authority_residue","fail_permanent_prompt_field_or_semantic_binding_residue","dormant_definition","blocked_predecessor","fail_atomic_nonemission","accepted_exact_source_identifier","accepted_expressly_admitted_official_alias","unresolved_multiple","zero_candidates","one_candidate","multiple_candidates","complete_nonempty_reference_union","fail_empty_reference_union","SIMULATED_NONAUTHORITY","pending_same_state_execution","amendment20_same_state_nonauthority_v1","REVISION22_REGISTRY_REPIN","A20_SOURCE_RELATIONS_SETTLED_DISPATCH_DISABLED","A20_NORMAL_R04_REQUIRED","A20_R05_REQUIRED","A20_HISTORICAL_R06_REQUIRED","A20_MISSING_REASON_SUCCESSOR_ACTIVE","A20_CLASSIFIER_REBUILD_REQUIRED","A20_TERMINAL_MOVEMENT_REQUIRED","A20_ASSIGNMENT_REBUILD_REQUIRED","A20_LOGICAL_RANGE_REBUILD_REQUIRED","A20_STORAGE_POPULATION_REBUILD_REQUIRED","A20_CONSTRUCTIBILITY_REQUIRED","A20_FULL_RELATION_IDENTITY_REQUIRED","A20_COMPARATOR_REQUIRED","A20_Q5_REQUIRED","A20_SLOT_REBUILD_REQUIRED","A20_INVENTORY_REBUILD_REQUIRED","A20_G17_C01_REBUILD_REQUIRED","A20_VB6_REQUIRED","A20_SUCCESSOR_BUNDLES_REQUIRED","A20_MIGRATIONS_REQUIRED","A20_CAPTURE_REQUIRED","A20_RECEIPT_REQUIRED","A20_REGISTRATION_REQUIRED","A20_SEALED_RUN_REQUIRED","A20_WALL_LEDGER_REQUIRED","A20_PUBLICATION_REQUIRED","A20_SUCCESSOR_LIFECYCLE_COMPLETE"]},"prefix_identity":{"blob_oid":"1eba7ff6366bad1999de36c9f7261ad6939ad86a","byte_size":4025587,"raw_sha256":"38139b8ddd24ef7be09e8f149960e8e0b6e39699d84f3783827eff6c294a9ae9"},"prompt_field_semantic_binding":{"attachment_dispositions":["accepted_exact_source_identifier","accepted_expressly_admitted_official_alias","unresolved_multiple"],"binding_built_before_candidate_rows_read":true,"c68_regression":{"candidate_raw_field_ids":["V11804","V11805"],"draft_disposition":"unresolved_multiple","interview_wave":1985,"printed_direct_field_id":"V11804","question_token":"C68.","source_prompt_occurrence_id":"psid-questionnaire-occurrence:4cd66190a898d568dd20c27140f44f1dff53d229f664f537722624d00c9b4b67"},"candidate_arrays_complete_stable_unique_source_order":true,"candidate_count_is_raw_field_array_length_strict_integer":true,"candidate_disposition_is_iff_count_partition":true,"candidate_set_id_is_sha256_of_canonical_remaining_members":true,"candidate_set_row_ids_and_prompt_ids_unique":true,"candidate_sets_materialized":true,"collision_census":{"complete_official_prompt_count":818,"domain":"historical_same_coordinate_leading_question_token_conflicts","multiple_count":46},"complete_official_prompt_candidate_census":{"additional_noncollision_candidate_sets":[{"candidate_raw_field_ids":["V3585","V3586"],"interview_wave":1974},{"candidate_raw_field_ids":["V11649","V11648"],"interview_wave":1985},{"candidate_raw_field_ids":["V11616","V11676"],"interview_wave":1985}],"complete_official_prompt_count":818,"domain":"prompt_level_stable_unique_complete_candidate_union","multiple_count":49},"construction_stage":"before_O_P","coordinate_distinct_span_collapse_aborts":true,"coordinate_distinct_spans_must_have_distinct_row_bodies":true,"direct_identifier_priority_forbidden":true,"empty_reference_union_is_strict_boolean_zero_length_equality":true,"exact_duplicate_evidence_emission_aborts":true,"full_prompt_candidate_census":{"domain":"multiple_candidates_over_full_prompt_denominator","multiple_count":2349,"prompt_count":21971},"joint_support_and_subsumption_maximality_required":true,"mandatory_ambiguity_regressions":["Family","Dl7./D17.","D2."],"positive_attachment_bases":["exact_source_identifier","expressly_admitted_official_alias"],"post_o_p_exact_token_joins_without_silent_unions":true,"post_o_p_relations":["occurrence_raw_field_reference_rows","positive_field_join_rows","nonempty_reference_and_raw_field_projections","unique_same_wave_attachment","purpose_expansion","reverse_covers"],"post_o_p_relations_use_completed_purpose_ontology":true,"prompt_field_candidate_set_dispositions":["zero_candidates","one_candidate","multiple_candidates"],"prompt_field_candidate_set_id_prefix":"psid-prompt-field-candidate-set:","prompt_field_candidate_set_id_preimage":["source_prompt_occurrence_id","interview_wave","candidate_prompt_field_evidence_ids","candidate_raw_field_ids","candidate_count","candidate_disposition"],"prompt_field_candidate_set_order":"complete_prompt_source_order","prompt_field_candidate_set_row_keys":["prompt_field_candidate_set_id","source_prompt_occurrence_id","interview_wave","candidate_prompt_field_evidence_ids","candidate_raw_field_ids","candidate_count","candidate_disposition"],"prompt_field_evidence_id_canonicalization":"python-json-sort-keys-compact-ascii-no-nan-lf-v1","prompt_field_evidence_id_prefix":"psid-prompt-field-evidence:","prompt_field_evidence_id_preimage":["source_prompt_occurrence_id","interview_wave","questionnaire_span","prompt_source_locator_ids","field_source_document_id","field_source_row_id","field_source_member","raw_field_id","attachment_basis","official_alias_statement_ids","attachment_disposition","candidate_raw_field_ids"],"prompt_field_evidence_order":["complete_prompt_source_position","interview_wave","source_prompt_occurrence_id","questionnaire_span.utf8_byte_start","questionnaire_span.utf8_byte_end","attachment_branch_direct_before_question_token","field_reconstruction_document_row_member_order"],"prompt_field_row_keys":["prompt_field_evidence_id","source_prompt_occurrence_id","interview_wave","questionnaire_span","prompt_source_locator_ids","field_source_document_id","field_source_row_id","field_source_member","raw_field_id","attachment_basis","official_alias_statement_ids","attachment_disposition","candidate_raw_field_ids"],"questionnaire_span_basis":"prompt_source_utf8_byte_half_open_interval","questionnaire_span_bounds_strict_integers_excluding_booleans":true,"questionnaire_span_keys":["utf8_byte_start","utf8_byte_end"],"questionnaire_span_minimal_exact_identifier_token_match":true,"questionnaire_span_requires_0_le_start_lt_end_le_prompt_byte_length":true,"required_unresolved_semantic_binding_count":0,"semantic_binding_coordinates":["role","job_slot_id","questionnaire_component_slot_id","slot_kind","field_purpose"],"semantic_binding_dispositions":["semantically_bound","no_supported_predicate_dimension","unresolved_semantic_binding"],"semantic_binding_identity_requires_deep_equality":["row_count","ordered_keyset_sha256","row_domain_sha256"],"semantic_binding_serialization":"near_match_source_annotation_rows","separate_semantic_binding_rows_serialization_permitted":false,"zero_candidate_group_disposition_is_iff_empty_boolean":true,"zero_candidate_group_id_is_sha256_of_canonical_remaining_members":true,"zero_candidate_group_ids_and_positive_ids_unique":true,"zero_candidate_group_one_per_qualifying_positive_occurrence":true,"zero_candidate_grouping_probe":{"accepted_attachment_required_for_codebook_supported_rule":true,"accepted_positive_group_with_empty_reference_union_count":null,"candidate_set_prompt_count":21971,"diagnostic_zero_candidate_observation":14450,"difference_explained":false,"observations_are_nonauthority":true,"sweep_zero_candidate_observation":15428},"zero_candidate_positive_group_dispositions":["complete_nonempty_reference_union","fail_empty_reference_union"],"zero_candidate_positive_group_id_prefix":"psid-zero-candidate-positive-group:","zero_candidate_positive_group_id_preimage":["positive_occurrence_id","zero_candidate_source_prompt_occurrence_ids","all_source_prompt_occurrence_ids","complete_reference_union_ids","empty_reference_union","group_disposition"],"zero_candidate_positive_group_order":"positive_occurrence_order","zero_candidate_positive_group_row_keys":["zero_candidate_positive_group_id","positive_occurrence_id","zero_candidate_source_prompt_occurrence_ids","all_source_prompt_occurrence_ids","complete_reference_union_ids","empty_reference_union","group_disposition"],"zero_candidate_prompt_arrays_complete_positive_row_projections":true,"zero_candidate_reference_union_complete_stable_unique":true,"zero_or_multiple_candidates_fail_without_source_resolution":true},"purpose_authority":{"authority_gate_uses_reconciled_outcomes":true,"completed_ontology_order":["interview_and_role_attachment","amount","reporting_unit","month_or_exposure","assignment","employee_self_or_mixed","incorporation","government_level","industry","occupation","enrollment","job_identifier","state_of_residence","section_218_group","section_218_position","public_retirement_system_participation","federal_retirement_system","federal_service","railroad_covered_employer","railroad_covered_service","ministerial_service","clergy_remuneration","church_employee_service","religious_order_service","clergy_or_religious_exemption","domestic_service","agricultural_service","election_work","family_service","casual_service","foreign_government_service","international_organization_service","nonresident_alien_status","employer_school_nexus","statutory_student_service","source_underdetermined"],"disposition_relation_total_under_completed_ontology":true,"exact_prompt_cover_and_zero_gap_extra_duplicate_overlap_conflict":true,"exact_row_agreement_is_authority_gate":false,"independent_compiler_count":2,"inherited_complete_rows_requiring_source_regrounding":818,"macro_per_prompt_jaccard_minimum_calibration_diagnostic":"90%","manual_origin_grandfathering_permitted":false,"official_purpose_order":["interview_and_role_attachment","amount","reporting_unit","month_or_exposure","assignment","employee_self_or_mixed","incorporation","government_level","industry","occupation","enrollment","job_identifier","state_of_residence","section_218_group","section_218_position","public_retirement_system_participation","federal_retirement_system","federal_service","railroad_covered_employer","railroad_covered_service","ministerial_service","clergy_remuneration","church_employee_service","religious_order_service","clergy_or_religious_exemption","domestic_service","agricultural_service","election_work","family_service","casual_service","foreign_government_service","international_organization_service","nonresident_alien_status","employer_school_nexus","statutory_student_service"],"prompt_denominator_a4_freeze_slot":null,"purpose_arrays_nonempty_stable_unique_in_official_order":true,"purpose_authority_rule_row_keys":["purpose_authority_source_id","rule_kind","registered_evidence_statement_ids","exact_prompt_scope_predicate","explicit_exclusions","explicit_official_purposes","projected_prompt_count","projected_prompt_keyset_sha256"],"purpose_mapping_row_keys":["source_prompt_occurrence_id","authority_basis","purpose_authority_source_id","evidence_statement_ids","explicit_official_purposes","purpose_mapping_disposition","reconciled_adjudication_ruling_id"],"required_disposition_counts":{"U":0,"complete_official_mapping":null,"source_underdetermined":null},"source_backed_alternative_selected":"ontology_projection","source_backed_alternatives":["occurrence_kind_or_denominator_correction","ontology_projection","separately_tagged_no_applicable_purpose_arm"],"source_classification_row_id_overload_forbidden":true,"source_conflict_reopens_row":true,"source_underdetermined_count_a4_freeze_slot":null,"source_underdetermined_is_no_applicable_purpose":false,"source_underdetermined_means_authenticated_sources_determine_no_nonempty_subset":true,"source_underdetermined_requires_reconciled_adjudication_ruling":true,"source_underdetermined_uses_determined_row_provenance_authentication":true,"transactional_atomic_nonemission":true,"u_definition":"prompt_without_lawful_completed_ontology_disposition"},"r04_q5":{"a19_digest_dependency_order_preserved":["D0","search_implementation","A_h","final_rows","D1"],"a19_purpose_mapping_is_historical_nonconsumable_on_a20_normal_path":true,"construction_order":["authenticate_fixed_historical_denominators_and_a20_source_domains","construct_and_seal_missing_purpose_rules_and_successor_binding","compile_purpose_prompt_field_and_semantic_inputs","compute_purpose_U_and_independent_acceptance_results","select_failure_or_normal_member","normal_only_construct_H_and_source_only_O_H","normal_only_require_O_H_before_O_P","normal_only_construct_O_P_bindings_joins_covers_expansion_D0_search_D1_and_R04","normal_only_R05_strict_certificate_and_dual_reconstruction"],"failure_arms_serialize_a20_shape_additions":false,"forbidden_selected_failure_member_serialization":["questionnaire_occurrence_rows","all_pass_only_arrays","Q5","R05_certificate","authority","production_output"],"g17_c01_expected_and_actual_shapes_equal":true,"historical_a19_failure_member_byte_size":877,"historical_a19_failure_member_raw_sha256":"1651c50ff1f171ac420e55982cb060db70946f9283999c3d9edb2fa140d467c5","inherited_semantic_relation_member":"near_match_source_annotation_rows","inherited_semantic_relation_position":"after_expanded_disposition_rows","normal_effective_header_insert_before":"positive_occurrence_row_count","normal_effective_header_successor_members":["purpose_authority_mapping_row_count","purpose_authority_mapping_keyset_sha256","purpose_authority_mapping_domain_sha256","purpose_authority_mapping_disposition_counts","prompt_field_evidence_row_count","prompt_field_evidence_keyset_sha256","prompt_field_evidence_domain_sha256","prompt_field_evidence_disposition_counts","prompt_field_candidate_set_row_count","prompt_field_candidate_set_keyset_sha256","prompt_field_candidate_set_domain_sha256","prompt_field_candidate_set_disposition_counts","zero_candidate_positive_group_row_count","zero_candidate_positive_group_keyset_sha256","zero_candidate_positive_group_domain_sha256","zero_candidate_positive_group_empty_union_count"],"normal_era_successor_sequence":["hierarchy_rows","purpose_authority_mapping_rows","prompt_field_evidence_rows","prompt_field_candidate_set_rows","zero_candidate_positive_group_rows","positive_occurrence_rows"],"o_h_precedes_o_p_on_normal_arm":true,"o_h_source_only":true,"o_p_order":["interview_and_role_attachment","amount","reporting_unit","month_or_exposure","assignment","employee_self_or_mixed","incorporation","government_level","industry","occupation","enrollment","job_identifier","state_of_residence","section_218_group","section_218_position","public_retirement_system_participation","federal_retirement_system","federal_service","railroad_covered_employer","railroad_covered_service","ministerial_service","clergy_remuneration","church_employee_service","religious_order_service","clergy_or_religious_exemption","domestic_service","agricultural_service","election_work","family_service","casual_service","foreign_government_service","international_organization_service","nonresident_alien_status","employer_school_nexus","statutory_student_service","source_underdetermined"],"per_era_rows_use_direct_era_order_concatenation":true,"permitted_selector_input_reads":["questionnaire_occurrence_rows","fixed_prompt_denominator","purpose_authority_mapping_rows","prompt_field_candidate_set_rows","selector_inputs"],"purpose_expansion_domain":"completed_purpose_ontology","purpose_rule_projection_domain":"completed_purpose_ontology","purpose_totality_alone_passes_r04":false,"replaced_a19_effective_header_members":["purpose_mapping_row_count","purpose_mapping_keyset_sha256","purpose_mapping_domain_sha256","purpose_mapping_disposition_counts"],"replaced_a19_era_sequence":["hierarchy_rows","purpose_mapping_rows","positive_occurrence_rows"],"selector_purpose_domain":"completed_purpose_ontology","source_document_manifest_additions":["a20_successor_source_binding_identity","missing_reason_source_domain_identity","purpose_source_domain_identity","missing_reason_rule_set_identity","purpose_rule_set_identity","prompt_field_evidence_identity","semantic_binding_identity"],"source_document_manifest_insert_after":"source_document_domain_sha256"},"r06_lifecycle":{"ambient_pytest_addopts_removed":true,"blocked_predecessor_output_identity":null,"collected_node_id_array_canonical_byte_size":28268,"collected_node_id_array_raw_sha256":"09071bf4d9a9a5ee8b9ccc4d8d5c0bd91705c04d3c7c99d6ef155dfdc0dfdf05","collected_node_id_count":223,"collection_command_after_interpreter":["-m","pytest","--collect-only","-q","tests/data/test_psid_codebook_extraction_validation.py","tests/data/test_psid_missing_reason_authority_artifact.py","tests/data/test_psid_missing_reason_authority_unit.py","tests/estimates/test_birth_evidence_artifact.py","tests/test_rebuild_amendment11_missing_reason_authority.py","tests/test_replay_amendment11_no_movement.py"],"dormant_definition_before_certification_permitted":true,"dormant_definition_creates_instance_or_selection":false,"dormant_lifecycle_row_count":26,"dormant_lifecycle_rows":[{"first_add_index":1,"input_identity_ids":["revision22_registry_repin_identity","a20_successor_source_binding_identity","dormant_lifecycle_definition_identity"],"lifecycle_stage_id":"A20_SOURCE_RELATIONS_SETTLED_DISPATCH_DISABLED","output_identity_id":null,"predecessor_stage_ids":["REVISION22_REGISTRY_REPIN"],"schema_id":"a20_source_settlement.v1","selection_enabled":false,"status":"dormant_definition"},{"first_add_index":2,"input_identity_ids":["a20_source_settlement_identity","historical_a19_build_input_identity"],"lifecycle_stage_id":"A20_NORMAL_R04_REQUIRED","output_identity_id":null,"predecessor_stage_ids":["A20_SOURCE_RELATIONS_SETTLED_DISPATCH_DISABLED"],"schema_id":"a20_normal_r04.v1","selection_enabled":false,"status":"dormant_definition"},{"first_add_index":3,"input_identity_ids":["a20_normal_r04_identity"],"lifecycle_stage_id":"A20_R05_REQUIRED","output_identity_id":null,"predecessor_stage_ids":["A20_NORMAL_R04_REQUIRED"],"schema_id":"a20_r05_certificate.v1","selection_enabled":false,"status":"dormant_definition"},{"first_add_index":4,"input_identity_ids":["a20_r05_certificate_identity","r06_six_module_identity","r06_collected_node_id_identity","historical_a11_replay_identity"],"lifecycle_stage_id":"A20_HISTORICAL_R06_REQUIRED","output_identity_id":null,"predecessor_stage_ids":["A20_R05_REQUIRED"],"schema_id":"a20_historical_r06_binding.v1","selection_enabled":false,"status":"dormant_definition"},{"first_add_index":5,"input_identity_ids":["a20_historical_r06_identity","missing_reason_successor_relation_identity"],"lifecycle_stage_id":"A20_MISSING_REASON_SUCCESSOR_ACTIVE","output_identity_id":null,"predecessor_stage_ids":["A20_HISTORICAL_R06_REQUIRED"],"schema_id":"a20_missing_reason_successor_relation.v1","selection_enabled":false,"status":"dormant_definition"},{"first_add_index":6,"input_identity_ids":["a20_active_missing_reason_identity","historical_classifier_input_identity"],"lifecycle_stage_id":"A20_CLASSIFIER_REBUILD_REQUIRED","output_identity_id":null,"predecessor_stage_ids":["A20_MISSING_REASON_SUCCESSOR_ACTIVE"],"schema_id":"a20_classifier_rebuild.v1","selection_enabled":false,"status":"dormant_definition"},{"first_add_index":7,"input_identity_ids":["a20_classifier_rebuild_identity"],"lifecycle_stage_id":"A20_TERMINAL_MOVEMENT_REQUIRED","output_identity_id":null,"predecessor_stage_ids":["A20_CLASSIFIER_REBUILD_REQUIRED"],"schema_id":"a20_terminal_movement.v1","selection_enabled":false,"status":"dormant_definition"},{"first_add_index":8,"input_identity_ids":["a20_terminal_movement_identity"],"lifecycle_stage_id":"A20_ASSIGNMENT_REBUILD_REQUIRED","output_identity_id":null,"predecessor_stage_ids":["A20_TERMINAL_MOVEMENT_REQUIRED"],"schema_id":"a20_assignment_rebuild.v1","selection_enabled":false,"status":"dormant_definition"},{"first_add_index":9,"input_identity_ids":["a20_assignment_rebuild_identity"],"lifecycle_stage_id":"A20_LOGICAL_RANGE_REBUILD_REQUIRED","output_identity_id":null,"predecessor_stage_ids":["A20_ASSIGNMENT_REBUILD_REQUIRED"],"schema_id":"a20_logical_range_rebuild.v1","selection_enabled":false,"status":"dormant_definition"},{"first_add_index":10,"input_identity_ids":["a20_logical_range_rebuild_identity"],"lifecycle_stage_id":"A20_STORAGE_POPULATION_REBUILD_REQUIRED","output_identity_id":null,"predecessor_stage_ids":["A20_LOGICAL_RANGE_REBUILD_REQUIRED"],"schema_id":"a20_storage_population_rebuild.v1","selection_enabled":false,"status":"dormant_definition"},{"first_add_index":11,"input_identity_ids":["a20_storage_population_rebuild_identity"],"lifecycle_stage_id":"A20_CONSTRUCTIBILITY_REQUIRED","output_identity_id":null,"predecessor_stage_ids":["A20_STORAGE_POPULATION_REBUILD_REQUIRED"],"schema_id":"a20_constructibility.v1","selection_enabled":false,"status":"dormant_definition"},{"first_add_index":12,"input_identity_ids":["a20_constructibility_identity"],"lifecycle_stage_id":"A20_FULL_RELATION_IDENTITY_REQUIRED","output_identity_id":null,"predecessor_stage_ids":["A20_CONSTRUCTIBILITY_REQUIRED"],"schema_id":"a20_full_relation_identity.v1","selection_enabled":false,"status":"dormant_definition"},{"first_add_index":13,"input_identity_ids":["a20_full_relation_identity"],"lifecycle_stage_id":"A20_COMPARATOR_REQUIRED","output_identity_id":null,"predecessor_stage_ids":["A20_FULL_RELATION_IDENTITY_REQUIRED"],"schema_id":"a20_comparator_census.v1","selection_enabled":false,"status":"dormant_definition"},{"first_add_index":14,"input_identity_ids":["a20_comparator_census_identity"],"lifecycle_stage_id":"A20_Q5_REQUIRED","output_identity_id":null,"predecessor_stage_ids":["A20_COMPARATOR_REQUIRED"],"schema_id":"a20_q5.v1","selection_enabled":false,"status":"dormant_definition"},{"first_add_index":15,"input_identity_ids":["a20_q5_identity"],"lifecycle_stage_id":"A20_SLOT_REBUILD_REQUIRED","output_identity_id":null,"predecessor_stage_ids":["A20_Q5_REQUIRED"],"schema_id":"a20_slot_rebuild.v1","selection_enabled":false,"status":"dormant_definition"},{"first_add_index":16,"input_identity_ids":["a20_slot_rebuild_identity"],"lifecycle_stage_id":"A20_INVENTORY_REBUILD_REQUIRED","output_identity_id":null,"predecessor_stage_ids":["A20_SLOT_REBUILD_REQUIRED"],"schema_id":"a20_inventory_rebuild.v1","selection_enabled":false,"status":"dormant_definition"},{"first_add_index":17,"input_identity_ids":["a20_inventory_rebuild_identity"],"lifecycle_stage_id":"A20_G17_C01_REBUILD_REQUIRED","output_identity_id":null,"predecessor_stage_ids":["A20_INVENTORY_REBUILD_REQUIRED"],"schema_id":"a20_g17_c01_rebuild.v1","selection_enabled":false,"status":"dormant_definition"},{"first_add_index":18,"input_identity_ids":["a20_g17_c01_rebuild_identity"],"lifecycle_stage_id":"A20_VB6_REQUIRED","output_identity_id":null,"predecessor_stage_ids":["A20_G17_C01_REBUILD_REQUIRED"],"schema_id":"a20_vb6_successor.v1","selection_enabled":false,"status":"dormant_definition"},{"first_add_index":19,"input_identity_ids":["a20_vb6_identity"],"lifecycle_stage_id":"A20_SUCCESSOR_BUNDLES_REQUIRED","output_identity_id":null,"predecessor_stage_ids":["A20_VB6_REQUIRED"],"schema_id":"a20_successor_bundles.v1","selection_enabled":false,"status":"dormant_definition"},{"first_add_index":20,"input_identity_ids":["a20_successor_bundles_identity"],"lifecycle_stage_id":"A20_MIGRATIONS_REQUIRED","output_identity_id":null,"predecessor_stage_ids":["A20_SUCCESSOR_BUNDLES_REQUIRED"],"schema_id":"a20_migrations.v1","selection_enabled":false,"status":"dormant_definition"},{"first_add_index":21,"input_identity_ids":["a20_migrations_identity"],"lifecycle_stage_id":"A20_CAPTURE_REQUIRED","output_identity_id":null,"predecessor_stage_ids":["A20_MIGRATIONS_REQUIRED"],"schema_id":"a20_capture.v1","selection_enabled":false,"status":"dormant_definition"},{"first_add_index":22,"input_identity_ids":["a20_capture_identity"],"lifecycle_stage_id":"A20_RECEIPT_REQUIRED","output_identity_id":null,"predecessor_stage_ids":["A20_CAPTURE_REQUIRED"],"schema_id":"a20_receipt.v1","selection_enabled":false,"status":"dormant_definition"},{"first_add_index":23,"input_identity_ids":["a20_receipt_identity"],"lifecycle_stage_id":"A20_REGISTRATION_REQUIRED","output_identity_id":null,"predecessor_stage_ids":["A20_RECEIPT_REQUIRED"],"schema_id":"a20_registration.v1","selection_enabled":false,"status":"dormant_definition"},{"first_add_index":24,"input_identity_ids":["a20_registration_identity"],"lifecycle_stage_id":"A20_SEALED_RUN_REQUIRED","output_identity_id":null,"predecessor_stage_ids":["A20_REGISTRATION_REQUIRED"],"schema_id":"a20_sealed_run.v1","selection_enabled":false,"status":"dormant_definition"},{"first_add_index":25,"input_identity_ids":["a20_sealed_run_identity"],"lifecycle_stage_id":"A20_WALL_LEDGER_REQUIRED","output_identity_id":null,"predecessor_stage_ids":["A20_SEALED_RUN_REQUIRED"],"schema_id":"a20_wall_ledger.v1","selection_enabled":false,"status":"dormant_definition"},{"first_add_index":26,"input_identity_ids":["a20_wall_ledger_identity"],"lifecycle_stage_id":"A20_PUBLICATION_REQUIRED","output_identity_id":null,"predecessor_stage_ids":["A20_WALL_LEDGER_REQUIRED"],"schema_id":"a20_publication.v1","selection_enabled":false,"status":"dormant_definition"}],"evidence_settlement_before_r06_requires_dispatch_disabled":true,"fail_atomic_nonemission_output_identity":null,"first_collected_node_id":"tests/data/test_psid_codebook_extraction_validation.py::test_exact_nested_derivation_schemas_accept_generated_shapes[_text_derivation]","fresh_recomputation_required":["89599_field_classifier","terminal_movement","assignments_logical_ranges_storage","constructibility_and_full_relation_identity","comparator_census","Q5","slot_inventory_full_G17_C01_and_V_B6","successor_bundles_through_publication"],"historical_r06_result_preserved":{"blocked_literal_count":524538,"exit_code":2,"numeric_range_structural_null_count":37283,"source_authorized_literal_count":52},"historical_zero_movement_assumption_permitted":false,"inherited_git_environment_removed":true,"interpreter_selector":"executing_process_sys.executable","last_collected_node_id":"tests/test_replay_amendment11_no_movement.py::test_reason_mutation_changes_field_source_identity_but_not_terminal","lifecycle_envelope_keys":["lifecycle_stage_id","schema_id","predecessor_stage_ids","input_identity_ids","output_identity_id","first_add_index","selection_enabled","status"],"lifecycle_statuses":["dormant_definition","blocked_predecessor","pass","fail_atomic_nonemission"],"module_path_domain_sha256":"a5099c464482c5b652e31e5dfa958703a4ae4c75c1dc1e4caa03cb2aef408063","output_identity_id_prefix":"a20-lifecycle-output:","output_identity_preimage":["lifecycle_stage_id","schema_id","predecessor_stage_ids","input_identity_ids","exact_output_payload_identity"],"output_identity_preimage_canonicalization":"python-json-sort-keys-compact-ascii-no-nan-lf-v1","revision22_repin_next_required_state":"A20_SOURCE_RELATIONS_SETTLED_DISPATCH_DISABLED","selection_enabled_only_on_passing_first_add_index":5,"selection_first_add_dispatch_requires_r04_r05_r06_order":true,"terminal_next_required_state":"A20_SUCCESSOR_LIFECYCLE_COMPLETE","test_command_after_interpreter":["-m","pytest","tests/data/test_psid_codebook_extraction_validation.py","tests/data/test_psid_missing_reason_authority_artifact.py","tests/data/test_psid_missing_reason_authority_unit.py","tests/estimates/test_birth_evidence_artifact.py","tests/test_rebuild_amendment11_missing_reason_authority.py","tests/test_replay_amendment11_no_movement.py"],"test_environment":{"PYTHONPATH":"src:."},"test_file_identities":[{"byte_size":13718,"git_blob":"7b2f33af3ff6a4e389a944e349aa222f6ca41519","mode":"100644","path":"tests/data/test_psid_codebook_extraction_validation.py","raw_sha256":"7af8a2847b4428fa7376598cc48333d008f225389eee461f3edae58ca624ff67"},{"byte_size":18129,"git_blob":"c8863f4a6a5e915666f0cce2cac4817e73839e9f","mode":"100644","path":"tests/data/test_psid_missing_reason_authority_artifact.py","raw_sha256":"4f425c776ddba30f3b861812cdcbd0abef5b10ae0f41608bcaa6d456c9cdcd85"},{"byte_size":18252,"git_blob":"499aa397f75e1d2f62e7c91a929f9ecdcf71a478","mode":"100644","path":"tests/data/test_psid_missing_reason_authority_unit.py","raw_sha256":"5e9b7cc33fd560ce5c472c6ac146f07a6b7b238003c6e96f715e417679149cda"},{"byte_size":25883,"git_blob":"d4e838a1123d4e07c6f472ff64cfd6c11462f4a8","mode":"100644","path":"tests/estimates/test_birth_evidence_artifact.py","raw_sha256":"70acf9c2f36f9f88a7e5e2c8c7b5825427d6a44cf1926b0a6c0c7cf4bbb7d5d5"},{"byte_size":22828,"git_blob":"632357933ea37c982d18402d249b74147cd80823","mode":"100644","path":"tests/test_rebuild_amendment11_missing_reason_authority.py","raw_sha256":"eedbab9e3ba3eaad19f08d36472b2fbc53cc5dc62b417a3600d5cb4360368dcb"},{"byte_size":19309,"git_blob":"cc4c1c6d65c89ad97feb0b4f04e6c5d2ecd2405f","mode":"100644","path":"tests/test_replay_amendment11_no_movement.py","raw_sha256":"0875ac524e0cd2e7f3cb6e601026b0d2db5b459c6f426fe5182ac08ebaef9ec1"}],"unratified_next_required_state":"A20_SUCCESSOR_PROGRAM_STOP"},"ratification_receipt":{"amendment20_external_receipt_path":"docs/analysis/amendment_20_ratification/executed_transition_receipt_v2.json","candidate_production_registry_identity":{"byte_size":55473,"git_blob":"92a24e3af4358f75cbead00f223837a68c2f9da8","mode":"100644","path":"scripts/covered_earnings_correction_registry.py","raw_sha256":"bd60336e3e388e5ef12f3f204b9bb08938c27be4db57f9e6fca6582aed7efb16"},"current_terminal_registry_cross_binding_required_iff_a20_terminal_revision22":true,"decimal_grammar":"[1-9][0-9]*|[1-9][0-9]{0,2}(,[0-9]{3})+","distinct_verdict_artifact_count":2,"external_receipt_candidate_ancestry_not_required":true,"external_receipt_first_add_precedes_or_equals_closure_first_add":true,"external_receipt_mode":"100644","external_receipt_outside_candidate_and_scratch":true,"external_receipt_strict_canonical_tracked_head_worktree_read":true,"inherited_external_receipt_path_template":"docs/analysis/amendment__ratification/executed_transition_receipt_v2.json","later_amendment_requires_own_exact_receipt_topology_projection":true,"later_revision_authenticates_historical_a20_design_under_30_2_3":true,"lf_only_exactly_one_terminal_lf":true,"public_oracle_validates_projection_verdicts_and_receipt":true,"qualifying_verdict_line_count":8,"qualifying_verdict_lines":["# RATIFY","attested_design_byte_size: ","attested_design_raw_sha256: <64 lowercase hex>","attested_design_blob_oid: <40 lowercase hex>","executed_transition_receipt_byte_size: ","executed_transition_receipt_raw_sha256: <64 lowercase hex>","executed_transition_receipt_schema: executed_transition_state.v2","---"],"receipt_candidate_design_exactly_cross_binds_historical_a20_closure_and_verdicts":true,"receipt_candidate_design_tree_mode_blob_rederived":true,"receipt_is_additional_operativity_condition":false,"receipt_public_result_booleans_not_sufficient":true,"receipt_rederives_synthetic_closure_standins_and_registry_binding":true,"receipt_schema":{"candidate_commit_identity_keys":["commit","tree","sole_parent"],"candidate_or_scratch_HEAD_member_superseded":true,"canonicalization":"ascii_json_sorted_keys_no_insignificant_whitespace_no_nonfinite_values_one_terminal_lf","changed_path_count":4,"changed_path_roles":["simulated_verdict_1","simulated_verdict_2","synthetic_amendment20_closure","scratch_registry_binding"],"closed_without_defaults_or_extra_keys":true,"closure_identity_keys":["path","raw_byte_size","raw_sha256","git_blob"],"expected_changed_path_domain_canonical_byte_size":260,"expected_changed_path_domain_sha256":"5a7912498c4d959fef337f2a1d1cf85a2f254fa29d825d365ccf4fe214ad48a7","expected_changed_paths":["docs/analysis/amendment_20_ratification/sol-ce-amend20-sim-r1-verdict.md","docs/analysis/amendment_20_ratification/sol-ce-amend20-sim-r2-verdict.md","docs/analysis/amendment_20_ratification/closure_v1.json","scripts/covered_earnings_correction_registry.py"],"full_pinned_battery_keys":["executed","exit_code","test_path","test_mode_blob_bytes_sha256","exact_command","collected","passed","failed","skipped","deselected","xfailed","xpassed","simulated_state_identity_sha256"],"integer_fields":["public_oracle.exit_code","full_pinned_battery.exit_code","full_pinned_battery.collected","full_pinned_battery.passed","full_pinned_battery.failed","full_pinned_battery.skipped","full_pinned_battery.deselected","full_pinned_battery.xfailed","full_pinned_battery.xpassed"],"manifest_authority":"NONAUTHORITY","manifest_keys":["schema_version","simulated_state_authority","candidate_commit_identity","scratch_transition","terminal_revision","canonical_registry_binding","ordered_closure_identities","full_pinned_battery_test_identity"],"manifest_schema_version":"executed_transition_state.v2","nested_state_identities_equal_top_level":true,"public_oracle_keys":["entrypoint","executed","exit_code","operative_amendments","simulated_state_identity_sha256"],"scratch_sole_parent_equals_candidate_commit":true,"scratch_transition_keys":["commit","tree","sole_parent","changed_paths","changed_path_domain_sha256"],"test_identity_keys":["path","mode","git_blob","raw_byte_size","raw_sha256"],"top_level_keys":["simulated_state_authority","simulated_state_identity_sha256","simulated_state_manifest","terminal_revision","public_oracle","full_pinned_battery"]},"same_candidate_triple_and_receipt_pair_required":true,"scratch":{"allowed_changed_paths":["docs/analysis/amendment_20_ratification/sol-ce-amend20-sim-r1-verdict.md","docs/analysis/amendment_20_ratification/sol-ce-amend20-sim-r2-verdict.md","docs/analysis/amendment_20_ratification/closure_v1.json","scripts/covered_earnings_correction_registry.py"],"candidate_commit_symbol":"C","ordered_closure_domain":[13,14,15,16,17,18,19,20],"scratch_commit_symbol":"S","scratch_is_strict_child_of_candidate":true,"standin_is_nonauthority_nonmergeable_noncopyable_nonreusable":true,"standin_is_qualifying_verdict":false,"standin_prefix_line_count":4,"standin_terminal_lines":["executed_transition_receipt_status: pending_same_state_execution","simulation_context: amendment20_same_state_nonauthority_v1","---"],"terminal_revision":22},"scratch_commit_forbidden_as_production_ancestor":true,"strict_utf8_no_bom_nul_cr":true},"schema_version":"amendment_20_dual_authority_successor_law.v1","source_infrastructure":{"current_url_or_latest_edition_substitution_forbidden":true,"domains_authenticate_foreign_keys_independently":true,"evidence_statement_row_keys":["evidence_statement_id","evidence_source_id","page_or_section_locator","utf8_byte_start","utf8_byte_end","exact_statement_raw_sha256","extraction_tool_identity","recovery_provenance_id"],"historical_domains_preserved":{"a11_source_count":47,"a19_build_input_repair_seal_count":22,"a19_build_input_row_count":279,"a19_build_input_source_document_count":257,"questionnaire_document_count":81},"included_and_excluded_counts_sum_to_physical_count":true,"inclusion_exclusion_complete_and_disjoint":true,"independent_reconstructor_count":2,"machine_local_absolute_paths_forbidden":true,"mixed_semantic_payload_or_shared_accepted_digest_aborts_both":true,"path_rule":"repository_relative_canonical_traversal_free","physical_relation":"a20_physical_source_rows","physical_source_row_keys":["evidence_source_id","upstream_capture_or_registry_identity","document_role","release_or_wave","representation","official_url","canonical_local_path","storage_identity","byte_size","raw_sha256","access_disposition","licensing_disposition","statement_locator_ids","extraction_tool_identity","recovered_source_provenance"],"reconstructors_require_count_order_keyset_rows_and_digest_equality":true,"semantic_domain_identity_keys":["domain_id","domain_version","included_source_rows","included_source_count","included_source_keyset_sha256","included_source_domain_sha256","excluded_source_rows","excluded_source_count","excluded_source_keyset_sha256","excluded_source_domain_sha256","admitted_statement_rows","statement_count","statement_keyset_sha256","statement_domain_sha256","status"],"semantic_domain_order":["missing_reason_source_domain","purpose_source_domain"],"semantic_domains":{"missing_reason_source_domain":{"domain_id":"missing_reason_source_domain","expected_identity":null,"required_final_status":"pass"},"purpose_source_domain":{"domain_id":"purpose_source_domain","expected_identity":null,"required_final_status":"pass"}},"shared_physical_bytes_imply_shared_semantic_admission":false,"statement_relation":"a20_evidence_statement_rows","successor_source_binding_expected_identity":null,"successor_source_binding_keys":["historical_a19_build_input_identity","physical_source_identity","evidence_statement_identity","missing_reason_source_domain_identity","purpose_source_domain_identity","missing_reason_authority_status","purpose_authority_status","prompt_field_semantic_binding_status","missing_reason_rule_set_identity","missing_reason_successor_relation_identity","missing_representation_bridge_identity","purpose_rule_set_identity","purpose_authority_mapping_identity","prompt_field_evidence_identity","prompt_field_candidate_set_identity","zero_candidate_positive_group_identity","semantic_binding_identity","r04_q5_shape_identity","missing_reason_failure_shadow_identity","purpose_failure_shadow_identity","prompt_field_semantic_failure_shadow_identity","active_identity_bindings_sha256","canonicalization","status"]},"successor_routing":{"a19_pin_fallback_for_terminal_a20_permitted":false,"a20_pins_selected_before_a19_pins":true,"amendment20_boundary_count":1,"current_production":{"closure_count":7,"ordered_closure_domain":[13,14,15,16,17,18,19],"reject_unratified_a20_suffix":true,"revision":21,"terminal_amendment":19},"immutable_prefix_amendment":19,"immutable_prefix_revision":21,"later_amendment_validates_inherited_a20_projection_first":true,"proposed_revision":22,"terminal_amendment":20,"terminal_successor_state":"A20_SUCCESSOR_LIFECYCLE_COMPLETE"},"supersession_coverage":["19.3.3_prompt_purpose_manifest_era_semantic_and_post_o_p_joins","20.4.2_and_33.2_33.3_33.7_frozen_q5_shapes","19.4.2_26.6.1_26.10.1_g17_header_q5_inventory_slot_projections","25.2_through_25.4_historical_missing_reason_census_and_settlement","25.5_25.10.1_25.10.2_32.4.4_32.7_32.8_33.4_successor_stop","25.6.6_32.4.2_32.4.3_32.7_r06_selector_input_and_result","25.9_25.10_26.10.3_dc71_lifecycle_definition_timing","26.6.3_26.10.1_33.2.2_33.2.3_33.7_construction_order","26.11.2_complete_r04_r05_r06_gate","28.2.1_28.4_verdict_operator_closure_order","29.4.4_29.4.5_source_member_identity_and_reconstruction","29.4.1_canonicalization_and_identity_equations","30.2.3_30.2.4_verdict_checking_and_public_atomic_operativity","30.2.2_five_key_registry_context_and_caller_context_prohibition","30.2.1_amendment_revision_arithmetic","31.3.1_31.3.2_31.3.3_receipt_and_nonexistent_31.5_anchor","32.2.1_32.2.2_33.8_historical_279_build_input_envelope","32.4.4_false_r06_lifecycle_booleans","30.4.1_31.2.2_32.5.1_33.5.1_implementation_pins_and_review","33.2.2_33.2.3_a19_purpose_rows_and_failure_member","33.3.2_d0_search_proof_d1_construction","33.4_obsolete_campaign_pin_and_a20_out_of_scope_label","33.5.2_33.5.3_a19_projection_routing_and_activation","33.6_mutation_inventory_and_inherited_census","33.7_construction_ambiguity_q5_and_reconstruction_rows","33.8_questionnaire_occurrence_read_vs_serialization_scope","33.9_terminal_a19_prospective_effect","20.3_21.3_21.5_22.2_22.5_23.2_23.5_24.2_24.6_algorithms","19.6_19.8_20.7_20.8_21.8_21.9_22.8_22.9_23.8_23.9_24.9_24.10_25.9_25.10_artifacts","27.3_27.6_28.2.2_29.4.7_seals_closures_and_census"]} +~~~ + +### 34.13 Terminal prospective effect + +**Amendment 20 is a prospective, unratified, evidence-incomplete, and +inoperative draft. The operative registry remains revision 21 with exactly +Amendments 13 through 19, and ordinary production loading must reject this +suffix. This draft cures the nine confirmed legal seams, directly closes +seven suspected structural seams, and enacts fail-closed evidence probes for +the zero-candidate grouping and `MD=` representation bridge. It defines but +does not instantiate the complete successor lifecycle. It emits no source +admission, authority rule, settlement, R04/R05/R06 object, Q5, inventory, +production artifact, verdict, receipt, closure, or registry repin. Only a +later exact A4 freeze, one revision-22 same-state demonstration, the external +receipt, two qualifying +affirmative verdicts, lawful operator integration, A20 closure, and real +revision-22 registry repin can activate it. After that activation, X-stage +settlement and every R04/downstream gate execute in §34.7 order and may still +fail closed. A frozen permanent-failure outcome is ratifiable law but never +production readiness. If complete evidence identities cannot be frozen, this +draft remains unratifiable; if the frozen evidence proves permanent residue, +that exact failure controls. Invoking A21 requires the chartered +kill/recharter event.** diff --git a/scripts/validate_amendment13_execution_law.py b/scripts/validate_amendment13_execution_law.py index d55d77f8..5a8f318b 100644 --- a/scripts/validate_amendment13_execution_law.py +++ b/scripts/validate_amendment13_execution_law.py @@ -11,18 +11,20 @@ from __future__ import annotations import argparse +import ast import copy import hashlib import json import os import re +import stat import subprocess import sys import tempfile from collections import Counter, defaultdict from collections.abc import Callable, Mapping, Sequence from functools import lru_cache -from pathlib import Path +from pathlib import Path, PurePosixPath from typing import Any ROOT = Path(__file__).resolve().parents[1] @@ -189,6 +191,15 @@ class LawError(RuntimeError): b"\n## 33. AMENDMENT SECTION \xe2\x80\x94 Amendment 19: source-" b"hierarchy member-construction cure\n" ) +REVISION21_BYTE_SIZE = 4_025_587 +REVISION21_SHA256 = ( + "38139b8ddd24ef7be09e8f149960e8e0b6e39699d84f3783827eff6c294a9ae9" +) +REVISION21_BLOB_OID = "1eba7ff6366bad1999de36c9f7261ad6939ad86a" +AMENDMENT20_BOUNDARY = ( + b"\n## 34. AMENDMENT SECTION \xe2\x80\x94 Amendment 20: dual-authority " + b"covered-earnings correction\n" +) FIRST_CLOSURE_AMENDMENT = 13 HISTORICAL_TERMINAL_REVISION = 16 FORBIDDEN_STANDALONE_REVISION = 17 @@ -2452,74 +2463,1697 @@ class LawError(RuntimeError): }, } -A13_SECTION_SEMANTIC_SHA256: Mapping[str, str] = { - "27.2": "2e1d4e8282e393f2f8f8092c5b9823d69a4e6926fb5fbd753b77813e47f7941e", - "27.3": "50b5a2e780a4b5b7152390e85e01df5f5397f5263fb2dd3dae43947a96f91ff0", - "27.4": "ae7dd9ea588a2242f52d4e66bd3662909eee0f987a1d582db21786837c47253c", - "27.5": "f5ee9246c5826b5b65e90149cc2e2c7574eb32f49df472ce528fc0690ab26d46", - "27.6": "b8b23250e218093d892c6ad286f05226469d5abf08a1f87d8a0942bbbbef5d08", - "27.7": "2dfcffcba99639a6d9b00efc6d0d06364a4c0e2fd522238f07dc715228d8ad2e", - "27.8": "fdc5441ef8c2f60bb8334658b4c44bcd52f8355b4681a495e81c4b7aaaa5479e", -} -A14_SECTION_SEMANTIC_SHA256 = ( - "8d17464268b95d500dcc4d7640edee0f26180a70172cdb3a3966a8e6d2408062" -) -A15_SECTION_SEMANTIC_SHA256 = ( - "a1e7bcb2aabc2b43cc92b09e1d8bf96d644d377ae70d81d9c5f40d7fafa94f3b" +A20_SECTION_SEMANTIC_SHA256: str | None = ( + "32fdc956786f4d65dca75d38d553c7e04411e0a01ebe7d0e60cf11d046f80ff8" ) -A16_SECTION_SEMANTIC_SHA256 = ( - "8ed37933bc04d9c2233d62c74385bd03d8e0862067147a295218e37bcd11125a" -) - -A13_COMPARATOR_ROWS = ( +A20_CANONICALIZATION = "python-json-sort-keys-compact-ascii-no-nan-lf-v1" +A20_COMMON_IDENTITY_NAMES = [ + "physical_source_identity", + "evidence_statement_identity", + "missing_reason_source_domain_identity", + "purpose_source_domain_identity", + "a20_successor_source_binding_identity", + "r04_q5_shape_identity", + "r06_six_module_identity", + "r06_collected_node_id_identity", + "dormant_lifecycle_definition_identity", +] +A20_ARM_IDENTITY_CONTRACTS = { + "missing_reason_authority_status": { + "pass_status": "pass", + "failure_status": "fail_permanent_missing_reason_authority_residue", + "pass_identity_names": [ + "missing_reason_rule_set_identity", + "missing_reason_successor_relation_identity", + "missing_representation_bridge_identity", + ], + "forbidden_output_paths": [ + "docs/analysis/amendment_20_ratification/evidence_freeze/" + "missing_reason_rule_set_identity.json", + "docs/analysis/amendment_20_ratification/evidence_freeze/" + "missing_reason_successor_relation_identity.json", + "docs/analysis/amendment_20_ratification/evidence_freeze/" + "missing_representation_bridge_identity.json", + ], + "failure_shadow_identity_name": ( + "missing_reason_failure_shadow_identity" + ), + }, + "purpose_authority_status": { + "pass_status": "pass", + "failure_status": "fail_permanent_purpose_authority_residue", + "pass_identity_names": [ + "purpose_rule_set_identity", + "purpose_authority_mapping_identity", + ], + "forbidden_output_paths": [ + "docs/analysis/amendment_20_ratification/evidence_freeze/" + "purpose_rule_set_identity.json", + "docs/analysis/amendment_20_ratification/evidence_freeze/" + "purpose_authority_mapping_identity.json", + ], + "failure_shadow_identity_name": "purpose_failure_shadow_identity", + }, + "prompt_field_semantic_binding_status": { + "pass_status": "pass", + "failure_status": ( + "fail_permanent_prompt_field_or_semantic_binding_residue" + ), + "pass_identity_names": [ + "prompt_field_evidence_identity", + "prompt_field_candidate_set_identity", + "zero_candidate_positive_group_identity", + "semantic_binding_identity", + ], + "forbidden_output_paths": [ + "docs/analysis/amendment_20_ratification/evidence_freeze/" + "prompt_field_evidence_identity.json", + "docs/analysis/amendment_20_ratification/evidence_freeze/" + "prompt_field_candidate_set_identity.json", + "docs/analysis/amendment_20_ratification/evidence_freeze/" + "zero_candidate_positive_group_identity.json", + "docs/analysis/amendment_20_ratification/evidence_freeze/" + "semantic_binding_identity.json", + ], + "failure_shadow_identity_name": ( + "prompt_field_semantic_failure_shadow_identity" + ), + }, +} +A20_EXPECTED_IDENTITY_NAMES = [ + "physical_source_identity", + "evidence_statement_identity", + "missing_reason_source_domain_identity", + "purpose_source_domain_identity", + "a20_successor_source_binding_identity", + "missing_reason_rule_set_identity", + "missing_reason_successor_relation_identity", + "missing_representation_bridge_identity", + "purpose_rule_set_identity", + "purpose_authority_mapping_identity", + "prompt_field_evidence_identity", + "prompt_field_candidate_set_identity", + "zero_candidate_positive_group_identity", + "semantic_binding_identity", + "r04_q5_shape_identity", + "r06_six_module_identity", + "r06_collected_node_id_identity", + "dormant_lifecycle_definition_identity", + "missing_reason_failure_shadow_identity", + "purpose_failure_shadow_identity", + "prompt_field_semantic_failure_shadow_identity", +] +A20_PASS_IDENTITY_KEYS = [ + "identity_name", + "row_count", + "ordered_keyset_sha256", + "row_domain_sha256", + "status", +] +A20_ARM_PASS_IDENTITY_KEYS = [ + "identity_name", + "arm_status_member", + "arm_status", + "row_count", + "ordered_keyset_sha256", + "row_domain_sha256", + "status", +] +A20_SUCCESSOR_BINDING_IDENTITY_KEYS = [ + "identity_name", + "row_count", + "ordered_keyset_sha256", + "row_domain_sha256", + "arm_status_bindings", + "active_identity_bindings_sha256", + "status", +] +A20_FAILURE_SHADOW_IDENTITY_KEYS = [ + "schema_version", + "identity_name", + "arm_status_member", + "arm_status", + "shadow_row_count", + "shadow_ordered_keyset_sha256", + "shadow_row_domain_sha256", + "complement_identity", + "forbidden_output_identity_names", + "forbidden_output_paths", + "nonemission_evidence", + "status", +] +A20_NONEMISSION_COMPLEMENT_IDENTITY_KEYS = [ + "schema_version", + "complement_of_identity_names", + "row_count", + "ordered_keyset_sha256", + "row_domain_sha256", + "status", +] +A20_REPOSITORY_MANIFEST_ROW_KEYS = [ + "path", + "mode", + "git_blob", + "byte_size", + "raw_sha256", +] +A20_FAILURE_NONEMISSION_EVIDENCE_KEYS = [ + "execution_commit", + "execution_tree_oid", + "repository_manifest_rows_before", + "repository_manifest_sha256_before", + "repository_manifest_rows_after", + "repository_manifest_sha256_after", + "repository_clean_before", + "repository_clean_after", + "forbidden_outputs_absent_after_execution", +] +A20_EVIDENCE_FREEZE = { + "schema_version": "a20_evidence_freeze.v1", + "amendment20_evidence_freeze_status": ( + "not_instantiated_a4_required_before_ratify" + ), + "missing_reason_authority_status": None, + "purpose_authority_status": None, + "prompt_field_semantic_binding_status": None, + "expected_identity_bindings": { + name: None for name in A20_EXPECTED_IDENTITY_NAMES + }, + "amendment20_ratification_ready": False, +} +A20_EVIDENCE_FREEZE_CONTRACT = { + "object": A20_EVIDENCE_FREEZE, + "final_required_evidence_freeze_status": "pass_a4_exact_freeze", + "final_arm_status_domains": { + "missing_reason_authority_status": [ + "pass", + "fail_permanent_missing_reason_authority_residue", + ], + "purpose_authority_status": [ + "pass", + "fail_permanent_purpose_authority_residue", + ], + "prompt_field_semantic_binding_status": [ + "pass", + "fail_permanent_prompt_field_or_semantic_binding_residue", + ], + }, + "identity_contract": { + "common_identity_names": A20_COMMON_IDENTITY_NAMES, + "arm_identity_contracts": A20_ARM_IDENTITY_CONTRACTS, + "pass_identity_keys": A20_PASS_IDENTITY_KEYS, + "arm_pass_identity_keys": A20_ARM_PASS_IDENTITY_KEYS, + "successor_binding_identity_keys": ( + A20_SUCCESSOR_BINDING_IDENTITY_KEYS + ), + "failure_shadow_identity_keys": A20_FAILURE_SHADOW_IDENTITY_KEYS, + "nonemission_complement_identity_keys": ( + A20_NONEMISSION_COMPLEMENT_IDENTITY_KEYS + ), + "failure_nonemission_evidence_keys": ( + A20_FAILURE_NONEMISSION_EVIDENCE_KEYS + ), + "repository_manifest_row_keys": A20_REPOSITORY_MANIFEST_ROW_KEYS, + "successor_binding_identity_name": ( + "a20_successor_source_binding_identity" + ), + "successor_binding_digest_excludes_self": True, + "failure_shadow_rows_are_exact_forbidden_output_complement": True, + "failure_shadow_paths_are_exact_arm_contract_paths": True, + "lifecycle_booleans_are_not_accepted_as_self_attestation": True, + }, + "ratification_readiness_iff_freeze_shape_statuses_and_identities": True, + "semantic_arm_pass_required_for_ratification": False, + "absent_identity_is_not_zero_digest_or_wildcard": True, + "authority_selection_permitted": False, + "r04_or_later_permitted": False, +} +A20_CONTROLLING_EXTERNAL_RECORDS = [ + { + "logical_path": "e8-ops/sol-ce-a20-charter.md", + "byte_size": 27_368, + "raw_sha256": ( + "5ecd4092f3fc62ef894866a1a5b505d6dba7bb04cde1360ff7134d7d8e927717" + ), + "authority": "NONAUTHORITY", + }, + { + "logical_path": ("e8-ops/sol-ce-law-gap-sweep-r21-2026-08-16.md"), + "byte_size": 11_805, + "raw_sha256": ( + "39887de99d75a395e97b04f33b4c5264a6828f56c9321cfe248b4ba11a7e5846" + ), + "authority": "NONAUTHORITY", + }, +] +A20_EVIDENCE_CAMPAIGN_CONTRACT = { + "stage_order": [ + "E0_banked_evidence_reauthentication", + "E1_shared_source_closure_and_separate_domain_projections", + "E2_compilers_representation_bridges_and_measured_pilots", + "A1_concentrated_queues", + "A2_recurring_remainder", + "A3_occurrence_local_residue_with_capacity_kills", + "A4_dual_review_reconciliation_and_exact_identity_freeze", + "C20_ratification_and_revision_22_activation", + "X1_authoritative_settlement_missing_dispatch_disabled", + "X2_complete_normal_R04_and_R05", + "historical_R06_replay_and_first_add", + "fresh_reconstruction", + "Q5", + "slot_inventory_G17_C01_and_V_B6", + "sealed_publication_chain", + ], + "rounds_formula": "ceil(2L/(3q))", + "q_definition": ( + "observed_independently_reviewed_logical_decisions_per_lane_day" + ), + "forecast_as_of": "2026-08-15", + "conditional_p50": "2026-11-09", + "conditional_p80": "2027-01-22", + "dates_are_nonauthority_conditional_planning_metadata": True, + "fail_closed_kill_categories": [ + "source_admission", + "missing_rule_scope", + "purpose_entailment", + "family_equivalence", + "legacy_vocabulary", + "circular_attachment", + "prompt_field_ambiguity", + "reviewer_origin", + "cross_arm_contamination", + "missing_convention_arm_capacity", + "missing_ledger_capacity", + "purpose_ledger_capacity", + "acceptance_exact_cover_and_reconstruction", + "complete_R04", + "downstream_reconstruction_and_publication", + ], + "permanent_residue_remains_fail_closed": True, +} +A20_PHYSICAL_SOURCE_ROW_KEYS = [ + "evidence_source_id", + "upstream_capture_or_registry_identity", + "document_role", + "release_or_wave", + "representation", + "official_url", + "canonical_local_path", + "storage_identity", + "byte_size", + "raw_sha256", + "access_disposition", + "licensing_disposition", + "statement_locator_ids", + "extraction_tool_identity", + "recovered_source_provenance", +] +A20_EVIDENCE_STATEMENT_ROW_KEYS = [ + "evidence_statement_id", + "evidence_source_id", + "page_or_section_locator", + "utf8_byte_start", + "utf8_byte_end", + "exact_statement_raw_sha256", + "extraction_tool_identity", + "recovery_provenance_id", +] +A20_SEMANTIC_DOMAIN_IDENTITY_KEYS = [ + "domain_id", + "domain_version", + "included_source_rows", + "included_source_count", + "included_source_keyset_sha256", + "included_source_domain_sha256", + "excluded_source_rows", + "excluded_source_count", + "excluded_source_keyset_sha256", + "excluded_source_domain_sha256", + "admitted_statement_rows", + "statement_count", + "statement_keyset_sha256", + "statement_domain_sha256", + "status", +] +A20_SOURCE_INFRASTRUCTURE_CONTRACT = { + "physical_relation": "a20_physical_source_rows", + "physical_source_row_keys": A20_PHYSICAL_SOURCE_ROW_KEYS, + "statement_relation": "a20_evidence_statement_rows", + "evidence_statement_row_keys": A20_EVIDENCE_STATEMENT_ROW_KEYS, + "semantic_domain_order": [ + "missing_reason_source_domain", + "purpose_source_domain", + ], + "semantic_domain_identity_keys": A20_SEMANTIC_DOMAIN_IDENTITY_KEYS, + "semantic_domains": { + "missing_reason_source_domain": { + "domain_id": "missing_reason_source_domain", + "expected_identity": None, + "required_final_status": "pass", + }, + "purpose_source_domain": { + "domain_id": "purpose_source_domain", + "expected_identity": None, + "required_final_status": "pass", + }, + }, + "inclusion_exclusion_complete_and_disjoint": True, + "included_and_excluded_counts_sum_to_physical_count": True, + "domains_authenticate_foreign_keys_independently": True, + "shared_physical_bytes_imply_shared_semantic_admission": False, + "mixed_semantic_payload_or_shared_accepted_digest_aborts_both": True, + "path_rule": "repository_relative_canonical_traversal_free", + "machine_local_absolute_paths_forbidden": True, + "current_url_or_latest_edition_substitution_forbidden": True, + "historical_domains_preserved": { + "a11_source_count": 47, + "questionnaire_document_count": 81, + "a19_build_input_source_document_count": 257, + "a19_build_input_repair_seal_count": 22, + "a19_build_input_row_count": 279, + }, + "successor_source_binding_keys": [ + "historical_a19_build_input_identity", + "physical_source_identity", + "evidence_statement_identity", + "missing_reason_source_domain_identity", + "purpose_source_domain_identity", + "missing_reason_authority_status", + "purpose_authority_status", + "prompt_field_semantic_binding_status", + "missing_reason_rule_set_identity", + "missing_reason_successor_relation_identity", + "missing_representation_bridge_identity", + "purpose_rule_set_identity", + "purpose_authority_mapping_identity", + "prompt_field_evidence_identity", + "prompt_field_candidate_set_identity", + "zero_candidate_positive_group_identity", + "semantic_binding_identity", + "r04_q5_shape_identity", + "missing_reason_failure_shadow_identity", + "purpose_failure_shadow_identity", + "prompt_field_semantic_failure_shadow_identity", + "active_identity_bindings_sha256", + "canonicalization", + "status", + ], + "successor_source_binding_expected_identity": None, + "independent_reconstructor_count": 2, + "reconstructors_require_count_order_keyset_rows_and_digest_equality": ( + True + ), +} +A20_MISSING_REASON_AUTHORITY_CONTRACT = { + "authority_rule_row_keys": [ + "authority_rule_id", + "registered_evidence_source_ids", + "registered_statement_ids", + "rule_kind", + "exact_scope_predicate", + "explicit_exclusions", + "strict_boolean_disposition", + "projected_occurrence_count", + "projected_occurrence_keyset_sha256", + "overlap_conflict_complement_results", + ], + "occurrence_identity_position_order": [ + "schema_tag", + "global_member_position", + "source_document_position", + "source_row_position", + "entry_position", + "source_document_id", + "codebook_field_row_id", + "ordered_nonempty_locator_id_array", + "entry_reference", + "entry_kind", + "exact_source_value_or_range_lexeme", + "exact_nonempty_source_meaning", + ], + "formerly_unresolved_literal_occurrence_count": 524_538, + "inherited_source_authorized_literal_count": 52, + "numeric_structural_null_range_count": 37_283, + "claim_type": "strict_json_boolean_excluding_integer_coercion", + "projection_requirements": [ + "exact", + "nonzero", + "disjoint", + "collectively_exhaustive", + "exception_complete", + ], + "conflict_precedes_incomplete_coverage": True, + "agreeing_duplicate_rules_abort": True, + "candidate_defaults_forbidden": True, + "independent_compiler_count": 2, + "transactional_atomic_nonemission": True, + "missing_true_reason_id_prefix": "psid-source-missing-reason:", + "missing_false_reason": None, + "numeric_range_reason": None, + "historical_a11_and_a18_results_preserved": True, + "representation_bridge_probe": { + "relation": "missing_representation_bridge_rows", + "direct_field_ceiling_observation": 54_898, + "gross_source_era_ceiling_observation": 71_635, + "diagnostic_shadow_observation": 59_424, + "zero_projection_observation": 87, + "observations_are_nonauthority": True, + "accepted_bridge_identity": None, + "u24_e2_93md_claims_accepted": 0, + "bridge_required_before_acceptance": True, + }, +} +A20_PURPOSE_AUTHORITY_CONTRACT = { + "official_purpose_order": A19_OFFICIAL_PURPOSES, + "completed_ontology_order": [ + *A19_OFFICIAL_PURPOSES, + "source_underdetermined", + ], + "purpose_authority_rule_row_keys": [ + "purpose_authority_source_id", + "rule_kind", + "registered_evidence_statement_ids", + "exact_prompt_scope_predicate", + "explicit_exclusions", + "explicit_official_purposes", + "projected_prompt_count", + "projected_prompt_keyset_sha256", + ], + "purpose_mapping_row_keys": [ + "source_prompt_occurrence_id", + "authority_basis", + "purpose_authority_source_id", + "evidence_statement_ids", + "explicit_official_purposes", + "purpose_mapping_disposition", + "reconciled_adjudication_ruling_id", + ], + "prompt_denominator_a4_freeze_slot": None, + "required_disposition_counts": { + "complete_official_mapping": None, + "source_underdetermined": None, + "U": 0, + }, + "source_underdetermined_count_a4_freeze_slot": None, + "source_underdetermined_requires_reconciled_adjudication_ruling": True, + "source_underdetermined_uses_determined_row_provenance_authentication": True, + "source_underdetermined_means_authenticated_sources_determine_no_nonempty_subset": True, + "source_underdetermined_is_no_applicable_purpose": False, + "disposition_relation_total_under_completed_ontology": True, + "u_definition": "prompt_without_lawful_completed_ontology_disposition", + "authority_gate_uses_reconciled_outcomes": True, + "exact_row_agreement_is_authority_gate": False, + "macro_per_prompt_jaccard_minimum_calibration_diagnostic": "90%", + "inherited_complete_rows_requiring_source_regrounding": 818, + "manual_origin_grandfathering_permitted": False, + "source_conflict_reopens_row": True, + "purpose_arrays_nonempty_stable_unique_in_official_order": True, + "exact_prompt_cover_and_zero_gap_extra_duplicate_overlap_conflict": True, + "independent_compiler_count": 2, + "transactional_atomic_nonemission": True, + "source_backed_alternatives": [ + "occurrence_kind_or_denominator_correction", + "ontology_projection", + "separately_tagged_no_applicable_purpose_arm", + ], + "source_backed_alternative_selected": "ontology_projection", + "source_classification_row_id_overload_forbidden": True, +} +A20_PROMPT_FIELD_SEMANTIC_BINDING_CONTRACT = { + "prompt_field_row_keys": [ + "prompt_field_evidence_id", + "source_prompt_occurrence_id", + "interview_wave", + "questionnaire_span", + "prompt_source_locator_ids", + "field_source_document_id", + "field_source_row_id", + "field_source_member", + "raw_field_id", + "attachment_basis", + "official_alias_statement_ids", + "attachment_disposition", + "candidate_raw_field_ids", + ], + "questionnaire_span_keys": ["utf8_byte_start", "utf8_byte_end"], + "questionnaire_span_basis": "prompt_source_utf8_byte_half_open_interval", + "questionnaire_span_minimal_exact_identifier_token_match": True, + "questionnaire_span_bounds_strict_integers_excluding_booleans": True, + "questionnaire_span_requires_0_le_start_lt_end_le_prompt_byte_length": True, + "prompt_field_evidence_id_prefix": "psid-prompt-field-evidence:", + "prompt_field_evidence_id_preimage": [ + "source_prompt_occurrence_id", + "interview_wave", + "questionnaire_span", + "prompt_source_locator_ids", + "field_source_document_id", + "field_source_row_id", + "field_source_member", + "raw_field_id", + "attachment_basis", + "official_alias_statement_ids", + "attachment_disposition", + "candidate_raw_field_ids", + ], + "prompt_field_evidence_id_canonicalization": A20_CANONICALIZATION, + "prompt_field_evidence_order": [ + "complete_prompt_source_position", + "interview_wave", + "source_prompt_occurrence_id", + "questionnaire_span.utf8_byte_start", + "questionnaire_span.utf8_byte_end", + "attachment_branch_direct_before_question_token", + "field_reconstruction_document_row_member_order", + ], + "exact_duplicate_evidence_emission_aborts": True, + "coordinate_distinct_spans_must_have_distinct_row_bodies": True, + "coordinate_distinct_span_collapse_aborts": True, + "construction_stage": "before_O_P", + "positive_attachment_bases": [ + "exact_source_identifier", + "expressly_admitted_official_alias", + ], + "attachment_dispositions": [ + "accepted_exact_source_identifier", + "accepted_expressly_admitted_official_alias", + "unresolved_multiple", + ], + "candidate_sets_materialized": True, + "zero_or_multiple_candidates_fail_without_source_resolution": True, + "direct_identifier_priority_forbidden": True, + "collision_census": { + "domain": "historical_same_coordinate_leading_question_token_conflicts", + "complete_official_prompt_count": 818, + "multiple_count": 46, + }, + "complete_official_prompt_candidate_census": { + "domain": "prompt_level_stable_unique_complete_candidate_union", + "complete_official_prompt_count": 818, + "multiple_count": 49, + "additional_noncollision_candidate_sets": [ + { + "interview_wave": 1974, + "candidate_raw_field_ids": ["V3585", "V3586"], + }, + { + "interview_wave": 1985, + "candidate_raw_field_ids": ["V11649", "V11648"], + }, + { + "interview_wave": 1985, + "candidate_raw_field_ids": ["V11616", "V11676"], + }, + ], + }, + "full_prompt_candidate_census": { + "domain": "multiple_candidates_over_full_prompt_denominator", + "prompt_count": 21_971, + "multiple_count": 2_349, + }, + "c68_regression": { + "source_prompt_occurrence_id": ( + "psid-questionnaire-occurrence:" + "4cd66190a898d568dd20c27140f44f1dff53d229f664f537722624d00c9b4b67" + ), + "interview_wave": 1985, + "printed_direct_field_id": "V11804", + "question_token": "C68.", + "candidate_raw_field_ids": ["V11804", "V11805"], + "draft_disposition": "unresolved_multiple", + }, + "prompt_field_candidate_set_row_keys": [ + "prompt_field_candidate_set_id", + "source_prompt_occurrence_id", + "interview_wave", + "candidate_prompt_field_evidence_ids", + "candidate_raw_field_ids", + "candidate_count", + "candidate_disposition", + ], + "prompt_field_candidate_set_id_prefix": ( + "psid-prompt-field-candidate-set:" + ), + "prompt_field_candidate_set_id_preimage": [ + "source_prompt_occurrence_id", + "interview_wave", + "candidate_prompt_field_evidence_ids", + "candidate_raw_field_ids", + "candidate_count", + "candidate_disposition", + ], + "prompt_field_candidate_set_dispositions": [ + "zero_candidates", + "one_candidate", + "multiple_candidates", + ], + "prompt_field_candidate_set_order": "complete_prompt_source_order", + "candidate_arrays_complete_stable_unique_source_order": True, + "candidate_count_is_raw_field_array_length_strict_integer": True, + "candidate_disposition_is_iff_count_partition": True, + "candidate_set_id_is_sha256_of_canonical_remaining_members": True, + "candidate_set_row_ids_and_prompt_ids_unique": True, + "zero_candidate_positive_group_row_keys": [ + "zero_candidate_positive_group_id", + "positive_occurrence_id", + "zero_candidate_source_prompt_occurrence_ids", + "all_source_prompt_occurrence_ids", + "complete_reference_union_ids", + "empty_reference_union", + "group_disposition", + ], + "zero_candidate_positive_group_id_prefix": ( + "psid-zero-candidate-positive-group:" + ), + "zero_candidate_positive_group_id_preimage": [ + "positive_occurrence_id", + "zero_candidate_source_prompt_occurrence_ids", + "all_source_prompt_occurrence_ids", + "complete_reference_union_ids", + "empty_reference_union", + "group_disposition", + ], + "zero_candidate_positive_group_dispositions": [ + "complete_nonempty_reference_union", + "fail_empty_reference_union", + ], + "zero_candidate_positive_group_order": "positive_occurrence_order", + "zero_candidate_group_one_per_qualifying_positive_occurrence": True, + "zero_candidate_prompt_arrays_complete_positive_row_projections": True, + "zero_candidate_reference_union_complete_stable_unique": True, + "empty_reference_union_is_strict_boolean_zero_length_equality": True, + "zero_candidate_group_disposition_is_iff_empty_boolean": True, + "zero_candidate_group_id_is_sha256_of_canonical_remaining_members": True, + "zero_candidate_group_ids_and_positive_ids_unique": True, + "zero_candidate_grouping_probe": { + "candidate_set_prompt_count": 21_971, + "sweep_zero_candidate_observation": 15_428, + "diagnostic_zero_candidate_observation": 14_450, + "observations_are_nonauthority": True, + "difference_explained": False, + "accepted_positive_group_with_empty_reference_union_count": None, + "accepted_attachment_required_for_codebook_supported_rule": True, + }, + "semantic_binding_coordinates": [ + "role", + "job_slot_id", + "questionnaire_component_slot_id", + "slot_kind", + "field_purpose", + ], + "semantic_binding_dispositions": [ + "semantically_bound", + "no_supported_predicate_dimension", + "unresolved_semantic_binding", + ], + "required_unresolved_semantic_binding_count": 0, + "semantic_binding_serialization": "near_match_source_annotation_rows", + "separate_semantic_binding_rows_serialization_permitted": False, + "semantic_binding_identity_requires_deep_equality": [ + "row_count", + "ordered_keyset_sha256", + "row_domain_sha256", + ], + "binding_built_before_candidate_rows_read": True, + "joint_support_and_subsumption_maximality_required": True, + "post_o_p_relations": [ + "occurrence_raw_field_reference_rows", + "positive_field_join_rows", + "nonempty_reference_and_raw_field_projections", + "unique_same_wave_attachment", + "purpose_expansion", + "reverse_covers", + ], + "post_o_p_relations_use_completed_purpose_ontology": True, + "post_o_p_exact_token_joins_without_silent_unions": True, + "mandatory_ambiguity_regressions": ["Family", "Dl7./D17.", "D2."], +} +A20_R04_Q5_CONTRACT = { + "construction_order": [ + "authenticate_fixed_historical_denominators_and_a20_source_domains", + "construct_and_seal_missing_purpose_rules_and_successor_binding", + "compile_purpose_prompt_field_and_semantic_inputs", + "compute_purpose_U_and_independent_acceptance_results", + "select_failure_or_normal_member", + "normal_only_construct_H_and_source_only_O_H", + "normal_only_require_O_H_before_O_P", + "normal_only_construct_O_P_bindings_joins_covers_expansion_D0_search_D1_and_R04", + "normal_only_R05_strict_certificate_and_dual_reconstruction", + ], + "purpose_totality_alone_passes_r04": False, + "selector_purpose_domain": "completed_purpose_ontology", + "o_p_order": [*A19_OFFICIAL_PURPOSES, "source_underdetermined"], + "purpose_expansion_domain": "completed_purpose_ontology", + "purpose_rule_projection_domain": "completed_purpose_ontology", + "o_h_source_only": True, + "o_h_precedes_o_p_on_normal_arm": True, + "permitted_selector_input_reads": [ + "questionnaire_occurrence_rows", + "fixed_prompt_denominator", + "purpose_authority_mapping_rows", + "prompt_field_candidate_set_rows", + "selector_inputs", + ], + "forbidden_selected_failure_member_serialization": [ + "questionnaire_occurrence_rows", + "all_pass_only_arrays", + "Q5", + "R05_certificate", + "authority", + "production_output", + ], + "historical_a19_failure_member_byte_size": 877, + "historical_a19_failure_member_raw_sha256": ( + "1651c50ff1f171ac420e55982cb060db70946f9283999c3d9edb2fa140d467c5" + ), + "source_document_manifest_insert_after": "source_document_domain_sha256", + "source_document_manifest_additions": [ + "a20_successor_source_binding_identity", + "missing_reason_source_domain_identity", + "purpose_source_domain_identity", + "missing_reason_rule_set_identity", + "purpose_rule_set_identity", + "prompt_field_evidence_identity", + "semantic_binding_identity", + ], + "replaced_a19_effective_header_members": [ + "purpose_mapping_row_count", + "purpose_mapping_keyset_sha256", + "purpose_mapping_domain_sha256", + "purpose_mapping_disposition_counts", + ], + "normal_effective_header_successor_members": [ + "purpose_authority_mapping_row_count", + "purpose_authority_mapping_keyset_sha256", + "purpose_authority_mapping_domain_sha256", + "purpose_authority_mapping_disposition_counts", + "prompt_field_evidence_row_count", + "prompt_field_evidence_keyset_sha256", + "prompt_field_evidence_domain_sha256", + "prompt_field_evidence_disposition_counts", + "prompt_field_candidate_set_row_count", + "prompt_field_candidate_set_keyset_sha256", + "prompt_field_candidate_set_domain_sha256", + "prompt_field_candidate_set_disposition_counts", + "zero_candidate_positive_group_row_count", + "zero_candidate_positive_group_keyset_sha256", + "zero_candidate_positive_group_domain_sha256", + "zero_candidate_positive_group_empty_union_count", + ], + "normal_effective_header_insert_before": "positive_occurrence_row_count", + "replaced_a19_era_sequence": [ + "hierarchy_rows", + "purpose_mapping_rows", + "positive_occurrence_rows", + ], + "normal_era_successor_sequence": [ + "hierarchy_rows", + "purpose_authority_mapping_rows", + "prompt_field_evidence_rows", + "prompt_field_candidate_set_rows", + "zero_candidate_positive_group_rows", + "positive_occurrence_rows", + ], + "inherited_semantic_relation_member": "near_match_source_annotation_rows", + "inherited_semantic_relation_position": "after_expanded_disposition_rows", + "per_era_rows_use_direct_era_order_concatenation": True, + "g17_c01_expected_and_actual_shapes_equal": True, + "failure_arms_serialize_a20_shape_additions": False, + "a19_purpose_mapping_is_historical_nonconsumable_on_a20_normal_path": ( + True + ), + "a19_digest_dependency_order_preserved": [ + "D0", + "search_implementation", + "A_h", + "final_rows", + "D1", + ], +} +A20_R06_FILE_IDENTITIES = [ + { + "path": "tests/data/test_psid_codebook_extraction_validation.py", + "mode": "100644", + "git_blob": "7b2f33af3ff6a4e389a944e349aa222f6ca41519", + "byte_size": 13_718, + "raw_sha256": ( + "7af8a2847b4428fa7376598cc48333d008f225389eee461f3edae58ca624ff67" + ), + }, + { + "path": "tests/data/test_psid_missing_reason_authority_artifact.py", + "mode": "100644", + "git_blob": "c8863f4a6a5e915666f0cce2cac4817e73839e9f", + "byte_size": 18_129, + "raw_sha256": ( + "4f425c776ddba30f3b861812cdcbd0abef5b10ae0f41608bcaa6d456c9cdcd85" + ), + }, + { + "path": "tests/data/test_psid_missing_reason_authority_unit.py", + "mode": "100644", + "git_blob": "499aa397f75e1d2f62e7c91a929f9ecdcf71a478", + "byte_size": 18_252, + "raw_sha256": ( + "5e9b7cc33fd560ce5c472c6ac146f07a6b7b238003c6e96f715e417679149cda" + ), + }, + { + "path": "tests/estimates/test_birth_evidence_artifact.py", + "mode": "100644", + "git_blob": "d4e838a1123d4e07c6f472ff64cfd6c11462f4a8", + "byte_size": 25_883, + "raw_sha256": ( + "70acf9c2f36f9f88a7e5e2c8c7b5825427d6a44cf1926b0a6c0c7cf4bbb7d5d5" + ), + }, + { + "path": "tests/test_rebuild_amendment11_missing_reason_authority.py", + "mode": "100644", + "git_blob": "632357933ea37c982d18402d249b74147cd80823", + "byte_size": 22_828, + "raw_sha256": ( + "eedbab9e3ba3eaad19f08d36472b2fbc53cc5dc62b417a3600d5cb4360368dcb" + ), + }, + { + "path": "tests/test_replay_amendment11_no_movement.py", + "mode": "100644", + "git_blob": "cc4c1c6d65c89ad97feb0b4f04e6c5d2ecd2405f", + "byte_size": 19_309, + "raw_sha256": ( + "0875ac524e0cd2e7f3cb6e601026b0d2db5b459c6f426fe5182ac08ebaef9ec1" + ), + }, +] +_A20_LIFECYCLE_ROW_SPECS = ( ( - "DC-72", - "§§26.10.1–26.10.3, DC-64, §26.11, and §27.2 Amendment-12 ratification identity", - "replaced-by-named-successor: every revision-14 D12 document-only locator and the obsolete no-ratification clause select actual Amendment-12 history by exact commit/blob/bytes/dual-attestation identity; every other ceremony, noninstantiation, and stop survives", + "A20_SOURCE_RELATIONS_SETTLED_DISPATCH_DISABLED", + "a20_source_settlement.v1", + ["REVISION22_REGISTRY_REPIN"], + [ + "revision22_registry_repin_identity", + "a20_successor_source_binding_identity", + "dormant_lifecycle_definition_identity", + ], ), ( - "DC-73", - "§§26.7.2, 27.3, and 27.4 exact 28 incompatible proof rows", - "replaced-by-named-successor: terminal no-alias successor, deterministic predecessor-family map, retained predecessor, supersession edge, overlay, and era membership", + "A20_NORMAL_R04_REQUIRED", + "a20_normal_r04.v1", + ["A20_SOURCE_RELATIONS_SETTLED_DISPATCH_DISABLED"], + [ + "a20_source_settlement_identity", + "historical_a19_build_input_identity", + ], ), ( - "DC-74", - "§§26.7, 26.11.2, and 27.5 exact ten incomplete fragments and five prior continuation citations", - "replaced-by-named-successor for the ten only: eight disclosed terminal fragments plus two exact G75 compositions; five-citation Amendment-12 domain lawfully unchanged", + "A20_R05_REQUIRED", + "a20_r05_certificate.v1", + ["A20_NORMAL_R04_REQUIRED"], + ["a20_normal_r04_identity"], ), ( - "DC-75", - "§§26.7.1, 27.3, and 27.6 doc-036 and six-era reseal", - "lawfully-unchanged-with-reason: eight sole-field changes were already determinate; the new proof successor now permits one coherent nine-row overlay and all six exact successor-seal domains", + "A20_HISTORICAL_R06_REQUIRED", + "a20_historical_r06_binding.v1", + ["A20_R05_REQUIRED"], + [ + "a20_r05_certificate_identity", + "r06_six_module_identity", + "r06_collected_node_id_identity", + "historical_a11_replay_identity", + ], ), ( - "DC-76", - "§§26.8–26.9 and 27.7 validation evidence, mutations, and 14 law gaps", - "lawfully-unchanged-with-reason: 71 historical attacks remain exact; seven new attacks are separate; all 14 law gaps and every row outside 46 remain untouched", + "A20_MISSING_REASON_SUCCESSOR_ACTIVE", + "a20_missing_reason_successor_relation.v1", + ["A20_HISTORICAL_R06_REQUIRED"], + [ + "a20_historical_r06_identity", + "missing_reason_successor_relation_identity", + ], ), ( - "DC-77", - "§§25.10, 26.10–26.11, and 27.8 lifecycle, authority, Q5, and production after applying DC-72's D12 locator", - "lawfully-unchanged-with-reason: apart from the exact ratification locator named in DC-72, the draft emits no authority, tier-2 execution occurs later if ratified, and the independent Amendment-11 blocker remains controlling", + "A20_CLASSIFIER_REBUILD_REQUIRED", + "a20_classifier_rebuild.v1", + ["A20_MISSING_REASON_SUCCESSOR_ACTIVE"], + [ + "a20_active_missing_reason_identity", + "historical_classifier_input_identity", + ], ), -) - - -def _require(condition: bool, message: str) -> None: - if not condition: - raise LawError(message) - - -def _require_exact_keys( - value: Mapping[str, Any], expected: set[str], label: str -) -> None: - _require(set(value) == expected, f"{label} keyset drift") - - -def canonical_json_bytes(value: Any) -> bytes: - """Return the law's compact, sorted, terminal-LF JSON bytes.""" - - try: + ( + "A20_TERMINAL_MOVEMENT_REQUIRED", + "a20_terminal_movement.v1", + ["A20_CLASSIFIER_REBUILD_REQUIRED"], + ["a20_classifier_rebuild_identity"], + ), + ( + "A20_ASSIGNMENT_REBUILD_REQUIRED", + "a20_assignment_rebuild.v1", + ["A20_TERMINAL_MOVEMENT_REQUIRED"], + ["a20_terminal_movement_identity"], + ), + ( + "A20_LOGICAL_RANGE_REBUILD_REQUIRED", + "a20_logical_range_rebuild.v1", + ["A20_ASSIGNMENT_REBUILD_REQUIRED"], + ["a20_assignment_rebuild_identity"], + ), + ( + "A20_STORAGE_POPULATION_REBUILD_REQUIRED", + "a20_storage_population_rebuild.v1", + ["A20_LOGICAL_RANGE_REBUILD_REQUIRED"], + ["a20_logical_range_rebuild_identity"], + ), + ( + "A20_CONSTRUCTIBILITY_REQUIRED", + "a20_constructibility.v1", + ["A20_STORAGE_POPULATION_REBUILD_REQUIRED"], + ["a20_storage_population_rebuild_identity"], + ), + ( + "A20_FULL_RELATION_IDENTITY_REQUIRED", + "a20_full_relation_identity.v1", + ["A20_CONSTRUCTIBILITY_REQUIRED"], + ["a20_constructibility_identity"], + ), + ( + "A20_COMPARATOR_REQUIRED", + "a20_comparator_census.v1", + ["A20_FULL_RELATION_IDENTITY_REQUIRED"], + ["a20_full_relation_identity"], + ), + ( + "A20_Q5_REQUIRED", + "a20_q5.v1", + ["A20_COMPARATOR_REQUIRED"], + ["a20_comparator_census_identity"], + ), + ( + "A20_SLOT_REBUILD_REQUIRED", + "a20_slot_rebuild.v1", + ["A20_Q5_REQUIRED"], + ["a20_q5_identity"], + ), + ( + "A20_INVENTORY_REBUILD_REQUIRED", + "a20_inventory_rebuild.v1", + ["A20_SLOT_REBUILD_REQUIRED"], + ["a20_slot_rebuild_identity"], + ), + ( + "A20_G17_C01_REBUILD_REQUIRED", + "a20_g17_c01_rebuild.v1", + ["A20_INVENTORY_REBUILD_REQUIRED"], + ["a20_inventory_rebuild_identity"], + ), + ( + "A20_VB6_REQUIRED", + "a20_vb6_successor.v1", + ["A20_G17_C01_REBUILD_REQUIRED"], + ["a20_g17_c01_rebuild_identity"], + ), + ( + "A20_SUCCESSOR_BUNDLES_REQUIRED", + "a20_successor_bundles.v1", + ["A20_VB6_REQUIRED"], + ["a20_vb6_identity"], + ), + ( + "A20_MIGRATIONS_REQUIRED", + "a20_migrations.v1", + ["A20_SUCCESSOR_BUNDLES_REQUIRED"], + ["a20_successor_bundles_identity"], + ), + ( + "A20_CAPTURE_REQUIRED", + "a20_capture.v1", + ["A20_MIGRATIONS_REQUIRED"], + ["a20_migrations_identity"], + ), + ( + "A20_RECEIPT_REQUIRED", + "a20_receipt.v1", + ["A20_CAPTURE_REQUIRED"], + ["a20_capture_identity"], + ), + ( + "A20_REGISTRATION_REQUIRED", + "a20_registration.v1", + ["A20_RECEIPT_REQUIRED"], + ["a20_receipt_identity"], + ), + ( + "A20_SEALED_RUN_REQUIRED", + "a20_sealed_run.v1", + ["A20_REGISTRATION_REQUIRED"], + ["a20_registration_identity"], + ), + ( + "A20_WALL_LEDGER_REQUIRED", + "a20_wall_ledger.v1", + ["A20_SEALED_RUN_REQUIRED"], + ["a20_sealed_run_identity"], + ), + ( + "A20_PUBLICATION_REQUIRED", + "a20_publication.v1", + ["A20_WALL_LEDGER_REQUIRED"], + ["a20_wall_ledger_identity"], + ), +) +A20_DORMANT_LIFECYCLE_ROWS = [ + { + "lifecycle_stage_id": stage_id, + "schema_id": schema_id, + "predecessor_stage_ids": predecessor_ids, + "input_identity_ids": input_ids, + "output_identity_id": None, + "first_add_index": index, + "selection_enabled": False, + "status": "dormant_definition", + } + for index, (stage_id, schema_id, predecessor_ids, input_ids) in enumerate( + _A20_LIFECYCLE_ROW_SPECS, + start=1, + ) +] +A20_R06_LIFECYCLE_CONTRACT = { + "interpreter_selector": "executing_process_sys.executable", + "test_command_after_interpreter": [ + "-m", + "pytest", + *[row["path"] for row in A20_R06_FILE_IDENTITIES], + ], + "collection_command_after_interpreter": [ + "-m", + "pytest", + "--collect-only", + "-q", + *[row["path"] for row in A20_R06_FILE_IDENTITIES], + ], + "test_environment": {"PYTHONPATH": "src:."}, + "inherited_git_environment_removed": True, + "ambient_pytest_addopts_removed": True, + "test_file_identities": A20_R06_FILE_IDENTITIES, + "module_path_domain_sha256": ( + "a5099c464482c5b652e31e5dfa958703a4ae4c75c1dc1e4caa03cb2aef408063" + ), + "collected_node_id_count": 223, + "collected_node_id_array_canonical_byte_size": 28_268, + "collected_node_id_array_raw_sha256": ( + "09071bf4d9a9a5ee8b9ccc4d8d5c0bd91705c04d3c7c99d6ef155dfdc0dfdf05" + ), + "first_collected_node_id": ( + "tests/data/test_psid_codebook_extraction_validation.py::" + "test_exact_nested_derivation_schemas_accept_generated_shapes" + "[_text_derivation]" + ), + "last_collected_node_id": ( + "tests/test_replay_amendment11_no_movement.py::" + "test_reason_mutation_changes_field_source_identity_but_not_terminal" + ), + "historical_r06_result_preserved": { + "exit_code": 2, + "source_authorized_literal_count": 52, + "blocked_literal_count": 524_538, + "numeric_range_structural_null_count": 37_283, + }, + "dormant_definition_before_certification_permitted": True, + "dormant_definition_creates_instance_or_selection": False, + "evidence_settlement_before_r06_requires_dispatch_disabled": True, + "lifecycle_envelope_keys": [ + "lifecycle_stage_id", + "schema_id", + "predecessor_stage_ids", + "input_identity_ids", + "output_identity_id", + "first_add_index", + "selection_enabled", + "status", + ], + "lifecycle_statuses": [ + "dormant_definition", + "blocked_predecessor", + "pass", + "fail_atomic_nonemission", + ], + "dormant_lifecycle_rows": A20_DORMANT_LIFECYCLE_ROWS, + "dormant_lifecycle_row_count": 26, + "output_identity_id_prefix": "a20-lifecycle-output:", + "output_identity_preimage": [ + "lifecycle_stage_id", + "schema_id", + "predecessor_stage_ids", + "input_identity_ids", + "exact_output_payload_identity", + ], + "output_identity_preimage_canonicalization": A20_CANONICALIZATION, + "selection_enabled_only_on_passing_first_add_index": 5, + "blocked_predecessor_output_identity": None, + "fail_atomic_nonemission_output_identity": None, + "unratified_next_required_state": "A20_SUCCESSOR_PROGRAM_STOP", + "revision22_repin_next_required_state": ( + "A20_SOURCE_RELATIONS_SETTLED_DISPATCH_DISABLED" + ), + "terminal_next_required_state": "A20_SUCCESSOR_LIFECYCLE_COMPLETE", + "selection_first_add_dispatch_requires_r04_r05_r06_order": True, + "fresh_recomputation_required": [ + "89599_field_classifier", + "terminal_movement", + "assignments_logical_ranges_storage", + "constructibility_and_full_relation_identity", + "comparator_census", + "Q5", + "slot_inventory_full_G17_C01_and_V_B6", + "successor_bundles_through_publication", + ], + "historical_zero_movement_assumption_permitted": False, +} +A20_EXECUTED_TRANSITION_RECEIPT_PATH = ( + "docs/analysis/amendment_20_ratification/" + "executed_transition_receipt_v2.json" +) +A20_PRODUCTION_REGISTRY_IDENTITY = { + "path": "scripts/covered_earnings_correction_registry.py", + "mode": "100644", + "git_blob": "92a24e3af4358f75cbead00f223837a68c2f9da8", + "byte_size": 55_473, + "raw_sha256": ( + "bd60336e3e388e5ef12f3f204b9bb089" "38c27be4db57f9e6fca6582aed7efb16" + ), +} +A20_RECEIPT_SCHEMA = { + **A17_RECEIPT_SCHEMA, + "manifest_keys": [ + "schema_version", + "simulated_state_authority", + "candidate_commit_identity", + "scratch_transition", + "terminal_revision", + "canonical_registry_binding", + "ordered_closure_identities", + "full_pinned_battery_test_identity", + ], + "manifest_schema_version": "executed_transition_state.v2", + "candidate_commit_identity_keys": ["commit", "tree", "sole_parent"], + "scratch_transition_keys": [ + "commit", + "tree", + "sole_parent", + "changed_paths", + "changed_path_domain_sha256", + ], + "scratch_sole_parent_equals_candidate_commit": True, + "expected_changed_paths": [ + ( + "docs/analysis/amendment_20_ratification/" + "sol-ce-amend20-sim-r1-verdict.md" + ), + ( + "docs/analysis/amendment_20_ratification/" + "sol-ce-amend20-sim-r2-verdict.md" + ), + "docs/analysis/amendment_20_ratification/closure_v1.json", + "scripts/covered_earnings_correction_registry.py", + ], + "expected_changed_path_domain_canonical_byte_size": 260, + "expected_changed_path_domain_sha256": ( + "5a7912498c4d959fef337f2a1d1cf85a2f254fa29d825d365ccf4fe214ad48a7" + ), + "changed_path_count": 4, + "changed_path_roles": [ + "simulated_verdict_1", + "simulated_verdict_2", + "synthetic_amendment20_closure", + "scratch_registry_binding", + ], + "candidate_or_scratch_HEAD_member_superseded": True, +} +A20_RATIFICATION_RECEIPT_CONTRACT = { + "amendment20_external_receipt_path": ( + A20_EXECUTED_TRANSITION_RECEIPT_PATH + ), + "inherited_external_receipt_path_template": ( + "docs/analysis/amendment__ratification/" + "executed_transition_receipt_v2.json" + ), + "external_receipt_mode": "100644", + "candidate_production_registry_identity": A20_PRODUCTION_REGISTRY_IDENTITY, + "external_receipt_outside_candidate_and_scratch": True, + "external_receipt_strict_canonical_tracked_head_worktree_read": True, + "external_receipt_candidate_ancestry_not_required": True, + "external_receipt_first_add_precedes_or_equals_closure_first_add": True, + "scratch_commit_forbidden_as_production_ancestor": True, + "receipt_candidate_design_tree_mode_blob_rederived": True, + "receipt_candidate_design_exactly_cross_binds_historical_a20_closure_and_verdicts": True, + "current_terminal_registry_cross_binding_required_iff_a20_terminal_revision22": True, + "later_revision_authenticates_historical_a20_design_under_30_2_3": True, + "receipt_rederives_synthetic_closure_standins_and_registry_binding": True, + "receipt_public_result_booleans_not_sufficient": True, + "later_amendment_requires_own_exact_receipt_topology_projection": True, + "qualifying_verdict_line_count": 8, + "qualifying_verdict_lines": [ + "# RATIFY", + "attested_design_byte_size: ", + "attested_design_raw_sha256: <64 lowercase hex>", + "attested_design_blob_oid: <40 lowercase hex>", + "executed_transition_receipt_byte_size: ", + "executed_transition_receipt_raw_sha256: <64 lowercase hex>", + "executed_transition_receipt_schema: executed_transition_state.v2", + "---", + ], + "decimal_grammar": ("[1-9][0-9]*|[1-9][0-9]{0,2}(,[0-9]{3})+"), + "strict_utf8_no_bom_nul_cr": True, + "lf_only_exactly_one_terminal_lf": True, + "distinct_verdict_artifact_count": 2, + "same_candidate_triple_and_receipt_pair_required": True, + "scratch": { + "candidate_commit_symbol": "C", + "scratch_commit_symbol": "S", + "scratch_is_strict_child_of_candidate": True, + "terminal_revision": 22, + "ordered_closure_domain": [13, 14, 15, 16, 17, 18, 19, 20], + "allowed_changed_paths": A20_RECEIPT_SCHEMA["expected_changed_paths"], + "standin_prefix_line_count": 4, + "standin_terminal_lines": [ + ( + "executed_transition_receipt_status: " + "pending_same_state_execution" + ), + ("simulation_context: " "amendment20_same_state_nonauthority_v1"), + "---", + ], + "standin_is_qualifying_verdict": False, + "standin_is_nonauthority_nonmergeable_noncopyable_nonreusable": True, + }, + "receipt_schema": A20_RECEIPT_SCHEMA, + "receipt_is_additional_operativity_condition": False, + "public_oracle_validates_projection_verdicts_and_receipt": True, +} +A20_SUCCESSOR_ROUTING_CONTRACT = { + "immutable_prefix_amendment": 19, + "immutable_prefix_revision": 21, + "terminal_amendment": 20, + "proposed_revision": 22, + "amendment20_boundary_count": 1, + "a20_pins_selected_before_a19_pins": True, + "a19_pin_fallback_for_terminal_a20_permitted": False, + "later_amendment_validates_inherited_a20_projection_first": True, + "current_production": { + "revision": 21, + "terminal_amendment": 19, + "ordered_closure_domain": [13, 14, 15, 16, 17, 18, 19], + "closure_count": 7, + "reject_unratified_a20_suffix": True, + }, + "terminal_successor_state": "A20_SUCCESSOR_LIFECYCLE_COMPLETE", +} +A20_FULL_PINNED_BATTERY_COLLECTED = 220 +A20_FULL_PINNED_BATTERY_COMMAND = ( + "executing_process_sys.executable -m pytest -q " + "tests/test_validate_amendment13_execution_law.py" +) +A20_ACTIVATION_TRANSITION = { + "activation_affecting": True, + "terminal_revision": 22, + "terminal_amendment": 20, + "ordered_closure_domain": [13, 14, 15, 16, 17, 18, 19, 20], + "closure_count": 8, + "closure_count_subtrahend": 14, + "public_entrypoint": "validate_ratification_operativity", + "same_state_required": True, + "full_pinned_battery_required": True, + "full_pinned_battery_collected": A20_FULL_PINNED_BATTERY_COLLECTED, + "full_pinned_battery_exact_command": A20_FULL_PINNED_BATTERY_COMMAND, + "all_nonpassing_counts": 0, + "receipt_inside_candidate_bytes": False, + "activation_requires_operator_integration_closure_and_registry_repin": ( + True + ), + "production_registry_changed_by_draft": False, +} +A20_EXPECTED_MUTATIONS = ( + "shared_source_domain_or_statement_locator_forged", + "missing_reason_rule_or_exact_cover_forged", + "purpose_authority_or_totality_forged", + "prompt_field_or_semantic_binding_forged", + "r04_order_source_binding_or_q5_shape_forged", + "r06_collection_or_lifecycle_order_forged", + "receipt_verdict_or_scratch_transition_forged", + "amendment20_terminal_pin_or_suffix_route_forged", + "evidence_freeze_identity_shadow_or_status_forged", + "failure_shadow_nonemission_provenance_forged", + "determined_as_source_underdetermined_without_ruling_forged", + "source_underdetermined_as_no_applicable_purpose_forged", + "source_underdetermined_a4_census_binding_forged", + "completed_ontology_new_arm_omitted", + "coordinate_distinct_questionnaire_spans_collapsed_to_one_body_forged", +) +A20_MUTATION_DOMAIN_BYTE_SIZE = 738 +A20_MUTATION_DOMAIN_SHA256 = ( + "eab546538a26abac04f559b73646bbca9d240832ae9d9ee82c6295a1462d0e2b" +) +A20_INHERITED_MUTATION_CENSUSES = [ + { + "inventory": "inherited_complete_certificate", + "count": 100, + "raw_sha256": ( + "fe2efd7b96c24b7cbd3c6ce350d44906eb5a88b8b35ee77565c1b133cbf1f3e3" + ), + }, + { + "inventory": "amendment16", + "count": 7, + "raw_sha256": A16_MUTATION_DOMAIN_SHA256, + }, + { + "inventory": "amendment17", + "count": 3, + "raw_sha256": A17_MUTATION_DOMAIN_SHA256, + }, + { + "inventory": "amendment18", + "count": 3, + "raw_sha256": A18_MUTATION_DOMAIN_SHA256, + }, + { + "inventory": "amendment19", + "count": 3, + "raw_sha256": A19_MUTATION_DOMAIN_SHA256, + }, +] +A20_NEW_IDENTIFIERS = { + "schema": [ + "amendment_20_dual_authority_successor_law.v1", + "executed_transition_state.v2", + "a20_evidence_freeze.v1", + "a20_failure_shadow_identity.v1", + "a20_nonemission_complement_identity.v1", + "a20_physical_source_registry.v1", + "a20_evidence_statement_registry.v1", + "a20_missing_reason_source_domain.v1", + "a20_purpose_source_domain.v1", + "a20_successor_source_binding.v1", + "a20_missing_reason_authority_rules.v1", + "a20_missing_reason_successor_relation.v1", + "a20_missing_representation_bridge.v1", + "a20_purpose_authority_rules.v1", + "a20_purpose_authority_mapping.v1", + "a20_prompt_field_evidence.v1", + "a20_prompt_field_candidate_sets.v1", + "a20_zero_candidate_positive_groups.v1", + "a20_source_settlement.v1", + "a20_normal_r04.v1", + "a20_r05_certificate.v1", + "a20_historical_r06_binding.v1", + "a20_classifier_rebuild.v1", + "a20_terminal_movement.v1", + "a20_assignment_rebuild.v1", + "a20_logical_range_rebuild.v1", + "a20_storage_population_rebuild.v1", + "a20_constructibility.v1", + "a20_full_relation_identity.v1", + "a20_comparator_census.v1", + "a20_q5.v1", + "a20_slot_rebuild.v1", + "a20_inventory_rebuild.v1", + "a20_g17_c01_rebuild.v1", + "a20_vb6_successor.v1", + "a20_successor_bundles.v1", + "a20_migrations.v1", + "a20_capture.v1", + "a20_receipt.v1", + "a20_registration.v1", + "a20_sealed_run.v1", + "a20_wall_ledger.v1", + "a20_publication.v1", + ], + "status_lifecycle_authority": [ + "not_instantiated_a4_required_before_ratify", + "pass_a4_exact_freeze", + "fail_permanent_missing_reason_authority_residue", + "fail_permanent_purpose_authority_residue", + "fail_permanent_prompt_field_or_semantic_binding_residue", + "dormant_definition", + "blocked_predecessor", + "fail_atomic_nonemission", + "accepted_exact_source_identifier", + "accepted_expressly_admitted_official_alias", + "unresolved_multiple", + "zero_candidates", + "one_candidate", + "multiple_candidates", + "complete_nonempty_reference_union", + "fail_empty_reference_union", + "SIMULATED_NONAUTHORITY", + "pending_same_state_execution", + "amendment20_same_state_nonauthority_v1", + "REVISION22_REGISTRY_REPIN", + "A20_SOURCE_RELATIONS_SETTLED_DISPATCH_DISABLED", + "A20_NORMAL_R04_REQUIRED", + "A20_R05_REQUIRED", + "A20_HISTORICAL_R06_REQUIRED", + "A20_MISSING_REASON_SUCCESSOR_ACTIVE", + "A20_CLASSIFIER_REBUILD_REQUIRED", + "A20_TERMINAL_MOVEMENT_REQUIRED", + "A20_ASSIGNMENT_REBUILD_REQUIRED", + "A20_LOGICAL_RANGE_REBUILD_REQUIRED", + "A20_STORAGE_POPULATION_REBUILD_REQUIRED", + "A20_CONSTRUCTIBILITY_REQUIRED", + "A20_FULL_RELATION_IDENTITY_REQUIRED", + "A20_COMPARATOR_REQUIRED", + "A20_Q5_REQUIRED", + "A20_SLOT_REBUILD_REQUIRED", + "A20_INVENTORY_REBUILD_REQUIRED", + "A20_G17_C01_REBUILD_REQUIRED", + "A20_VB6_REQUIRED", + "A20_SUCCESSOR_BUNDLES_REQUIRED", + "A20_MIGRATIONS_REQUIRED", + "A20_CAPTURE_REQUIRED", + "A20_RECEIPT_REQUIRED", + "A20_REGISTRATION_REQUIRED", + "A20_SEALED_RUN_REQUIRED", + "A20_WALL_LEDGER_REQUIRED", + "A20_PUBLICATION_REQUIRED", + "A20_SUCCESSOR_LIFECYCLE_COMPLETE", + ], + "member": [ + "amendment20_evidence_freeze", + "amendment20_evidence_freeze_status", + "missing_reason_authority_status", + "purpose_authority_status", + "prompt_field_semantic_binding_status", + "expected_identity_bindings", + "amendment20_ratification_ready", + "missing_reason_failure_shadow_identity", + "purpose_failure_shadow_identity", + "prompt_field_semantic_failure_shadow_identity", + "arm_status_bindings", + "active_identity_bindings_sha256", + "arm_status_member", + "arm_status", + "shadow_row_count", + "shadow_ordered_keyset_sha256", + "shadow_row_domain_sha256", + "complement_identity", + "complement_of_identity_names", + "forbidden_output_identity_names", + "forbidden_output_paths", + "nonemission_evidence", + "repository_manifest_rows_before", + "repository_manifest_rows_after", + "forbidden_outputs_absent_after_execution", + "a20_successor_source_binding_identity", + "missing_reason_source_domain_identity", + "purpose_source_domain_identity", + "missing_reason_rule_set_identity", + "purpose_rule_set_identity", + "prompt_field_evidence_identity", + "semantic_binding_identity", + "purpose_authority_mapping_row_count", + "purpose_authority_mapping_keyset_sha256", + "purpose_authority_mapping_domain_sha256", + "purpose_authority_mapping_disposition_counts", + "prompt_field_evidence_row_count", + "prompt_field_evidence_keyset_sha256", + "prompt_field_evidence_domain_sha256", + "prompt_field_evidence_disposition_counts", + "prompt_field_candidate_set_row_count", + "prompt_field_candidate_set_keyset_sha256", + "prompt_field_candidate_set_domain_sha256", + "prompt_field_candidate_set_disposition_counts", + "zero_candidate_positive_group_row_count", + "zero_candidate_positive_group_keyset_sha256", + "zero_candidate_positive_group_domain_sha256", + "zero_candidate_positive_group_empty_union_count", + "purpose_authority_mapping_rows", + "prompt_field_evidence_rows", + "prompt_field_candidate_set_rows", + "zero_candidate_positive_group_rows", + "SIMULATED_STATE_AUTHORITY", + "SIMULATION_CONTEXT", + "candidate_commit_identity", + "scratch_transition", + "changed_paths", + "changed_path_domain_sha256", + ], + "identity_prefix": [ + "psid-prompt-field-evidence:", + "psid-prompt-field-candidate-set:", + "psid-zero-candidate-positive-group:", + "a20-lifecycle-output:", + ], + "python": [ + "_validate_amendment20_draft_design", + "_validate_amendment20_ratification_design", + "_validate_inherited_amendment20_ratification_design", + "_validate_amendment20_evidence_freeze", + "_canonical_amendment20_repository_path", + "_read_amendment20_worktree_file", + "_reconstruct_amendment20_repository_manifest", + "_validate_amendment20_nonemission_evidence", + "_parse_amendment20_implementation_pins", + "_parse_amendment20_projection", + "run_amendment20_contract_mutation_tests", + "validate_amendment20_qualifying_verdict", + "_validate_amendment20_scratch_transition_context", + "_amendment20_registry_behavior_ast", + "_parse_amendment20_scratch_registry_binding", + "_validate_amendment20_transition_receipt", + "_validate_amendment20_r06_collection_binding", + ], +} +A20_SUPERSESSION_COVERAGE = [ + "19.3.3_prompt_purpose_manifest_era_semantic_and_post_o_p_joins", + "20.4.2_and_33.2_33.3_33.7_frozen_q5_shapes", + "19.4.2_26.6.1_26.10.1_g17_header_q5_inventory_slot_projections", + "25.2_through_25.4_historical_missing_reason_census_and_settlement", + "25.5_25.10.1_25.10.2_32.4.4_32.7_32.8_33.4_successor_stop", + "25.6.6_32.4.2_32.4.3_32.7_r06_selector_input_and_result", + "25.9_25.10_26.10.3_dc71_lifecycle_definition_timing", + "26.6.3_26.10.1_33.2.2_33.2.3_33.7_construction_order", + "26.11.2_complete_r04_r05_r06_gate", + "28.2.1_28.4_verdict_operator_closure_order", + "29.4.4_29.4.5_source_member_identity_and_reconstruction", + "29.4.1_canonicalization_and_identity_equations", + "30.2.3_30.2.4_verdict_checking_and_public_atomic_operativity", + "30.2.2_five_key_registry_context_and_caller_context_prohibition", + "30.2.1_amendment_revision_arithmetic", + "31.3.1_31.3.2_31.3.3_receipt_and_nonexistent_31.5_anchor", + "32.2.1_32.2.2_33.8_historical_279_build_input_envelope", + "32.4.4_false_r06_lifecycle_booleans", + "30.4.1_31.2.2_32.5.1_33.5.1_implementation_pins_and_review", + "33.2.2_33.2.3_a19_purpose_rows_and_failure_member", + "33.3.2_d0_search_proof_d1_construction", + "33.4_obsolete_campaign_pin_and_a20_out_of_scope_label", + "33.5.2_33.5.3_a19_projection_routing_and_activation", + "33.6_mutation_inventory_and_inherited_census", + "33.7_construction_ambiguity_q5_and_reconstruction_rows", + "33.8_questionnaire_occurrence_read_vs_serialization_scope", + "33.9_terminal_a19_prospective_effect", + "20.3_21.3_21.5_22.2_22.5_23.2_23.5_24.2_24.6_algorithms", + "19.6_19.8_20.7_20.8_21.8_21.9_22.8_22.9_23.8_23.9_24.9_24.10_25.9_25.10_artifacts", + "27.3_27.6_28.2.2_29.4.7_seals_closures_and_census", +] +A20_NORMATIVE_MANIFEST = { + "schema_version": "amendment_20_dual_authority_successor_law.v1", + "canonicalization": A20_CANONICALIZATION, + "prefix_identity": { + "blob_oid": REVISION21_BLOB_OID, + "byte_size": REVISION21_BYTE_SIZE, + "raw_sha256": REVISION21_SHA256, + }, + "controlling_external_records": A20_CONTROLLING_EXTERNAL_RECORDS, + "amendment20_evidence_freeze": A20_EVIDENCE_FREEZE, + "evidence_freeze_contract": A20_EVIDENCE_FREEZE_CONTRACT, + "evidence_campaign": A20_EVIDENCE_CAMPAIGN_CONTRACT, + "source_infrastructure": A20_SOURCE_INFRASTRUCTURE_CONTRACT, + "missing_reason_authority": A20_MISSING_REASON_AUTHORITY_CONTRACT, + "purpose_authority": A20_PURPOSE_AUTHORITY_CONTRACT, + "prompt_field_semantic_binding": ( + A20_PROMPT_FIELD_SEMANTIC_BINDING_CONTRACT + ), + "r04_q5": A20_R04_Q5_CONTRACT, + "r06_lifecycle": A20_R06_LIFECYCLE_CONTRACT, + "ratification_receipt": A20_RATIFICATION_RECEIPT_CONTRACT, + "successor_routing": A20_SUCCESSOR_ROUTING_CONTRACT, + "activation_transition": A20_ACTIVATION_TRANSITION, + "mutation_inventory": list(A20_EXPECTED_MUTATIONS), + "mutation_domain_byte_size": A20_MUTATION_DOMAIN_BYTE_SIZE, + "mutation_domain_sha256": A20_MUTATION_DOMAIN_SHA256, + "inherited_mutation_censuses": A20_INHERITED_MUTATION_CENSUSES, + "supersession_coverage": A20_SUPERSESSION_COVERAGE, + "new_identifiers": A20_NEW_IDENTIFIERS, +} + +A13_SECTION_SEMANTIC_SHA256: Mapping[str, str] = { + "27.2": "2e1d4e8282e393f2f8f8092c5b9823d69a4e6926fb5fbd753b77813e47f7941e", + "27.3": "50b5a2e780a4b5b7152390e85e01df5f5397f5263fb2dd3dae43947a96f91ff0", + "27.4": "ae7dd9ea588a2242f52d4e66bd3662909eee0f987a1d582db21786837c47253c", + "27.5": "f5ee9246c5826b5b65e90149cc2e2c7574eb32f49df472ce528fc0690ab26d46", + "27.6": "b8b23250e218093d892c6ad286f05226469d5abf08a1f87d8a0942bbbbef5d08", + "27.7": "2dfcffcba99639a6d9b00efc6d0d06364a4c0e2fd522238f07dc715228d8ad2e", + "27.8": "fdc5441ef8c2f60bb8334658b4c44bcd52f8355b4681a495e81c4b7aaaa5479e", +} +A14_SECTION_SEMANTIC_SHA256 = ( + "8d17464268b95d500dcc4d7640edee0f26180a70172cdb3a3966a8e6d2408062" +) +A15_SECTION_SEMANTIC_SHA256 = ( + "a1e7bcb2aabc2b43cc92b09e1d8bf96d644d377ae70d81d9c5f40d7fafa94f3b" +) +A16_SECTION_SEMANTIC_SHA256 = ( + "8ed37933bc04d9c2233d62c74385bd03d8e0862067147a295218e37bcd11125a" +) + +A13_COMPARATOR_ROWS = ( + ( + "DC-72", + "§§26.10.1–26.10.3, DC-64, §26.11, and §27.2 Amendment-12 ratification identity", + "replaced-by-named-successor: every revision-14 D12 document-only locator and the obsolete no-ratification clause select actual Amendment-12 history by exact commit/blob/bytes/dual-attestation identity; every other ceremony, noninstantiation, and stop survives", + ), + ( + "DC-73", + "§§26.7.2, 27.3, and 27.4 exact 28 incompatible proof rows", + "replaced-by-named-successor: terminal no-alias successor, deterministic predecessor-family map, retained predecessor, supersession edge, overlay, and era membership", + ), + ( + "DC-74", + "§§26.7, 26.11.2, and 27.5 exact ten incomplete fragments and five prior continuation citations", + "replaced-by-named-successor for the ten only: eight disclosed terminal fragments plus two exact G75 compositions; five-citation Amendment-12 domain lawfully unchanged", + ), + ( + "DC-75", + "§§26.7.1, 27.3, and 27.6 doc-036 and six-era reseal", + "lawfully-unchanged-with-reason: eight sole-field changes were already determinate; the new proof successor now permits one coherent nine-row overlay and all six exact successor-seal domains", + ), + ( + "DC-76", + "§§26.8–26.9 and 27.7 validation evidence, mutations, and 14 law gaps", + "lawfully-unchanged-with-reason: 71 historical attacks remain exact; seven new attacks are separate; all 14 law gaps and every row outside 46 remain untouched", + ), + ( + "DC-77", + "§§25.10, 26.10–26.11, and 27.8 lifecycle, authority, Q5, and production after applying DC-72's D12 locator", + "lawfully-unchanged-with-reason: apart from the exact ratification locator named in DC-72, the draft emits no authority, tier-2 execution occurs later if ratified, and the independent Amendment-11 blocker remains controlling", + ), +) + + +def _require(condition: bool, message: str) -> None: + if not condition: + raise LawError(message) + + +def _require_exact_keys( + value: Mapping[str, Any], expected: set[str], label: str +) -> None: + _require(set(value) == expected, f"{label} keyset drift") + + +def canonical_json_bytes(value: Any) -> bytes: + """Return the law's compact, sorted, terminal-LF JSON bytes.""" + + try: text = json.dumps( value, allow_nan=False, @@ -3860,6 +5494,38 @@ def _normalize_implementation_pin_values(section: str) -> str: "publisher_sha256", ) +_A20_IMPLEMENTATION_PIN_PATTERN = re.compile( + r"The Amendment-20-governed active identity is exactly mode " + r"`(?P[0-9]+)` and these\n" + r"three path/blob/byte/hash rows:\n\n" + r"\| Path \| Git blob \| Bytes \| Raw SHA-256 \|\n" + r"\|---\|---\|---:\|---\|\n" + r"\| `scripts/validate_amendment13_execution_law\.py` \| " + r"`(?P[0-9a-f]{40})` \| " + r"(?P[0-9][0-9,]*) \| " + r"`(?P[0-9a-f]{64})` \|\n" + r"\| `tests/test_validate_amendment13_execution_law\.py` \| " + r"`(?P[0-9a-f]{40})` \| " + r"(?P[0-9][0-9,]*) \| " + r"`(?P[0-9a-f]{64})` \|\n" + r"\| `scripts/build_amendment13_tier2_repairs\.py` \| " + r"`(?P[0-9a-f]{40})` \| " + r"(?P[0-9][0-9,]*) \| " + r"`(?P[0-9a-f]{64})` \|\n" +) +_A20_IMPLEMENTATION_PIN_VALUE_GROUPS = ( + "mode", + "validator_blob", + "validator_size", + "validator_sha256", + "test_blob", + "test_size", + "test_sha256", + "publisher_blob", + "publisher_size", + "publisher_sha256", +) + def _amendment15_text(raw: bytes) -> str: _require( @@ -5133,431 +6799,1289 @@ def _parse_amendment19_projection(raw: bytes) -> dict[str, Any]: } -def _parse_active_implementation_pins(raw: bytes) -> dict[str, Any]: - """Select the newest append-only implementation-pin successor.""" - - if len(raw) > REVISION20_BYTE_SIZE: - return _parse_amendment19_implementation_pins(raw) - if len(raw) > REVISION19_BYTE_SIZE: - return _parse_amendment18_implementation_pins(raw) - if len(raw) > REVISION18_BYTE_SIZE: - return _parse_amendment17_implementation_pins(raw) - if len(raw) > REVISION17_BYTE_SIZE: - return _parse_amendment16_implementation_pins(raw) - if len(raw) > REVISION16_BYTE_SIZE: - return _parse_amendment15_implementation_pins(raw) - return _parse_amendment14_projection(raw)["implementation_pins"] - +def _amendment20_text(raw: bytes) -> str: + """Return only A20 while authenticating the complete revision-21 prefix.""" -def _parse_amendment16_law_values(section: str) -> dict[str, Any]: - lines = _fenced_lines_after( - section, - "The A16 projection exact-parses and independently compares at least " - "these\nenacted values:\n\n", - "Amendment-16 ratification law values", + _require( + len(raw) > REVISION21_BYTE_SIZE + and _sha256(raw[:REVISION21_BYTE_SIZE]) == REVISION21_SHA256 + and _git_blob_oid(raw[:REVISION21_BYTE_SIZE]) == REVISION21_BLOB_OID + and raw[REVISION21_BYTE_SIZE:].startswith(AMENDMENT20_BOUNDARY) + and raw.count(AMENDMENT20_BOUNDARY) == 1 + and raw.endswith(b"\n"), + "governing Amendment-20 document violates immutable-prefix law", ) - expected_names = tuple(A16_RATIFICATION_LAW_VALUES) + suffix = raw[REVISION21_BYTE_SIZE:] + headings = list(_AMENDMENT_SECTION_PATTERN.finditer(suffix)) _require( - len(lines) == len(expected_names), - "Amendment-16 ratification law value count drift", + headings and int(headings[0].group("amendment")) == 20, + "governing Amendment-20 boundary sequence drift", ) - values: dict[str, Any] = {} - for expected_name, line in zip(expected_names, lines, strict=True): - _require(" = " in line, "Amendment-16 ratification law row drift") - name, serialized = line.split(" = ", 1) + if len(headings) > 1: + next_boundary = headings[1].start() _require( - name == expected_name, - "Amendment-16 ratification law value order drift", + next_boundary > 0 + and suffix[next_boundary - 1 : next_boundary] == b"\n", + "governing Amendment-20 successor boundary drift", ) - if serialized.startswith("["): - try: - value = json.loads(serialized) - except json.JSONDecodeError as error: - raise LawError( - "Amendment-16 ratification law array drift" - ) from error - elif serialized.isdigit(): - value = int(serialized) - else: - value = serialized - values[name] = value - return values + suffix = suffix[: next_boundary - 1] + try: + return suffix.decode("utf-8") + except UnicodeDecodeError as error: + raise LawError("governing Amendment-20 suffix is not UTF-8") from error -def _parse_a16_verdict_artifacts(section: str) -> list[dict[str, Any]]: - rows = _markdown_table( - section, - "| Path | Bytes | Raw SHA-256 |", - "|---|---:|---|", - 2, - "Amendment-15 verdict identities in Amendment 16", +def _amendment20_implementation_pin_match(section: str) -> re.Match[str]: + matches = list(_A20_IMPLEMENTATION_PIN_PATTERN.finditer(section)) + _require( + len(matches) == 1, + "Amendment-20 implementation pin block grammar drift", ) - return [ - { - "path": _code_tokens(path, 1, "A15 verdict path")[0], - "byte_size": int(size.replace(",", "")), - "raw_sha256": _code_tokens(raw_sha, 1, "A15 verdict SHA-256")[0], - } - for path, size, raw_sha in rows - ] + return matches[0] -def _parse_a14_historical_binding_from_a16(section: str) -> dict[str, Any]: - rows = _markdown_table( - section, - "| Historical closure | Exact path | Bytes | Raw SHA-256 |", - "|---|---|---:|---|", - 1, - "Amendment-14 historical closure binding in Amendment 16", - ) - label, path, size, raw_sha = rows[0] - _require( - label == "Amendment 14", - "Amendment-14 historical closure label drift", - ) +def _normalize_amendment20_implementation_pin_values(section: str) -> str: + """Normalize only the ten independently authenticated A20 pin values.""" + + match = _amendment20_implementation_pin_match(section) + parts: list[str] = [] + cursor = 0 + for group in _A20_IMPLEMENTATION_PIN_VALUE_GROUPS: + start, end = match.span(group) + _require(start >= cursor, "Amendment-20 pin capture ordering drift") + parts.extend((section[cursor:start], f"<{group.upper()}>")) + cursor = end + parts.append(section[cursor:]) + return "".join(parts) + + +def _parse_amendment20_implementation_pins(raw: bytes) -> dict[str, Any]: + section = _amendment20_text(raw) + match = _amendment20_implementation_pin_match(section) return { - "path": _code_tokens(path, 1, "historical A14 closure path")[0], - "raw_byte_size": int(size.replace(",", "")), - "raw_sha256": _code_tokens( - raw_sha, - 1, - "historical A14 closure SHA-256", - )[0], + "mode": match.group("mode"), + "files": [ + { + "path": "scripts/validate_amendment13_execution_law.py", + "blob_oid": match.group("validator_blob"), + "byte_size": int( + match.group("validator_size").replace(",", "") + ), + "sha256": match.group("validator_sha256"), + }, + { + "path": "tests/test_validate_amendment13_execution_law.py", + "blob_oid": match.group("test_blob"), + "byte_size": int(match.group("test_size").replace(",", "")), + "sha256": match.group("test_sha256"), + }, + { + "path": "scripts/build_amendment13_tier2_repairs.py", + "blob_oid": match.group("publisher_blob"), + "byte_size": int( + match.group("publisher_size").replace(",", "") + ), + "sha256": match.group("publisher_sha256"), + }, + ], } -def _parse_a15_expected_closure_from_a16( - section: str, - verdict_artifacts: Sequence[Mapping[str, Any]], -) -> dict[str, Any]: - rows = _markdown_table( +def _parse_a20_normative_manifest(section: str) -> dict[str, Any]: + marker = ( + "The exact Amendment-20 normative manifest is this one-line " + "terminal-LF canonical JSON value:\n\n" + ) + remainder = _unique_after( section, - "| Closure member | Exact value |", - "|---|---|", - 8, - "Amendment-15 closure values in Amendment 16", + marker, + "Amendment-20 normative manifest", ) - values = {name: value for name, value in rows} _require( - values["`verdict_artifacts`"] - == "the exact two ordered §30.3.2 path/byte/SHA objects", - "Amendment-15 closure verdict reference drift", + remainder.startswith("~~~text\n"), + "Amendment-20 normative manifest fence start drift", + ) + fenced = remainder[len("~~~text\n") :] + _require( + "\n~~~\n" in fenced, + "Amendment-20 normative manifest fence end drift", + ) + body, _ = fenced.split("\n~~~\n", 1) + _require( + "\n" not in body and bool(body), + "Amendment-20 normative manifest line shape drift", + ) + return _strict_canonical_json( + body.encode("ascii") + b"\n", + "Amendment-20 normative manifest", ) - return { - "amendment_number": int( - _code_tokens( - values["`amendment_number`"], - 1, - "A15 closure amendment number", - )[0] - ), - "attested_candidate_design_blob_oid": _code_tokens( - values["`attested_candidate_design_blob_oid`"], - 1, - "A15 closure design blob", - )[0], - "attested_candidate_design_byte_size": int( - _code_tokens( - values["`attested_candidate_design_byte_size`"], - 1, - "A15 closure design size", - )[0] - ), - "attested_candidate_design_raw_sha256": _code_tokens( - values["`attested_candidate_design_raw_sha256`"], - 1, - "A15 closure design SHA-256", - )[0], - "ratification_commit": _code_tokens( - values["`ratification_commit`"], - 1, - "A15 closure ratification commit", - )[0], - "ratification_commit_sole_parent": _code_tokens( - values["`ratification_commit_sole_parent`"], - 1, - "A15 closure ratification parent", - )[0], - "operator_merge_commit": _code_tokens( - values["`operator_merge_commit`"], - 1, - "A15 closure operator merge", - )[0], - "verdict_artifacts": [dict(row) for row in verdict_artifacts], - } -def _parse_a16_historical_r05_binding(section: str) -> dict[str, Any]: - lines = _fenced_lines_after( - section, - "The serialized member remains historical Amendment-15 material:\n\n", - "Amendment-16 historical R05 binding", +def _validate_amendment20_evidence_freeze( + freeze: Mapping[str, Any], + freeze_contract: Mapping[str, Any], + *, + require_ratification_ready: bool, +) -> None: + """Validate the closed drafting or status-dependent A4 identity shape.""" + + _require_exact_keys( + freeze, + set(A20_EVIDENCE_FREEZE), + "Amendment-20 evidence freeze", ) - expected_names = tuple(A16_HISTORICAL_R05_BINDING) + identity_contract = freeze_contract.get("identity_contract") _require( - len(lines) == len(expected_names), - "Amendment-16 historical R05 binding count drift", + isinstance(identity_contract, Mapping) + and identity_contract.get("common_identity_names") + == A20_COMMON_IDENTITY_NAMES + and identity_contract.get("arm_identity_contracts") + == A20_ARM_IDENTITY_CONTRACTS + and identity_contract.get("pass_identity_keys") + == A20_PASS_IDENTITY_KEYS + and identity_contract.get("arm_pass_identity_keys") + == A20_ARM_PASS_IDENTITY_KEYS + and identity_contract.get("successor_binding_identity_keys") + == A20_SUCCESSOR_BINDING_IDENTITY_KEYS + and identity_contract.get("failure_shadow_identity_keys") + == A20_FAILURE_SHADOW_IDENTITY_KEYS + and identity_contract.get("nonemission_complement_identity_keys") + == A20_NONEMISSION_COMPLEMENT_IDENTITY_KEYS + and identity_contract.get("failure_nonemission_evidence_keys") + == A20_FAILURE_NONEMISSION_EVIDENCE_KEYS + and identity_contract.get("repository_manifest_row_keys") + == A20_REPOSITORY_MANIFEST_ROW_KEYS + and identity_contract.get("successor_binding_identity_name") + == "a20_successor_source_binding_identity" + and identity_contract.get("successor_binding_digest_excludes_self") + is True + and identity_contract.get( + "failure_shadow_rows_are_exact_forbidden_output_complement" + ) + is True + and identity_contract.get( + "failure_shadow_paths_are_exact_arm_contract_paths" + ) + is True + and identity_contract.get( + "lifecycle_booleans_are_not_accepted_as_self_attestation" + ) + is True, + "Amendment-20 evidence-freeze identity contract drift", ) - binding: dict[str, Any] = {} - for expected_name, line in zip(expected_names, lines, strict=True): - _require(" = " in line, "Amendment-16 historical R05 row drift") - name, value = line.split(" = ", 1) + bindings = freeze.get("expected_identity_bindings") + _require( + freeze.get("schema_version") == "a20_evidence_freeze.v1" + and isinstance(bindings, Mapping) + and len(bindings) == len(A20_EXPECTED_IDENTITY_NAMES) + and set(bindings) == set(A20_EXPECTED_IDENTITY_NAMES) + and type(freeze.get("amendment20_ratification_ready")) is bool, + "Amendment-20 evidence-freeze object drift", + ) + + drafting_status = "not_instantiated_a4_required_before_ratify" + freeze_status = freeze.get("amendment20_evidence_freeze_status") + if freeze_status == drafting_status: _require( - name == expected_name, - "Amendment-16 historical R05 binding order drift", + all( + freeze.get(status_member) is None + for status_member in A20_ARM_IDENTITY_CONTRACTS + ) + and all(identity is None for identity in bindings.values()) + and freeze["amendment20_ratification_ready"] is False, + "Amendment-20 drafting evidence-freeze shape drift", ) - binding[name] = int(value) if value.isdigit() else value - return binding - + _require( + not require_ratification_ready, + "Amendment-20 evidence freeze is not ratification-ready", + ) + return -def _parse_amendment16_projection(raw: bytes) -> dict[str, Any]: - section = _amendment16_text(raw) - verdict_artifacts = _parse_a16_verdict_artifacts(section) - oracle_mutations = _fenced_lines_after( - section, - "The Amendment-16 operativity enforcement inventory is exactly:\n\n", - "Amendment-16 oracle mutations", - ) - mutation_digest = _code_after( - section, - "The ordered canonical name-array domain SHA-256 is\n", - "Amendment-16 oracle mutation digest", - ) + status_domains = freeze_contract.get("final_arm_status_domains") _require( - _sha256(canonical_json_bytes(oracle_mutations)) == mutation_digest, - "Amendment-16 oracle mutation name-array digest drift", + freeze_status + == freeze_contract.get("final_required_evidence_freeze_status") + and isinstance(status_domains, Mapping) + and set(status_domains) == set(A20_ARM_IDENTITY_CONTRACTS) + and all( + freeze.get(status_member) in status_domains[status_member] + for status_member in A20_ARM_IDENTITY_CONTRACTS + ) + and freeze["amendment20_ratification_ready"] is True, + "Amendment-20 evidence freeze is not ratification-ready", ) - projection = { - "section_semantic_sha256": _sha256( - _normalize_amendment16_implementation_pin_values(section).encode( - "utf-8" + + def nonzero_lower_hex(value: Any, length: int) -> bool: + return _is_lower_hex(value, length) and value != "0" * length + + def validate_digest_identity( + identity: Any, + identity_name: str, + *, + arm_status_member: str | None = None, + arm_status: str | None = None, + ) -> None: + expected_keys = ( + A20_PASS_IDENTITY_KEYS + if arm_status_member is None + else A20_ARM_PASS_IDENTITY_KEYS + ) + _require( + isinstance(identity, Mapping), + f"Amendment-20 {identity_name} identity is absent", + ) + _require_exact_keys( + identity, + set(expected_keys), + f"Amendment-20 {identity_name} identity", + ) + _require( + identity["identity_name"] == identity_name + and type(identity["row_count"]) is int + and identity["row_count"] > 0 + and nonzero_lower_hex(identity["ordered_keyset_sha256"], 64) + and nonzero_lower_hex(identity["row_domain_sha256"], 64) + and identity["status"] == "pass", + f"Amendment-20 {identity_name} identity count/digest/status drift", + ) + if arm_status_member is not None: + _require( + identity["arm_status_member"] == arm_status_member + and identity["arm_status"] == arm_status == "pass", + f"Amendment-20 {identity_name} arm-status cross-binding drift", ) - ), - "ratification_law_values": _parse_amendment16_law_values(section), - "ordered_domain_expression": _code_after( - section, - "ordered closure domain is every integer amendment\nnumber in " - "Python's half-open ", - "Amendment-16 ordered domain expression", - ), - "generated_closure_path_rule": _code_after( - section, - "zero based, is Amendment `13 + i`; its generated path is\n", - "Amendment-16 generated closure path rule", - ), - "combined_closure_paths": _fenced_lines_after( - section, - "The next lawful repin selects revision 18 and binds exactly " - "these four ordered\npaths:\n\n", - "Amendment-16 combined closure paths", - ), - "a14_historical_closure_binding": ( - _parse_a14_historical_binding_from_a16(section) - ), - "a15_verdict_artifacts": verdict_artifacts, - "a15_expected_closure": _parse_a15_expected_closure_from_a16( - section, verdict_artifacts - ), - "ratification_sequence": _fenced_lines_after( - section, - "The combined sequence is:\n\n", - "Amendment-16 ratification sequence", - ), - "historical_r05_binding": _parse_a16_historical_r05_binding(section), - "implementation_pins": _parse_amendment16_implementation_pins(raw), - "oracle_mutations": oracle_mutations, - "oracle_mutation_domain_sha256": mutation_digest, - "supersession_map": _markdown_table( - section, - "| Earlier normative anchor | Amendment-16 disposition |", - "|---|---|", - 11, - "Amendment-16 supersession map", - ), - "schema_operation_identifiers": _fenced_lines_after( - section, - "The exact Amendment-16 schema and operation identifiers are:\n\n", - "Amendment-16 schema and operation identifiers", - ), - "status_identifiers": _fenced_lines_after( - section, - "The exact Amendment-16 status identifiers are:\n\n", - "Amendment-16 status identifiers", - ), - "python_identifiers": _fenced_lines_after( - section, - "The exact new public/private Python identifiers are:\n\n", - "Amendment-16 Python identifiers", - ), - } - inventories = ( - projection["schema_operation_identifiers"], - projection["status_identifiers"], - projection["python_identifiers"], + + successor_binding_name = "a20_successor_source_binding_identity" + for identity_name in A20_COMMON_IDENTITY_NAMES: + if identity_name != successor_binding_name: + validate_digest_identity(bindings[identity_name], identity_name) + + for status_member, arm_contract in A20_ARM_IDENTITY_CONTRACTS.items(): + arm_status = freeze[status_member] + pass_identity_names = arm_contract["pass_identity_names"] + forbidden_output_paths = arm_contract["forbidden_output_paths"] + shadow_name = arm_contract["failure_shadow_identity_name"] + if arm_status == arm_contract["pass_status"]: + _require( + bindings[shadow_name] is None, + f"Amendment-20 {status_member} pass carries a failure shadow", + ) + for identity_name in pass_identity_names: + validate_digest_identity( + bindings[identity_name], + identity_name, + arm_status_member=status_member, + arm_status=arm_status, + ) + continue + + _require( + arm_status == arm_contract["failure_status"] + and all(bindings[name] is None for name in pass_identity_names), + f"Amendment-20 {status_member} failure emitted a forbidden identity", + ) + shadow = bindings[shadow_name] + _require( + isinstance(shadow, Mapping), + f"Amendment-20 {status_member} failure shadow is absent", + ) + _require_exact_keys( + shadow, + set(A20_FAILURE_SHADOW_IDENTITY_KEYS), + f"Amendment-20 {status_member} failure shadow", + ) + complement_rows = [ + {"emitted": False, "identity_name": name} + for name in pass_identity_names + ] + complement_keyset_sha256 = _sha256( + canonical_json_bytes(pass_identity_names) + ) + complement_domain_sha256 = _sha256( + canonical_json_bytes(complement_rows) + ) + _require( + shadow["schema_version"] == "a20_failure_shadow_identity.v1" + and shadow["identity_name"] == shadow_name + and shadow["arm_status_member"] == status_member + and shadow["arm_status"] == arm_status + and shadow["forbidden_output_identity_names"] + == pass_identity_names + and shadow["forbidden_output_paths"] == forbidden_output_paths + and len(forbidden_output_paths) == len(pass_identity_names) + and type(shadow["shadow_row_count"]) is int + and shadow["shadow_row_count"] == len(pass_identity_names) + and shadow["shadow_ordered_keyset_sha256"] + == complement_keyset_sha256 + and shadow["shadow_row_domain_sha256"] == complement_domain_sha256 + and shadow["status"] == arm_status, + f"Amendment-20 {status_member} failure-shadow cross-binding drift", + ) + + complement = shadow["complement_identity"] + _require( + isinstance(complement, Mapping), + f"Amendment-20 {status_member} nonemission complement is absent", + ) + _require_exact_keys( + complement, + set(A20_NONEMISSION_COMPLEMENT_IDENTITY_KEYS), + f"Amendment-20 {status_member} nonemission complement", + ) + _require( + complement["schema_version"] + == "a20_nonemission_complement_identity.v1" + and complement["complement_of_identity_names"] + == pass_identity_names + and type(complement["row_count"]) is int + and complement["row_count"] == len(pass_identity_names) + and complement["ordered_keyset_sha256"] == complement_keyset_sha256 + and complement["row_domain_sha256"] == complement_domain_sha256 + and complement["status"] == arm_status, + f"Amendment-20 {status_member} nonemission complement drift", + ) + + nonemission = shadow["nonemission_evidence"] + _require( + isinstance(nonemission, Mapping), + f"Amendment-20 {status_member} nonemission evidence is absent", + ) + _require_exact_keys( + nonemission, + set(A20_FAILURE_NONEMISSION_EVIDENCE_KEYS), + f"Amendment-20 {status_member} nonemission evidence", + ) + _require( + nonzero_lower_hex(nonemission["execution_commit"], 40) + and nonzero_lower_hex(nonemission["execution_tree_oid"], 40), + f"Amendment-20 {status_member} nonemission object identity drift", + ) + _validate_amendment20_nonemission_evidence( + nonemission, + forbidden_output_paths, + status_member=status_member, + ) + + successor_binding = bindings[successor_binding_name] + _require( + isinstance(successor_binding, Mapping), + "Amendment-20 successor source-binding identity is absent", + ) + _require_exact_keys( + successor_binding, + set(A20_SUCCESSOR_BINDING_IDENTITY_KEYS), + "Amendment-20 successor source-binding identity", ) + arm_status_bindings = { + status_member: freeze[status_member] + for status_member in A20_ARM_IDENTITY_CONTRACTS + } + active_binding_preimage = { + "arm_status_bindings": arm_status_bindings, + "expected_identity_bindings": { + identity_name: bindings[identity_name] + for identity_name in A20_EXPECTED_IDENTITY_NAMES + if identity_name != successor_binding_name + }, + } _require( - all(len(values) == len(set(values)) for values in inventories) - and set(inventories[0]).isdisjoint(inventories[1]) - and set(inventories[0]).isdisjoint(inventories[2]) - and set(inventories[1]).isdisjoint(inventories[2]), - "Amendment-16 enacted identifier inventory consistency drift", + successor_binding["identity_name"] == successor_binding_name + and type(successor_binding["row_count"]) is int + and successor_binding["row_count"] > 0 + and nonzero_lower_hex(successor_binding["ordered_keyset_sha256"], 64) + and nonzero_lower_hex(successor_binding["row_domain_sha256"], 64) + and successor_binding["arm_status_bindings"] == arm_status_bindings + and successor_binding["active_identity_bindings_sha256"] + == _sha256(canonical_json_bytes(active_binding_preimage)) + and successor_binding["status"] == "pass", + "Amendment-20 successor source-binding identity cross-binding drift", ) - return projection -def _amendment14_text(raw: bytes) -> str: +def _validate_a20_manifest_contract( + manifest: Mapping[str, Any], + *, + require_ratification_ready: bool = False, +) -> None: + """Validate every A20 limb from one closed normative projection.""" + _require( - len(raw) > REVISION15_BYTE_SIZE - and _sha256(raw[:REVISION15_BYTE_SIZE]) == REVISION15_SHA256 - and raw[REVISION15_BYTE_SIZE:].startswith(AMENDMENT14_BOUNDARY) - and raw.endswith(b"\n"), - "governing Amendment-14 document violates immutable-prefix law", + manifest["controlling_external_records"] + == A20_CONTROLLING_EXTERNAL_RECORDS, + "Amendment-20 controlling external-record pins drift", ) - suffix = raw[REVISION15_BYTE_SIZE:] - if AMENDMENT15_BOUNDARY in suffix: - _require( - suffix.count(AMENDMENT15_BOUNDARY) == 1, - "governing document has an ambiguous Amendment-15 boundary", - ) - suffix = suffix[: suffix.index(AMENDMENT15_BOUNDARY)] - try: - return suffix.decode("utf-8") - except UnicodeDecodeError as error: - raise LawError("governing Amendment-14 suffix is not UTF-8") from error - -def _parse_a14_verdict_artifacts(section: str) -> list[dict[str, Any]]: - rows = _markdown_table( - section, - "| Path | Bytes | Raw SHA-256 |", - "|---|---:|---|", - 2, - "Amendment-13 verdict identities", + source = manifest["source_infrastructure"] + _require( + source["physical_source_row_keys"] == A20_PHYSICAL_SOURCE_ROW_KEYS + and source["evidence_statement_row_keys"] + == A20_EVIDENCE_STATEMENT_ROW_KEYS + and source["path_rule"] + == "repository_relative_canonical_traversal_free" + and source["machine_local_absolute_paths_forbidden"] is True + and source["historical_domains_preserved"] + == { + "a11_source_count": 47, + "questionnaire_document_count": 81, + "a19_build_input_source_document_count": 257, + "a19_build_input_repair_seal_count": 22, + "a19_build_input_row_count": 279, + } + and source["semantic_domain_order"] + == ["missing_reason_source_domain", "purpose_source_domain"] + and source["semantic_domain_identity_keys"] + == A20_SEMANTIC_DOMAIN_IDENTITY_KEYS + and source["successor_source_binding_keys"] + == A20_SOURCE_INFRASTRUCTURE_CONTRACT["successor_source_binding_keys"] + and all( + member in source["semantic_domain_identity_keys"] + for member in ( + "included_source_rows", + "included_source_count", + "included_source_keyset_sha256", + "included_source_domain_sha256", + "excluded_source_rows", + "excluded_source_count", + "excluded_source_keyset_sha256", + "excluded_source_domain_sha256", + "admitted_statement_rows", + "statement_count", + "statement_keyset_sha256", + "statement_domain_sha256", + "status", + ) + ), + "Amendment-20 separate semantic-domain contract drift", ) - return [ - { - "path": _code_tokens(path, 1, "A13 verdict path")[0], - "byte_size": int(size.replace(",", "")), - "raw_sha256": _code_tokens(raw_sha, 1, "A13 verdict SHA-256")[0], + missing = manifest["missing_reason_authority"] + _require( + missing["formerly_unresolved_literal_occurrence_count"] == 524_538 + and len(missing["occurrence_identity_position_order"]) == 12 + and missing["claim_type"] + == "strict_json_boolean_excluding_integer_coercion" + and missing["projection_requirements"] + == [ + "exact", + "nonzero", + "disjoint", + "collectively_exhaustive", + "exception_complete", + ] + and missing["representation_bridge_probe"][ + "observations_are_nonauthority" + ] + is True + and missing["representation_bridge_probe"]["accepted_bridge_identity"] + is None + and missing["representation_bridge_probe"][ + "bridge_required_before_acceptance" + ] + is True + and missing["transactional_atomic_nonemission"] is True, + "Amendment-20 missing-reason authority contract drift", + ) + purpose = manifest["purpose_authority"] + _require( + purpose["official_purpose_order"] == A19_OFFICIAL_PURPOSES + and purpose["completed_ontology_order"] + == [*A19_OFFICIAL_PURPOSES, "source_underdetermined"] + and purpose["prompt_denominator_a4_freeze_slot"] is None + and purpose["required_disposition_counts"] + == { + "complete_official_mapping": None, + "source_underdetermined": None, + "U": 0, } - for path, size, raw_sha in rows - ] + and purpose["source_underdetermined_count_a4_freeze_slot"] is None + and purpose[ + "source_underdetermined_requires_reconciled_adjudication_ruling" + ] + is True + and purpose[ + "source_underdetermined_uses_determined_row_provenance_authentication" + ] + is True + and purpose["source_underdetermined_is_no_applicable_purpose"] is False + and purpose["disposition_relation_total_under_completed_ontology"] + is True + and purpose["authority_gate_uses_reconciled_outcomes"] is True + and purpose["exact_row_agreement_is_authority_gate"] is False + and purpose["source_backed_alternative_selected"] + == "ontology_projection" + and purpose["inherited_complete_rows_requiring_source_regrounding"] + == 818 + and purpose["manual_origin_grandfathering_permitted"] is False + and purpose["purpose_arrays_nonempty_stable_unique_in_official_order"] + is True + and purpose[ + "exact_prompt_cover_and_zero_gap_extra_duplicate_overlap_conflict" + ] + is True, + "Amendment-20 purpose-authority totality contract drift", + ) + prompt = manifest["prompt_field_semantic_binding"] + _require( + prompt["collision_census"] + == { + "domain": ( + "historical_same_coordinate_leading_question_token_conflicts" + ), + "complete_official_prompt_count": 818, + "multiple_count": 46, + } + and prompt["complete_official_prompt_candidate_census"] + == A20_PROMPT_FIELD_SEMANTIC_BINDING_CONTRACT[ + "complete_official_prompt_candidate_census" + ] + and prompt["full_prompt_candidate_census"] + == { + "domain": "multiple_candidates_over_full_prompt_denominator", + "prompt_count": 21_971, + "multiple_count": 2_349, + } + and len(prompt["prompt_field_row_keys"]) == 13 + and prompt["questionnaire_span_keys"] + == ["utf8_byte_start", "utf8_byte_end"] + and prompt["prompt_field_evidence_id_prefix"] + == "psid-prompt-field-evidence:" + and len(prompt["prompt_field_evidence_id_preimage"]) == 12 + and prompt["coordinate_distinct_span_collapse_aborts"] is True + and prompt["exact_duplicate_evidence_emission_aborts"] is True + and prompt["c68_regression"]["candidate_raw_field_ids"] + == ["V11804", "V11805"] + and prompt["c68_regression"]["draft_disposition"] + == "unresolved_multiple" + and prompt["direct_identifier_priority_forbidden"] is True + and prompt["required_unresolved_semantic_binding_count"] == 0 + and prompt["attachment_dispositions"] + == [ + "accepted_exact_source_identifier", + "accepted_expressly_admitted_official_alias", + "unresolved_multiple", + ] + and len(prompt["prompt_field_candidate_set_row_keys"]) == 7 + and prompt["prompt_field_candidate_set_dispositions"] + == ["zero_candidates", "one_candidate", "multiple_candidates"] + and prompt["candidate_arrays_complete_stable_unique_source_order"] + is True + and prompt["candidate_disposition_is_iff_count_partition"] is True + and prompt["candidate_set_id_is_sha256_of_canonical_remaining_members"] + is True + and prompt["candidate_set_row_ids_and_prompt_ids_unique"] is True + and prompt["candidate_count_is_raw_field_array_length_strict_integer"] + is True + and len(prompt["zero_candidate_positive_group_row_keys"]) == 7 + and prompt["zero_candidate_positive_group_dispositions"] + == [ + "complete_nonempty_reference_union", + "fail_empty_reference_union", + ] + and prompt[ + "zero_candidate_group_one_per_qualifying_positive_occurrence" + ] + is True + and prompt[ + "zero_candidate_prompt_arrays_complete_positive_row_projections" + ] + is True + and prompt["zero_candidate_reference_union_complete_stable_unique"] + is True + and prompt["zero_candidate_group_disposition_is_iff_empty_boolean"] + is True + and prompt[ + "zero_candidate_group_id_is_sha256_of_canonical_remaining_members" + ] + is True + and prompt["zero_candidate_group_ids_and_positive_ids_unique"] is True + and prompt[ + "empty_reference_union_is_strict_boolean_zero_length_equality" + ] + is True + and prompt["zero_candidate_grouping_probe"] + == { + "candidate_set_prompt_count": 21_971, + "sweep_zero_candidate_observation": 15_428, + "diagnostic_zero_candidate_observation": 14_450, + "observations_are_nonauthority": True, + "difference_explained": False, + "accepted_positive_group_with_empty_reference_union_count": None, + "accepted_attachment_required_for_codebook_supported_rule": True, + } + and prompt["semantic_binding_serialization"] + == "near_match_source_annotation_rows" + and prompt["separate_semantic_binding_rows_serialization_permitted"] + is False + and prompt["semantic_binding_identity_requires_deep_equality"] + == ["row_count", "ordered_keyset_sha256", "row_domain_sha256"] + and prompt["binding_built_before_candidate_rows_read"] is True, + "Amendment-20 prompt-field or semantic-binding contract drift", + ) + r04 = manifest["r04_q5"] + _require( + r04["construction_order"] == A20_R04_Q5_CONTRACT["construction_order"] + and r04["o_h_precedes_o_p_on_normal_arm"] is True + and r04["purpose_totality_alone_passes_r04"] is False + and r04["selector_purpose_domain"] == "completed_purpose_ontology" + and r04["o_p_order"] + == [*A19_OFFICIAL_PURPOSES, "source_underdetermined"] + and r04["purpose_expansion_domain"] == "completed_purpose_ontology" + and r04["purpose_rule_projection_domain"] + == "completed_purpose_ontology" + and "questionnaire_occurrence_rows" + in r04["permitted_selector_input_reads"] + and "questionnaire_occurrence_rows" + in r04["forbidden_selected_failure_member_serialization"] + and r04["source_document_manifest_additions"] + == A20_R04_Q5_CONTRACT["source_document_manifest_additions"] + and r04["normal_effective_header_successor_members"] + == A20_R04_Q5_CONTRACT["normal_effective_header_successor_members"] + and r04["normal_era_successor_sequence"] + == A20_R04_Q5_CONTRACT["normal_era_successor_sequence"] + and r04["a19_digest_dependency_order_preserved"] + == ["D0", "search_implementation", "A_h", "final_rows", "D1"] + and r04[ + "a19_purpose_mapping_is_historical_nonconsumable_on_a20_normal_path" + ] + is True, + "Amendment-20 R04 order or Q5 shape contract drift", + ) + r06 = manifest["r06_lifecycle"] + _require( + r06["interpreter_selector"] == "executing_process_sys.executable" + and r06["ambient_pytest_addopts_removed"] is True + and r06["collection_command_after_interpreter"] + == [ + "-m", + "pytest", + "--collect-only", + "-q", + *[row["path"] for row in A20_R06_FILE_IDENTITIES], + ] + and len(r06["test_file_identities"]) == 6 + and r06["test_file_identities"] == A20_R06_FILE_IDENTITIES + and r06["collected_node_id_count"] == 223 + and r06["collected_node_id_array_canonical_byte_size"] == 28_268 + and r06["collected_node_id_array_raw_sha256"] + == "09071bf4d9a9a5ee8b9ccc4d8d5c0bd91705c04d3c7c99d6ef155dfdc0dfdf05" + and r06["dormant_definition_before_certification_permitted"] is True + and r06["dormant_definition_creates_instance_or_selection"] is False + and r06["dormant_lifecycle_row_count"] == 26 + and r06["dormant_lifecycle_rows"] == A20_DORMANT_LIFECYCLE_ROWS + and [row["first_add_index"] for row in r06["dormant_lifecycle_rows"]] + == list(range(1, 27)) + and r06["selection_first_add_dispatch_requires_r04_r05_r06_order"] + is True, + "Amendment-20 R06 collection or lifecycle contract drift", + ) + freeze_contract = manifest["evidence_freeze_contract"] + freeze = manifest["amendment20_evidence_freeze"] + _require( + freeze_contract == A20_EVIDENCE_FREEZE_CONTRACT + and freeze == freeze_contract["object"], + "Amendment-20 evidence-freeze object drift", + ) + _validate_amendment20_evidence_freeze( + freeze, + freeze_contract, + require_ratification_ready=require_ratification_ready, + ) + receipt = manifest["ratification_receipt"] + _require( + receipt["amendment20_external_receipt_path"] + == A20_EXECUTED_TRANSITION_RECEIPT_PATH + and receipt["inherited_external_receipt_path_template"] + == ( + "docs/analysis/amendment__ratification/" + "executed_transition_receipt_v2.json" + ) + and receipt["external_receipt_mode"] == "100644" + and receipt["candidate_production_registry_identity"] + == A20_PRODUCTION_REGISTRY_IDENTITY + and receipt[ + "external_receipt_strict_canonical_tracked_head_worktree_read" + ] + is True + and receipt["external_receipt_candidate_ancestry_not_required"] is True + and receipt[ + "external_receipt_first_add_precedes_or_equals_closure_first_add" + ] + is True + and receipt["scratch_commit_forbidden_as_production_ancestor"] is True + and receipt["receipt_candidate_design_tree_mode_blob_rederived"] + is True + and receipt[ + "receipt_candidate_design_exactly_cross_binds_historical_a20_closure_and_verdicts" + ] + is True + and receipt[ + "current_terminal_registry_cross_binding_required_iff_a20_terminal_revision22" + ] + is True + and receipt[ + "later_revision_authenticates_historical_a20_design_under_30_2_3" + ] + is True + and receipt[ + "receipt_rederives_synthetic_closure_standins_and_registry_binding" + ] + is True + and receipt["receipt_public_result_booleans_not_sufficient"] is True + and receipt[ + "later_amendment_requires_own_exact_receipt_topology_projection" + ] + is True + and receipt["qualifying_verdict_line_count"] == 8 + and receipt["qualifying_verdict_lines"][-2] + == "executed_transition_receipt_schema: executed_transition_state.v2" + and receipt["scratch"]["standin_prefix_line_count"] == 4 + and receipt["receipt_schema"]["top_level_keys"] + == A17_RECEIPT_SCHEMA["top_level_keys"] + and receipt["receipt_schema"]["manifest_schema_version"] + == "executed_transition_state.v2" + and receipt["receipt_schema"][ + "candidate_or_scratch_HEAD_member_superseded" + ] + is True + and len( + canonical_json_bytes( + receipt["receipt_schema"]["expected_changed_paths"] + ) + ) + == 260 + and _sha256( + canonical_json_bytes( + receipt["receipt_schema"]["expected_changed_paths"] + ) + ) + == "5a7912498c4d959fef337f2a1d1cf85a2f254fa29d825d365ccf4fe214ad48a7", + "Amendment-20 verdict, receipt, or scratch contract drift", + ) + campaign = manifest["evidence_campaign"] + _require( + campaign == A20_EVIDENCE_CAMPAIGN_CONTRACT + and campaign["rounds_formula"] == "ceil(2L/(3q))" + and campaign["forecast_as_of"] == "2026-08-15" + and campaign["conditional_p50"] == "2026-11-09" + and campaign["conditional_p80"] == "2027-01-22" + and campaign["dates_are_nonauthority_conditional_planning_metadata"] + is True, + "Amendment-20 evidence-campaign contract drift", + ) + mutations = manifest["mutation_inventory"] + mutation_raw = canonical_json_bytes(mutations) + _require( + mutations == list(A20_EXPECTED_MUTATIONS) + and len(mutation_raw) == A20_MUTATION_DOMAIN_BYTE_SIZE + and _sha256(mutation_raw) == A20_MUTATION_DOMAIN_SHA256, + "Amendment-20 mutation inventory drift", + ) + routing = manifest["successor_routing"] + activation = manifest["activation_transition"] + _require( + routing == A20_SUCCESSOR_ROUTING_CONTRACT + and activation == A20_ACTIVATION_TRANSITION + and routing["a20_pins_selected_before_a19_pins"] is True + and routing["a19_pin_fallback_for_terminal_a20_permitted"] is False + and activation["ordered_closure_domain"] + == [13, 14, 15, 16, 17, 18, 19, 20] + and activation["closure_count"] == 8, + "Amendment-20 successor routing or activation contract drift", + ) + _require( + manifest["supersession_coverage"] == A20_SUPERSESSION_COVERAGE + and len(manifest["supersession_coverage"]) == 30 + and any("30.2.2" in row for row in manifest["supersession_coverage"]), + "Amendment-20 supersession coverage drift", + ) + _require( + all( + "A21" not in identifier + for values in manifest["new_identifiers"].values() + for identifier in values + ) + and all( + len(values) == len(set(values)) + for values in manifest["new_identifiers"].values() + ) + and sum(len(values) for values in manifest["new_identifiers"].values()) + == len( + { + identifier + for values in manifest["new_identifiers"].values() + for identifier in values + } + ), + "Amendment-20 manifest invents an A21 identifier", + ) + _require( + manifest == A20_NORMATIVE_MANIFEST, + "Amendment-20 normative manifest drift", + ) -def _parse_a13_expected_closure( - section: str, - verdict_artifacts: Sequence[Mapping[str, Any]], -) -> dict[str, Any]: - rows = _markdown_table( +def _parse_amendment20_projection(raw: bytes) -> dict[str, Any]: + section = _amendment20_text(raw) + manifest = _parse_a20_normative_manifest(section) + _validate_a20_manifest_contract(manifest) + supersession_rows = _markdown_table( section, - "| Closure member | Exact value |", + "| Earlier normative anchor | Amendment-20 disposition |", "|---|---|", - 8, - "Amendment-13 closure values", + len(manifest["supersession_coverage"]), + "Amendment-20 supersession disposition", + ) + mutation_disposition_position = manifest["supersession_coverage"].index( + "33.6_mutation_inventory_and_inherited_census" ) - values = {name: value for name, value in rows} _require( - values["`verdict_artifacts`"] - == "the exact two ordered \u00a728.3.1 path/byte/SHA objects", - "Amendment-13 closure verdict reference drift", + len(manifest["mutation_inventory"]) == 15 + and supersession_rows[mutation_disposition_position] + == [ + "§33.6 mutation inventory and inherited census", + "Preserved as three A19 names after the earlier 113 attacks. " + "A20 runs the five inherited censuses separately, then its " + "own fifteen-name inventory.", + ], + "Amendment-20 mutation inventory prose disposition drift", ) return { - "amendment_number": int( - _code_tokens( - values["`amendment_number`"], - 1, - "A13 closure amendment number", - )[0] - ), - "attested_candidate_design_blob_oid": _code_tokens( - values["`attested_candidate_design_blob_oid`"], - 1, - "A13 closure design blob", - )[0], - "attested_candidate_design_byte_size": int( - _code_tokens( - values["`attested_candidate_design_byte_size`"], - 1, - "A13 closure design size", - )[0] + "section_semantic_sha256": _sha256( + _normalize_amendment20_implementation_pin_values(section).encode( + "utf-8" + ) ), - "attested_candidate_design_raw_sha256": _code_tokens( - values["`attested_candidate_design_raw_sha256`"], - 1, - "A13 closure design SHA-256", - )[0], - "ratification_commit": _code_tokens( + "implementation_pins": _parse_amendment20_implementation_pins(raw), + "normative_manifest": manifest, + } + + +def _parse_active_implementation_pins(raw: bytes) -> dict[str, Any]: + """Select the newest append-only implementation-pin successor.""" + + if len(raw) > REVISION21_BYTE_SIZE: + return _parse_amendment20_implementation_pins(raw) + if len(raw) > REVISION20_BYTE_SIZE: + return _parse_amendment19_implementation_pins(raw) + if len(raw) > REVISION19_BYTE_SIZE: + return _parse_amendment18_implementation_pins(raw) + if len(raw) > REVISION18_BYTE_SIZE: + return _parse_amendment17_implementation_pins(raw) + if len(raw) > REVISION17_BYTE_SIZE: + return _parse_amendment16_implementation_pins(raw) + if len(raw) > REVISION16_BYTE_SIZE: + return _parse_amendment15_implementation_pins(raw) + return _parse_amendment14_projection(raw)["implementation_pins"] + + +def _parse_amendment16_law_values(section: str) -> dict[str, Any]: + lines = _fenced_lines_after( + section, + "The A16 projection exact-parses and independently compares at least " + "these\nenacted values:\n\n", + "Amendment-16 ratification law values", + ) + expected_names = tuple(A16_RATIFICATION_LAW_VALUES) + _require( + len(lines) == len(expected_names), + "Amendment-16 ratification law value count drift", + ) + values: dict[str, Any] = {} + for expected_name, line in zip(expected_names, lines, strict=True): + _require(" = " in line, "Amendment-16 ratification law row drift") + name, serialized = line.split(" = ", 1) + _require( + name == expected_name, + "Amendment-16 ratification law value order drift", + ) + if serialized.startswith("["): + try: + value = json.loads(serialized) + except json.JSONDecodeError as error: + raise LawError( + "Amendment-16 ratification law array drift" + ) from error + elif serialized.isdigit(): + value = int(serialized) + else: + value = serialized + values[name] = value + return values + + +def _parse_a16_verdict_artifacts(section: str) -> list[dict[str, Any]]: + rows = _markdown_table( + section, + "| Path | Bytes | Raw SHA-256 |", + "|---|---:|---|", + 2, + "Amendment-15 verdict identities in Amendment 16", + ) + return [ + { + "path": _code_tokens(path, 1, "A15 verdict path")[0], + "byte_size": int(size.replace(",", "")), + "raw_sha256": _code_tokens(raw_sha, 1, "A15 verdict SHA-256")[0], + } + for path, size, raw_sha in rows + ] + + +def _parse_a14_historical_binding_from_a16(section: str) -> dict[str, Any]: + rows = _markdown_table( + section, + "| Historical closure | Exact path | Bytes | Raw SHA-256 |", + "|---|---|---:|---|", + 1, + "Amendment-14 historical closure binding in Amendment 16", + ) + label, path, size, raw_sha = rows[0] + _require( + label == "Amendment 14", + "Amendment-14 historical closure label drift", + ) + return { + "path": _code_tokens(path, 1, "historical A14 closure path")[0], + "raw_byte_size": int(size.replace(",", "")), + "raw_sha256": _code_tokens( + raw_sha, + 1, + "historical A14 closure SHA-256", + )[0], + } + + +def _parse_a15_expected_closure_from_a16( + section: str, + verdict_artifacts: Sequence[Mapping[str, Any]], +) -> dict[str, Any]: + rows = _markdown_table( + section, + "| Closure member | Exact value |", + "|---|---|", + 8, + "Amendment-15 closure values in Amendment 16", + ) + values = {name: value for name, value in rows} + _require( + values["`verdict_artifacts`"] + == "the exact two ordered §30.3.2 path/byte/SHA objects", + "Amendment-15 closure verdict reference drift", + ) + return { + "amendment_number": int( + _code_tokens( + values["`amendment_number`"], + 1, + "A15 closure amendment number", + )[0] + ), + "attested_candidate_design_blob_oid": _code_tokens( + values["`attested_candidate_design_blob_oid`"], + 1, + "A15 closure design blob", + )[0], + "attested_candidate_design_byte_size": int( + _code_tokens( + values["`attested_candidate_design_byte_size`"], + 1, + "A15 closure design size", + )[0] + ), + "attested_candidate_design_raw_sha256": _code_tokens( + values["`attested_candidate_design_raw_sha256`"], + 1, + "A15 closure design SHA-256", + )[0], + "ratification_commit": _code_tokens( values["`ratification_commit`"], 1, - "A13 closure ratification commit", + "A15 closure ratification commit", )[0], "ratification_commit_sole_parent": _code_tokens( values["`ratification_commit_sole_parent`"], 1, - "A13 closure ratification parent", + "A15 closure ratification parent", )[0], "operator_merge_commit": _code_tokens( values["`operator_merge_commit`"], 1, - "A13 closure operator merge", + "A15 closure operator merge", )[0], "verdict_artifacts": [dict(row) for row in verdict_artifacts], } -def _parse_amendment14_projection(raw: bytes) -> dict[str, Any]: - section = _amendment14_text(raw) - verdict_artifacts = _parse_a14_verdict_artifacts(section) +def _parse_a16_historical_r05_binding(section: str) -> dict[str, Any]: + lines = _fenced_lines_after( + section, + "The serialized member remains historical Amendment-15 material:\n\n", + "Amendment-16 historical R05 binding", + ) + expected_names = tuple(A16_HISTORICAL_R05_BINDING) + _require( + len(lines) == len(expected_names), + "Amendment-16 historical R05 binding count drift", + ) + binding: dict[str, Any] = {} + for expected_name, line in zip(expected_names, lines, strict=True): + _require(" = " in line, "Amendment-16 historical R05 row drift") + name, value = line.split(" = ", 1) + _require( + name == expected_name, + "Amendment-16 historical R05 binding order drift", + ) + binding[name] = int(value) if value.isdigit() else value + return binding + + +def _parse_amendment16_projection(raw: bytes) -> dict[str, Any]: + section = _amendment16_text(raw) + verdict_artifacts = _parse_a16_verdict_artifacts(section) + oracle_mutations = _fenced_lines_after( + section, + "The Amendment-16 operativity enforcement inventory is exactly:\n\n", + "Amendment-16 oracle mutations", + ) + mutation_digest = _code_after( + section, + "The ordered canonical name-array domain SHA-256 is\n", + "Amendment-16 oracle mutation digest", + ) + _require( + _sha256(canonical_json_bytes(oracle_mutations)) == mutation_digest, + "Amendment-16 oracle mutation name-array digest drift", + ) projection = { "section_semantic_sha256": _sha256( - _normalize_implementation_pin_values(section).encode() + _normalize_amendment16_implementation_pin_values(section).encode( + "utf-8" + ) ), - "closure_top_level_keys": _fenced_lines_after( + "ratification_law_values": _parse_amendment16_law_values(section), + "ordered_domain_expression": _code_after( section, - "eight top-level keys in canonical sorted-key serialization:\n\n", - "Amendment-14 closure top-level keys", + "ordered closure domain is every integer amendment\nnumber in " + "Python's half-open ", + "Amendment-16 ordered domain expression", ), - "closure_verdict_keys": _fenced_lines_after( + "generated_closure_path_rule": _code_after( section, - "object has exactly these three keys:\n\n", - "Amendment-14 closure verdict keys", + "zero based, is Amendment `13 + i`; its generated path is\n", + "Amendment-16 generated closure path rule", ), - "registry_closure_binding_keys": _fenced_lines_after( + "combined_closure_paths": _fenced_lines_after( section, - "Each row has exactly:\n\n", - "Amendment-14 registry closure binding keys", + "The next lawful repin selects revision 18 and binds exactly " + "these four ordered\npaths:\n\n", + "Amendment-16 combined closure paths", ), - "a13_verdict_artifacts": verdict_artifacts, - "a13_expected_closure": _parse_a13_expected_closure( + "a14_historical_closure_binding": ( + _parse_a14_historical_binding_from_a16(section) + ), + "a15_verdict_artifacts": verdict_artifacts, + "a15_expected_closure": _parse_a15_expected_closure_from_a16( section, verdict_artifacts ), "ratification_sequence": _fenced_lines_after( section, - "The exact Amendment-14 sequence is:\n\n", - "Amendment-14 ratification sequence", + "The combined sequence is:\n\n", + "Amendment-16 ratification sequence", ), - "implementation_pins": _parse_implementation_pins(section), - "semantic_mutations": _fenced_lines_after( + "historical_r05_binding": _parse_a16_historical_r05_binding(section), + "implementation_pins": _parse_amendment16_implementation_pins(raw), + "oracle_mutations": oracle_mutations, + "oracle_mutation_domain_sha256": mutation_digest, + "supersession_map": _markdown_table( section, - "Amendment 13's exact seven semantic mutations survive unchanged:\n\n", - "Amendment-14 semantic mutations", + "| Earlier normative anchor | Amendment-16 disposition |", + "|---|---|", + 11, + "Amendment-16 supersession map", ), - "enforcement_mutations": _fenced_lines_after( + "schema_operation_identifiers": _fenced_lines_after( section, - "The Amendment-14 enforcement inventory is exactly:\n\n", - "Amendment-14 enforcement mutations", + "The exact Amendment-16 schema and operation identifiers are:\n\n", + "Amendment-16 schema and operation identifiers", ), - "removed_mutations": _fenced_lines_after( + "status_identifiers": _fenced_lines_after( section, - "Two predecessor enforcement mutations are removed:\n\n", - "Amendment-14 removed mutations", + "The exact Amendment-16 status identifiers are:\n\n", + "Amendment-16 status identifiers", ), - "schema_binding_identifiers": _fenced_lines_after( + "python_identifiers": _fenced_lines_after( section, - "The exact Amendment-14 schema and binding identifiers are:\n\n", - "Amendment-14 schema and binding identifiers", + "The exact new public/private Python identifiers are:\n\n", + "Amendment-16 Python identifiers", ), - "path_templates": _fenced_lines_after( + } + inventories = ( + projection["schema_operation_identifiers"], + projection["status_identifiers"], + projection["python_identifiers"], + ) + _require( + all(len(values) == len(set(values)) for values in inventories) + and set(inventories[0]).isdisjoint(inventories[1]) + and set(inventories[0]).isdisjoint(inventories[2]) + and set(inventories[1]).isdisjoint(inventories[2]), + "Amendment-16 enacted identifier inventory consistency drift", + ) + return projection + + +def _amendment14_text(raw: bytes) -> str: + _require( + len(raw) > REVISION15_BYTE_SIZE + and _sha256(raw[:REVISION15_BYTE_SIZE]) == REVISION15_SHA256 + and raw[REVISION15_BYTE_SIZE:].startswith(AMENDMENT14_BOUNDARY) + and raw.endswith(b"\n"), + "governing Amendment-14 document violates immutable-prefix law", + ) + suffix = raw[REVISION15_BYTE_SIZE:] + if AMENDMENT15_BOUNDARY in suffix: + _require( + suffix.count(AMENDMENT15_BOUNDARY) == 1, + "governing document has an ambiguous Amendment-15 boundary", + ) + suffix = suffix[: suffix.index(AMENDMENT15_BOUNDARY)] + try: + return suffix.decode("utf-8") + except UnicodeDecodeError as error: + raise LawError("governing Amendment-14 suffix is not UTF-8") from error + + +def _parse_a14_verdict_artifacts(section: str) -> list[dict[str, Any]]: + rows = _markdown_table( + section, + "| Path | Bytes | Raw SHA-256 |", + "|---|---:|---|", + 2, + "Amendment-13 verdict identities", + ) + return [ + { + "path": _code_tokens(path, 1, "A13 verdict path")[0], + "byte_size": int(size.replace(",", "")), + "raw_sha256": _code_tokens(raw_sha, 1, "A13 verdict SHA-256")[0], + } + for path, size, raw_sha in rows + ] + + +def _parse_a13_expected_closure( + section: str, + verdict_artifacts: Sequence[Mapping[str, Any]], +) -> dict[str, Any]: + rows = _markdown_table( + section, + "| Closure member | Exact value |", + "|---|---|", + 8, + "Amendment-13 closure values", + ) + values = {name: value for name, value in rows} + _require( + values["`verdict_artifacts`"] + == "the exact two ordered \u00a728.3.1 path/byte/SHA objects", + "Amendment-13 closure verdict reference drift", + ) + return { + "amendment_number": int( + _code_tokens( + values["`amendment_number`"], + 1, + "A13 closure amendment number", + )[0] + ), + "attested_candidate_design_blob_oid": _code_tokens( + values["`attested_candidate_design_blob_oid`"], + 1, + "A13 closure design blob", + )[0], + "attested_candidate_design_byte_size": int( + _code_tokens( + values["`attested_candidate_design_byte_size`"], + 1, + "A13 closure design size", + )[0] + ), + "attested_candidate_design_raw_sha256": _code_tokens( + values["`attested_candidate_design_raw_sha256`"], + 1, + "A13 closure design SHA-256", + )[0], + "ratification_commit": _code_tokens( + values["`ratification_commit`"], + 1, + "A13 closure ratification commit", + )[0], + "ratification_commit_sole_parent": _code_tokens( + values["`ratification_commit_sole_parent`"], + 1, + "A13 closure ratification parent", + )[0], + "operator_merge_commit": _code_tokens( + values["`operator_merge_commit`"], + 1, + "A13 closure operator merge", + )[0], + "verdict_artifacts": [dict(row) for row in verdict_artifacts], + } + + +def _parse_amendment14_projection(raw: bytes) -> dict[str, Any]: + section = _amendment14_text(raw) + verdict_artifacts = _parse_a14_verdict_artifacts(section) + projection = { + "section_semantic_sha256": _sha256( + _normalize_implementation_pin_values(section).encode() + ), + "closure_top_level_keys": _fenced_lines_after( + section, + "eight top-level keys in canonical sorted-key serialization:\n\n", + "Amendment-14 closure top-level keys", + ), + "closure_verdict_keys": _fenced_lines_after( + section, + "object has exactly these three keys:\n\n", + "Amendment-14 closure verdict keys", + ), + "registry_closure_binding_keys": _fenced_lines_after( + section, + "Each row has exactly:\n\n", + "Amendment-14 registry closure binding keys", + ), + "a13_verdict_artifacts": verdict_artifacts, + "a13_expected_closure": _parse_a13_expected_closure( + section, verdict_artifacts + ), + "ratification_sequence": _fenced_lines_after( + section, + "The exact Amendment-14 sequence is:\n\n", + "Amendment-14 ratification sequence", + ), + "implementation_pins": _parse_implementation_pins(section), + "semantic_mutations": _fenced_lines_after( + section, + "Amendment 13's exact seven semantic mutations survive unchanged:\n\n", + "Amendment-14 semantic mutations", + ), + "enforcement_mutations": _fenced_lines_after( + section, + "The Amendment-14 enforcement inventory is exactly:\n\n", + "Amendment-14 enforcement mutations", + ), + "removed_mutations": _fenced_lines_after( + section, + "Two predecessor enforcement mutations are removed:\n\n", + "Amendment-14 removed mutations", + ), + "schema_binding_identifiers": _fenced_lines_after( + section, + "The exact Amendment-14 schema and binding identifiers are:\n\n", + "Amendment-14 schema and binding identifiers", + ), + "path_templates": _fenced_lines_after( section, "The exact Amendment-14 path templates are:\n\n", "Amendment-14 path templates", @@ -5690,6 +8214,7 @@ def _parse_document_semantic_projection(raw: bytes) -> dict[str, Any]: "amendment17": _parse_amendment17_projection(raw), "amendment18": _parse_amendment18_projection(raw), "amendment19": _parse_amendment19_projection(raw), + "amendment20": _parse_amendment20_projection(raw), } _validate_identifier_inventory_consistency(projection) return projection @@ -6008,544 +8533,2040 @@ def _execution_doc036_projection(law: Mapping[str, Any]) -> dict[str, Any]: } -def _execution_scope_projection(law: Mapping[str, Any]) -> dict[str, Any]: - continuation = law["amendment12_continuation_domain"] - integrity = law["integrity"] - return { - "law_gap_ids": copy.deepcopy(law["untouched_law_gap_predecessor_ids"]), - "law_gap_id_domain_sha256": integrity["law_gap_id_domain_sha256"], - "fixture_status": DRAFT_STATUS, - "authority_emitted": False, - "certification_emitted": False, - "top_level_keys": list(law), - "continuation_domain_keys": list(continuation), - "source_artifact_identity_keys": list( - continuation["source_artifact_identity"] - ), - "git_order_keys": list(law["git_order_law"]), - "integrity_keys": list(integrity), - "prospective_domain_pins": [ - {"domain": name, "count": count, "sha256": sha256} - for name, count, sha256 in PROSPECTIVE_DOMAIN_PINS - ], - "semantic_mutations": list(A13_EXPECTED_MUTATIONS), - "enforcement_mutations": list(A13_HISTORICAL_ENFORCEMENT_MUTATIONS), - } +def _execution_scope_projection(law: Mapping[str, Any]) -> dict[str, Any]: + continuation = law["amendment12_continuation_domain"] + integrity = law["integrity"] + return { + "law_gap_ids": copy.deepcopy(law["untouched_law_gap_predecessor_ids"]), + "law_gap_id_domain_sha256": integrity["law_gap_id_domain_sha256"], + "fixture_status": DRAFT_STATUS, + "authority_emitted": False, + "certification_emitted": False, + "top_level_keys": list(law), + "continuation_domain_keys": list(continuation), + "source_artifact_identity_keys": list( + continuation["source_artifact_identity"] + ), + "git_order_keys": list(law["git_order_law"]), + "integrity_keys": list(integrity), + "prospective_domain_pins": [ + {"domain": name, "count": count, "sha256": sha256} + for name, count, sha256 in PROSPECTIVE_DOMAIN_PINS + ], + "semantic_mutations": list(A13_EXPECTED_MUTATIONS), + "enforcement_mutations": list(A13_HISTORICAL_ENFORCEMENT_MUTATIONS), + } + + +def _canonical_amendment14_projection() -> dict[str, Any]: + return { + "section_semantic_sha256": A14_SECTION_SEMANTIC_SHA256, + "closure_top_level_keys": list(CLOSURE_TOP_LEVEL_KEYS), + "closure_verdict_keys": list(CLOSURE_VERDICT_KEYS), + "registry_closure_binding_keys": list(REGISTRY_CLOSURE_BINDING_KEYS), + "a13_verdict_artifacts": [dict(row) for row in A13_VERDICT_ARTIFACTS], + "a13_expected_closure": copy.deepcopy(A13_EXPECTED_CLOSURE), + "ratification_sequence": list(A14_RATIFICATION_SEQUENCE), + "implementation_pins": None, + "semantic_mutations": list(A13_EXPECTED_MUTATIONS), + "enforcement_mutations": list(A13_ENFORCEMENT_EXPECTED_MUTATIONS), + "removed_mutations": list(REMOVED_PKI_MUTATIONS), + "schema_binding_identifiers": list(A14_SCHEMA_BINDING_IDENTIFIERS), + "path_templates": list(A14_PATH_TEMPLATES), + "status_operation_identifiers": list(A14_STATUS_OPERATION_IDENTIFIERS), + } + + +def _canonical_amendment15_projection() -> dict[str, Any]: + return { + "section_semantic_sha256": A15_SECTION_SEMANTIC_SHA256, + "implementation_pins": None, + "mutation_bindings": None, + } + + +def _canonical_amendment16_projection() -> dict[str, Any]: + return { + "section_semantic_sha256": A16_SECTION_SEMANTIC_SHA256, + "ratification_law_values": copy.deepcopy(A16_RATIFICATION_LAW_VALUES), + "ordered_domain_expression": "range(13, R - 1)", + "generated_closure_path_rule": ( + "docs/analysis/amendment_{13+i}_ratification/closure_v1.json" + ), + "combined_closure_paths": list(A16_COMBINED_CLOSURE_PATHS), + "a14_historical_closure_binding": copy.deepcopy( + A14_HISTORICAL_CLOSURE_BINDING + ), + "a15_verdict_artifacts": [dict(row) for row in A15_VERDICT_ARTIFACTS], + "a15_expected_closure": copy.deepcopy(A15_EXPECTED_CLOSURE), + "ratification_sequence": list(A16_RATIFICATION_SEQUENCE), + "historical_r05_binding": copy.deepcopy(A16_HISTORICAL_R05_BINDING), + "implementation_pins": None, + "oracle_mutations": list(A16_EXPECTED_MUTATIONS), + "oracle_mutation_domain_sha256": A16_MUTATION_DOMAIN_SHA256, + "supersession_map": None, + "schema_operation_identifiers": list(A16_SCHEMA_OPERATION_IDENTIFIERS), + "status_identifiers": list(A16_STATUS_IDENTIFIERS), + "python_identifiers": list(A16_PYTHON_IDENTIFIERS), + } + + +def _canonical_amendment17_projection() -> dict[str, Any]: + return { + "section_semantic_sha256": A17_SECTION_SEMANTIC_SHA256, + "implementation_pins": None, + "revision_domain_rules": list(A17_REVISION_DOMAIN_RULES), + "executed_transition_obligation": copy.deepcopy( + A17_EXECUTED_TRANSITION_OBLIGATION + ), + "receipt_schema": copy.deepcopy(A17_RECEIPT_SCHEMA), + "transition_registry_binding": copy.deepcopy( + A17_TRANSITION_REGISTRY_BINDING + ), + "transition_closure_identities": [ + dict(row) for row in A17_TRANSITION_CLOSURE_IDENTITIES + ], + "transition_verdict_artifacts": [ + dict(row) for row in A17_TRANSITION_VERDICT_ARTIFACTS + ], + "required_public_output": list(A17_REQUIRED_PUBLIC_OUTPUT), + "full_pinned_battery": copy.deepcopy(A17_FULL_PINNED_BATTERY), + "test_ceremony_mutations": list(A17_EXPECTED_MUTATIONS), + "test_ceremony_mutation_domain_sha256": (A17_MUTATION_DOMAIN_SHA256), + "mutation_census": copy.deepcopy(A17_MUTATION_CENSUS), + "supersession_map": [list(row) for row in A17_SUPERSESSION_MAP], + } + + +def _canonical_amendment18_projection() -> dict[str, Any]: + return { + "section_semantic_sha256": A18_SECTION_SEMANTIC_SHA256, + "implementation_pins": None, + "build_input_domain_contract": copy.deepcopy( + A18_BUILD_INPUT_DOMAIN_CONTRACT + ), + "historical_r05_binding": copy.deepcopy(A18_HISTORICAL_R05_BINDING), + "r06_result_contract": copy.deepcopy(A18_R06_RESULT_CONTRACT), + "activation_transition": copy.deepcopy(A18_ACTIVATION_TRANSITION), + "contract_mutations": list(A18_EXPECTED_MUTATIONS), + "contract_mutation_domain_sha256": A18_MUTATION_DOMAIN_SHA256, + "mutation_census": copy.deepcopy(A18_MUTATION_CENSUS), + "supersession_map": [list(row) for row in A18_SUPERSESSION_MAP], + "new_identifiers": copy.deepcopy(A18_NEW_IDENTIFIERS), + } + + +def _canonical_amendment19_projection() -> dict[str, Any]: + return { + "section_semantic_sha256": A19_SECTION_SEMANTIC_SHA256, + "implementation_pins": None, + "normative_manifest": copy.deepcopy(A19_NORMATIVE_MANIFEST), + } + + +def _canonical_amendment20_projection() -> dict[str, Any]: + return { + "section_semantic_sha256": A20_SECTION_SEMANTIC_SHA256, + "implementation_pins": None, + "normative_manifest": copy.deepcopy(A20_NORMATIVE_MANIFEST), + } + + +@lru_cache(maxsize=1) +def _canonical_draft_document_projection() -> dict[str, Any]: + """Build the immutable document cross-check independently of a caller law.""" + + law = _construct_execution_law( + governing_amendment13_ratification_identity=( + GOVERNING_A13_CANDIDATE_IDENTITY + ), + status=DRAFT_STATUS, + ) + integrity = law["integrity"] + for name, count, sha256 in PROSPECTIVE_DOMAIN_PINS: + count_key, sha_key = { + "Repair overlays": ("overlay_count", "overlay_domain_sha256"), + "All repair successors": ( + "repair_count", + "successor_domain_sha256", + ), + "Supersession edges": ( + "supersession_count", + "supersession_domain_sha256", + ), + "Successor-era seal fixtures": ( + "successor_era_seal_count", + "successor_era_seal_domain_sha256", + ), + }[name] + _require( + integrity[count_key] == count and integrity[sha_key] == sha256, + f"prospective {name} Python pin drift", + ) + _require( + tuple( + row["successor_era_seal_id"] + for row in law["successor_era_seal_rows"] + ) + == PROSPECTIVE_ERA_SEAL_IDS, + "prospective successor-era Python pin drift", + ) + return { + "section_semantic_sha256": dict(A13_SECTION_SEMANTIC_SHA256), + "identity": _execution_identity_projection(law), + "overlays": _execution_overlay_projection(law), + "proof": _execution_proof_projection(law), + "fragments": _execution_fragment_projection(law), + "doc036": _execution_doc036_projection(law), + "scope": _execution_scope_projection(law), + "comparator": { + "search_augmentation": list(A13_SEARCH_AUGMENTATION), + "comparator_rows": [list(row) for row in A13_COMPARATOR_ROWS], + "schema_literals": list(A13_SCHEMA_LITERALS), + "content_id_prefixes": list(A13_CONTENT_ID_PREFIXES), + "status_relation_operation_codes": list( + A13_STATUS_RELATION_OPERATION_CODES + ), + "successor_kind_literals": list(A13_SUCCESSOR_KIND_LITERALS), + }, + "amendment14": _canonical_amendment14_projection(), + "amendment15": _canonical_amendment15_projection(), + "amendment16": _canonical_amendment16_projection(), + "amendment17": _canonical_amendment17_projection(), + "amendment18": _canonical_amendment18_projection(), + "amendment19": _canonical_amendment19_projection(), + "amendment20": _canonical_amendment20_projection(), + } + + +def _git_blob_oid(raw: bytes) -> str: + return hashlib.sha1( + b"blob " + str(len(raw)).encode() + b"\0" + raw + ).hexdigest() + + +def _verify_implementation_pins(pins: Mapping[str, Any]) -> None: + """Authenticate active file identities against the worktree and HEAD.""" + + _require_exact_keys( + pins, + {"mode", "files"}, + "Amendment-14 implementation pins", + ) + current_design = (ROOT / DESIGN_PATH).read_bytes() + label = "Amendment-14" + if len(current_design) > REVISION21_BYTE_SIZE: + pins = _parse_amendment20_implementation_pins(current_design) + label = "Amendment-20" + elif len(current_design) > REVISION20_BYTE_SIZE: + pins = _parse_amendment19_implementation_pins(current_design) + label = "Amendment-19" + elif len(current_design) > REVISION19_BYTE_SIZE: + pins = _parse_amendment18_implementation_pins(current_design) + label = "Amendment-18" + elif len(current_design) > REVISION18_BYTE_SIZE: + pins = _parse_amendment17_implementation_pins(current_design) + label = "Amendment-17" + elif len(current_design) > REVISION17_BYTE_SIZE: + pins = _parse_amendment16_implementation_pins(current_design) + label = "Amendment-16" + elif len(current_design) > REVISION16_BYTE_SIZE: + pins = _parse_amendment15_implementation_pins(current_design) + label = "Amendment-15" + _require( + pins["mode"] == DESIGN_MODE + and [row["path"] for row in pins["files"]] + == [ + "scripts/validate_amendment13_execution_law.py", + "tests/test_validate_amendment13_execution_law.py", + "scripts/build_amendment13_tier2_repairs.py", + ], + f"{label} implementation pin domain drift", + ) + for row in pins["files"]: + _require_exact_keys( + row, + {"path", "blob_oid", "byte_size", "sha256"}, + f"{label} implementation file pin", + ) + _require( + _is_lower_hex(row["blob_oid"], 40) + and type(row["byte_size"]) is int + and row["byte_size"] > 0 + and _is_lower_hex(row["sha256"], 64), + f"{label} implementation file pin is malformed", + ) + tree_line = str( + _git("ls-tree", "HEAD", "--", row["path"], text=True) + ).strip() + _require( + tree_line + == f"{pins['mode']} blob {row['blob_oid']}\t{row['path']}", + f"{label} implementation HEAD tree-entry pin drift", + ) + head_raw = _git("show", f"HEAD:{row['path']}") + worktree_raw = (ROOT / row["path"]).read_bytes() + _require( + isinstance(head_raw, bytes) + and worktree_raw == head_raw + and len(head_raw) == row["byte_size"] + and _sha256(head_raw) == row["sha256"] + and _git_blob_oid(head_raw) == row["blob_oid"], + f"{label} implementation blob identity mismatch", + ) + + +def _validate_document_semantic_projection( + raw: bytes, + law: Mapping[str, Any], +) -> dict[str, Any]: + """Require the governing bytes, Python controls, and fixture to agree.""" + + projection = _parse_document_semantic_projection(raw) + del law # Never let a caller-mutated law redefine the governing bytes. + expected = copy.deepcopy(_canonical_draft_document_projection()) + expected["scope"]["implementation_pins"] = projection["scope"][ + "implementation_pins" + ] + expected["amendment14"]["implementation_pins"] = projection["amendment14"][ + "implementation_pins" + ] + expected["amendment15"]["implementation_pins"] = projection["amendment15"][ + "implementation_pins" + ] + expected["amendment15"]["mutation_bindings"] = projection["amendment15"][ + "mutation_bindings" + ] + expected["amendment16"]["implementation_pins"] = projection["amendment16"][ + "implementation_pins" + ] + expected["amendment16"]["supersession_map"] = projection["amendment16"][ + "supersession_map" + ] + expected["amendment17"]["implementation_pins"] = projection["amendment17"][ + "implementation_pins" + ] + expected["amendment18"]["implementation_pins"] = projection["amendment18"][ + "implementation_pins" + ] + expected["amendment19"]["implementation_pins"] = projection["amendment19"][ + "implementation_pins" + ] + expected["amendment20"]["implementation_pins"] = projection["amendment20"][ + "implementation_pins" + ] + _require( + projection == expected, + "governing Amendment-14/15/16/17/18/19/20 document semantic projection " + "drift", + ) + _verify_implementation_pins( + projection["amendment14"]["implementation_pins"] + ) + return projection + + +@lru_cache(maxsize=1) +def _amendment12_continuation_projection() -> tuple[tuple[Any, ...], ...]: + """Re-derive the five inherited continuation citations from pinned bytes.""" + + raw = (ROOT / A12_SWEEP_PATH).read_bytes() + _require( + len(raw) == A12_SWEEP_BYTE_SIZE and _sha256(raw) == A12_SWEEP_SHA256, + "Amendment-12 continuation source artifact identity drift", + ) + artifact = a12.strict_json_loads(raw, A12_SWEEP_PATH) + projection: list[tuple[Any, ...]] = [] + for row in artifact["alias_evidence_semantic_adjudication_rows"]: + citation = row["continuation_composition_citation"] + if citation is None: + continue + instruction_ids = row["source_instruction_occurrence_ids"] + _require( + len(instruction_ids) == 1, + "Amendment-12 continuation citation has non-singleton instruction", + ) + continuation_id = instruction_ids[0] + expected_citation = ( + a12.CONTINUATION_ALIAS_CITATIONS_BY_INSTRUCTION.get( + continuation_id + ) + ) + _require( + expected_citation is not None + and all( + citation[key] == value + for key, value in expected_citation.items() + ) + and citation["leading_occurrence_id"] + == expected_citation["leading_occurrence_id"] + and citation["continuation_occurrence_id"] == continuation_id, + "Amendment-12 continuation citation projection drift", + ) + projection.append( + ( + row["document_source_position"], + row["source_local_evidence_id"], + citation["leading_occurrence_id"], + continuation_id, + ) + ) + canonical_projection = [list(row) for row in projection] + raw_projection = canonical_json_bytes(canonical_projection) + _require( + len(raw_projection) == A12_CONTINUATION_PROJECTION_BYTE_SIZE + and _sha256(raw_projection) == A12_CONTINUATION_PROJECTION_SHA256, + "Amendment-12 continuation projection identity drift", + ) + return tuple(projection) + + +def _run_git( + *arguments: str, + text: bool = False, +) -> subprocess.CompletedProcess[bytes] | subprocess.CompletedProcess[str]: + """Run raw-object Git with ambient Git controls removed.""" + + environment = { + key: value + for key, value in os.environ.items() + if not key.startswith("GIT_") + } + environment["GIT_NO_REPLACE_OBJECTS"] = "1" + return subprocess.run( + ["git", "--no-replace-objects", *arguments], + cwd=ROOT, + check=False, + capture_output=True, + text=text, + env=environment, + ) + + +def _git(*arguments: str, text: bool = False) -> bytes | str: + result = _run_git(*arguments, text=text) + _require( + result.returncode == 0, f"git command failed: {' '.join(arguments)}" + ) + return result.stdout + + +def _require_exact_commit_object(object_id: str, label: str) -> None: + result = _run_git( + "rev-parse", + "--verify", + f"{object_id}^{{commit}}", + text=True, + ) + _require( + result.returncode == 0 and result.stdout.strip() == object_id, + f"{label} is not an exact commit object", + ) + + +def _canonical_amendment20_repository_path(path: Any) -> bool: + """Recognize one canonical, traversal-free UTF-8 repository path.""" + + if not isinstance(path, str) or not path: + return False + try: + path.encode("utf-8") + except UnicodeEncodeError: + return False + candidate = PurePosixPath(path) + return ( + not candidate.is_absolute() + and candidate.as_posix() == path + and all(part not in {"", ".", ".."} for part in candidate.parts) + ) + + +def _read_amendment20_worktree_file( + path: str, + *, + verification_root: Path, +) -> tuple[bytes, str]: + """Reread one regular file or symlink from the execution worktree.""" + + worktree_path = verification_root / path + try: + metadata = worktree_path.lstat() + if stat.S_ISLNK(metadata.st_mode): + return os.fsencode(os.readlink(worktree_path)), "120000" + _require( + stat.S_ISREG(metadata.st_mode), + "Amendment-20 manifest member is not a file", + ) + mode = "100755" if metadata.st_mode & 0o111 else "100644" + return worktree_path.read_bytes(), mode + except OSError as error: + raise LawError( + "Amendment-20 manifest working bytes cannot be reread" + ) from error + + +def _reconstruct_amendment20_repository_manifest( + execution_tree_oid: str, + *, + verification_root: Path, +) -> tuple[list[dict[str, Any]], tuple[str, ...]]: + """Rebuild the complete tracked/untracked §29.4.1 manifest.""" + + tree_listing = _run_git( + "-C", + str(verification_root), + "ls-tree", + "-rz", + "--full-tree", + execution_tree_oid, + ) + _require( + tree_listing.returncode == 0 + and isinstance(tree_listing.stdout, bytes), + "Amendment-20 execution tree cannot be enumerated", + ) + rows: list[dict[str, Any]] = [] + tracked_paths: set[str] = set() + for raw_entry in tree_listing.stdout.split(b"\0"): + if not raw_entry: + continue + try: + raw_metadata, raw_path = raw_entry.split(b"\t", 1) + mode, object_type, raw_oid = raw_metadata.split(b" ", 2) + path = raw_path.decode("utf-8") + object_id = raw_oid.decode("ascii") + mode_text = mode.decode("ascii") + object_type_text = object_type.decode("ascii") + except (UnicodeDecodeError, ValueError) as error: + raise LawError( + "Amendment-20 execution tree has a noncanonical entry" + ) from error + _require( + _canonical_amendment20_repository_path(path) + and path not in tracked_paths + and object_type_text == "blob" + and mode_text in {"100644", "100755", "120000"} + and _is_lower_hex(object_id, 40), + "Amendment-20 execution tree has an unsupported entry", + ) + blob_result = _run_git( + "-C", + str(verification_root), + "cat-file", + "blob", + object_id, + ) + _require( + blob_result.returncode == 0 + and isinstance(blob_result.stdout, bytes) + and _git_blob_oid(blob_result.stdout) == object_id, + "Amendment-20 execution tree blob cannot be authenticated", + ) + working_raw, working_mode = _read_amendment20_worktree_file( + path, + verification_root=verification_root, + ) + _require( + working_mode == mode_text and working_raw == blob_result.stdout, + "Amendment-20 tracked working bytes do not exact-match the tree", + ) + tracked_paths.add(path) + rows.append( + { + "path": path, + "mode": mode_text, + "git_blob": object_id, + "byte_size": len(blob_result.stdout), + "raw_sha256": _sha256(blob_result.stdout), + } + ) + + untracked_listing = _run_git( + "-C", + str(verification_root), + "ls-files", + "--others", + "--exclude-standard", + "-z", + ) + _require( + untracked_listing.returncode == 0 + and isinstance(untracked_listing.stdout, bytes), + "Amendment-20 nonignored untracked paths cannot be enumerated", + ) + untracked_paths: list[str] = [] + for raw_path in untracked_listing.stdout.split(b"\0"): + if not raw_path: + continue + try: + path = raw_path.decode("utf-8") + except UnicodeDecodeError as error: + raise LawError( + "Amendment-20 untracked path is not UTF-8" + ) from error + _require( + _canonical_amendment20_repository_path(path) + and path not in tracked_paths + and path not in untracked_paths, + "Amendment-20 untracked path is noncanonical or duplicated", + ) + raw, mode_text = _read_amendment20_worktree_file( + path, + verification_root=verification_root, + ) + untracked_paths.append(path) + rows.append( + { + "path": path, + "mode": mode_text, + "git_blob": _git_blob_oid(raw), + "byte_size": len(raw), + "raw_sha256": _sha256(raw), + } + ) + + rows.sort(key=lambda row: row["path"].encode("utf-8")) + index_result = _run_git( + "-C", + str(verification_root), + "diff", + "--cached", + "--quiet", + execution_tree_oid, + "--", + ) + _require( + index_result.returncode == 0, + "Amendment-20 repository index does not exact-match the tree", + ) + status_result = _run_git( + "-C", + str(verification_root), + "status", + "--porcelain=v1", + "-z", + "--untracked-files=all", + ) + _require( + status_result.returncode == 0 and status_result.stdout == b"", + "Amendment-20 repository is not exactly clean", + ) + return rows, tuple(untracked_paths) + + +def _validate_amendment20_nonemission_evidence( + nonemission: Mapping[str, Any], + forbidden_output_paths: Sequence[str], + *, + status_member: str, +) -> None: + """Authenticate failure nonemission without trusting lifecycle booleans.""" + + label = f"Amendment-20 {status_member}" + execution_commit = nonemission["execution_commit"] + execution_tree_oid = nonemission["execution_tree_oid"] + commit_result = _run_git( + "rev-parse", + "--verify", + f"{execution_commit}^{{commit}}", + text=True, + ) + _require( + commit_result.returncode == 0 + and commit_result.stdout.strip() == execution_commit, + f"{label} execution commit is not an exact commit object", + ) + tree_result = _run_git( + "rev-parse", + "--verify", + f"{execution_tree_oid}^{{tree}}", + text=True, + ) + _require( + tree_result.returncode == 0 + and tree_result.stdout.strip() == execution_tree_oid, + f"{label} execution tree is not an exact tree object", + ) + commit_tree_result = _run_git( + "rev-parse", + "--verify", + f"{execution_commit}^{{tree}}", + text=True, + ) + _require( + commit_tree_result.returncode == 0 + and commit_tree_result.stdout.strip() == execution_tree_oid, + f"{label} execution commit/tree binding drift", + ) + + supplied_manifests: list[list[dict[str, Any]]] = [] + for phase in ("before", "after"): + manifest = nonemission[f"repository_manifest_rows_{phase}"] + _require( + isinstance(manifest, list), + f"{label} repository manifest {phase} is not an array", + ) + paths: list[str] = [] + for row in manifest: + _require( + isinstance(row, Mapping), + f"{label} repository manifest {phase} row is not an object", + ) + _require_exact_keys( + row, + set(A20_REPOSITORY_MANIFEST_ROW_KEYS), + f"{label} repository manifest {phase} row", + ) + _require( + _canonical_amendment20_repository_path(row["path"]) + and row["mode"] in {"100644", "100755", "120000"} + and _is_lower_hex(row["git_blob"], 40) + and type(row["byte_size"]) is int + and row["byte_size"] >= 0 + and _is_lower_hex(row["raw_sha256"], 64), + f"{label} repository manifest {phase} row identity drift", + ) + paths.append(row["path"]) + _require( + paths == sorted(paths, key=lambda path: path.encode("utf-8")) + and len(paths) == len(set(paths)), + f"{label} repository manifest {phase} order/domain drift", + ) + supplied_manifests.append([dict(row) for row in manifest]) + + before_rows, after_rows = supplied_manifests + with tempfile.TemporaryDirectory( + prefix="a20-verification-checkout-" + ) as temporary: + verification_root = Path(temporary) / "checkout" + checkout_needs_cleanup = False + try: + checkout_result = _run_git( + "worktree", + "add", + "--detach", + "--quiet", + str(verification_root), + execution_commit, + ) + checkout_needs_cleanup = ( + checkout_result.returncode == 0 or verification_root.exists() + ) + _require( + checkout_result.returncode == 0, + f"{label} execution commit cannot be materialized", + ) + checkout_head = _run_git( + "-C", + str(verification_root), + "rev-parse", + "--verify", + "HEAD^{commit}", + text=True, + ) + _require( + checkout_head.returncode == 0 + and checkout_head.stdout.strip() == execution_commit, + f"{label} verification checkout identity drift", + ) + reconstructed_rows, untracked_paths = ( + _reconstruct_amendment20_repository_manifest( + execution_tree_oid, + verification_root=verification_root, + ) + ) + finally: + if checkout_needs_cleanup: + cleanup_result = _run_git( + "worktree", + "remove", + "--force", + str(verification_root), + ) + _require( + cleanup_result.returncode == 0, + f"{label} verification checkout cleanup failed", + ) + _require( + before_rows == reconstructed_rows and after_rows == reconstructed_rows, + f"{label} repository manifest authentication drift", + ) + before_sha256 = _sha256(canonical_json_bytes(before_rows)) + after_sha256 = _sha256(canonical_json_bytes(after_rows)) + _require( + nonemission["repository_manifest_sha256_before"] == before_sha256 + and nonemission["repository_manifest_sha256_after"] == after_sha256 + and before_rows == after_rows + and before_sha256 == after_sha256, + f"{label} repository manifest digest or equality drift", + ) + _require( + all( + _canonical_amendment20_repository_path(path) + for path in forbidden_output_paths + ) + and len(forbidden_output_paths) == len(set(forbidden_output_paths)), + f"{label} forbidden output path domain drift", + ) + after_paths = {row["path"] for row in after_rows} + forbidden_outputs_absent = all( + path not in after_paths for path in forbidden_output_paths + ) + repository_clean = not untracked_paths + _require( + repository_clean + and forbidden_outputs_absent + and nonemission["repository_clean_before"] is repository_clean + and nonemission["repository_clean_after"] is repository_clean + and nonemission["forbidden_outputs_absent_after_execution"] + is forbidden_outputs_absent, + f"{label} independently derived nonemission facts drift", + ) + + +def _validate_amendment12_ratification_identity( + identity: Mapping[str, Any], +) -> None: + _require_exact_keys( + identity, + { + "ratification_commit", + "ratification_parents", + "document_path", + "document_mode", + "document_blob_oid", + "document_byte_size", + "document_sha256", + "dual_ratify_attestations", + }, + "Amendment-12 ratification identity", + ) + _require( + identity["document_path"] == DESIGN_PATH + and identity["document_mode"] == DESIGN_MODE, + "ratification identity selects another document path or mode", + ) + _require( + isinstance(identity["ratification_parents"], list) + and len(identity["ratification_parents"]) == 1, + "ratification identity does not name one parent", + ) + parent_line = str( + _git( + "rev-list", + "--parents", + "-n", + "1", + identity["ratification_commit"], + text=True, + ) + ).strip() + _require( + parent_line.split() + == [ + identity["ratification_commit"], + identity["ratification_parents"][0], + ], + "ratification commit is not the exact single-parent commit", + ) + tree_line = str( + _git( + "ls-tree", + identity["ratification_commit"], + "--", + identity["document_path"], + text=True, + ) + ).strip() + _require( + tree_line + == ( + f"{identity['document_mode']} blob " + f"{identity['document_blob_oid']}\t{identity['document_path']}" + ), + "ratification commit does not select the supplied document blob", + ) + raw = _git( + "show", + f"{identity['ratification_commit']}:{identity['document_path']}", + ) + _require( + isinstance(raw, bytes), "ratification blob read was not raw bytes" + ) + _require( + len(raw) == identity["document_byte_size"] + and _sha256(raw) == identity["document_sha256"] + and hashlib.sha1( + b"blob " + str(len(raw)).encode() + b"\0" + raw + ).hexdigest() + == identity["document_blob_oid"], + "ratification document bytes do not match the dual-hash identity", + ) + _require( + identity == AMENDMENT12_RATIFICATION_IDENTITY, + "ratification identity is not the exact attested document identity", + ) + + +def _is_lower_hex(value: Any, length: int) -> bool: + return ( + isinstance(value, str) + and len(value) == length + and all(character in "0123456789abcdef" for character in value) + ) + + +def _strict_canonical_json(raw: bytes, label: str) -> dict[str, Any]: + try: + value = a12.strict_json_loads(raw, label) + except a12.BuildError as error: + raise LawError(f"{label} is invalid strict JSON") from error + _require( + isinstance(value, dict) and canonical_json_bytes(value) == raw, + f"{label} is not canonical JSON", + ) + _require_no_unpaired_surrogates(value, label) + return value + + +def _require_no_unpaired_surrogates(value: Any, label: str) -> None: + """Reject surrogate code points admitted by Python's JSON decoder.""" + + if isinstance(value, str): + _require( + not any(0xD800 <= ord(character) <= 0xDFFF for character in value), + f"{label} contains an unpaired Unicode surrogate", + ) + return + if isinstance(value, Mapping): + for key, member in value.items(): + _require_no_unpaired_surrogates(key, label) + _require_no_unpaired_surrogates(member, label) + return + if isinstance(value, list): + for member in value: + _require_no_unpaired_surrogates(member, label) + + +_A20_DECIMAL_GRAMMAR = r"(?:[1-9][0-9]*|[1-9][0-9]{0,2}(?:,[0-9]{3})+)" +_A20_QUALIFYING_VERDICT_PATTERN = re.compile( + rf"\A# RATIFY\n" + rf"attested_design_byte_size: (?P{_A20_DECIMAL_GRAMMAR})\n" + rf"attested_design_raw_sha256: (?P[0-9a-f]{{64}})\n" + rf"attested_design_blob_oid: (?P[0-9a-f]{{40}})\n" + rf"executed_transition_receipt_byte_size: " + rf"(?P{_A20_DECIMAL_GRAMMAR})\n" + rf"executed_transition_receipt_raw_sha256: " + rf"(?P[0-9a-f]{{64}})\n" + rf"executed_transition_receipt_schema: executed_transition_state\.v2\n" + rf"---\n\Z" +) +_A20_SIMULATED_STANDIN_PATTERN = re.compile( + rf"\A# RATIFY\n" + rf"attested_design_byte_size: (?P{_A20_DECIMAL_GRAMMAR})\n" + rf"attested_design_raw_sha256: (?P[0-9a-f]{{64}})\n" + rf"attested_design_blob_oid: (?P[0-9a-f]{{40}})\n" + rf"executed_transition_receipt_status: pending_same_state_execution\n" + rf"simulation_context: amendment20_same_state_nonauthority_v1\n" + rf"---\n\Z" +) -def _canonical_amendment14_projection() -> dict[str, Any]: - return { - "section_semantic_sha256": A14_SECTION_SEMANTIC_SHA256, - "closure_top_level_keys": list(CLOSURE_TOP_LEVEL_KEYS), - "closure_verdict_keys": list(CLOSURE_VERDICT_KEYS), - "registry_closure_binding_keys": list(REGISTRY_CLOSURE_BINDING_KEYS), - "a13_verdict_artifacts": [dict(row) for row in A13_VERDICT_ARTIFACTS], - "a13_expected_closure": copy.deepcopy(A13_EXPECTED_CLOSURE), - "ratification_sequence": list(A14_RATIFICATION_SEQUENCE), - "implementation_pins": None, - "semantic_mutations": list(A13_EXPECTED_MUTATIONS), - "enforcement_mutations": list(A13_ENFORCEMENT_EXPECTED_MUTATIONS), - "removed_mutations": list(REMOVED_PKI_MUTATIONS), - "schema_binding_identifiers": list(A14_SCHEMA_BINDING_IDENTIFIERS), - "path_templates": list(A14_PATH_TEMPLATES), - "status_operation_identifiers": list(A14_STATUS_OPERATION_IDENTIFIERS), - } +def _decode_amendment20_verdict(raw: bytes, label: str) -> str: + _require(isinstance(raw, bytes), f"{label} is not bytes") + _require( + not raw.startswith(b"\xef\xbb\xbf") + and b"\x00" not in raw + and b"\r" not in raw + and raw.endswith(b"\n") + and not raw.endswith(b"\n\n"), + f"{label} violates strict UTF-8/LF framing", + ) + try: + return raw.decode("utf-8", errors="strict") + except UnicodeDecodeError as error: + raise LawError(f"{label} is not strict UTF-8") from error -def _canonical_amendment15_projection() -> dict[str, Any]: - return { - "section_semantic_sha256": A15_SECTION_SEMANTIC_SHA256, - "implementation_pins": None, - "mutation_bindings": None, - } +def _a20_decimal(value: str, label: str) -> int: + _require( + re.fullmatch(_A20_DECIMAL_GRAMMAR, value) is not None, + f"{label} decimal grammar drift", + ) + parsed = int(value.replace(",", "")) + _require(parsed > 0, f"{label} must be positive") + return parsed -def _canonical_amendment16_projection() -> dict[str, Any]: - return { - "section_semantic_sha256": A16_SECTION_SEMANTIC_SHA256, - "ratification_law_values": copy.deepcopy(A16_RATIFICATION_LAW_VALUES), - "ordered_domain_expression": "range(13, R - 1)", - "generated_closure_path_rule": ( - "docs/analysis/amendment_{13+i}_ratification/closure_v1.json" +def validate_amendment20_qualifying_verdict( + raw: bytes, + *, + design_byte_size: int, + design_raw_sha256: str, + design_blob_oid: str, + receipt_byte_size: int, + receipt_raw_sha256: str, +) -> dict[str, Any]: + """Strict-parse one A20 qualifying verdict and verify its attestations.""" + + _require( + type(design_byte_size) is int + and design_byte_size > 0 + and _is_lower_hex(design_raw_sha256, 64) + and _is_lower_hex(design_blob_oid, 40), + "Amendment-20 expected design attestation is malformed", + ) + _require( + type(receipt_byte_size) is int + and receipt_byte_size > 0 + and _is_lower_hex(receipt_raw_sha256, 64), + "Amendment-20 expected receipt attestation is malformed", + ) + text = _decode_amendment20_verdict( + raw, + "Amendment-20 qualifying verdict", + ) + match = _A20_QUALIFYING_VERDICT_PATTERN.fullmatch(text) + _require( + match is not None, "Amendment-20 qualifying verdict grammar drift" + ) + parsed = { + "design_byte_size": _a20_decimal( + match.group("design_size"), + "Amendment-20 design byte size", ), - "combined_closure_paths": list(A16_COMBINED_CLOSURE_PATHS), - "a14_historical_closure_binding": copy.deepcopy( - A14_HISTORICAL_CLOSURE_BINDING + "design_raw_sha256": match.group("design_sha"), + "design_blob_oid": match.group("design_blob"), + "receipt_byte_size": _a20_decimal( + match.group("receipt_size"), + "Amendment-20 receipt byte size", ), - "a15_verdict_artifacts": [dict(row) for row in A15_VERDICT_ARTIFACTS], - "a15_expected_closure": copy.deepcopy(A15_EXPECTED_CLOSURE), - "ratification_sequence": list(A16_RATIFICATION_SEQUENCE), - "historical_r05_binding": copy.deepcopy(A16_HISTORICAL_R05_BINDING), - "implementation_pins": None, - "oracle_mutations": list(A16_EXPECTED_MUTATIONS), - "oracle_mutation_domain_sha256": A16_MUTATION_DOMAIN_SHA256, - "supersession_map": None, - "schema_operation_identifiers": list(A16_SCHEMA_OPERATION_IDENTIFIERS), - "status_identifiers": list(A16_STATUS_IDENTIFIERS), - "python_identifiers": list(A16_PYTHON_IDENTIFIERS), + "receipt_raw_sha256": match.group("receipt_sha"), + "receipt_schema": "executed_transition_state.v2", } + _require( + parsed["design_byte_size"] == design_byte_size + and parsed["design_raw_sha256"] == design_raw_sha256 + and parsed["design_blob_oid"] == design_blob_oid, + "Amendment-20 verdict design attestation mismatch", + ) + _require( + parsed["receipt_byte_size"] == receipt_byte_size + and parsed["receipt_raw_sha256"] == receipt_raw_sha256, + "Amendment-20 verdict receipt attestation mismatch", + ) + return parsed -def _canonical_amendment17_projection() -> dict[str, Any]: - return { - "section_semantic_sha256": A17_SECTION_SEMANTIC_SHA256, - "implementation_pins": None, - "revision_domain_rules": list(A17_REVISION_DOMAIN_RULES), - "executed_transition_obligation": copy.deepcopy( - A17_EXECUTED_TRANSITION_OBLIGATION - ), - "receipt_schema": copy.deepcopy(A17_RECEIPT_SCHEMA), - "transition_registry_binding": copy.deepcopy( - A17_TRANSITION_REGISTRY_BINDING +def _validate_amendment20_simulated_standin( + raw: bytes, + *, + design_byte_size: int, + design_raw_sha256: str, + design_blob_oid: str, +) -> dict[str, Any]: + """Accept only the distinct seven-line scratch-construction stand-in.""" + + _require( + type(design_byte_size) is int + and design_byte_size > 0 + and _is_lower_hex(design_raw_sha256, 64) + and _is_lower_hex(design_blob_oid, 40), + "Amendment-20 stand-in expected design attestation is malformed", + ) + text = _decode_amendment20_verdict( + raw, + "Amendment-20 simulated stand-in", + ) + match = _A20_SIMULATED_STANDIN_PATTERN.fullmatch(text) + _require( + match is not None, "Amendment-20 simulated stand-in grammar drift" + ) + parsed = { + "design_byte_size": _a20_decimal( + match.group("design_size"), + "Amendment-20 stand-in design byte size", ), - "transition_closure_identities": [ - dict(row) for row in A17_TRANSITION_CLOSURE_IDENTITIES - ], - "transition_verdict_artifacts": [ - dict(row) for row in A17_TRANSITION_VERDICT_ARTIFACTS - ], - "required_public_output": list(A17_REQUIRED_PUBLIC_OUTPUT), - "full_pinned_battery": copy.deepcopy(A17_FULL_PINNED_BATTERY), - "test_ceremony_mutations": list(A17_EXPECTED_MUTATIONS), - "test_ceremony_mutation_domain_sha256": (A17_MUTATION_DOMAIN_SHA256), - "mutation_census": copy.deepcopy(A17_MUTATION_CENSUS), - "supersession_map": [list(row) for row in A17_SUPERSESSION_MAP], + "design_raw_sha256": match.group("design_sha"), + "design_blob_oid": match.group("design_blob"), + "executed_transition_receipt_status": ("pending_same_state_execution"), + "simulation_context": "amendment20_same_state_nonauthority_v1", } + _require( + parsed["design_byte_size"] == design_byte_size + and parsed["design_raw_sha256"] == design_raw_sha256 + and parsed["design_blob_oid"] == design_blob_oid, + "Amendment-20 stand-in design attestation mismatch", + ) + return parsed -def _canonical_amendment18_projection() -> dict[str, Any]: - return { - "section_semantic_sha256": A18_SECTION_SEMANTIC_SHA256, - "implementation_pins": None, - "build_input_domain_contract": copy.deepcopy( - A18_BUILD_INPUT_DOMAIN_CONTRACT - ), - "historical_r05_binding": copy.deepcopy(A18_HISTORICAL_R05_BINDING), - "r06_result_contract": copy.deepcopy(A18_R06_RESULT_CONTRACT), - "activation_transition": copy.deepcopy(A18_ACTIVATION_TRANSITION), - "contract_mutations": list(A18_EXPECTED_MUTATIONS), - "contract_mutation_domain_sha256": A18_MUTATION_DOMAIN_SHA256, - "mutation_census": copy.deepcopy(A18_MUTATION_CENSUS), - "supersession_map": [list(row) for row in A18_SUPERSESSION_MAP], - "new_identifiers": copy.deepcopy(A18_NEW_IDENTIFIERS), - } +def _validate_amendment20_r06_collection_binding() -> dict[str, Any]: + """Reauthenticate the six pinned files and exact 223-node collection.""" + for row in A20_R06_FILE_IDENTITIES: + path = row["path"] + try: + worktree_raw = (ROOT / path).read_bytes() + except OSError as error: + raise LawError( + f"Amendment-20 R06 file is missing: {path}" + ) from error + head_raw = _git("show", f"HEAD:{path}") + tree_line = str(_git("ls-tree", "HEAD", "--", path, text=True)).strip() + _require( + isinstance(head_raw, bytes) + and worktree_raw == head_raw + and tree_line == f"{row['mode']} blob {row['git_blob']}\t{path}" + and len(worktree_raw) == row["byte_size"] + and _sha256(worktree_raw) == row["raw_sha256"] + and _git_blob_oid(worktree_raw) == row["git_blob"], + f"Amendment-20 R06 pinned file identity drift: {path}", + ) -def _canonical_amendment19_projection() -> dict[str, Any]: + environment = { + key: value + for key, value in os.environ.items() + if not key.startswith("GIT_") and key != "PYTEST_ADDOPTS" + } + environment["PYTHONPATH"] = "src:." + command = [ + sys.executable, + *A20_R06_LIFECYCLE_CONTRACT["collection_command_after_interpreter"], + ] + result = subprocess.run( + command, + cwd=ROOT, + check=False, + capture_output=True, + text=True, + env=environment, + ) + _require( + result.returncode == 0, + "Amendment-20 R06 exact collection command failed", + ) + node_ids = [ + line + for line in result.stdout.splitlines() + if "::" in line + and any( + line.startswith(f"{row['path']}::") + for row in A20_R06_FILE_IDENTITIES + ) + ] + raw = canonical_json_bytes(node_ids) + _require( + len(node_ids) == A20_R06_LIFECYCLE_CONTRACT["collected_node_id_count"] + and len(raw) + == A20_R06_LIFECYCLE_CONTRACT[ + "collected_node_id_array_canonical_byte_size" + ] + and _sha256(raw) + == A20_R06_LIFECYCLE_CONTRACT["collected_node_id_array_raw_sha256"] + and node_ids[0] + == A20_R06_LIFECYCLE_CONTRACT["first_collected_node_id"] + and node_ids[-1] + == A20_R06_LIFECYCLE_CONTRACT["last_collected_node_id"], + "Amendment-20 R06 collected-node identity drift", + ) return { - "section_semantic_sha256": A19_SECTION_SEMANTIC_SHA256, - "implementation_pins": None, - "normative_manifest": copy.deepcopy(A19_NORMATIVE_MANIFEST), + "command": command, + "environment": {"PYTHONPATH": "src:."}, + "file_identities": [dict(row) for row in A20_R06_FILE_IDENTITIES], + "node_ids": node_ids, + "node_id_array_canonical_byte_size": len(raw), + "node_id_array_raw_sha256": _sha256(raw), } -@lru_cache(maxsize=1) -def _canonical_draft_document_projection() -> dict[str, Any]: - """Build the immutable document cross-check independently of a caller law.""" +def _validate_amendment20_scratch_transition_context( + standin_bytes: Mapping[str, bytes], +) -> dict[str, Any]: + """Authenticate the one Git/registry context in which stand-ins exist.""" - law = _construct_execution_law( - governing_amendment13_ratification_identity=( - GOVERNING_A13_CANDIDATE_IDENTITY + expected_paths = A20_RECEIPT_SCHEMA["expected_changed_paths"] + verdict_paths = expected_paths[:2] + _require( + set(standin_bytes) == set(verdict_paths), + "Amendment-20 scratch stand-in path domain drift", + ) + scratch_commit = str(_git("rev-parse", "HEAD", text=True)).strip() + detached = _run_git("symbolic-ref", "-q", "HEAD", text=True) + containing_refs = str( + _git( + "for-each-ref", + "--format=%(refname)", + "--contains", + scratch_commit, + text=True, + ) + ).splitlines() + replace_refs = str( + _git("for-each-ref", "--format=%(refname)", "refs/replace", text=True) + ).splitlines() + status_rows = str(_git("status", "--porcelain", text=True)).splitlines() + _require( + detached.returncode != 0 + and containing_refs == [] + and replace_refs == [] + and status_rows == [], + "Amendment-20 scratch must be detached, unreachable, replace-free, and clean", + ) + parent_line = str( + _git("rev-list", "--parents", "-n", "1", scratch_commit, text=True) + ).strip() + parent_tokens = parent_line.split() + _require( + len(parent_tokens) == 2 and parent_tokens[0] == scratch_commit, + "Amendment-20 scratch commit does not have one candidate parent", + ) + candidate_commit = parent_tokens[1] + candidate_parent_line = str( + _git("rev-list", "--parents", "-n", "1", candidate_commit, text=True) + ).strip() + candidate_parent_tokens = candidate_parent_line.split() + _require( + len(candidate_parent_tokens) == 2 + and candidate_parent_tokens[0] == candidate_commit, + "Amendment-20 candidate commit does not have one parent", + ) + candidate_tree = str( + _git("rev-parse", f"{candidate_commit}^{{tree}}", text=True) + ).strip() + scratch_tree = str( + _git("rev-parse", f"{scratch_commit}^{{tree}}", text=True) + ).strip() + changed_paths = str( + _git( + "diff-tree", + "--no-commit-id", + "--name-only", + "-r", + scratch_commit, + text=True, + ) + ).splitlines() + _require( + len(changed_paths) == A20_RECEIPT_SCHEMA["changed_path_count"] + and len(set(changed_paths)) == A20_RECEIPT_SCHEMA["changed_path_count"] + and set(changed_paths) == set(expected_paths) + and len(canonical_json_bytes(expected_paths)) + == A20_RECEIPT_SCHEMA[ + "expected_changed_path_domain_canonical_byte_size" + ] + and _sha256(canonical_json_bytes(expected_paths)) + == A20_RECEIPT_SCHEMA["expected_changed_path_domain_sha256"], + "Amendment-20 scratch changed-path domain drift", + ) + candidate_raw = _git("show", f"{candidate_commit}:{DESIGN_PATH}") + _require( + isinstance(candidate_raw, bytes), + "Amendment-20 candidate design read was not raw bytes", + ) + candidate_design_tree_line = str( + _git( + "ls-tree", + candidate_commit, + "--", + DESIGN_PATH, + text=True, + ) + ).strip() + _require( + candidate_design_tree_line + == ( + f"{DESIGN_MODE} blob {_git_blob_oid(candidate_raw)}\t" + f"{DESIGN_PATH}" ), - status=DRAFT_STATUS, + "Amendment-20 candidate design tree identity drift", ) - integrity = law["integrity"] - for name, count, sha256 in PROSPECTIVE_DOMAIN_PINS: - count_key, sha_key = { - "Repair overlays": ("overlay_count", "overlay_domain_sha256"), - "All repair successors": ( - "repair_count", - "successor_domain_sha256", - ), - "Supersession edges": ( - "supersession_count", - "supersession_domain_sha256", - ), - "Successor-era seal fixtures": ( - "successor_era_seal_count", - "successor_era_seal_domain_sha256", - ), - }[name] + _validate_amendment20_ratification_design(candidate_raw) + candidate_pins = _parse_amendment20_implementation_pins(candidate_raw) + for row in candidate_pins["files"]: + tree_line = str( + _git("ls-tree", candidate_commit, "--", row["path"], text=True) + ).strip() + file_raw = _git("show", f"{candidate_commit}:{row['path']}") + _require( + tree_line + == ( + f"{candidate_pins['mode']} blob {row['blob_oid']}\t" + f"{row['path']}" + ) + and isinstance(file_raw, bytes) + and len(file_raw) == row["byte_size"] + and _sha256(file_raw) == row["sha256"] + and _git_blob_oid(file_raw) == row["blob_oid"], + "Amendment-20 candidate implementation pin mismatch", + ) + + import covered_earnings_correction_registry as registry + + _require( + getattr(registry, "SIMULATED_STATE_AUTHORITY", None) == "NONAUTHORITY" + and getattr(registry, "SIMULATION_CONTEXT", None) + == "amendment20_same_state_nonauthority_v1", + "Amendment-20 scratch registry context is absent", + ) + registry_binding = _validate_registry_ratification_context( + registry.design_binding() + ) + _require( + registry_binding["revision"] == 22 + and _ratification_amendment_numbers(22) + == (13, 14, 15, 16, 17, 18, 19, 20) + and registry_binding["ratification_commit"] == candidate_commit + and registry_binding["blob_sha256"] == _sha256(candidate_raw), + "Amendment-20 scratch registry does not bind candidate revision 22", + ) + closure_raw = _git("show", f"{scratch_commit}:{expected_paths[2]}") + _require( + isinstance(closure_raw, bytes), + "Amendment-20 synthetic closure read was not raw bytes", + ) + closure = _strict_canonical_json( + closure_raw, + "Amendment-20 synthetic scratch closure", + ) + _validate_closure_shape(closure, 20) + _require( + closure["attested_candidate_design_byte_size"] == len(candidate_raw) + and closure["attested_candidate_design_raw_sha256"] + == _sha256(candidate_raw) + and closure["attested_candidate_design_blob_oid"] + == _git_blob_oid(candidate_raw) + and closure["ratification_commit"] == candidate_commit + and closure["operator_merge_commit"] == candidate_commit + and closure["ratification_commit_sole_parent"] + == candidate_parent_tokens[1] + and [row["path"] for row in closure["verdict_artifacts"]] + == verdict_paths, + "Amendment-20 synthetic closure does not bind candidate and stand-ins", + ) + for row in closure["verdict_artifacts"]: + raw = standin_bytes[row["path"]] _require( - integrity[count_key] == count and integrity[sha_key] == sha256, - f"prospective {name} Python pin drift", + len(raw) == row["byte_size"] and _sha256(raw) == row["raw_sha256"], + "Amendment-20 synthetic closure stand-in identity mismatch", ) - _require( - tuple( - row["successor_era_seal_id"] - for row in law["successor_era_seal_rows"] + _validate_amendment20_simulated_standin( + raw, + design_byte_size=len(candidate_raw), + design_raw_sha256=_sha256(candidate_raw), + design_blob_oid=_git_blob_oid(candidate_raw), ) - == PROSPECTIVE_ERA_SEAL_IDS, - "prospective successor-era Python pin drift", - ) return { - "section_semantic_sha256": dict(A13_SECTION_SEMANTIC_SHA256), - "identity": _execution_identity_projection(law), - "overlays": _execution_overlay_projection(law), - "proof": _execution_proof_projection(law), - "fragments": _execution_fragment_projection(law), - "doc036": _execution_doc036_projection(law), - "scope": _execution_scope_projection(law), - "comparator": { - "search_augmentation": list(A13_SEARCH_AUGMENTATION), - "comparator_rows": [list(row) for row in A13_COMPARATOR_ROWS], - "schema_literals": list(A13_SCHEMA_LITERALS), - "content_id_prefixes": list(A13_CONTENT_ID_PREFIXES), - "status_relation_operation_codes": list( - A13_STATUS_RELATION_OPERATION_CODES + "candidate_commit_identity": { + "commit": candidate_commit, + "tree": candidate_tree, + "sole_parent": candidate_parent_tokens[1], + }, + "scratch_transition": { + "commit": scratch_commit, + "tree": scratch_tree, + "sole_parent": candidate_commit, + "changed_paths": list(expected_paths), + "changed_path_domain_sha256": _sha256( + canonical_json_bytes(expected_paths) ), - "successor_kind_literals": list(A13_SUCCESSOR_KIND_LITERALS), }, - "amendment14": _canonical_amendment14_projection(), - "amendment15": _canonical_amendment15_projection(), - "amendment16": _canonical_amendment16_projection(), - "amendment17": _canonical_amendment17_projection(), - "amendment18": _canonical_amendment18_projection(), - "amendment19": _canonical_amendment19_projection(), + "changed_paths": list(expected_paths), + "registry_binding": registry_binding, + "closure": closure, } -def _git_blob_oid(raw: bytes) -> str: - return hashlib.sha1( - b"blob " + str(len(raw)).encode() + b"\0" + raw - ).hexdigest() +def _amendment20_registry_behavior_ast( + raw: bytes, + label: str, +) -> tuple[str, Counter[str], set[str]]: + """Normalize only the closed scratch-binding assignment statements.""" + + binding_names = { + "DESIGN_PATH", + "DESIGN_RATIFICATION_COMMIT", + "DESIGN_REVISION", + "DESIGN_BYTE_SIZE", + "DESIGN_BLOB_SHA256", + "RATIFICATION_CLOSURE_BINDINGS", + "SIMULATED_STATE_AUTHORITY", + "SIMULATION_CONTEXT", + } + try: + module = ast.parse(raw.decode("utf-8")) + except (UnicodeDecodeError, SyntaxError) as error: + raise LawError(f"{label} is not valid UTF-8 Python") from error + removed_counts: Counter[str] = Counter() + literal_names: set[str] = set() + retained: list[ast.stmt] = [] + for node in module.body: + name: str | None = None + value_node: ast.expr | None = None + if ( + isinstance(node, ast.Assign) + and len(node.targets) == 1 + and isinstance(node.targets[0], ast.Name) + ): + name = node.targets[0].id + value_node = node.value + elif isinstance(node, ast.AnnAssign) and isinstance( + node.target, ast.Name + ): + name = node.target.id + value_node = node.value + if name in binding_names: + removed_counts[name] += 1 + if value_node is not None: + try: + ast.literal_eval(value_node) + except (ValueError, TypeError): + pass + else: + literal_names.add(name) + else: + retained.append(node) + module.body = retained + + def mutated_binding_names(target: ast.AST) -> set[str]: + if isinstance(target, ast.Name): + return {target.id} if target.id in binding_names else set() + if isinstance(target, (ast.Attribute, ast.Subscript)): + return mutated_binding_names(target.value) + if isinstance(target, (ast.Tuple, ast.List)): + return { + name + for element in target.elts + for name in mutated_binding_names(element) + } + if isinstance(target, ast.Starred): + return mutated_binding_names(target.value) + return set() + + mutated_names = { + name + for node in ast.walk(module) + if isinstance(getattr(node, "ctx", None), (ast.Store, ast.Del)) + for name in mutated_binding_names(node) + } + _require( + mutated_names == set(), + f"{label} mutates a closed binding name outside its literal assignment", + ) + return ( + ast.dump(module, include_attributes=False), + removed_counts, + literal_names, + ) -def _verify_implementation_pins(pins: Mapping[str, Any]) -> None: - """Authenticate active file identities against the worktree and HEAD.""" +def _parse_amendment20_scratch_registry_binding( + raw: bytes, + *, + candidate_raw: bytes, +) -> dict[str, Any]: + """Extract the closed literal A20 scratch binding without executing it.""" + + required_names = { + "DESIGN_PATH", + "DESIGN_RATIFICATION_COMMIT", + "DESIGN_REVISION", + "DESIGN_BYTE_SIZE", + "DESIGN_BLOB_SHA256", + "RATIFICATION_CLOSURE_BINDINGS", + "SIMULATED_STATE_AUTHORITY", + "SIMULATION_CONTEXT", + } + try: + source = raw.decode("utf-8") + module = ast.parse(source) + except (UnicodeDecodeError, SyntaxError) as error: + raise LawError( + "Amendment-20 scratch registry source is not valid UTF-8 Python" + ) from error + assignments: dict[str, list[Any]] = {name: [] for name in required_names} + for node in module.body: + name: str | None = None + value_node: ast.expr | None = None + if ( + isinstance(node, ast.Assign) + and len(node.targets) == 1 + and isinstance(node.targets[0], ast.Name) + ): + name = node.targets[0].id + value_node = node.value + elif isinstance(node, ast.AnnAssign) and isinstance( + node.target, ast.Name + ): + name = node.target.id + value_node = node.value + if name not in required_names or value_node is None: + continue + try: + assignments[name].append(ast.literal_eval(value_node)) + except (ValueError, TypeError) as error: + raise LawError( + f"Amendment-20 scratch registry {name} is not literal" + ) from error + _require( + all(len(values) == 1 for values in assignments.values()), + "Amendment-20 scratch registry literal assignment domain drift", + ) + scratch_behavior, scratch_counts, scratch_literal_names = ( + _amendment20_registry_behavior_ast( + raw, + "Amendment-20 scratch registry source", + ) + ) + candidate_behavior, candidate_counts, candidate_literal_names = ( + _amendment20_registry_behavior_ast( + candidate_raw, + "Amendment-20 candidate registry source", + ) + ) + candidate_names = required_names - { + "SIMULATED_STATE_AUTHORITY", + "SIMULATION_CONTEXT", + } + _require( + scratch_counts == Counter({name: 1 for name in required_names}) + and scratch_literal_names == required_names + and candidate_counts == Counter({name: 1 for name in candidate_names}) + and candidate_literal_names == candidate_names + and scratch_behavior == candidate_behavior, + "Amendment-20 scratch registry behavior differs from candidate", + ) + values = {name: rows[0] for name, rows in assignments.items()} + closures = values["RATIFICATION_CLOSURE_BINDINGS"] + _require( + values["DESIGN_PATH"] == DESIGN_PATH + and _is_lower_hex(values["DESIGN_RATIFICATION_COMMIT"], 40) + and type(values["DESIGN_REVISION"]) is int + and values["DESIGN_REVISION"] == 22 + and type(values["DESIGN_BYTE_SIZE"]) is int + and values["DESIGN_BYTE_SIZE"] > 0 + and _is_lower_hex(values["DESIGN_BLOB_SHA256"], 64) + and isinstance(closures, (list, tuple)) + and all(isinstance(row, Mapping) for row in closures) + and values["SIMULATED_STATE_AUTHORITY"] == "NONAUTHORITY" + and values["SIMULATION_CONTEXT"] + == "amendment20_same_state_nonauthority_v1", + "Amendment-20 scratch registry literal value drift", + ) + return { + "design_byte_size": values["DESIGN_BYTE_SIZE"], + "binding": { + "path": values["DESIGN_PATH"], + "ratification_commit": values["DESIGN_RATIFICATION_COMMIT"], + "revision": values["DESIGN_REVISION"], + "blob_sha256": values["DESIGN_BLOB_SHA256"], + "ratification_closures": [dict(row) for row in closures], + }, + "simulated_state_authority": values["SIMULATED_STATE_AUTHORITY"], + "simulation_context": values["SIMULATION_CONTEXT"], + } + +def _validate_amendment20_transition_receipt( + receipt: Mapping[str, Any], +) -> dict[str, Any]: + """Validate receipt-v2 shape, results, and Git-derived identities.""" + + schema = A20_RECEIPT_SCHEMA + tracked_receipt_raw = _read_public_repository_file( + A20_EXECUTED_TRANSITION_RECEIPT_PATH, + "Amendment-20 executed-transition receipt", + require_regular_mode=True, + ) + _require( + tracked_receipt_raw == canonical_json_bytes(receipt), + "Amendment-20 receipt object differs from fixed tracked bytes", + ) _require_exact_keys( - pins, - {"mode", "files"}, - "Amendment-14 implementation pins", + receipt, + set(schema["top_level_keys"]), + "Amendment-20 transition receipt", ) - current_design = (ROOT / DESIGN_PATH).read_bytes() - label = "Amendment-14" - if len(current_design) > REVISION20_BYTE_SIZE: - pins = _parse_amendment19_implementation_pins(current_design) - label = "Amendment-19" - elif len(current_design) > REVISION19_BYTE_SIZE: - pins = _parse_amendment18_implementation_pins(current_design) - label = "Amendment-18" - elif len(current_design) > REVISION18_BYTE_SIZE: - pins = _parse_amendment17_implementation_pins(current_design) - label = "Amendment-17" - elif len(current_design) > REVISION17_BYTE_SIZE: - pins = _parse_amendment16_implementation_pins(current_design) - label = "Amendment-16" - elif len(current_design) > REVISION16_BYTE_SIZE: - pins = _parse_amendment15_implementation_pins(current_design) - label = "Amendment-15" + manifest = receipt["simulated_state_manifest"] _require( - pins["mode"] == DESIGN_MODE - and [row["path"] for row in pins["files"]] - == [ - "scripts/validate_amendment13_execution_law.py", - "tests/test_validate_amendment13_execution_law.py", - "scripts/build_amendment13_tier2_repairs.py", - ], - f"{label} implementation pin domain drift", + isinstance(manifest, Mapping), + "Amendment-20 receipt manifest is not an object", ) - for row in pins["files"]: - _require_exact_keys( - row, - {"path", "blob_oid", "byte_size", "sha256"}, - f"{label} implementation file pin", + _require_exact_keys( + manifest, + set(schema["manifest_keys"]), + "Amendment-20 transition receipt manifest", + ) + candidate = manifest["candidate_commit_identity"] + scratch = manifest["scratch_transition"] + _require( + isinstance(candidate, Mapping) and isinstance(scratch, Mapping), + "Amendment-20 receipt C/S identity is not an object", + ) + _require_exact_keys( + candidate, + set(schema["candidate_commit_identity_keys"]), + "Amendment-20 candidate commit identity", + ) + _require_exact_keys( + scratch, + set(schema["scratch_transition_keys"]), + "Amendment-20 scratch transition identity", + ) + _require( + manifest["schema_version"] == "executed_transition_state.v2" + and manifest["simulated_state_authority"] == "NONAUTHORITY" + and manifest["terminal_revision"] == 22 + and receipt["simulated_state_authority"] == "NONAUTHORITY" + and receipt["terminal_revision"] == 22 + and all( + _is_lower_hex(candidate[key], 40) + for key in ("commit", "tree", "sole_parent") ) - _require( - _is_lower_hex(row["blob_oid"], 40) - and type(row["byte_size"]) is int - and row["byte_size"] > 0 - and _is_lower_hex(row["sha256"], 64), - f"{label} implementation file pin is malformed", + and all( + _is_lower_hex(scratch[key], 40) + for key in ("commit", "tree", "sole_parent") ) - tree_line = str( - _git("ls-tree", "HEAD", "--", row["path"], text=True) - ).strip() - _require( - tree_line - == f"{pins['mode']} blob {row['blob_oid']}\t{row['path']}", - f"{label} implementation HEAD tree-entry pin drift", + and scratch["sole_parent"] == candidate["commit"] + and scratch["changed_paths"] == schema["expected_changed_paths"] + and scratch["changed_path_domain_sha256"] + == schema["expected_changed_path_domain_sha256"], + "Amendment-20 receipt C/S topology or changed paths drift", + ) + _require( + receipt["simulated_state_identity_sha256"] + == _sha256(canonical_json_bytes(manifest)), + "Amendment-20 receipt state identity drift", + ) + state_identity = receipt["simulated_state_identity_sha256"] + candidate_parent = str( + _git( + "rev-list", + "--parents", + "-n", + "1", + candidate["commit"], + text=True, + ) + ).split() + scratch_parent = str( + _git( + "rev-list", + "--parents", + "-n", + "1", + scratch["commit"], + text=True, + ) + ).split() + resolved_candidate_tree = str( + _git("rev-parse", f"{candidate['commit']}^{{tree}}", text=True) + ).strip() + resolved_scratch_tree = str( + _git("rev-parse", f"{scratch['commit']}^{{tree}}", text=True) + ).strip() + resolved_paths = str( + _git( + "diff-tree", + "--no-commit-id", + "--name-only", + "-r", + scratch["commit"], + text=True, + ) + ).splitlines() + containing_refs = str( + _git( + "for-each-ref", + "--format=%(refname)", + "--contains", + scratch["commit"], + text=True, + ) + ).splitlines() + replace_refs = str( + _git( + "for-each-ref", + "--format=%(refname)", + "refs/replace", + text=True, + ) + ).splitlines() + _require( + candidate_parent == [candidate["commit"], candidate["sole_parent"]] + and scratch_parent == [scratch["commit"], candidate["commit"]] + and resolved_candidate_tree == candidate["tree"] + and resolved_scratch_tree == scratch["tree"] + and len(resolved_paths) == schema["changed_path_count"] + and len(set(resolved_paths)) == schema["changed_path_count"] + and set(resolved_paths) == set(schema["expected_changed_paths"]) + and _sha256(canonical_json_bytes(schema["expected_changed_paths"])) + == scratch["changed_path_domain_sha256"] + and containing_refs == [] + and replace_refs == [], + "Amendment-20 receipt Git-resolved C/S identity drift", + ) + for commit in (candidate["commit"], scratch["commit"]): + receipt_in_transition = _run_git( + "cat-file", + "-e", + f"{commit}:{A20_EXECUTED_TRANSITION_RECEIPT_PATH}", ) - head_raw = _git("show", f"HEAD:{row['path']}") - worktree_raw = (ROOT / row["path"]).read_bytes() _require( - isinstance(head_raw, bytes) - and worktree_raw == head_raw - and len(head_raw) == row["byte_size"] - and _sha256(head_raw) == row["sha256"] - and _git_blob_oid(head_raw) == row["blob_oid"], - f"{label} implementation blob identity mismatch", + receipt_in_transition.returncode != 0, + "Amendment-20 external receipt is present inside C or S", ) - - -def _validate_document_semantic_projection( - raw: bytes, - law: Mapping[str, Any], -) -> dict[str, Any]: - """Require the governing bytes, Python controls, and fixture to agree.""" - - projection = _parse_document_semantic_projection(raw) - del law # Never let a caller-mutated law redefine the governing bytes. - expected = copy.deepcopy(_canonical_draft_document_projection()) - expected["scope"]["implementation_pins"] = projection["scope"][ - "implementation_pins" - ] - expected["amendment14"]["implementation_pins"] = projection["amendment14"][ - "implementation_pins" - ] - expected["amendment15"]["implementation_pins"] = projection["amendment15"][ - "implementation_pins" - ] - expected["amendment15"]["mutation_bindings"] = projection["amendment15"][ - "mutation_bindings" - ] - expected["amendment16"]["implementation_pins"] = projection["amendment16"][ - "implementation_pins" - ] - expected["amendment16"]["supersession_map"] = projection["amendment16"][ - "supersession_map" - ] - expected["amendment17"]["implementation_pins"] = projection["amendment17"][ - "implementation_pins" - ] - expected["amendment18"]["implementation_pins"] = projection["amendment18"][ - "implementation_pins" - ] - expected["amendment19"]["implementation_pins"] = projection["amendment19"][ - "implementation_pins" - ] + closure_path = _ratification_closure_path(20) + receipt_first_adds = str( + _git( + "log", + "--format=%H", + "--diff-filter=A", + "--", + A20_EXECUTED_TRANSITION_RECEIPT_PATH, + text=True, + ) + ).splitlines() + closure_first_adds = str( + _git( + "log", + "--format=%H", + "--diff-filter=A", + "--", + closure_path, + text=True, + ) + ).splitlines() _require( - projection == expected, - "governing Amendment-14/15/16/17/18/19 document semantic projection " - "drift", + len(receipt_first_adds) == 1 + and len(closure_first_adds) == 1 + and _is_lower_hex(receipt_first_adds[0], 40) + and _is_lower_hex(closure_first_adds[0], 40), + "Amendment-20 receipt or closure first-add identity drift", + ) + receipt_first_add = receipt_first_adds[0] + closure_first_add = closure_first_adds[0] + receipt_precedes_closure = _run_git( + "merge-base", + "--is-ancestor", + receipt_first_add, + closure_first_add, + ) + scratch_precedes_head = _run_git( + "merge-base", + "--is-ancestor", + scratch["commit"], + "HEAD", ) - _verify_implementation_pins( - projection["amendment14"]["implementation_pins"] + _require( + receipt_precedes_closure.returncode == 0 + and scratch_precedes_head.returncode != 0, + "Amendment-20 receipt chronology or scratch isolation drift", + ) + registry_binding = _validate_registry_ratification_context( + manifest["canonical_registry_binding"] + ) + _require( + registry_binding["revision"] == 22 + and registry_binding["ratification_commit"] == candidate["commit"], + "Amendment-20 receipt registry candidate binding drift", ) - return projection - -@lru_cache(maxsize=1) -def _amendment12_continuation_projection() -> tuple[tuple[Any, ...], ...]: - """Re-derive the five inherited continuation citations from pinned bytes.""" + candidate_raw = _git("show", f"{candidate['commit']}:{DESIGN_PATH}") + _require( + isinstance(candidate_raw, bytes) + and registry_binding["blob_sha256"] == _sha256(candidate_raw), + "Amendment-20 receipt candidate design identity drift", + ) + candidate_design_tree_line = str( + _git( + "ls-tree", + candidate["commit"], + "--", + DESIGN_PATH, + text=True, + ) + ).strip() + _require( + candidate_design_tree_line + == ( + f"{DESIGN_MODE} blob {_git_blob_oid(candidate_raw)}\t" + f"{DESIGN_PATH}" + ), + "Amendment-20 receipt candidate design tree identity drift", + ) + _validate_amendment20_ratification_design(candidate_raw) + pins = _parse_amendment20_implementation_pins(candidate_raw) + for row in pins["files"]: + file_raw = _git("show", f"{candidate['commit']}:{row['path']}") + tree_line = str( + _git( + "ls-tree", + candidate["commit"], + "--", + row["path"], + text=True, + ) + ).strip() + _require( + isinstance(file_raw, bytes) + and tree_line + == f"{pins['mode']} blob {row['blob_oid']}\t{row['path']}" + and len(file_raw) == row["byte_size"] + and _sha256(file_raw) == row["sha256"] + and _git_blob_oid(file_raw) == row["blob_oid"], + "Amendment-20 receipt candidate implementation pin drift", + ) - raw = (ROOT / A12_SWEEP_PATH).read_bytes() + closure_identities = manifest["ordered_closure_identities"] _require( - len(raw) == A12_SWEEP_BYTE_SIZE and _sha256(raw) == A12_SWEEP_SHA256, - "Amendment-12 continuation source artifact identity drift", + isinstance(closure_identities, list) and len(closure_identities) == 8, + "Amendment-20 receipt ordered closure identity domain drift", ) - artifact = a12.strict_json_loads(raw, A12_SWEEP_PATH) - projection: list[tuple[Any, ...]] = [] - for row in artifact["alias_evidence_semantic_adjudication_rows"]: - citation = row["continuation_composition_citation"] - if citation is None: - continue - instruction_ids = row["source_instruction_occurrence_ids"] + for amendment_number, row, binding in zip( + range(13, 21), + closure_identities, + registry_binding["ratification_closures"], + strict=True, + ): _require( - len(instruction_ids) == 1, - "Amendment-12 continuation citation has non-singleton instruction", + isinstance(row, Mapping), + "Amendment-20 receipt closure identity is not an object", ) - continuation_id = instruction_ids[0] - expected_citation = ( - a12.CONTINUATION_ALIAS_CITATIONS_BY_INSTRUCTION.get( - continuation_id - ) + _require_exact_keys( + row, + set(schema["closure_identity_keys"]), + "Amendment-20 receipt closure identity", ) + expected_path = _ratification_closure_path(amendment_number) _require( - expected_citation is not None - and all( - citation[key] == value - for key, value in expected_citation.items() - ) - and citation["leading_occurrence_id"] - == expected_citation["leading_occurrence_id"] - and citation["continuation_occurrence_id"] == continuation_id, - "Amendment-12 continuation citation projection drift", + row["path"] == expected_path + and { + "path": row["path"], + "raw_byte_size": row["raw_byte_size"], + "raw_sha256": row["raw_sha256"], + } + == binding + and type(row["raw_byte_size"]) is int + and row["raw_byte_size"] > 0 + and _is_lower_hex(row["raw_sha256"], 64) + and _is_lower_hex(row["git_blob"], 40), + "Amendment-20 receipt closure identity value drift", ) - projection.append( - ( - row["document_source_position"], - row["source_local_evidence_id"], - citation["leading_occurrence_id"], - continuation_id, + closure_bytes = _git("show", f"{scratch['commit']}:{expected_path}") + tree_line = str( + _git( + "ls-tree", + scratch["commit"], + "--", + expected_path, + text=True, ) + ).strip() + _require( + isinstance(closure_bytes, bytes) + and len(closure_bytes) == row["raw_byte_size"] + and _sha256(closure_bytes) == row["raw_sha256"] + and _git_blob_oid(closure_bytes) == row["git_blob"] + and tree_line + == f"{DESIGN_MODE} blob {row['git_blob']}\t{expected_path}", + "Amendment-20 receipt closure Git identity drift", ) - canonical_projection = [list(row) for row in projection] - raw_projection = canonical_json_bytes(canonical_projection) - _require( - len(raw_projection) == A12_CONTINUATION_PROJECTION_BYTE_SIZE - and _sha256(raw_projection) == A12_CONTINUATION_PROJECTION_SHA256, - "Amendment-12 continuation projection identity drift", - ) - return tuple(projection) - - -def _run_git( - *arguments: str, - text: bool = False, -) -> subprocess.CompletedProcess[bytes] | subprocess.CompletedProcess[str]: - """Run raw-object Git with ambient Git controls removed.""" - environment = { - key: value - for key, value in os.environ.items() - if not key.startswith("GIT_") - } - environment["GIT_NO_REPLACE_OBJECTS"] = "1" - return subprocess.run( - ["git", "--no-replace-objects", *arguments], - cwd=ROOT, - check=False, - capture_output=True, - text=text, - env=environment, + synthetic_closure_path = schema["expected_changed_paths"][2] + synthetic_closure_raw = _git( + "show", f"{scratch['commit']}:{synthetic_closure_path}" ) - - -def _git(*arguments: str, text: bool = False) -> bytes | str: - result = _run_git(*arguments, text=text) _require( - result.returncode == 0, f"git command failed: {' '.join(arguments)}" + isinstance(synthetic_closure_raw, bytes), + "Amendment-20 synthetic closure read was not raw bytes", ) - return result.stdout - - -def _require_exact_commit_object(object_id: str, label: str) -> None: - result = _run_git( - "rev-parse", - "--verify", - f"{object_id}^{{commit}}", - text=True, + synthetic_closure = _strict_canonical_json( + synthetic_closure_raw, + "Amendment-20 receipt synthetic closure", ) + _validate_closure_shape(synthetic_closure, 20) + standin_paths = schema["expected_changed_paths"][:2] _require( - result.returncode == 0 and result.stdout.strip() == object_id, - f"{label} is not an exact commit object", - ) - + synthetic_closure["attested_candidate_design_blob_oid"] + == _git_blob_oid(candidate_raw) + and synthetic_closure["attested_candidate_design_byte_size"] + == len(candidate_raw) + and synthetic_closure["attested_candidate_design_raw_sha256"] + == _sha256(candidate_raw) + and synthetic_closure["ratification_commit"] == candidate["commit"] + and synthetic_closure["operator_merge_commit"] == candidate["commit"] + and synthetic_closure["ratification_commit_sole_parent"] + == candidate["sole_parent"] + and [row["path"] for row in synthetic_closure["verdict_artifacts"]] + == standin_paths, + "Amendment-20 receipt synthetic closure candidate binding drift", + ) + for row in synthetic_closure["verdict_artifacts"]: + path = row["path"] + standin_raw = _git("show", f"{scratch['commit']}:{path}") + tree_line = str( + _git("ls-tree", scratch["commit"], "--", path, text=True) + ).strip() + _require( + isinstance(standin_raw, bytes) + and tree_line + == f"{DESIGN_MODE} blob {_git_blob_oid(standin_raw)}\t{path}" + and len(standin_raw) == row["byte_size"] + and _sha256(standin_raw) == row["raw_sha256"], + "Amendment-20 receipt synthetic stand-in identity drift", + ) + _validate_amendment20_simulated_standin( + standin_raw, + design_byte_size=len(candidate_raw), + design_raw_sha256=_sha256(candidate_raw), + design_blob_oid=_git_blob_oid(candidate_raw), + ) -def _validate_amendment12_ratification_identity( - identity: Mapping[str, Any], -) -> None: - _require_exact_keys( - identity, - { - "ratification_commit", - "ratification_parents", - "document_path", - "document_mode", - "document_blob_oid", - "document_byte_size", - "document_sha256", - "dual_ratify_attestations", - }, - "Amendment-12 ratification identity", - ) - _require( - identity["document_path"] == DESIGN_PATH - and identity["document_mode"] == DESIGN_MODE, - "ratification identity selects another document path or mode", + scratch_registry_path = schema["expected_changed_paths"][3] + candidate_registry_raw = _git( + "show", f"{candidate['commit']}:{scratch_registry_path}" ) - _require( - isinstance(identity["ratification_parents"], list) - and len(identity["ratification_parents"]) == 1, - "ratification identity does not name one parent", + scratch_registry_raw = _git( + "show", f"{scratch['commit']}:{scratch_registry_path}" ) - parent_line = str( + candidate_registry_tree_line = str( _git( - "rev-list", - "--parents", - "-n", - "1", - identity["ratification_commit"], + "ls-tree", + candidate["commit"], + "--", + scratch_registry_path, text=True, ) ).strip() - _require( - parent_line.split() - == [ - identity["ratification_commit"], - identity["ratification_parents"][0], - ], - "ratification commit is not the exact single-parent commit", - ) - tree_line = str( + scratch_registry_tree_line = str( _git( "ls-tree", - identity["ratification_commit"], + scratch["commit"], "--", - identity["document_path"], + scratch_registry_path, text=True, ) ).strip() _require( - tree_line + scratch_registry_path == A20_PRODUCTION_REGISTRY_IDENTITY["path"] + and isinstance(candidate_registry_raw, bytes) + and isinstance(scratch_registry_raw, bytes) + and len(candidate_registry_raw) + == A20_PRODUCTION_REGISTRY_IDENTITY["byte_size"] + and _sha256(candidate_registry_raw) + == A20_PRODUCTION_REGISTRY_IDENTITY["raw_sha256"] + and _git_blob_oid(candidate_registry_raw) + == A20_PRODUCTION_REGISTRY_IDENTITY["git_blob"] + and candidate_registry_tree_line == ( - f"{identity['document_mode']} blob " - f"{identity['document_blob_oid']}\t{identity['document_path']}" + f"{A20_PRODUCTION_REGISTRY_IDENTITY['mode']} blob " + f"{A20_PRODUCTION_REGISTRY_IDENTITY['git_blob']}\t" + f"{scratch_registry_path}" + ) + and scratch_registry_tree_line + == ( + f"{DESIGN_MODE} blob {_git_blob_oid(scratch_registry_raw)}\t" + f"{scratch_registry_path}" ), - "ratification commit does not select the supplied document blob", + "Amendment-20 scratch registry tree identity drift", ) - raw = _git( - "show", - f"{identity['ratification_commit']}:{identity['document_path']}", + scratch_registry = _parse_amendment20_scratch_registry_binding( + scratch_registry_raw, + candidate_raw=candidate_registry_raw, ) _require( - isinstance(raw, bytes), "ratification blob read was not raw bytes" + scratch_registry["binding"] == registry_binding + and scratch_registry["binding"]["ratification_commit"] + == candidate["commit"] + and scratch_registry["design_byte_size"] == len(candidate_raw) + and scratch_registry["binding"]["blob_sha256"] + == _sha256(candidate_raw), + "Amendment-20 scratch registry does not bind receipt candidate state", ) + + test_identity = manifest["full_pinned_battery_test_identity"] _require( - len(raw) == identity["document_byte_size"] - and _sha256(raw) == identity["document_sha256"] - and hashlib.sha1( - b"blob " + str(len(raw)).encode() + b"\0" + raw - ).hexdigest() - == identity["document_blob_oid"], - "ratification document bytes do not match the dual-hash identity", + isinstance(test_identity, Mapping), + "Amendment-20 receipt test identity is not an object", ) + _require_exact_keys( + test_identity, + set(schema["test_identity_keys"]), + "Amendment-20 receipt test identity", + ) + test_path = "tests/test_validate_amendment13_execution_law.py" + test_pin = next(row for row in pins["files"] if row["path"] == test_path) + expected_test_identity = { + "path": test_path, + "mode": pins["mode"], + "git_blob": test_pin["blob_oid"], + "raw_byte_size": test_pin["byte_size"], + "raw_sha256": test_pin["sha256"], + } _require( - identity == AMENDMENT12_RATIFICATION_IDENTITY, - "ratification identity is not the exact attested document identity", + dict(test_identity) == expected_test_identity, + "Amendment-20 receipt test identity differs from candidate pin", ) - -def _is_lower_hex(value: Any, length: int) -> bool: - return ( - isinstance(value, str) - and len(value) == length - and all(character in "0123456789abcdef" for character in value) + public_oracle = receipt["public_oracle"] + battery = receipt["full_pinned_battery"] + _require( + isinstance(public_oracle, Mapping) and isinstance(battery, Mapping), + "Amendment-20 receipt executed result is not an object", + ) + _require_exact_keys( + public_oracle, + set(schema["public_oracle_keys"]), + "Amendment-20 receipt public oracle result", + ) + _require_exact_keys( + battery, + set(schema["full_pinned_battery_keys"]), + "Amendment-20 receipt full pinned battery result", ) - - -def _strict_canonical_json(raw: bytes, label: str) -> dict[str, Any]: - try: - value = a12.strict_json_loads(raw, label) - except a12.BuildError as error: - raise LawError(f"{label} is invalid strict JSON") from error _require( - isinstance(value, dict) and canonical_json_bytes(value) == raw, - f"{label} is not canonical JSON", + public_oracle["entrypoint"] == "validate_ratification_operativity" + and public_oracle["executed"] is True + and type(public_oracle["exit_code"]) is int + and public_oracle["exit_code"] == 0 + and public_oracle["operative_amendments"] == list(range(13, 21)) + and public_oracle["simulated_state_identity_sha256"] == state_identity, + "Amendment-20 receipt public oracle result drift", + ) + integer_fields = ( + "exit_code", + "collected", + "passed", + "failed", + "skipped", + "deselected", + "xfailed", + "xpassed", ) - _require_no_unpaired_surrogates(value, label) - return value - - -def _require_no_unpaired_surrogates(value: Any, label: str) -> None: - """Reject surrogate code points admitted by Python's JSON decoder.""" - - if isinstance(value, str): - _require( - not any(0xD800 <= ord(character) <= 0xDFFF for character in value), - f"{label} contains an unpaired Unicode surrogate", + _require( + battery["executed"] is True + and all(type(battery[key]) is int for key in integer_fields) + and battery["exit_code"] == 0 + and battery["test_path"] == test_path + and battery["test_mode_blob_bytes_sha256"] == test_identity + and battery["exact_command"] == A20_FULL_PINNED_BATTERY_COMMAND + and battery["collected"] == A20_FULL_PINNED_BATTERY_COLLECTED + and battery["passed"] == A20_FULL_PINNED_BATTERY_COLLECTED + and all( + battery[key] == 0 + for key in ( + "failed", + "skipped", + "deselected", + "xfailed", + "xpassed", + ) ) - return - if isinstance(value, Mapping): - for key, member in value.items(): - _require_no_unpaired_surrogates(key, label) - _require_no_unpaired_surrogates(member, label) - return - if isinstance(value, list): - for member in value: - _require_no_unpaired_surrogates(member, label) + and battery["simulated_state_identity_sha256"] == state_identity, + "Amendment-20 receipt full pinned battery result drift", + ) + return dict(receipt) def _validate_closure_shape( @@ -6848,6 +10869,92 @@ def _validate_amendment19_ratification_design(raw: bytes) -> None: _validate_inherited_amendment19_ratification_design(raw) +def _validate_amendment20_draft_design(raw: bytes) -> None: + """Accept the exact-prefix, fail-closed A20 drafting surface.""" + + _require( + _terminal_design_amendment(raw) == 20, + "Amendment-20 draft design is not terminal Amendment 20", + ) + section = _amendment20_text(raw) + _validate_inherited_amendment19_ratification_design(raw) + section_numbers = [ + int(match.group(1)) + for match in re.finditer(r"^### 34\.([0-9]+)\b", section, re.MULTILINE) + ] + _require( + section_numbers == list(range(1, 14)) + and section.count( + "`amendment20_evidence_freeze_status` is exactly\n" + "`not_instantiated_a4_required_before_ratify`" + ) + == 1 + and section.count("`amendment20_ratification_ready` is false") == 1, + "Amendment-20 draft status or section structure drift", + ) + final_manifest_marker = ( + "The exact Amendment-20 normative manifest is this one-line " + "terminal-LF canonical JSON value:\n\n" + ) + if final_manifest_marker in section: + projection = _parse_amendment20_projection(raw) + if A20_SECTION_SEMANTIC_SHA256 is not None: + _require( + projection["section_semantic_sha256"] + == A20_SECTION_SEMANTIC_SHA256, + "Amendment-20 draft semantic projection drift", + ) + else: + _require( + section.count( + "The exact Amendment-20 normative manifest will be inserted " + "here as one-line\n" + ) + == 1 + and section.count( + "The exact A20 active three-path implementation pin table is " + "deliberately\npending the final code/test freeze" + ) + == 1, + "Amendment-20 pending manifest or implementation-pin marker drift", + ) + + +def _validate_inherited_amendment20_ratification_design(raw: bytes) -> None: + """Preserve exact revision-21 and ratification-ready A20 in successors.""" + + _require( + len(raw) > REVISION21_BYTE_SIZE + and _sha256(raw[:REVISION21_BYTE_SIZE]) == REVISION21_SHA256 + and _git_blob_oid(raw[:REVISION21_BYTE_SIZE]) == REVISION21_BLOB_OID + and raw[REVISION21_BYTE_SIZE:].startswith(AMENDMENT20_BOUNDARY), + "Amendment-20 ratification design lacks the immutable revision-21 " + "prefix or Amendment-20 boundary", + ) + _validate_inherited_amendment19_ratification_design(raw) + projection = _parse_amendment20_projection(raw) + _validate_a20_manifest_contract( + projection["normative_manifest"], + require_ratification_ready=True, + ) + _require( + isinstance(A20_SECTION_SEMANTIC_SHA256, str) + and projection["section_semantic_sha256"] + == A20_SECTION_SEMANTIC_SHA256, + "Amendment-20 ratification design semantic projection drift", + ) + + +def _validate_amendment20_ratification_design(raw: bytes) -> None: + """Require terminal A20 and reject the current evidence-incomplete draft.""" + + _require( + _terminal_design_amendment(raw) == 20, + "Amendment-20 ratification design is not terminal Amendment 20", + ) + _validate_inherited_amendment20_ratification_design(raw) + + def _validate_non_a13_ratification_design( raw: bytes, amendment_number: int, @@ -6877,10 +10984,10 @@ def _validate_non_a13_ratification_design( _validate_amendment18_ratification_design(raw) elif amendment_number == 19: _validate_amendment19_ratification_design(raw) - elif amendment_number > 19: - _validate_inherited_amendment19_ratification_design(raw) - elif amendment_number > 18: - _validate_inherited_amendment18_ratification_design(raw) + elif amendment_number == 20: + _validate_amendment20_ratification_design(raw) + elif amendment_number > 20: + _validate_inherited_amendment20_ratification_design(raw) def _validate_ratification_closure( @@ -6892,9 +10999,15 @@ def _validate_ratification_closure( verify_git: bool, ratification_design_raw: bytes | None = None, registry_design_binding: Mapping[str, Any] | None = None, + amendment20_transition_receipt_raw: bytes | None = None, ) -> dict[str, Any]: """Validate registry-selected closure bytes and their exact artifacts.""" + _require( + amendment_number <= 20, + "post-Amendment-20 receipt topology requires exact successor law", + ) + _require( isinstance(closure_raw, bytes), "ratification closure is missing", @@ -6923,6 +11036,7 @@ def _validate_ratification_closure( ) closure = _strict_canonical_json(closure_raw, expected_path) _validate_closure_shape(closure, amendment_number) + is_terminal_closure = False if amendment_number == 13: _require( closure == A13_EXPECTED_CLOSURE, @@ -6952,6 +11066,7 @@ def _validate_ratification_closure( amendment_number in amendment_numbers, "closure amendment is outside the terminal registry domain", ) + is_terminal_closure = amendment_number == amendment_numbers[-1] if ( amendment_number == 14 and registry_design_binding["revision"] @@ -6961,7 +11076,7 @@ def _validate_ratification_closure( dict(closure_binding) == A14_HISTORICAL_CLOSURE_BINDING, "Amendment-14 historical closure binding drift", ) - if amendment_number == amendment_numbers[-1]: + if is_terminal_closure: revision = registry_design_binding["revision"] _require( revision == amendment_number + 2 @@ -6983,6 +11098,56 @@ def _validate_ratification_closure( set(verdict_bytes) == {row["path"] for row in verdicts}, "ratification closure verdict artifact domain drift", ) + amendment20_attestations: list[dict[str, Any]] = [] + receipt_byte_size: int | None = None + receipt_raw_sha256: str | None = None + if amendment_number > 20: + raise LawError( + "post-Amendment-20 receipt topology requires exact successor law" + ) + if amendment_number == 20: + _require( + isinstance(amendment20_transition_receipt_raw, bytes), + "Amendment-20 external transition receipt is missing", + ) + receipt = _strict_canonical_json( + amendment20_transition_receipt_raw, + A20_EXECUTED_TRANSITION_RECEIPT_PATH, + ) + _validate_amendment20_transition_receipt(receipt) + _require( + isinstance(registry_design_binding, Mapping), + "Amendment-20 closure lacks registry candidate cross-binding", + ) + receipt_candidate_commit = receipt["simulated_state_manifest"][ + "candidate_commit_identity" + ]["commit"] + receipt_candidate_raw = _git( + "show", + f"{receipt_candidate_commit}:{DESIGN_PATH}", + ) + _require( + isinstance(receipt_candidate_raw, bytes) + and len(receipt_candidate_raw) + == closure["attested_candidate_design_byte_size"] + and _sha256(receipt_candidate_raw) + == closure["attested_candidate_design_raw_sha256"] + and _git_blob_oid(receipt_candidate_raw) + == closure["attested_candidate_design_blob_oid"] + and ( + not is_terminal_closure + or registry_design_binding["blob_sha256"] + == _sha256(receipt_candidate_raw) + ), + "Amendment-20 receipt/closure/registry candidate cross-binding drift", + ) + receipt_byte_size = len(amendment20_transition_receipt_raw) + receipt_raw_sha256 = _sha256(amendment20_transition_receipt_raw) + else: + _require( + amendment20_transition_receipt_raw is None, + "pre-Amendment-20 closure received an inapplicable receipt", + ) for row in verdicts: raw = verdict_bytes[row["path"]] _require( @@ -6991,7 +11156,31 @@ def _validate_ratification_closure( and _sha256(raw) == row["raw_sha256"], "ratification closure verdict byte mismatch", ) - _verdict_attests_design(raw, closure) + if amendment_number >= 20: + amendment20_attestations.append( + validate_amendment20_qualifying_verdict( + raw, + design_byte_size=closure[ + "attested_candidate_design_byte_size" + ], + design_raw_sha256=closure[ + "attested_candidate_design_raw_sha256" + ], + design_blob_oid=closure[ + "attested_candidate_design_blob_oid" + ], + receipt_byte_size=receipt_byte_size, + receipt_raw_sha256=receipt_raw_sha256, + ) + ) + else: + _verdict_attests_design(raw, closure) + if amendment_number >= 20: + _require( + len(amendment20_attestations) == 2 + and amendment20_attestations[0] == amendment20_attestations[1], + "Amendment-20 verdicts do not attest one candidate and receipt", + ) commit = closure["ratification_commit"] if verify_git: @@ -7153,13 +11342,59 @@ def _validate_registry_ratification_context( return normalized +def _interregnum_amendment20_design_binding() -> dict[str, Any]: + """Resolve the registry identity across the Amendment-20 interregnum. + + The production registry stays fail-closed: ``design_binding`` still + rejects every unratified Amendment-20 suffix and this resolver + never widens that gate or registers anything. Between the + Amendment-20 draft merge and the revision-22 repin the repository + lawfully holds exactly one tree state the registry cannot + register: the pinned revision-21 prefix plus one lawful + Amendment-20 suffix. This resolver accepts that single state + byte-exactly (worktree equal to ``HEAD`` plus the complete + immutable-prefix authentication of ``_amendment20_text``) and + answers with the registry's own revision-21 identity so A13-era + consumers keep validating against ratified law. Any other + deviation re-raises the registration abort unchanged, and the + revision-22 repin disarms this branch permanently because the + registry pins stop matching the revision-21 constants. + """ + + import covered_earnings_correction_registry as registry + + try: + return registry.design_binding() + except registry.RegistrationAborted: + if not ( + registry.DESIGN_REVISION == 21 + and registry.DESIGN_PATH == DESIGN_PATH + and registry.DESIGN_BYTE_SIZE == REVISION21_BYTE_SIZE + and registry.DESIGN_BLOB_SHA256 == REVISION21_SHA256 + ): + raise + worktree_raw = (ROOT / DESIGN_PATH).read_bytes() + head = registry._run_git("show", f"HEAD:{DESIGN_PATH}") + if head.returncode != 0 or worktree_raw != head.stdout: + raise + _amendment20_text(worktree_raw) + return { + "path": registry.DESIGN_PATH, + "ratification_commit": registry.DESIGN_RATIFICATION_COMMIT, + "revision": registry.DESIGN_REVISION, + "blob_sha256": registry.DESIGN_BLOB_SHA256, + "ratification_closures": [ + dict(binding) + for binding in registry.RATIFICATION_CLOSURE_BINDINGS + ], + } + + def _public_registry_ratification_context() -> dict[str, Any]: """Load the current terminal registry-selected closure context.""" try: - import covered_earnings_correction_registry as registry - - design_binding = registry.design_binding() + design_binding = _interregnum_amendment20_design_binding() except Exception as error: raise LawError( "registry ratification closure binding is missing" @@ -7223,6 +11458,10 @@ def _validate_public_ratification_closure( amendment_number: int, context: Mapping[str, Any], ) -> dict[str, Any]: + _require( + amendment_number <= 20, + "post-Amendment-20 receipt topology requires exact successor law", + ) binding = _public_registry_closure_binding(amendment_number, context) closure_path = binding["path"] worktree_raw = _read_public_repository_file( @@ -7245,6 +11484,36 @@ def _validate_public_ratification_closure( ) for row in closure["verdict_artifacts"] } + if amendment_number == 20 and any( + b"executed_transition_receipt_status:" in raw + or b"simulation_context:" in raw + for raw in verdict_bytes.values() + ): + scratch = _validate_amendment20_scratch_transition_context( + verdict_bytes + ) + _require( + scratch["registry_binding"] == context + and scratch["closure"] == closure, + "Amendment-20 scratch public closure context drift", + ) + return closure + + if amendment_number == 20: + import covered_earnings_correction_registry as registry + + _require( + not hasattr(registry, "SIMULATED_STATE_AUTHORITY") + and not hasattr(registry, "SIMULATION_CONTEXT"), + "Amendment-20 scratch constants are forbidden with real verdicts", + ) + receipt_raw = _read_public_repository_file( + A20_EXECUTED_TRANSITION_RECEIPT_PATH, + "executed-transition receipt", + require_regular_mode=True, + ) + else: + receipt_raw = None return _validate_ratification_closure( worktree_raw, binding, @@ -7252,6 +11521,7 @@ def _validate_public_ratification_closure( amendment_number, verify_git=True, registry_design_binding=context if amendment_number != 13 else None, + amendment20_transition_receipt_raw=receipt_raw, ) @@ -7296,9 +11566,21 @@ def validate_ratification_operativity() -> dict[int, dict[str, Any]]: """Validate the exact complete closure domain under one registry snapshot.""" context = _public_registry_ratification_context() - _verify_implementation_pins( - _parse_active_implementation_pins((ROOT / DESIGN_PATH).read_bytes()) - ) + design_raw = (ROOT / DESIGN_PATH).read_bytes() + terminal_amendment = _terminal_design_amendment(design_raw) + if terminal_amendment == context["revision"] - 1: + _require( + context["revision"] == 21 + and len(design_raw) > REVISION21_BYTE_SIZE, + "ordinary registry/design terminal amendment mismatch", + ) + _amendment20_text(design_raw) + else: + _require( + terminal_amendment == context["revision"] - 2, + "ordinary registry/design terminal amendment mismatch", + ) + _verify_implementation_pins(_parse_active_implementation_pins(design_raw)) return _validate_ratification_operativity_context( context, _validate_public_ratification_closure, @@ -11932,6 +16214,779 @@ def run_amendment19_member_law_mutation_tests() -> tuple[str, ...]: return rejected_tuple +def run_amendment20_contract_mutation_tests() -> tuple[str, ...]: + """Authenticate inherited censuses, then run closed A20 mutations.""" + + global ROOT + + amendment19 = run_amendment19_member_law_mutation_tests() + expected_censuses = A20_INHERITED_MUTATION_CENSUSES + _require( + amendment19 == A19_EXPECTED_MUTATIONS + and expected_censuses + == [ + { + "inventory": "inherited_complete_certificate", + "count": 100, + "raw_sha256": ( + "fe2efd7b96c24b7cbd3c6ce350d44906" + "eb5a88b8b35ee77565c1b133cbf1f3e3" + ), + }, + { + "inventory": "amendment16", + "count": 7, + "raw_sha256": A16_MUTATION_DOMAIN_SHA256, + }, + { + "inventory": "amendment17", + "count": 3, + "raw_sha256": A17_MUTATION_DOMAIN_SHA256, + }, + { + "inventory": "amendment18", + "count": 3, + "raw_sha256": A18_MUTATION_DOMAIN_SHA256, + }, + { + "inventory": "amendment19", + "count": 3, + "raw_sha256": A19_MUTATION_DOMAIN_SHA256, + }, + ] + and sum(row["count"] for row in expected_censuses) == 116, + "Amendment-20 inherited mutation censuses drift", + ) + + rejected: list[str] = [] + + def reject_manifest_variants( + variants: Sequence[Mapping[str, Any]], + expected_message: str, + label: str, + ) -> None: + for position, candidate in enumerate(variants): + _expect_law_error( + lambda candidate=candidate: _validate_a20_manifest_contract( + candidate + ), + expected_message, + f"{label} {position}", + ) + + def synthetic_identity_digest(label: str) -> str: + return _sha256(canonical_json_bytes({"synthetic_identity": label})) + + def synthetic_pass_identity( + identity_name: str, + *, + arm_status_member: str | None = None, + ) -> dict[str, Any]: + identity = { + "identity_name": identity_name, + "row_count": 1, + "ordered_keyset_sha256": synthetic_identity_digest( + f"{identity_name}:keyset" + ), + "row_domain_sha256": synthetic_identity_digest( + f"{identity_name}:domain" + ), + "status": "pass", + } + if arm_status_member is not None: + identity = { + "identity_name": identity_name, + "arm_status_member": arm_status_member, + "arm_status": "pass", + "row_count": identity["row_count"], + "ordered_keyset_sha256": identity["ordered_keyset_sha256"], + "row_domain_sha256": identity["row_domain_sha256"], + "status": identity["status"], + } + return identity + + def synthetic_failure_shadow( + status_member: str, + arm_contract: Mapping[str, Any], + nonemission_evidence: Mapping[str, Any], + ) -> dict[str, Any]: + pass_identity_names = arm_contract["pass_identity_names"] + failure_status = arm_contract["failure_status"] + complement_rows = [ + {"emitted": False, "identity_name": name} + for name in pass_identity_names + ] + keyset_sha256 = _sha256(canonical_json_bytes(pass_identity_names)) + domain_sha256 = _sha256(canonical_json_bytes(complement_rows)) + return { + "schema_version": "a20_failure_shadow_identity.v1", + "identity_name": arm_contract["failure_shadow_identity_name"], + "arm_status_member": status_member, + "arm_status": failure_status, + "shadow_row_count": len(pass_identity_names), + "shadow_ordered_keyset_sha256": keyset_sha256, + "shadow_row_domain_sha256": domain_sha256, + "complement_identity": { + "schema_version": "a20_nonemission_complement_identity.v1", + "complement_of_identity_names": pass_identity_names, + "row_count": len(pass_identity_names), + "ordered_keyset_sha256": keyset_sha256, + "row_domain_sha256": domain_sha256, + "status": failure_status, + }, + "forbidden_output_identity_names": pass_identity_names, + "forbidden_output_paths": arm_contract["forbidden_output_paths"], + "nonemission_evidence": copy.deepcopy(nonemission_evidence), + "status": failure_status, + } + + def synthetic_ready_freeze( + failed_status_member: str | None = None, + *, + nonemission_evidence: Mapping[str, Any] | None = None, + ) -> dict[str, Any]: + bindings: dict[str, Any] = { + name: None for name in A20_EXPECTED_IDENTITY_NAMES + } + statuses = { + status_member: ( + arm_contract["failure_status"] + if status_member == failed_status_member + else arm_contract["pass_status"] + ) + for status_member, arm_contract in A20_ARM_IDENTITY_CONTRACTS.items() + } + successor_binding_name = "a20_successor_source_binding_identity" + for identity_name in A20_COMMON_IDENTITY_NAMES: + if identity_name != successor_binding_name: + bindings[identity_name] = synthetic_pass_identity( + identity_name + ) + for status_member, arm_contract in A20_ARM_IDENTITY_CONTRACTS.items(): + if statuses[status_member] == arm_contract["pass_status"]: + for identity_name in arm_contract["pass_identity_names"]: + bindings[identity_name] = synthetic_pass_identity( + identity_name, + arm_status_member=status_member, + ) + else: + _require( + nonemission_evidence is not None, + "Amendment-20 synthetic failure lacks real provenance", + ) + bindings[arm_contract["failure_shadow_identity_name"]] = ( + synthetic_failure_shadow( + status_member, + arm_contract, + nonemission_evidence, + ) + ) + active_binding_preimage = { + "arm_status_bindings": statuses, + "expected_identity_bindings": { + identity_name: bindings[identity_name] + for identity_name in A20_EXPECTED_IDENTITY_NAMES + if identity_name != successor_binding_name + }, + } + bindings[successor_binding_name] = { + "identity_name": successor_binding_name, + "row_count": 1, + "ordered_keyset_sha256": synthetic_identity_digest( + f"{successor_binding_name}:keyset" + ), + "row_domain_sha256": synthetic_identity_digest( + f"{successor_binding_name}:domain" + ), + "arm_status_bindings": statuses, + "active_identity_bindings_sha256": _sha256( + canonical_json_bytes(active_binding_preimage) + ), + "status": "pass", + } + return { + "schema_version": "a20_evidence_freeze.v1", + "amendment20_evidence_freeze_status": "pass_a4_exact_freeze", + **statuses, + "expected_identity_bindings": bindings, + "amendment20_ratification_ready": True, + } + + def rebind_synthetic_successor(freeze: Mapping[str, Any]) -> None: + statuses = { + status_member: freeze[status_member] + for status_member in A20_ARM_IDENTITY_CONTRACTS + } + bindings = freeze["expected_identity_bindings"] + successor_binding_name = "a20_successor_source_binding_identity" + active_binding_preimage = { + "arm_status_bindings": statuses, + "expected_identity_bindings": { + identity_name: bindings[identity_name] + for identity_name in A20_EXPECTED_IDENTITY_NAMES + if identity_name != successor_binding_name + }, + } + bindings[successor_binding_name]["arm_status_bindings"] = statuses + bindings[successor_binding_name]["active_identity_bindings_sha256"] = ( + _sha256(canonical_json_bytes(active_binding_preimage)) + ) + + source_variants = [] + variant = copy.deepcopy(A20_NORMATIVE_MANIFEST) + variant["source_infrastructure"]["semantic_domain_identity_keys"].remove( + "excluded_source_rows" + ) + source_variants.append(variant) + variant = copy.deepcopy(A20_NORMATIVE_MANIFEST) + variant["source_infrastructure"]["evidence_statement_row_keys"].remove( + "utf8_byte_start" + ) + source_variants.append(variant) + variant = copy.deepcopy(A20_NORMATIVE_MANIFEST) + variant["source_infrastructure"][ + "path_rule" + ] = "machine_local_absolute_path" + source_variants.append(variant) + variant = copy.deepcopy(A20_NORMATIVE_MANIFEST) + binding_keys = variant["source_infrastructure"][ + "successor_source_binding_keys" + ] + binding_keys[binding_keys.index("missing_reason_rule_set_identity")] = ( + "missing_rule_set_identity" + ) + source_variants.append(variant) + reject_manifest_variants( + source_variants, + "separate semantic-domain contract drift", + "Amendment-20 source domain/statement/path attack", + ) + rejected.append(A20_EXPECTED_MUTATIONS[0]) + + missing_variants = [] + variant = copy.deepcopy(A20_NORMATIVE_MANIFEST) + variant["missing_reason_authority"][ + "formerly_unresolved_literal_occurrence_count" + ] = 524_537 + missing_variants.append(variant) + variant = copy.deepcopy(A20_NORMATIVE_MANIFEST) + variant["missing_reason_authority"]["projection_requirements"].remove( + "collectively_exhaustive" + ) + missing_variants.append(variant) + variant = copy.deepcopy(A20_NORMATIVE_MANIFEST) + variant["missing_reason_authority"]["claim_type"] = "integer_coercible" + missing_variants.append(variant) + variant = copy.deepcopy(A20_NORMATIVE_MANIFEST) + variant["missing_reason_authority"]["representation_bridge_probe"][ + "bridge_required_before_acceptance" + ] = False + missing_variants.append(variant) + reject_manifest_variants( + missing_variants, + "missing-reason authority contract drift", + "Amendment-20 missing exact-cover/Boolean/MD attack", + ) + rejected.append(A20_EXPECTED_MUTATIONS[1]) + + purpose_variants = [] + variant = copy.deepcopy(A20_NORMATIVE_MANIFEST) + variant["purpose_authority"][ + "inherited_complete_rows_requiring_source_regrounding" + ] = 817 + purpose_variants.append(variant) + variant = copy.deepcopy(A20_NORMATIVE_MANIFEST) + variant["purpose_authority"]["required_disposition_counts"]["U"] = 1 + purpose_variants.append(variant) + variant = copy.deepcopy(A20_NORMATIVE_MANIFEST) + variant["purpose_authority"][ + "exact_prompt_cover_and_zero_gap_extra_duplicate_overlap_conflict" + ] = False + purpose_variants.append(variant) + variant = copy.deepcopy(A20_NORMATIVE_MANIFEST) + variant["purpose_authority"][ + "purpose_arrays_nonempty_stable_unique_in_official_order" + ] = False + purpose_variants.append(variant) + reject_manifest_variants( + purpose_variants, + "purpose-authority totality contract drift", + "Amendment-20 purpose 818/U/totality attack", + ) + rejected.append(A20_EXPECTED_MUTATIONS[2]) + + prompt_variants = [] + variant = copy.deepcopy(A20_NORMATIVE_MANIFEST) + variant["prompt_field_semantic_binding"]["c68_regression"][ + "candidate_raw_field_ids" + ] = ["V11804"] + prompt_variants.append(variant) + variant = copy.deepcopy(A20_NORMATIVE_MANIFEST) + variant["prompt_field_semantic_binding"]["collision_census"][ + "multiple_count" + ] = 45 + prompt_variants.append(variant) + variant = copy.deepcopy(A20_NORMATIVE_MANIFEST) + variant["prompt_field_semantic_binding"][ + "candidate_disposition_is_iff_count_partition" + ] = False + prompt_variants.append(variant) + variant = copy.deepcopy(A20_NORMATIVE_MANIFEST) + variant["prompt_field_semantic_binding"]["zero_candidate_grouping_probe"][ + "accepted_positive_group_with_empty_reference_union_count" + ] = 1 + prompt_variants.append(variant) + variant = copy.deepcopy(A20_NORMATIVE_MANIFEST) + variant["prompt_field_semantic_binding"][ + "required_unresolved_semantic_binding_count" + ] = 1 + prompt_variants.append(variant) + reject_manifest_variants( + prompt_variants, + "prompt-field or semantic-binding contract drift", + "Amendment-20 C68/46/zero/semantic attack", + ) + rejected.append(A20_EXPECTED_MUTATIONS[3]) + + r04_variants = [] + variant = copy.deepcopy(A20_NORMATIVE_MANIFEST) + variant["r04_q5"]["construction_order"][5:7] = reversed( + variant["r04_q5"]["construction_order"][5:7] + ) + r04_variants.append(variant) + variant = copy.deepcopy(A20_NORMATIVE_MANIFEST) + variant["r04_q5"]["normal_era_successor_sequence"].remove( + "prompt_field_candidate_set_rows" + ) + r04_variants.append(variant) + variant = copy.deepcopy(A20_NORMATIVE_MANIFEST) + variant["r04_q5"]["a19_digest_dependency_order_preserved"][0] = "D1" + r04_variants.append(variant) + reject_manifest_variants( + r04_variants, + "R04 order or Q5 shape contract drift", + "Amendment-20 order/Q5/D0 attack", + ) + variant = copy.deepcopy(A20_NORMATIVE_MANIFEST) + variant["source_infrastructure"]["historical_domains_preserved"][ + "a19_build_input_row_count" + ] = 278 + _expect_law_error( + lambda: _validate_a20_manifest_contract(variant), + "separate semantic-domain contract drift", + "Amendment-20 279-row source-binding attack", + ) + rejected.append(A20_EXPECTED_MUTATIONS[4]) + + _validate_amendment20_r06_collection_binding() + r06_variants = [] + variant = copy.deepcopy(A20_NORMATIVE_MANIFEST) + variant["r06_lifecycle"][ + "interpreter_selector" + ] = "fixed_interpreter_literal_forbidden" + r06_variants.append(variant) + variant = copy.deepcopy(A20_NORMATIVE_MANIFEST) + variant["r06_lifecycle"]["test_file_identities"][0]["byte_size"] += 1 + r06_variants.append(variant) + variant = copy.deepcopy(A20_NORMATIVE_MANIFEST) + variant["r06_lifecycle"]["collected_node_id_count"] = 222 + r06_variants.append(variant) + variant = copy.deepcopy(A20_NORMATIVE_MANIFEST) + variant["r06_lifecycle"]["dormant_lifecycle_rows"][4][ + "selection_enabled" + ] = True + r06_variants.append(variant) + reject_manifest_variants( + r06_variants, + "R06 collection or lifecycle contract drift", + "Amendment-20 interpreter/file/223/lifecycle attack", + ) + rejected.append(A20_EXPECTED_MUTATIONS[5]) + + valid_verdict = ( + "# RATIFY\n" + "attested_design_byte_size: 1\n" + f"attested_design_raw_sha256: {'a' * 64}\n" + f"attested_design_blob_oid: {'b' * 40}\n" + "executed_transition_receipt_byte_size: 2\n" + f"executed_transition_receipt_raw_sha256: {'c' * 64}\n" + "executed_transition_receipt_schema: executed_transition_state.v2\n" + "---\n" + ).encode() + validate_amendment20_qualifying_verdict( + valid_verdict, + design_byte_size=1, + design_raw_sha256="a" * 64, + design_blob_oid="b" * 40, + receipt_byte_size=2, + receipt_raw_sha256="c" * 64, + ) + _expect_law_error( + lambda: validate_amendment20_qualifying_verdict( + valid_verdict.replace(b"---\n", b"---\r\n"), + design_byte_size=1, + design_raw_sha256="a" * 64, + design_blob_oid="b" * 40, + receipt_byte_size=2, + receipt_raw_sha256="c" * 64, + ), + "strict UTF-8/LF framing", + "Amendment-20 verdict grammar attack", + ) + receipt_variants = [] + variant = copy.deepcopy(A20_NORMATIVE_MANIFEST) + variant["ratification_receipt"]["receipt_schema"][ + "manifest_schema_version" + ] = "executed_transition_state.v1" + receipt_variants.append(variant) + variant = copy.deepcopy(A20_NORMATIVE_MANIFEST) + variant["ratification_receipt"][ + "amendment20_external_receipt_path" + ] = "docs/analysis/amendment_20_ratification/receipt.json" + receipt_variants.append(variant) + reject_manifest_variants( + receipt_variants, + "verdict, receipt, or scratch contract drift", + "Amendment-20 receipt/fixed-path attack", + ) + scratch_verdict_paths = A20_RECEIPT_SCHEMA["expected_changed_paths"][:2] + try: + _validate_amendment20_scratch_transition_context( + { + path: b"forged scratch stand-in\n" + for path in scratch_verdict_paths + } + ) + except LawError: + pass + else: + raise LawError("Amendment-20 live scratch-context attack survived") + rejected.append(A20_EXPECTED_MUTATIONS[6]) + + routing_variants = [] + variant = copy.deepcopy(A20_NORMATIVE_MANIFEST) + variant["successor_routing"][ + "a19_pin_fallback_for_terminal_a20_permitted" + ] = True + routing_variants.append(variant) + variant = copy.deepcopy(A20_NORMATIVE_MANIFEST) + variant["successor_routing"]["terminal_amendment"] = 19 + routing_variants.append(variant) + variant = copy.deepcopy(A20_NORMATIVE_MANIFEST) + variant["activation_transition"]["terminal_revision"] = 21 + routing_variants.append(variant) + variant = copy.deepcopy(A20_NORMATIVE_MANIFEST) + variant["activation_transition"]["ordered_closure_domain"] = list( + range(13, 20) + ) + routing_variants.append(variant) + reject_manifest_variants( + routing_variants, + "successor routing or activation contract drift", + "Amendment-20 pin/terminal/revision/domain attack", + ) + rejected.append(A20_EXPECTED_MUTATIONS[7]) + + original_root = ROOT + with tempfile.TemporaryDirectory( + prefix="a20-nonemission-provenance-" + ) as temporary: + temporary_root = Path(temporary) + scratch = temporary_root / "repo" + _scratch_git(temporary_root, "init", "--quiet", str(scratch)) + _scratch_git(scratch, "config", "user.name", "A20 mutation test") + _scratch_git( + scratch, + "config", + "user.email", + "a20-mutation@example.invalid", + ) + sentinel_path = scratch / "tracked-sentinel.txt" + sentinel_path.write_bytes(b"authenticated A20 manifest state\n") + _scratch_git(scratch, "add", "tracked-sentinel.txt") + _scratch_git( + scratch, + "commit", + "--quiet", + "-m", + "Authenticated A20 nonemission control", + ) + execution_commit = str( + _scratch_git(scratch, "rev-parse", "HEAD") + ).strip() + execution_tree_oid = str( + _scratch_git(scratch, "rev-parse", "HEAD^{tree}") + ).strip() + ROOT = scratch + try: + manifest_rows, untracked_paths = ( + _reconstruct_amendment20_repository_manifest( + execution_tree_oid, + verification_root=scratch, + ) + ) + _require( + untracked_paths == () + and [row["path"] for row in manifest_rows] + == ["tracked-sentinel.txt"], + "Amendment-20 real scratch provenance control drift", + ) + manifest_sha256 = _sha256(canonical_json_bytes(manifest_rows)) + nonemission_evidence = { + "execution_commit": execution_commit, + "execution_tree_oid": execution_tree_oid, + "repository_manifest_rows_before": copy.deepcopy( + manifest_rows + ), + "repository_manifest_sha256_before": manifest_sha256, + "repository_manifest_rows_after": copy.deepcopy(manifest_rows), + "repository_manifest_sha256_after": manifest_sha256, + "repository_clean_before": True, + "repository_clean_after": True, + "forbidden_outputs_absent_after_execution": True, + } + + sentinel_path.write_bytes(b"later clean A20 manifest state\n") + _scratch_git(scratch, "add", "tracked-sentinel.txt") + _scratch_git( + scratch, + "commit", + "--quiet", + "-m", + "Later clean A20 repository state", + ) + later_commit = str( + _scratch_git(scratch, "rev-parse", "HEAD") + ).strip() + later_tree_oid = str( + _scratch_git(scratch, "rev-parse", "HEAD^{tree}") + ).strip() + worktree_state_before = _scratch_git( + scratch, + "worktree", + "list", + "--porcelain", + ) + _require( + later_commit != execution_commit + and later_tree_oid != execution_tree_oid + and sentinel_path.read_bytes() + != b"authenticated A20 manifest state\n" + and _scratch_git( + scratch, + "status", + "--porcelain=v1", + "-z", + text=False, + ) + == b"", + "Amendment-20 different-current-tree control drift", + ) + + ready_controls = [ + synthetic_ready_freeze(), + *[ + synthetic_ready_freeze( + status_member, + nonemission_evidence=nonemission_evidence, + ) + for status_member in A20_ARM_IDENTITY_CONTRACTS + ], + ] + for ready_freeze in ready_controls: + _validate_amendment20_evidence_freeze( + ready_freeze, + A20_EVIDENCE_FREEZE_CONTRACT, + require_ratification_ready=True, + ) + _require( + _scratch_git( + scratch, + "worktree", + "list", + "--porcelain", + ) + == worktree_state_before, + "Amendment-20 verification checkout cleanup drift", + ) + + forged_shadow = synthetic_ready_freeze( + "missing_reason_authority_status", + nonemission_evidence=nonemission_evidence, + ) + forged_shadow["expected_identity_bindings"][ + "missing_reason_failure_shadow_identity" + ]["shadow_row_domain_sha256"] = ("f" * 64) + _expect_law_error( + lambda: _validate_amendment20_evidence_freeze( + forged_shadow, + A20_EVIDENCE_FREEZE_CONTRACT, + require_ratification_ready=True, + ), + "failure-shadow cross-binding drift", + "Amendment-20 forged failure-shadow attack", + ) + + missing_complement = synthetic_ready_freeze( + "purpose_authority_status", + nonemission_evidence=nonemission_evidence, + ) + del missing_complement["expected_identity_bindings"][ + "purpose_failure_shadow_identity" + ]["complement_identity"] + _expect_law_error( + lambda: _validate_amendment20_evidence_freeze( + missing_complement, + A20_EVIDENCE_FREEZE_CONTRACT, + require_ratification_ready=True, + ), + "failure shadow keyset drift", + "Amendment-20 missing nonemission-complement attack", + ) + + status_flip = synthetic_ready_freeze( + "prompt_field_semantic_binding_status", + nonemission_evidence=nonemission_evidence, + ) + status_flip["prompt_field_semantic_binding_status"] = "pass" + _expect_law_error( + lambda: _validate_amendment20_evidence_freeze( + status_flip, + A20_EVIDENCE_FREEZE_CONTRACT, + require_ratification_ready=True, + ), + "pass carries a failure shadow", + "Amendment-20 arm-status flip attack", + ) + + truthy_mapping = synthetic_ready_freeze() + truthy_mapping["expected_identity_bindings"] = { + name: {"truthy": True} for name in A20_EXPECTED_IDENTITY_NAMES + } + _expect_law_error( + lambda: _validate_amendment20_evidence_freeze( + truthy_mapping, + A20_EVIDENCE_FREEZE_CONTRACT, + require_ratification_ready=True, + ), + "identity keyset drift", + "Amendment-20 truthy-mapping regression attack", + ) + rejected.append(A20_EXPECTED_MUTATIONS[8]) + + coherent_forgery = synthetic_ready_freeze( + "missing_reason_authority_status", + nonemission_evidence=nonemission_evidence, + ) + forged_nonemission = coherent_forgery[ + "expected_identity_bindings" + ]["missing_reason_failure_shadow_identity"]["nonemission_evidence"] + forged_nonemission.update( + { + "execution_commit": "4" * 40, + "execution_tree_oid": "5" * 40, + "repository_manifest_sha256_before": "6" * 64, + "repository_manifest_sha256_after": "6" * 64, + } + ) + rebind_synthetic_successor(coherent_forgery) + _require( + _run_git("cat-file", "-e", f"{'4' * 40}^{{commit}}").returncode + != 0 + and _run_git( + "cat-file", "-e", f"{'5' * 40}^{{tree}}" + ).returncode + != 0, + "Amendment-20 forged object control unexpectedly exists", + ) + _expect_law_error( + lambda: _validate_amendment20_evidence_freeze( + coherent_forgery, + A20_EVIDENCE_FREEZE_CONTRACT, + require_ratification_ready=True, + ), + "execution commit is not an exact commit object", + "Amendment-20 coherent nonemission provenance forgery", + ) + rejected.append(A20_EXPECTED_MUTATIONS[9]) + finally: + ROOT = original_root + + completed_ontology_variants = [] + variant = copy.deepcopy(A20_NORMATIVE_MANIFEST) + variant["purpose_authority"][ + "source_underdetermined_requires_reconciled_adjudication_ruling" + ] = False + completed_ontology_variants.append( + ( + variant, + "determined row rewritten without an adjudication ruling", + A20_EXPECTED_MUTATIONS[10], + ) + ) + variant = copy.deepcopy(A20_NORMATIVE_MANIFEST) + variant["purpose_authority"][ + "source_underdetermined_is_no_applicable_purpose" + ] = True + completed_ontology_variants.append( + ( + variant, + "source-underdetermined/no-applicable-purpose conflation", + A20_EXPECTED_MUTATIONS[11], + ) + ) + variant = copy.deepcopy(A20_NORMATIVE_MANIFEST) + variant["purpose_authority"][ + "source_underdetermined_count_a4_freeze_slot" + ] = 1 + completed_ontology_variants.append( + ( + variant, + "underdetermined census disagreement with the A4 binding", + A20_EXPECTED_MUTATIONS[12], + ) + ) + variant = copy.deepcopy(A20_NORMATIVE_MANIFEST) + del variant["purpose_authority"]["required_disposition_counts"][ + "source_underdetermined" + ] + completed_ontology_variants.append( + ( + variant, + "completed disposition object missing the new arm", + A20_EXPECTED_MUTATIONS[13], + ) + ) + for variant, label, mutation_name in completed_ontology_variants: + _expect_law_error( + lambda variant=variant: _validate_a20_manifest_contract(variant), + "purpose-authority totality contract drift", + f"Amendment-20 {label}", + ) + rejected.append(mutation_name) + + collapsed_span = copy.deepcopy(A20_NORMATIVE_MANIFEST) + collapsed_span["prompt_field_semantic_binding"][ + "coordinate_distinct_span_collapse_aborts" + ] = False + _expect_law_error( + lambda: _validate_a20_manifest_contract(collapsed_span), + "prompt-field or semantic-binding contract drift", + "Amendment-20 coordinate-distinct questionnaire spans collapsed", + ) + rejected.append(A20_EXPECTED_MUTATIONS[14]) + + rejected_tuple = tuple(rejected) + rejected_raw = canonical_json_bytes(list(rejected_tuple)) + _require( + rejected_tuple == A20_EXPECTED_MUTATIONS + and len(rejected_raw) == A20_MUTATION_DOMAIN_BYTE_SIZE + and _sha256(rejected_raw) == A20_MUTATION_DOMAIN_SHA256, + "Amendment-20 mutation inventory execution drift", + ) + return rejected_tuple + + def _run_public_registry_replace_ref_enforcement_mutation() -> None: """Reject substituted HEAD design bytes at the public registry gate.""" diff --git a/sol-ce-amend20-draft-report.md b/sol-ce-amend20-draft-report.md new file mode 100644 index 00000000..5a035edc --- /dev/null +++ b/sol-ce-amend20-draft-report.md @@ -0,0 +1,1031 @@ +# Amendment 20 draft report + +Date: 2026-08-17 +Branch: claude/ce-design-amendment20 +Base: dd33d6daa551b4ca10fc92a9681047afb285378b +Draft-law commit: 8fd20a695dcd01a7db1ad99ddb37606842159a05 +Implementation-contract commit: +73db9c476b2cf9578aa9e1affbcade50063401f7 +Historical-pin preservation commit: +892732677af52affc17b5f314969e22b92ae948e +STATUS: **LAWFUL-STOP** + +Byte citations use path:line@zero-based-byte-offset. Unless a different +object is named, citations into prospective §34 are pinned to final tracked +commit 8927326. External evidence citations use the independently pinned +logical record, line, and byte offset. + +## Exact byte, semantic, and evidence pins + +The operative immutable prefix is the complete design through §33 at base +dd33d6d: mode 100644, exactly 4,025,587 bytes, raw SHA-256 +38139b8ddd24ef7be09e8f149960e8e0b6e39699d84f3783827eff6c294a9ae9, +and Git blob 1eba7ff6366bad1999de36c9f7261ad6939ad86a. Its interval is +[0, 4,025,587). A direct byte comparison of the base design object with that +interval at 8927326 returned equal. The enacted pin is at +docs/design/covered_earnings_correction.md:56312@4025903. + +The final tracked prospective design object at 8927326 is mode +100644, exactly 4,147,625 bytes, raw SHA-256 +c888a6edc684ce6878193876970c4817e0480f32fc9243ba0c3b60cc249ff217, +and Git blob dd38131234915537bee0801cccb0c20360a03f2d. The normalized §34 +semantic SHA-256 is +530ac9a2e7ca3ded253fb250876e41240554d958ee34563cf001b6f02cf152b7. +The §34.12 canonical manifest is present, not omitted: its terminal-LF value +is 45,813 bytes with raw SHA-256 +751847dfa130864ce07be6f78fa929571fc9fc455152e02dd866588c093e16ce +(§34.12 begins at line 57626@4100314; the value begins at +57631@4100452). + +The controlling NONAUTHORITY evidence records are: + +| Record | Bytes | Raw SHA-256 | Relevant citation | +|---|---:|---|---| +| e8-ops/sol-ce-a20-charter.md | 27,368 | 5ecd4092f3fc62ef894866a1a5b505d6dba7bb04cde1360ff7134d7d8e927717 | charter 3@67; §34 pin 56320@4026346 | +| e8-ops/sol-ce-law-gap-sweep-r21-2026-08-16.md | 11,805 | 39887de99d75a395e97b04f33b4c5264a6828f56c9321cfe248b4ba11a7e5846 | sweep 14@719 and 77@6159; §34 pin 56324@4026534 | + +No machine-local parent path is enacted. These records fix campaign scope +and discovered defects, but establish no source meaning, alias, missingness, +purpose, field attachment, or semantic binding +(docs/design/covered_earnings_correction.md:56327@4026689). + +## Charter conformance + +| Charter requirement | Section 34 disposition | Result | +|---|---|---| +| One activation-affecting A20/revision 22 containing both arms (charter 9@640), with no planned A21 absent kill/recharter (charter 21@1701) | §34.1 fixes one two-arm law and the same A21 kill condition (56340@4027474). | CONFORMS | +| Shared physical source infrastructure but two closed semantic domains (charter 34@3656) | §34.2.1 fixes the physical/statement registries (56426@4032091); §34.2.2 fixes separate missing-reason and purpose domains (56478@4033740). | CONFORMS | +| Preserve A11's 47-source domain, the 81-document questionnaire domain, and A19's 257+22=279 input envelope (charter 53@4698) | The historical domains remain exact (56504@4035076); A20 uses a separately authenticated successor binding (56511@4035431). | CONFORMS | +| Exact missing-reason compiler over all 524,538 unresolved occurrences (charter 57@4977 and 74@5477) | §34.3 fixes the closed rule schema, 12-position identity, strict Boolean cover, dual reconstruction, and atomic nonemission (56533@4036656 and 56561@4037858). | CONFORMS; EVIDENCE PENDING | +| Closed 35-purpose space and complete source-grounded successor rows (charter 97@6953) | §34.4 preserves the ontology, requires 21,971 source-grounded rows and U == 0, and forbids silent grandfathering (56609@4040529 and 56651@4042016). | CONFORMS; EVIDENCE PENDING | +| Acyclic pre-O_P prompt-field relation, complete semantic bindings, and post-O_P joins (charter 149@9106 and 171@9962) | §§34.5–34.6 fix the pre-O_P relation, materialize all candidates, retain the inherited serialization, and require the normal joins (56679@4043259 and 56826@4050980). | CONFORMS; EVIDENCE PENDING | +| Exact R04, R05, historical R06, reconstruction, Q5, inventory, V-B6, and publication order (charter 197@11763) | §34.6 fixes the selector/Q5 order (56802@4049851); §34.7 fixes 26 dormant rows from settlement through publication without instantiating an output (56972@4058594). | CONFORMS | +| Terminal A20/revision 22, closure domain 13–20, complete projection/pins, and same-state ceremony (charter 241@14037) | §§34.8–34.9 fix the v2 receipt, verdicts, live scratch route, exact active pins, transition arithmetic, and ordinary production rejection (57083@4066954 and 57345@4081399). | CONFORMS; CEREMONY NOT EXECUTED | +| Conditional dates, measured-throughput formula, and closed kill criteria remain planning law, not authority | §34.1.1 preserves the exact stage order, ceil(2L/(3q)), 2026-11-09 p50, 2027-01-22 p80, and fail-closed kill/recharter rules (56377@4029768). | CONFORMS | +| A4 freezes separate manifests, rules, shadows, expected digests, negative cases, and lifecycle law (charter 306@18710) | §34.1 and §34.12 enact the exact freeze object, null drafting identities, three closed arm-status domains, 26 dormant definitions, and all machine contracts; the evidence campaign itself has not performed A4 (56347@4027882 and 57631@4100452). | STRUCTURALLY CONFORMS; A4 PENDING | + +## Law-gap cure coverage + +All nine CONFIRMED and all nine SUSPECTED findings are separately +dispositioned below. CURE means a closed legal and implementation contract. +MANDATORY PROBE means the factual proposition stays fail-closed until exact +source evidence answers it. + +| Finding | Sweep evidence | Section 34 disposition | Class | +|---|---|---|---| +| A-1 terminal-A19 pinned fixtures | sweep 14@719 | Historical A19 validation slices the exact revision-21 prefix; terminal and inherited A20 validation use their own projection (57345@4081399). | CURE | +| A-2 A19-only active implementation-pin resolution | sweep 14@719 | The exact A20 boundary selects the A20 three-row table before A19; A19 fallback for terminal A20 is forbidden (57345@4081399). | CURE | +| A-3 unbound historical R06 223-test count | sweep 14@719 | Six exact module identities and the terminal-LF 223-node-ID array bind the count; live recollection and drift failure are required (56935@4056621 and 56945@4057101). | CURE | +| C-1 46 singleton field-token violations, including 1985 C68 | sweep 49@3341 | Every candidate is materialized; all 46 require source-backed dispositions; direct-ID priority is forbidden and C68 is an exact mandatory regression (56714@4044674). | CURE | +| D-1 lifecycle definitions barred until post-certification | sweep 64@4642 | §34.7.2 expressly supersedes §26.10.3 and DC-71 only for dormant definitions, fixes 26 dormant rows, and leaves instantiation/selection behind the exact gates (56972@4058594). | CURE | +| E-1 A19 build order conflicts with §§26.6.3 and 26.10.1 | sweep 83@6482 | Purpose/source selectors precede the normal build; source-only O_H still precedes O_P; failure arms do not execute the normal build (56802@4049851). | CURE | +| E-2 §31.3 receipt not composed with §28.2.1 iff-four and §30.2.4; bad §31.5 map anchor | sweep 88@7681 | Receipt verification is incorporated into condition 1, not added as a fifth condition; the public oracle validates the semantic projection, both verdicts, and the reread external receipt; §34.11 names the real §31.3 anchors (57087@4067080 and 57432@4090836). | CURE | +| E-3 §20.4.2 frozen Q5 shapes omit A19/A20 deltas | sweep 93@8788 | §34.6.3 exhaustively fixes the A19 and A20 header/per-era additions and preserves every unnamed shape and order (56840@4051819). | CURE | +| E-4 §25.6.6 machine-local interpreter literal | sweep 98@9721 | Command position zero is the executing process's sys.executable; module order and environment law survive; no absolute interpreter is enacted (56935@4056621). | CURE | +| A-S1 A19-only prospective suffix loader | sweep 15@846 | Ordinary revision 21 rejects A20; only the exact Git-derived NONAUTHORITY scratch route accepts revision 22 before the later real repin (57342@4081238 and 57345@4081399). | CURE | +| A-S2 closed 279-row R04/R05 input envelope | sweep 15@846 | The 257+22=279 relation remains immutable; A20 enters only the separately authenticated successor composite and dual reconstructors (56504@4035076 and 56522@4036140). | CURE | +| B-01 underspecified pre-verdict synthetic state | sweep 30@1641 | Candidate C and strict-child scratch S, the exact four-path scratch delta, live public-entrypoint helper, distinct seven-line pending stand-ins, and fixed external receipt chronology are closed (57158@4071283; fixed receipt path 57126@4069143). | CURE | +| B-02 R06 false booleans versus pre-R06 evidence work | sweep 31@2005 | False values remain historical R06 facts; dispatch-disabled evidence and dormant definitions are distinct, and active unratified state remains A20_SUCCESSOR_PROGRAM_STOP (56977@4058967). | CURE | +| B-03 implicit UTF-8/LF/decimal verdict grammar | sweep 32@2293 | The exact eight-line real grammar fixes strict UTF-8, LF, decimal alternatives, three design fields, three receipt fields, schema v2, and terminal LF; the seven-line stand-in is separately nonqualifying (57087@4067080 and 57104@4067882). | CURE | +| C-S1 claimed 15,428 zero-candidate grouping | sweep 50@3591 | A4 must reconstruct all 21,971 candidate sets and the complete positive-row reference unions; both observed zero counts remain NONAUTHORITY until reproduced (56762@4047560). | MANDATORY PROBE | +| C-S2 54,898 ceiling versus 59,424 shadow and 87 zero projections | sweep 51@3744 | The MD= representation bridge must reconcile the distinct observations and all zero projections; the family contributes zero accepted claims until it does (56598@4039984). | MANDATORY PROBE | +| D-S1 successor domains might not bind both R04 reconstructors | sweep 65@5015 | Both reconstructors authenticate the historical envelope and independently reconstruct every A20 relation before reading candidate rows or status (56522@4036140). | CURE | +| E-S1 questionnaire_occurrence_rows read/serialization ambiguity | sweep 103@10743 | Required selector reads and forbidden failure-member serialization are separate closed scopes; the 877-byte historical member remains exact (56826@4050980). | CURE | + +Coverage count: **9/9 confirmed cured; 7/9 suspected structurally cured; +2/9 suspected converted into mandatory fail-closed evidence probes.** No +finding is omitted and neither probe is mislabeled as factual proof. + +## A4 evidence status and lawful stop + +The §34.12 manifest is populated with the exact current drafting state. Its +amendment20_evidence_freeze object fixes: + +- amendment20_evidence_freeze_status = + not_instantiated_a4_required_before_ratify; +- missing_reason_authority_status, purpose_authority_status, and + prompt_field_semantic_binding_status = JSON null; +- all 18 expected identity bindings = JSON null; and +- amendment20_ratification_ready = false. + +These are deliberate closed values, not an absent manifest, zero digest, +wildcard, estimated identity, or source claim. The charter and sweep are +NONAUTHORITY; no source identity or disposition was fabricated. + +A later exact A4 edit may set the freeze status only to +pass_a4_exact_freeze, must replace every expected binding with its nonempty +exact identity, and must set each arm to one member of its exact domain: + +| Arm | Final status domain | +|---|---| +| Missing-reason authority | pass; fail_permanent_missing_reason_authority_residue | +| Purpose authority | pass; fail_permanent_purpose_authority_residue | +| Prompt-field/semantic binding | pass; fail_permanent_prompt_field_or_semantic_binding_residue | + +Readiness becomes true if and only if the exact freeze shape, statuses, and +identity bindings are complete. A4 may therefore freeze either a semantic +pass or an exact permanent-failure outcome. The latter may make the exact law +ratifiable; it never permits R04, dispatch, lifecycle execution, or +production. Ratifiable law and production readiness are distinct. + +Exact continuation required to leave the current LAWFUL-STOP: + +1. Complete and reconcile the two independent evidence reviews. +2. Freeze the physical-source and statement registries, including provenance, + release/representation, repository-relative paths, bytes, hashes, + locators, extraction identities, access/licensing, and exclusions. +3. Freeze the separate missing-reason and purpose domain projections. +4. Freeze both rule sets and their complements; compile the exact 524,538 + missing-reason rows and 21,971 purpose rows twice independently. +5. Freeze prompt-field candidates/dispositions, all 46 collision outcomes, + the semantic-binding relation, post-O_P joins, negative cases, and the + complete zero-candidate grouping probe. +6. Freeze the historical/current MD= bridge or retain its exact permanent + nonpassing result. +7. Freeze all counts, keysets, row bytes, domain digests, censuses, + reconstruction results, lifecycle identities, and expected failures. +8. Prospectively update the already-present §34.12 manifest to the exact A4 + outcome, recompute the normalized semantic hash and implementation-pin + fixpoint, and rerun this supersession audit. +9. Run the complete pinned battery and same-state ceremony, publish the + external v2 receipt, obtain two qualifying verdicts, integrate, close A20, + and only then perform the real revision-22 registry repin. + +Any permanent residue controls fail-closed. It cannot be papered over by +reviewer agreement, an empty identity, or a prose-only assertion. + +## Supersession-map row audit + +The final §34.11 map has 30 rows. Each row below was checked against the +predecessor named by the law and the §34 limb that creates or limits the +deviation. + +| Row | Earlier anchor and final row citation | Own-limb disposition checked | Result | +|---:|---|---|---| +| 1 | §19.3.3 purpose/manifest/era/semantic/post-O_P joins; 57417@4085350 | §§34.4–34.6 replace only active A20 grounding, attachment, and enumerated shapes while preserving inherited ambiguity and normal joins. | COVERED | +| 2 | §20.4.2 and A19 Q5 changes; 57418@4086133 | §34.6.3 enumerates every permitted A19/A20 shape delta and preserves all unnamed shapes. | COVERED | +| 3 | §§19.4.2, 26.6.1, 26.10.1 G17/header/Q5/inventory/slot projections; 57419@4086429 | §34.6.3 composes exact expected and actual A20 additions and forbids them on failure arms. | COVERED | +| 4 | §§25.2–25.4 historical missing census; 57420@4086792 | §34.3 adds a separate successor without rewriting historical counts, abort, or nonemission. | COVERED | +| 5 | §§25.5, 25.10.1–2, 32.4.4, 32.7–32.8, 33.4 successor stop; 57421@4087103 | §§34.3 and 34.7 preserve the unratified stop and permit selection only after source settlement, normal R04, R05, and historical R06. | COVERED | +| 6 | §25.6.6 and §§32.4.2–32.4.3, 32.7 R06; 57422@4087613 | §34.7.1 changes only interpreter position zero and completes six-file/223-node identity. | COVERED | +| 7 | §§25.9–25.10, 26.10.3, DC-71 lifecycle timing; 57423@4087953 | §34.7.2 allows definitions only while retaining noninstantiation and exact gate order. | COVERED | +| 8 | §§26.6.3, 26.10.1, 33.2.2–3, 33.7 construction order; 57424@4088430 | §34.6.1 changes selector precedence and failure-arm execution, not source-only O_H before O_P. | COVERED | +| 9 | §26.11.2 complete R04/R05/R06 gate; 57425@4088708 | §§34.2–34.7 strengthen the gate and never treat U == 0 alone as passing. | COVERED | +| 10 | §§28.2.1 and 28.4; 57426@4088944 | §34.8 composes receipt verification into condition 1 while preserving the other iff conditions and real sequence. | COVERED | +| 11 | §§29.4.4–29.4.5 reconstruction; 57427@4089268 | §34.2.3 composes the separately authenticated A20 successor binding into both reconstructors. | COVERED | +| 12 | §29.4.1 canonicalization; 57428@4089542 | All §34 relations retain sorted compact ASCII JSON, finite values, and one terminal LF. | COVERED | +| 13 | §§30.2.3–30.2.4 verdict/public oracle; 57429@4089812 | §34.8.1 closes verdict grammar and adds the A20 projection/receipt check prospectively. | COVERED | +| 14 | §30.2.2 five-key registry context; 57430@4090076 | §34.8.2 permits only the Git-derived live scratch adapter and its two exact scratch constants; production remains five-key. | COVERED | +| 15 | §30.2.1 amendment/revision arithmetic; 57431@4090670 | §34.9.2 applies A20 → revision 22 and closure domain 13–20. | COVERED | +| 16 | §§31.3.1–3 and nonexistent §31.5 map anchor; 57432@4090836 | §34.8 preserves the six-key receipt top level, supersedes only the v2 topology/portable selector, and solves chronology with a nonqualifying stand-in. | COVERED | +| 17 | §§32.2.1–2 and 33.8 historical 279 envelope; 57433@4091409 | §34.2.3 preserves 279 and adds a separate composite instead of widening history. | COVERED | +| 18 | §32.4.4 false R06 booleans; 57434@4091640 | §34.7.2 scopes them to historical R06 output and preserves their values. | COVERED | +| 19 | §§30.4.1, 31.2.2, 32.5.1, 33.5.1 active pins; 57435@4091884 | §34.9.1 supplies the exact three-row A20 table and semantic-hash fixpoint while preserving historical tables. | COVERED | +| 20 | §§33.2.2–3 A19 purpose/failure member; 57436@4092229 | §§34.4 and 34.6 preserve the 877-byte history and require separate A20 rows/statuses. | COVERED | +| 21 | §33.3.2 D0/search/proof/D1; 57437@4092669 | §34.6.3 composes after the selector without recreating a digest cycle. | COVERED | +| 22 | §33.4 obsolete campaign pin and A20 out-of-scope label; 57438@4092825 | §34.1 pins the consolidated charter and changes only prospective A20 scope. | COVERED | +| 23 | §§33.5.2–3 routing/activation; 57439@4093038 | §34.9.2 adds terminal/inherited A20 validation and the revision-22 simulation. | COVERED | +| 24 | §33.6 mutations; 57440@4093280 | §34.10 preserves five inherited censuses separately, then applies the eight grouped A20 mutation names. | COVERED | +| 25 | Four §33.7 defect rows; 57441@4093477 | The map explicitly composes rows 1, 2, 6, 7, and 9; it implies no other semantic change. | COVERED | +| 26 | §33.8 occurrence read/serialization; 57442@4093732 | §34.6.2 separates required selector reads from forbidden failure-member serialization. | COVERED | +| 27 | §33.9 terminal A19 effect; 57443@4094037 | §34.13 becomes the terminal prospective effect while preserving A19 as historical law. | COVERED | +| 28 | §§20.3–24.6 downstream algorithms; 57444@4094219 | §34.7.2 requires fresh classifier-through-comparator execution and forbids copied results. | COVERED | +| 29 | §§19.6–25.10 artifact families; 57445@4094517 | §34.7.2 composes versioned successor envelopes and exact first-add order while preserving old artifacts. | COVERED | +| 30 | §§27.3–27.6 repairs/seals, §28.2.2 closure, §29.4.7 100-census; 57446@4094800 | §34.8/§34.10 preserve these bytes and deny them semantic authority. | COVERED | + +## Own-limb deviation walk + +The independent walk from new prose back to §§19–33 yielded this complete +mapping: + +| New limb | Map rows that cover its deviations | +|---|---| +| §§34.1–34.1.1 status, charter, campaign, and terminal scope | 22, 23, 27; the evidence record and campaign metadata are new, NONAUTHORITY manifest members | +| §34.2 source infrastructure and successor binding | 11, 12, 17 | +| §34.3 missing-reason successor and bridge probe | 4, 5, 28, 29 | +| §§34.4–34.5 purpose and prompt-field/semantic arms | 1, 9, 20 | +| §34.6 build order, failure serialization, and Q5 shapes | 2, 3, 8, 9, 21, 25, 26 | +| §34.7 R06 and 26-row lifecycle | 5, 6, 7, 18, 28, 29 | +| §34.8 verdict, receipt, scratch, and public route | 10, 13, 14, 15, 16, 30 | +| §34.9 pins, fixpoint, activation, and routing | 19, 23 | +| §34.10 mutations | 24 | +| §34.11 map/new identifiers | Self-describing inventory; creates no unlisted waiver | +| §34.12 machine projection | Implements §§34.1–34.11; creates no independent waiver | +| §34.13 terminal effect | 27 | + +No unmapped deviation was found at 8927326. This walk must be repeated after +any A4 manifest, normalized-hash, implementation-pin, receipt-topology, or +other prospective prose change. + +## Receipt and ceremony topology audit + +The receipt retains §31.3.3's exact six top-level keys: +simulated_state_authority, simulated_state_identity_sha256, +simulated_state_manifest, terminal_revision, public_oracle, and +full_pinned_battery. Its nested manifest is executed_transition_state.v2 and +replaces only the prior manifest topology with the exact candidate C, +strict-child scratch S, canonical registry binding, ordered closure +identities, and pinned battery identity +(docs/design/covered_earnings_correction.md:57241@4075727). + +The real receipt is the tracked mode-100644 path +docs/analysis/amendment_20_ratification/executed_transition_receipt_v2.json. +It is external to both C and S. Both real verdicts reread and bind its exact +bytes. S changes only two simulated verdicts, the synthetic A20 closure, and +the scratch registry binding; the public entrypoint itself invokes the live +Git-derived scratch helper. Before the receipt exists, each stand-in is +exactly seven lines: the RATIFY marker; the candidate design byte size, raw +SHA-256, and blob OID; pending_same_state_execution; the +amendment20_same_state_nonauthority_v1 context; and the terminal delimiter. +It contains no receipt claim and can never satisfy a real verdict. The real +eight-line grammar instead binds the design triple plus receipt byte size, +raw SHA-256, and executed_transition_state.v2 schema, under strict UTF-8/LF +and canonical-decimal rules (57094@4067481 and 57166@4071715). + +## Implementation surface + +| Field | Status/result | +|---|---| +| Implementation commits | 73db9c476b2cf9578aa9e1affbcade50063401f7 implements the contracts; 892732677af52affc17b5f314969e22b92ae948e preserves historical mutation-battery pins — COMPLETE | +| Draft, ratification, and inherited-A20 design validators | Implemented and projected by §34.11 identifiers | +| Exact revision-21/A20 boundary and prefix-sliced A19 validation | Implemented; terminal A20 cannot fall back to A19 pins | +| A20 implementation-pin parser and active resolver | Implemented; final active rows are the three identities below | +| Receipt/verdict contracts | Implemented for executed_transition_state.v2, the six-key outer receipt, fixed external path, strict eight-line real verdict, and distinct seven-line stand-in | +| Candidate/scratch topology | Implemented with external receipt outside C and S, exact four-path S delta, candidate triple binding, and live public-entrypoint scratch helper | +| R06 authentication | Implemented for executing-process sys.executable, six exact files, live 223-node recollection, canonical array digest, and endpoints | +| A20 mutation runner | Authenticates all 116 inherited attacks first, then the eight grouped A20 mutation names; each group contains one or more concrete fixtures/attacks, so this is not a claim of only eight tests | +| Lifecycle | Implemented as 26 exact dormant rows from source settlement through publication; unratified, post-repin, and terminal states are respectively A20_SUCCESSOR_PROGRAM_STOP, A20_SOURCE_RELATIONS_SETTLED_DISPATCH_DISABLED, and A20_SUCCESSOR_LIFECYCLE_COMPLETE | +| Semantic-hash fixpoint | Validator constant is 530ac9a2e7ca3ded253fb250876e41240554d958ee34563cf001b6f02cf152b7 at scripts/validate_amendment13_execution_law.py:2466@94608 | +| §34.12 manifest | PRESENT: 45,813 bytes; raw SHA-256 751847dfa130864ce07be6f78fa929571fc9fc455152e02dd866588c093e16ce; current A4 identities/statuses remain null/nonready | +| Production registry | UNTOUCHED; activation remains a later repin ceremony | + +The exact active implementation pin table at +docs/design/covered_earnings_correction.md:57320@4079670 is: + +| Path | Mode | Git blob | Bytes | Raw SHA-256 | +|---|---|---|---:|---| +| scripts/validate_amendment13_execution_law.py | 100644 | d87c97bd03706c1a3fa11c025cd00f9310b472f8 | 608,209 | 186051646c2745401ef881d360eb34af2b831b97764a1b46739fa2bad31a4551 | +| tests/test_validate_amendment13_execution_law.py | 100644 | 6ce1b81d7ca9cb9afed692f44b9c0e4f20ef6240 | 176,172 | 074664015dfd475a19ba7466afb8acf7079766e8c2b456ce88f602ccc53333a6 | +| scripts/build_amendment13_tier2_repairs.py | 100644 | 8e7550ff71cd43f3acd39b7fd1779b6e3a223581 | 111,145 | 2ff0ff39d7ca316fb78c1beb8164300991ea194e803795e642b544bd78b5ef1b | + +The implementation commit also updates tests/README-tiers.md and +tests/tier_counts.json mechanically for the test inventory. Those files are +not additions to §34.9.1's three-path active implementation-pin domain. + +## Tests and hygiene + +| Check | Status/result | +|---|---| +| Targeted Amendment 20 validator/tests | PASS — 16 passed, 201 deselected in 12.98s | +| uv run --no-sync pytest -q -k "amendment18 or amendment19" | The exact uv wrapper was attempted first but could not read sandbox-denied /Users/maxghenis/.cache/uv. Required shared-environment fallback PASS: PYTHONDONTWRITEBYTECODE=1 /Users/maxghenis/PolicyEngine/social-security-model/.venv-flip/bin/python -m pytest -q -k "amendment18 or amendment19" — 96 passed, 5,678 deselected in 600.55s | +| Full-suite collection and tier manifest | PASS — pytest --collect-only -q collected 5,774 tests in 2.88s; exact tiers: unit 1,563, artifact 2,684, integration_psid 848, reproduction_legacy 520, oracle_policyengine 159 | +| Full pinned battery | PASS — direct shared-environment command PYTHONDONTWRITEBYTECODE=1 /Users/maxghenis/PolicyEngine/social-security-model/.venv-flip/bin/python -m pytest -q tests/test_validate_amendment13_execution_law.py: 217 passed in 693.67s (0:11:33) | +| Public oracle on ordinary revision-21 registry | PASS — direct validate_ratification_operativity() reached the expected lawful stop with exact LawError: registry ratification closure binding is missing. An initial later-stage mismatch assumption was corrected and the exact assertion passed | +| Revision-22 scratch same-state oracle/receipt | **NOT EXECUTED: blocked by A4 and the later ceremony** | +| black -l 79 on touched Python files | PASS — shared .venv-flip Python -m black --check -l 79 on validator and test: 2 files left unchanged | +| ruff check on touched Python files | PASS — shared .venv-flip ruff check on validator and test: All checks passed | +| git diff --check | PASS; separate no-index whitespace check of this untracked report also clean | +| Immutable prefix and protected-surface comparison | PASS at 8927326 | + +## Ordered commit ledger + +Commits are ordered and must not be squashed. + +| Order | Commit | Scope | Status | +|---:|---|---|---| +| 1 | 8fd20a695dcd01a7db1ad99ddb37606842159a05 | Append initial prospective §34 draft only | COMPLETE | +| 2 | 73db9c476b2cf9578aa9e1affbcade50063401f7 | Complete §34/manifest/pin fixpoint and validator contracts/tests; no registry edit | COMPLETE | +| 3 | 892732677af52affc17b5f314969e22b92ae948e | Preserve inherited mutation-battery identities and repin the A20 test row/design object | COMPLETE | +| 4 | **HASH ASSIGNED BY ROOT WHEN COMMITTED** | This completed report; its own commit hash cannot be embedded without a circular self-pin | READY TO COMMIT | +| 5 | Later exact commit only after lawful A4 | Freeze identities/statuses, reclose manifest/pins, then ceremony artifacts in their lawful order | BLOCKED BY A4 | + +The repository commit hook expects a bd database that is absent in this +worktree. Commits 1 through 4 therefore used git commit --no-verify. This bypass +is only for the unavailable local hook and waives no test, formatting, lint, +byte, semantic, or ratification requirement. + +## Immutable-surface assertions + +At 8927326: + +- the design interval [0, 4,025,587) compares byte-equal to dd33d6d; +- gates.yaml is identical to dd33d6d; +- runs/ is identical to dd33d6d; +- committed docs/analysis/ is identical to dd33d6d; +- scripts/covered_earnings_correction_registry.py is identical to dd33d6d; +- no source evidence, closure, verdict, external receipt, registry repin, or + production artifact has been emitted; +- the only tracked paths changed from dd33d6d are the append-only design, + validator, main validator test, and the two mechanical test-tier ledgers; + and +- unrelated untracked .ceremony-log/ and CEREMONY_PROMPT.txt remain outside + this work and unstaged. + +## Final status + +**STATUS: LAWFUL-STOP.** The prospective §34 law, exact current-state machine +projection, normalized semantic-hash fixpoint, implementation pins, +validator contracts, and all 18 law-gap dispositions are drafted and +committed in the required ordered commits. The operative prefix, +gates, runs, committed analysis artifacts, and production registry remain +unchanged. All draft-stage targeted, inherited, full-file, collection, public +boundary, formatting, lint, and whitespace checks reported above pass. + +A4 has not frozen lawful source identities or compiled relations. The +current manifest therefore truthfully carries null A4 identities/statuses and +readiness false. The exact continuation is the nine-step A4 sequence above, +then the recomputed manifest/pin fixpoint, final battery, same-state scratch +execution, external v2 receipt, two qualifying verdicts, operator +integration, A20 closure, and real revision-22 registry repin. Until those +acts occur, no A20 authority, R04/R05/R06 result, lifecycle instance, +production output, receipt, closure, or activation exists. + +## Fix-1 — round-1 rewrite cures + +This append-only section records the cure made after both round-1 lanes +returned REWRITE. It supersedes only the stale earlier-report facts about the +18-binding freeze, eight-group mutation inventory, unconditional terminal- +registry comparison, implementation pins, semantic hash, manifest size, and +test inventory. All other conclusions remain unchanged. + +### Finding 1 — status-dependent permanent-failure identities + +Section 34 now requires 21 exact evidence-freeze binding names: nine common +identities, nine pass-output identities across the three arms, and three +arm-specific failure shadows. On `pass`, every output identity for that arm is +nonempty and its shadow is null. On the arm's exact permanent-failure status, +every forbidden output identity is null and the matching shadow is nonempty: + +- `missing_reason_failure_shadow_identity`; +- `purpose_failure_shadow_identity`; or +- `prompt_field_semantic_failure_shadow_identity`. + +Each `a20_failure_shadow_identity.v1` authenticates its identity name, exact +status member and value, row count, ordered keyset digest, row-domain digest, +forbidden-output domain, exact +`a20_nonemission_complement_identity.v1`, and §32.4.4-style nonemission +evidence. That evidence binds the execution commit and tree, equal before and +after repository manifests, clean before and after state, read-only and +network-disabled execution, captured stdout and stderr, and absence of every +forbidden output. The successor binding separately authenticates all three +statuses and the digest of the other 20 bindings. + +The dedicated freeze validator now closes exact keys, counts, nonzero +digests, status values, null/non-null complements, and cross-bindings for each +status. An arbitrary truthy mapping cannot satisfy readiness. The ninth +mutation group, +`evidence_freeze_identity_shadow_or_status_forged`, validates an all-pass +control and each single-arm permanent-failure control before proving rejection +of a forged shadow, a missing complement, a status flip, and the former +truthy-mapping regression. + +The current NONAUTHORITY A4 projection remains truthful and nonratifiable: +all 21 identity bindings and all three arm statuses are null, +`amendment20_evidence_freeze_status` is +`not_instantiated_a4_required_before_ratify`, and +`amendment20_ratification_ready` is false. No identity, successor relation, or +permanent-failure result was fabricated. + +### Finding 2 — historical A20 receipt at revision 23+ + +Section 34.8.1 and the validator now compare the receipt's candidate-design +SHA with the current terminal registry only while Amendment 20 is terminal at +revision 22. At revision 23 or later, the receipt instead cross-binds the +historical A20 closure, its two verdicts, and its internal revision-22 registry +binding. The validator independently rederives and authenticates the +historical A20 design commit, sole parent, tree, mode, blob, bytes, raw digest, +and semantic projection under §30.2.3; a later terminal registry's different +design is not compared with historical A20. + +`test__amendment20_historical_receipt_uses_a20_design_at_revision23` uses a +synthetic revision-23 context with different terminal design and registry +SHA values and proves that this historical path validates. + +### Reclosed projection, pins, and inventory + +| Field | Fix-1 value | +|---|---| +| Evidence-freeze binding names | 21 | +| A20 mutation groups | 9 | +| Mutation inventory bytes / SHA-256 | 415 / `52142486ece9aaa6a2a3d727ef34cd9ab287d7752cc0d7435711f8e864522df0` | +| §34.12 manifest bytes / SHA-256 | 49,792 / `7eee2527cfe573ec233ef1dd40d0c1759e2635bbd6ac1b8283afe86145a4839d` | +| Semantic-hash fixpoint | `f2b88a4638312a1c2ddc775a2b6226b43d7e481a9ef26efad1c27f77e3ba6f22` | +| Full pinned module inventory | 218 tests | +| Repository inventory | 5,775 tests | + +The controlling §34.9 implementation pins are: + +| Path | Git blob | Bytes | Raw SHA-256 | +|---|---|---:|---| +| `scripts/validate_amendment13_execution_law.py` | `4abbd96966091c1fab6e3eac85e03985fe6ab85d` | 633,401 | `f07361854df8b6045363efd4639bfd787e0cec5cb110e9ecf85704502b1277dc` | +| `tests/test_validate_amendment13_execution_law.py` | `f2da23a00f29bd08117855b19f7e625d2006e0c4` | 181,123 | `c1e508e86548c2f2f24a5dcae938186e2ce22c318d5c136b0a7dddcc419d72e1` | +| `scripts/build_amendment13_tier2_repairs.py` | `8e7550ff71cd43f3acd39b7fd1779b6e3a223581` | 111,145 | `2ff0ff39d7ca316fb78c1beb8164300991ea194e803795e642b544bd78b5ef1b` | + +### Fix-1 verification + +All final test results below were obtained from committed cure HEAD +`4a11610a7f0679cdfab04d0797de97dfa74c2a78` in this writable worktree. + +| Check | Status/result | +|---|---| +| Amendment 20 focused pinned-module selection | PASS — 17 passed, 201 deselected in 2.36s | +| Full Amendment 18/19/20 draft-stage battery | PASS — 113 passed, 5,662 deselected in 480.04s; this is the exact union of the 96 Amendment 18/19 and 17 Amendment 20 cases | +| Full pinned validator module | PASS — 218 passed in 558.56s | +| Full collection | PASS — 5,775 tests collected in 1.71s | +| Exact tier collection | PASS — unit 1,563; artifact 2,685; integration_psid 848; reproduction_legacy 520; oracle_policyengine 159 | +| Referee nonpasses | CLEARED — the formerly failing R06 case and four subprocess/temp-boundary errors all executed and passed in the writable combined battery | +| Public oracle on the ordinary revision-21 registry | PASS — exact lawful stop: `registry ratification closure binding is missing` | +| `black -l 79 --check .` | PASS — 592 files would be left unchanged | +| `ruff check .` | PASS — all checks passed | +| `git diff --check` | PASS | + +The initial project-local uv environment lacks the optional +`populace_dynamics` dependency required for repository-wide collection, and +the default uv cache was outside the prior read-only sandbox. Full +draft-stage execution and collection therefore used the repository's complete +shared `.venv-flip` environment. This diagnoses the environment boundary; it +does not waive or deselect a contract check. + +The first 4,025,587 design bytes compare byte-identical with `dd33d6d` and +retain raw SHA-256 +`38139b8ddd24ef7be09e8f149960e8e0b6e39699d84f3783827eff6c294a9ae9`. +`gates.yaml`, `runs/`, committed `docs/analysis/`, and +`scripts/covered_earnings_correction_registry.py` also remain unchanged. +No A4 authority, ceremony artifact, closure, receipt, verdict, registry repin, +or production output was created. + +### Fix-1 commit and status + +Commit `4a11610a7f0679cdfab04d0797de97dfa74c2a78` — +`Fix Amendment 20 round-1 findings (contracts)` — contains the prospective +§34 cure, validator implementation, mutation and revision-23 coverage, and +mechanical tier-count changes. The unavailable local `bd` database prevented +the repository hook from flushing, so the commit used `--no-verify`; no test, +formatting, lint, byte-identity, semantic-hash, or ratification requirement +was bypassed. The unrelated untracked `.ceremony-log/`, `CEREMONY_PROMPT.txt`, +and `FIX1_PROMPT.txt` remain untouched and unstaged. Nothing was pushed. + +**STATUS: LAWFUL-STOP.** Both round-1 rewrite findings are cured. A4 remains +uninstantiated, and Amendment 20 remains unratified and inactive. + +## Fix-2 — round-2 nonemission provenance authentication + +This append-only section records the sole cure made after both round-2 lanes +returned REWRITE. It supersedes only Fix-1's failure-shadow authentication +claim and the mechanically dependent mutation, manifest, semantic-hash, +implementation-pin, and test-count facts. The round-1 Finding 2 cure and all +§34.8 historical-receipt behavior remain unchanged. + +### Authenticated failure-shadow evidence + +Section 34.1.2 and the validator now require each permanent-failure shadow to +carry two complete §29.4.1 canonical repository-manifest arrays. Every row has +exactly `path`, `mode`, `git_blob`, `byte_size`, and `raw_sha256`, and the rows +are complete, unique, and ordered by unsigned UTF-8 path bytes. Each arm also +cross-binds a fixed, non-caller-selected repository path for every forbidden +pass output under +`docs/analysis/amendment_20_ratification/evidence_freeze/`. + +The validator now: + +- resolves the exact execution commit and tree with replacement objects and + inherited `GIT_*` controls disabled; +- proves that the commit resolves to the supplied tree; +- recursively enumerates the tree, authenticates every blob, rereads all + working bytes in the isolated verification checkout, and requires tracked + modes and bytes plus the index to exact-match that tree; +- enumerates and rereads every nonignored untracked path and requires exact + clean porcelain status, including rejection of intent-to-add state; +- deep-compares both supplied manifests with the independently reconstructed + manifest, rederives both terminal-LF canonical SHA-256 values, and requires + exact before/after row and digest equality; and +- independently proves that every fixed forbidden output path is absent from + the authenticated after-manifest. + +The accepted manifest-only schema retains clean and absence booleans solely +as redundant assertions that must exact-equal the independently derived +facts. It makes no unverifiable OS read-only, network, or captured-stream +claim; `repository_read_only`, `network_disabled`, `captured_streams`, and +every other extra assertion fail the exact evidence keyset. Thus no lifecycle +boolean supplies provenance or substitutes for authenticated objects and +manifests. + +### Real controls and killing mutation + +The accepted all-pass and three single-arm permanent-failure controls now use +one real temporary Git repository. The runner commits a tracked sentinel, +resolves its real commit/tree/blob identities, reconstructs the real manifest +and digest, validates all four controls, and restores the original repository +root in `finally`. No accepted control contains a fabricated commit, tree, or +manifest identity. + +The four pre-existing shallow regressions remain in the ninth mutation group +and still reject: altered shadow digest, missing complement, status flip with +the old identity union, and arbitrary truthy mappings. The new tenth group, +`failure_shadow_nonemission_provenance_forged`, starts from the accepted real +scratch control, substitutes nonexistent 40-hex commit/tree IDs and arbitrary +equal manifest hashes, retains the complete manifest rows and redundant +booleans, recomputes the outer successor digest, and fails specifically because +the execution commit is not an exact commit object. + +### Reclosed projection, pins, and inventory + +| Field | Fix-2 value | +|---|---| +| Evidence-freeze binding names | 21 (unchanged) | +| A20 mutation groups | 10 | +| Mutation inventory bytes / SHA-256 | 462 / `10d1466f38f8184940130b89508ac68b60408f8156bef35f65e2c09082bb7d5f` | +| §34.12 manifest bytes / SHA-256 | 51,288 / `e780602708fec38a111e0d6ed2c87f794b76a016447f57795a3b92d2c933146d` | +| Semantic-hash fixpoint | `4ac97bf387eaaf868516be1a7fd119e027d059c7f03b861b07a5ccd3a5580d74` | +| Full pinned module inventory | 219 tests | +| Repository inventory | 5,776 tests | + +The controlling §34.9 implementation pins are: + +| Path | Git blob | Bytes | Raw SHA-256 | +|---|---|---:|---| +| `scripts/validate_amendment13_execution_law.py` | `60420ce24a151ba22bd4ec8d1d8e5b4bc835e150` | 650,940 | `e49e41c59629d4cb4e06de33e577a8ac49985c4581fae55534777fff9ca11bb8` | +| `tests/test_validate_amendment13_execution_law.py` | `6102b174f7bed3c3e2102083b0af6943f9d5f4ef` | 182,525 | `8ebe2347ea468394f0c1098d6044ef9e028989db201137f7d1d32b701f564569` | +| `scripts/build_amendment13_tier2_repairs.py` | `8e7550ff71cd43f3acd39b7fd1779b6e3a223581` | 111,145 | `2ff0ff39d7ca316fb78c1beb8164300991ea194e803795e642b544bd78b5ef1b` | + +The normalized §34 suffix is 139,683 bytes. Replacing only the ten authorized +§34.9 captures reproduces the semantic hash above before and after the final +pin replacement. The canonical §34.12 manifest deep-equals the validator +constant. The closed §34.11 Python inventory also names all four new +provenance helpers. + +### Fix-2 verification + +All execution checks below used committed candidate `18f6c63` in the shared +repository `.venv-flip`; the report was then added to that same commit without +changing any design, validator, test, or tier-ledger byte. + +| Check | Status/result | +|---|---| +| Exact shared-venv Amendment 18/19/20 battery | PASS — 114 passed, 5,662 deselected in 1,201.99s | +| Pinned validator-module collection | PASS — 219 tests collected | +| Schema-current real-control and mutation replay | PASS — all four accepted controls validated; four shallow regressions and the coherent nonexistent-object forgery rejected | +| Lane-A command replay | PASS — archived 6,537-byte command SHA-256 `a0aaf7745efa1a04cd86da209c1aa94fcfd73c4600c8ec89d415f2bd8c004463`; coherent forgery REJECT; both forged objects absent | +| Lane-B command replay | PASS — archived 6,391-byte command SHA-256 `4e36281777a58c83bc338501bbe5a2ed799d3d57bfb7cef4db47a7db6b6c4141`; baseline and fully forged provenance REJECT; all four object probes absent | +| Round-1 Finding 2 regression | PASS — included in the 114-test battery; no Finding 2 implementation or test hunk changed | +| `black -l 79 --check .` | PASS — 592 files would be left unchanged | +| `ruff check .` | PASS — all checks passed | +| `git diff --check` | PASS | + +The exact 4,025,587-byte immutable design prefix remains byte-identical to +round-2 HEAD `e092c25`, with raw SHA-256 +`38139b8ddd24ef7be09e8f149960e8e0b6e39699d84f3783827eff6c294a9ae9` +and Git blob `1eba7ff6366bad1999de36c9f7261ad6939ad86a`. The final Fix-2 design +attestation is 4,165,468 bytes, raw SHA-256 +`b614645eca7bba31e026bb923fa5e9e7cffcf370bb25977e5faa235fc717b578`, +and Git blob `b755e480d980545692de4d09292b58ee6bae3242`. + +### Fix-2 commit and status + +The code/design candidate commit `18f6c63` used the exact title +`Fix Amendment 20 round-2 finding (nonemission provenance authentication)`. +This report is amended into that same commit; its resulting hash cannot be +embedded here without a circular self-reference. The unavailable local `bd` +database required `git commit --no-verify`; no test, formatting, lint, byte, +semantic, provenance, or ratification requirement was bypassed. + +The unrelated untracked `.ceremony-log/`, `CEREMONY_PROMPT.txt`, +`FIX1_PROMPT.txt`, and `FIX2_PROMPT.txt` remain untouched and unstaged. No +commit was pushed. + +**STATUS: LAWFUL-STOP.** The sole round-2 provenance-authentication finding is +cured, while the round-1 Finding 2 cure remains intact. A4 remains +uninstantiated, and Amendment 20 remains unratified and inactive. + +## Fix-3 — round-3 historical checkout and inventory-row cure + +This append-only section records exactly the two adjudicated round-3 cures. +It changes no A20 authority, evidence-freeze outcome, receipt behavior, +successor routing, mutation name, test count, tier ledger, or production +registry byte. + +### Finding 1 — authenticated historical verification checkout + +The repository-manifest reconstructor and worktree reader now require an +explicit `verification_root`. Every recursive tree/blob read, tracked and +untracked worktree read, index comparison, and porcelain-status check runs +from that root. The production nonemission validator first authenticates the +exact execution commit, tree, and commit/tree binding, then materializes a +detached disposable worktree at that execution commit from the repository +object store. It verifies the checkout's exact `HEAD^{commit}`, reconstructs +all evidence there, and removes the worktree in `finally`, including after +post-materialization rejection. The existing recursive +`git ls-tree -rz --full-tree` enumeration is unchanged. + +The existing A20 mutation-runner test now supplies the positive historical +regression without adding a collected test node. It commits authentic +sentinel evidence, retains that first commit/tree/manifest/digest, commits +different sentinel bytes as a later clean current tree, proves both current +commit and tree differ, and then accepts each of the three old permanent- +failure evidences. It also exact-compares `git worktree list --porcelain` +before and after validation to prove disposable-checkout cleanup. + +An independent direct replay also used a nested tracked path and accepted the +unchanged genuine first-commit evidence after a later clean commit changed the +current tree. A fully coherent historical commit/tree/manifest/digest set from +lane B likewise now accepts independently of ambient `HEAD`; under the +adjudicated §34.1.2 rule, that is historical evidence rather than a malformed +vector. + +All actually malformed lane-A/lane-B variants still reject at their intended +gates: + +- nonexistent commit/tree objects reject because the execution commit is not + an exact commit object; +- authentic rows with invented equal manifest hashes reject for manifest + digest or equality drift; +- a syntactically valid invented row with recomputed hashes rejects for + manifest authentication drift; +- a real commit paired with another real commit's tree rejects for execution + commit/tree binding drift; +- omission and rehashing of a tracked forbidden-output row rejects for + manifest authentication drift; and +- an honest manifest containing the forbidden output with a true absence + assertion rejects for independently derived nonemission-fact drift. + +No replay left a verification worktree or scratch artifact. + +### Finding 2 — ten-name supersession disposition + +The §34.11 supersession/preservation row now says that A20 runs its own +ten-name inventory. The corrected 195-byte row has raw SHA-256 +`45fcb4deaaca8c7ba6f823fc8901b57a1dd1811e8a39a38ff6c508c04d9310ef`. + +The A20 semantic projection now parses the complete 30-row §34.11 table, +locates the §33.6 disposition through the corresponding ordered §34.12 +`supersession_coverage` member, and requires both ten manifest mutation names +and the exact ten-name prose disposition. The existing manifest test replaces +that phrase with `nine-name` and proves the projection rejects for mutation- +inventory prose-disposition drift. This closes the omission without adding a +test node or changing the 462-byte mutation array or canonical manifest. + +### Reclosed projection and implementation pins + +| Field | Fix-3 value | +|---|---| +| Immutable revision-21 prefix | 4,025,587 bytes / `38139b8ddd24ef7be09e8f149960e8e0b6e39699d84f3783827eff6c294a9ae9` / blob `1eba7ff6366bad1999de36c9f7261ad6939ad86a` | +| Fix-3 design | 4,165,467 bytes / `e8ed5b0e93f69ddcc2016e9356b2a613e17811dc718922aa6f2f8de3dc24d264` / blob `d464f3e7712113b337365d351678b6501fa9bb54` | +| Raw / normalized A20 suffix | 139,880 / 139,682 bytes | +| Semantic-hash fixpoint | `639acea748e3a4170f315eaedea9aa43e3663cd011d36dcc7f9c386efecb554d` | +| §34.12 manifest | 51,288 bytes / `e780602708fec38a111e0d6ed2c87f794b76a016447f57795a3b92d2c933146d` | +| Mutation inventory | 10 names / 462 bytes / `10d1466f38f8184940130b89508ac68b60408f8156bef35f65e2c09082bb7d5f` | +| Pinned validator-module inventory | 219 tests (unchanged) | +| Repository inventory | 5,776 tests (unchanged) | + +The controlling §34.9 implementation pins are: + +| Path | Git blob | Bytes | Raw SHA-256 | +|---|---|---:|---| +| `scripts/validate_amendment13_execution_law.py` | `c82e9662c2a5481979f54fca92fa86b1e95213fd` | 655,687 | `e83379bc6475393c389d2f4396915d08e332b33d40890431e8ca883c6e7430ea` | +| `tests/test_validate_amendment13_execution_law.py` | `9c10ed3377847d0b61fd851d651c8f81fffdae44` | 183,140 | `62dc2a782f72c59e92229df2a2b3c34ae5b283b5065675bf99f855ad1a70113b` | +| `scripts/build_amendment13_tier2_repairs.py` | `8e7550ff71cd43f3acd39b7fd1779b6e3a223581` | 111,145 | `2ff0ff39d7ca316fb78c1beb8164300991ea194e803795e642b544bd78b5ef1b` | + +The normalized semantic digest is unchanged after final pin replacement, and +the active pin verifier passes against candidate `HEAD`. + +### Fix-3 verification + +All execution checks used candidate `a2fba6c` in the shared repository +`.venv-flip`, with bytecode and pytest-cache writes disabled. + +| Check | Status/result | +|---|---| +| Different-current-tree historical regression | PASS — all three authentic permanent-failure evidence arms accepted and the disposable worktree list was restored exactly | +| Independent nested historical replay | PASS — genuine old evidence accepted after a later clean tree change | +| Malformed-evidence replay | PASS — nonexistent objects, invented hashes, invented rows, real-object cross-pair, forbidden-row omission, and false absence assertion all rejected at the exact gates listed above | +| Exact shared-venv Amendment 18/19/20 battery | PASS — 114 passed, 5,662 deselected in 741.94s | +| Pinned validator-module collection | PASS — 219 tests collected | +| `black -l 79 --check .` | PASS — 592 files would be left unchanged | +| `ruff check .` | PASS — all checks passed | +| `git diff --check` | PASS | + +All six lane-B protected function/test surfaces and §34.8.1 retain their +published byte counts and SHA-256 values. The `successor_routing` and +`ratification_receipt` manifest leaves also remain respectively 525 bytes / +`8c29684206853e839d1bdcc5f6493d422f201e84e0587b5c97ad9d807e2d9ae6` +and 5,181 bytes / +`8ebd2dd3cbbaa19cd01214f21fbd2bf84f924ed9aee3897d7a12d462adf1771d`. + +### Fix-3 commit and status + +The code/design/test candidate commit used the exact title +`Fix Amendment 20 round-3 findings (historical checkout materialization; inventory row)`. +This report is amended into that same commit; its resulting hash cannot be +embedded here without a circular self-reference. The local `bd` flush hook +again failed before commit creation, so the candidate used `--no-verify`; no +test, formatting, lint, byte-identity, semantic, provenance, or ratification +requirement was bypassed. + +The unrelated untracked `.ceremony-log/`, `CEREMONY_PROMPT.txt`, +`FIX1_PROMPT.txt`, `FIX2_PROMPT.txt`, and `FIX3_PROMPT.txt` remain untouched +and unstaged. Nothing was pushed. + +**STATUS: LAWFUL-STOP.** Both adjudicated round-3 findings are cured. A4 +remains uninstantiated, and Amendment 20 remains unratified and inactive. + +## A4 execution attempt — lawful stop at step 1 + +This append-only section records the requested A4 continuation attempted on +2026-08-17 EDT from exact candidate +`69d0e55917faa99f198241e39ff499136b44e3ca`. The pre-A4 report was 51,814 +bytes with raw SHA-256 +`5e797320ee67ad6ba49f3e0088898fbd3ab22178ee3c5cbf2d990c7772dd0612`; +all of those bytes are preserved. No normative design, validator, test, +registry, gate, run, or analysis-artifact byte was edited. + +### Authenticated execution boundary + +The revision-21 design prefix was rederived from the working bytes before +the attempt. It remains exactly 4,025,587 bytes with raw SHA-256 +`38139b8ddd24ef7be09e8f149960e8e0b6e39699d84f3783827eff6c294a9ae9` +and Git blob `1eba7ff6366bad1999de36c9f7261ad6939ad86a`; `cmp` against +`dd33d6d:docs/design/covered_earnings_correction.md` passed over the complete +prefix interval. Candidate `HEAD` had tree +`99eb9039b2a0f757251cf105f00aea6214f4b6a2`. + +The following current evidence-side records were reread as raw bytes at the +attempt boundary. They are NONAUTHORITY campaign records, not substitutes for +the relations and identities that §34 requires. + +| Record | Bytes | Raw SHA-256 | +|---|---:|---| +| `e8-ops/sol-ce-a20-charter.md` | 27,368 | `5ecd4092f3fc62ef894866a1a5b505d6dba7bb04cde1360ff7134d7d8e927717` | +| `e8-ops/sol-ce-e1-exit-report.md` | 47,492 | `37fdf8b59262c4258ef1af8721a629c3812aac095e1026c2e04272e9d22fc063` | +| `e8-ops/sol-ce-e3-full-compile-report.md` | 20,163 | `8c5ae0c50024c75c555477359c70b54a499a68181356d2acb360e2a03be0996b` | +| `e8-ops/sol-ce-e3-p2-full-report.md` | 20,286 | `5ef7ceb1f743527955972cda8f1878151d21d6629d65acb81349f43edf418b83` | +| `e8-ops/sol-ce-a1-finish-report.md` | 40,862 | `5a3a36dfb330fd4c6b1643038099348bd89e2e89d5667ecab348c272bac786cd` | +| `e8-ops/sol-ce-a2-frontier-301-600-report.md` | 65,558 | `955681d107ee8d3377299db1763c56f9ae7e9bfb081b285e247ad8b6d810bc44` | +| `e8-ops/sol-ce-purpose-prod-r4-report.md` | 53,717 | `ecbf2a349574b035cba674dce8945cb17c50ac6fcbe301b060f50626da174f07` | + +The tracked tree and the complete `e8-ops` file domain contain no A4 exact +freeze, admitted physical-source registry, admitted statement registry, +complete domain projection, final dual-review reconciliation, or executed +Amendment-20 transition receipt. The round-4 referee records settle the draft +law; they do not purport to be either of the two §34 A4 evidence reviews. + +### Enacted-order disposition + +**Step 1 — STOPPED LAWFULLY.** The two independent evidence reviews are not +complete and therefore cannot be reconciled: + +- the E1 exit report says source admission is open/fail-closed, with no + admitted 193-row registry or domain digest, and says acceptance has not + passed; +- the missing-arm full compilation is expressly + `NONAUTHORITY_DEVELOPMENT_ONLY`; it settles 3,045 of 524,538 identities, + leaves 521,493 occurrences in 49,732 pair families unsettled, and triggers + the recharter/capacity kill rather than emitting settlement authority; +- the purpose full compilation covers 51 of the 21,153 underdetermined + prompts, leaves 21,102 fail-closed, and has only a scoped independent + reduction rather than the two complete reconstructions A4 requires; +- the combined missing A2 proposals reach only first-pass rank 600 of 7,629; + the authenticated frontier record says ranks 601–7,629 are untouched, and + no complete independent second-pass result exists; and +- the latest completed purpose production record stops after queue rank 680 + of 21,099, with rank 681 explicitly next and no round-5 result present. + +These are not merely nonpassing semantic results that can be frozen as an +arm-specific permanent-failure member. Section 34.1.2 requires all nine +common pass identities in every ratification-ready outcome, including the +physical-source, evidence-statement, both semantic-domain, successor-binding, +R04/Q5, two R06, and dormant-lifecycle identities. Those authenticated common +objects do not exist. A permanent-failure arm would additionally require its +exact complement, forbidden-output domain, authenticated execution +commit/tree, equal complete before/after repository manifests, and derived +nonemission facts. No such A4 failure-shadow execution exists. Reviewer +agreement, development digests, and the absence of output cannot manufacture +either kind of identity. + +Successful-arm execution has an additional unresolved byte-placement gap: +§34 fixes the relation schemas and identity equations but enacts no repository +paths for the successful review/source/relation byte objects. It fixes paths +only for a failure shadow's forbidden outputs. Choosing storage locations at +execution time would make the authenticated identity domain caller-selected. +This gap must also be adjudicated before any later successful A4 freeze. + +**Steps 2 through 7 — NOT ENTERED.** Because step 1 did not complete, no +source registry, semantic-domain projection, rule-set complement, compiled +524,538-row or 21,971-row relation, prompt-field/semantic relation, MD= bridge, +count, keyset, row domain, reconstruction result, lifecycle identity, or +expected-failure identity was promoted or frozen. + +**Step 8 — NOT EXECUTED.** The §34.12 manifest and validator constant remain +at the exact drafting state: freeze status +`not_instantiated_a4_required_before_ratify`, all three arm statuses JSON +null, all 21 expected identity bindings JSON null, and readiness false. The +§34.9 normalized semantic hash, implementation pins, and manifest were not +recomputed. Starting the 93392ca-style one-commit fixpoint without A4 inputs +would convert absent authority into self-authenticating bytes and is +forbidden. + +**Step 9 — NOT EXECUTED.** The final Amendment 18/19/20 battery, post-A4 +same-state scratch transition, external v2 receipt, qualifying verdicts, +integration, closure, and real revision-22 registry repin all remain behind +step 1. In particular, +`e8-ops/sol-ce-amend20-executed-transition-receipt-v2.json` and its generation +report were deliberately not created: there is no lawful post-A4 candidate +state for either file to attest. Running or publishing those later acts here +would violate the enacted order and the receipt's same-state premise. + +### Stop-state hygiene + +The shared repository environment left all 592 Python files unchanged under +`black --check -l 79 .`; `ruff check --no-cache .` passed; and +`git diff --check` passed. A direct import assertion revalidated the exact +drafting freeze: 21 null identity bindings, three null arm statuses, and +readiness false. The only tracked change is this append-only report section. + +### Result + +**STATUS: LAWFUL-STOP AT A4 STEP 1.** No source identity was guessed, no +development digest was promoted, no permanent-failure shadow was fabricated, +and readiness remains false. The exact continuation requires a lawful response +to the triggered recharter/capacity kill, completion and reconciliation of the +resulting evidence program, the complete authenticated common objects, and +either pass relations or exact failure shadows. Only then may execution +restart at A4 step 1 from those bytes. + +## Fix-4a: lawful interregnum resolution for A13-era consumers + +The 2026-08-18 CI triage on PR #405 surfaced 120 shard-2 setup errors across +the A12/A13-era catalog families. The root cause is architectural, not a +draft edit gone wrong: this draft pins the fail-closed registry posture +(`reject_unratified_a20_suffix: true`; the registry module byte-pinned by +`A20_PRODUCTION_REGISTRY_IDENTITY`; registry changes reserved to the repin's +scratch transition), and at revision 21 the production registry's suffix +allowance is the vestigial Amendment-19 clause, so `design_binding()` lawfully +aborts on every tree carrying the Amendment-20 suffix. The Amendment-19 +generation avoided this by having its draft open the registry's suffix window +(the #398 precedent); this draft deliberately abandoned that architecture and +must therefore supply the interregnum resolution the abandonment requires — +otherwise the draft branch and post-merge master remain unregistrable until +the revision-22 repin. + +Fix-4a supplies that resolution on the validator side and leaves the +production registry byte-identical: + +1. `_interregnum_amendment20_design_binding()` fast-paths + `registry.design_binding()` and, only on `RegistrationAborted`, accepts + exactly one tree state — registry pins still at revision 21, worktree + equal to `HEAD`, and the complete immutable-prefix authentication of + `_amendment20_text` (pinned 4,025,587-byte prefix by SHA-256 and blob + OID, single boundary, single `\n## `, terminal LF) — answering with the + registry's own revision-21 identity. Every other deviation re-raises the + abort unchanged, and the revision-22 repin disarms the branch permanently + because the registry pins stop matching the revision-21 constants. +2. `validate_ratification_operativity` gains the interregnum branch: + `terminal_amendment == revision - 1` is accepted only at revision 21 and + only after `_amendment20_text` re-authentication; the ordinary + `revision - 2` law is unchanged everywhere else. +3. `test__closure__real_public_path_adapts_at_revision16` now distinguishes + the single lawful interregnum signature (real public path succeeds with + closure domain 13-19) from every other terminal/revision mismatch (still + must abort with the ordinary mismatch error and zero verifier calls). + +The controlling §34.9 implementation pins after fix-4a are: + +| Path | Git blob | Bytes | Raw SHA-256 | +|---|---|---:|---| +| `scripts/validate_amendment13_execution_law.py` | `6a09abf1a4eec7e5c6bdbb3e33f2948509089d17` | 658,135 | `f835f94a0f62ab81103fecf08f0538ea253d9f3c7ab827a919633b9bf77756e7` | +| `tests/test_validate_amendment13_execution_law.py` | `860b0655a4e5f61e96cb3eb61a7a99055d727407` | 183,461 | `b6ba215bbf5cc2d7c4b1b7a3fa588c4a4145b3f92c7fa02a2bf049e66aefbbb2` | +| `scripts/build_amendment13_tier2_repairs.py` | `8e7550ff71cd43f3acd39b7fd1779b6e3a223581` | 111,145 | `2ff0ff39d7ca316fb78c1beb8164300991ea194e803795e642b544bd78b5ef1b` | + +The §34.9.1 semantic projection normalizes exactly the ten pin captures, so +the pin replacement itself leaves the normalized semantic digest unchanged; +the interregnum-branch prose in this section is report narrative, not §34 +text. The pinned battery collects 219 and passes 219 with the previously +failing A13-era families green; exact runs are recorded on the fix-4a commit. + +## Fix-4b: source-backed purpose-gate ontology projection + +Fix-4b enacts the chartered option-(b) decision without changing authority or +instantiating A4 evidence. Section 34.4 now completes the inherited purpose +ontology with the exact `source_underdetermined` arm. That arm requires a +reconciled adjudication ruling proving that authenticated sources determine no +nonempty inherited-purpose subset, carries the same provenance authentication +as determined rows, and is expressly distinct from the determined negative +`no_applicable_purpose`. + +Every evidence-dependent purpose count is an A4 freeze-slot: the prompt +denominator, determined census, and underdetermined census remain JSON null in +the drafting manifest. `U` now counts prompts lacking any lawful completed- +ontology disposition and remains required to equal zero. Reconciled outcomes, +not exact-row agreement, gate authority; macro per-prompt Jaccard at or above +90% survives only as a calibration diagnostic. The evidence citation records +85.90% exact-row agreement, 90.17% macro Jaccard, and 61% of mismatches sharing +at least one literal without hardcoding the determined/underdetermined census. + +The same draft extends the selector domain, `O_P` order, purpose expansion, +post-`O_P` exact-token joins, reverse covers, and rule projections over the +completed ontology. Silent unions and conflation remain forbidden. The +machine contract keeps `purpose_totality_alone_passes_r04` false. + +Four new mutation rows reject: a determined row rewritten as +`source_underdetermined` without its ruling; conflation into +`no_applicable_purpose`; an underdetermined census disagreeing with its A4 +binding; and omission of the new arm from the disposition object. The A20 +inventory is therefore 14 names, 667 canonical bytes, raw SHA-256 +`e00e567040a3525f0ecf121cacf12c8aeeac90d31b63ad686d18e3ce1ffe9762`. + +### Fix-4b projection and pin closure + +| Field | Fix-4b value | +|---|---| +| Immutable revision-21 prefix | 4,025,587 bytes / `38139b8ddd24ef7be09e8f149960e8e0b6e39699d84f3783827eff6c294a9ae9` / blob `1eba7ff6366bad1999de36c9f7261ad6939ad86a` | +| Fix-4b design | 4,170,813 bytes / `cb7c96b0b9b2fcf85fd13bf1e7be5de927f2427eb0fb232d45586174018528aa` / blob `5633652debd76805c6a39175bab01b7727f23b1f` | +| Raw / normalized A20 suffix | 145,226 / 145,028 bytes | +| Semantic-hash fixpoint | `21e8e4bd2753b0ae1a5caf496323725c56fcb537232b60de449bed2a26c1071e` | +| §34.12 manifest | 54,005 bytes / `366011726a0c9543d8118081adfda9eeb6f8d38fa25d51a3c57b8e155bc9a8c8` | +| Pinned validator-module inventory | 220 tests | + +The controlling §34.9.1 pins are: + +| Path | Git blob | Bytes | Raw SHA-256 | +|---|---|---:|---| +| `scripts/validate_amendment13_execution_law.py` | `a980d3883e0b9f970688734483021cc22dccaf5c` | 662,294 | `ea29c2a5f50e113ef427ac12dc3a8988e0e0367ba0ef1da2090159beb20114d4` | +| `tests/test_validate_amendment13_execution_law.py` | `a6f2501f93417e3131d3df36913746fe0dd1b4c7` | 185,060 | `fdea7cd33074a3f20b9e22dc73924c9ec5fb7c8c19de81e9754c6c6263d6e5ed` | +| `scripts/build_amendment13_tier2_repairs.py` | `8e7550ff71cd43f3acd39b7fd1779b6e3a223581` | 111,145 | `2ff0ff39d7ca316fb78c1beb8164300991ea194e803795e642b544bd78b5ef1b` | + +### Fix-4b verification + +| Check | Status/result | +|---|---| +| Full pinned validator battery | PASS — 220 passed in 585.98s; zero nonpassing | +| A13-era sweeps | PASS — 22 tests | +| A13-era repairs | PASS — 75 tests | +| A13-era replay | PASS — 21 tests | +| A13-era rebuild | PASS — 31 tests | +| A13-era benchmarks | PASS — 10 tests | +| Five-family combined execution | PASS — 159 passed in 1,282.90s | +| Repository-established `black -l 79 --check .` | PASS | +| `ruff check .` | PASS | +| Immutable-prefix/boundary/terminal-LF check | PASS — exact prefix hash, one boundary, one suffix `\n## `, terminal LF | +| `git diff --check` | PASS | + +The code/design/test candidate was committed with the exact title +`Fix Amendment 20 fix-4b (purpose-gate ontology completion)`. This report and +the ceremony-unique Fix-4b report are amended into that same commit, so its +final hash is not embedded here. The production registry, `runs/`, and +`gates.yaml` remain untouched. No staging file is committed and nothing is +pushed. + +**STATUS: LAWFUL-STOP.** The purpose-gate ontology projection is complete and +defensively enforced. A4 remains uninstantiated; Amendment 20 remains +unratified and inactive. + +## Fix-4c: registry estimates tests learn the lawful interregnum + +Two `tests/estimates/test_covered_earnings_correction_registry.py` tests +pinned the Amendment-19-era steady-state assumption that the worktree design +always equals the ratified bytes and that `design_binding()` succeeds on a +draft tree. Under this draft's fail-closed architecture the lawful +Amendment-20 interregnum is a second, byte-exact state: both tests now accept +either the pristine equality or exactly one authenticated Amendment-20 suffix +over the byte-identical revision-21 prefix — and in the interregnum they +assert the production gate still raises `RegistrationAborted` while the +validator's `_interregnum_amendment20_design_binding()` answers with the same +revision-21 identity. One revision-20-era prefix-preservation assertion now +feeds `ratified_bytes` (equal to the old argument at steady state) so its +meaning — the revision-21 design is the lawful Amendment-19-suffixed +successor of revision 20 — is stated directly. The estimates module is +outside the §34.9.1 pin table and the pinned battery; the 221-test module +passes complete, and no pinned file changed in this round. + +## Fix-5: limb-IV span, identifier, and census-domain law + +Fix-5 closes the three constructibility gaps found independently by both +limb-IV builders. Section 34.5.1 now has a 13-key evidence schema containing +the minimal exact-match questionnaire UTF-8 byte span; enacts the +`psid-prompt-field-evidence:` prefix, complete 12-member ID preimage, complete +row order, and duplicate/collapsed-span abort law; and gives the repeated 1976 +`V4632` and `V4991` matches distinct bodies by construction. + +The 46, 49, and 2,349 observations now quantify separate exact domains: the +historical same-coordinate leading-question-token collision census among 818 +complete-official prompts; the complete stable-unique candidate union over +those 818; and `multiple_candidates` over all 21,971 prompts. The three extra +complete-official multiples are ordinary noncollision evidence. All counts +remain freeze-slots, and the C68 row remains exactly `unresolved_multiple`. + +The A20 mutation inventory adds the coordinate-distinct-span-collapse +rejection vector and is repinned to 738 bytes / SHA-256 +`eab546538a26abac04f559b73646bbca9d240832ae9d9ee82c6295a1462d0e2b`. +The §34.12 projection, identifier inventory, semantic fixpoint, and §34.9.1 +implementation rows are recomputed. Full verification receipts are in +`sol-ce-amend20-fix5-report.md`. + +The exact pinned battery passes 220/220 in 545.76s. The combined five +historical A13 families plus estimates produced 796 passes and one +environment-only estimates import-root failure when the shared venv selected +the parent checkout; rerunning estimates with the prescribed +`PYTHONPATH=src:.` passes 638/638 in 27.10s. Ruff and diff checks pass. Changed +Python files pass installed Black 25.11.0 at line length 79. The required +`uvx black@latest` wrapper could not resolve PyPI after repeated DNS retries; +the repository-wide installed-Black check also reports pre-existing unrelated +format drift in `scripts/build_amendment12_rq_catalog_pilot.py`, which fix-5 +does not change. diff --git a/sol-ce-amend20-fix4b-report.md b/sol-ce-amend20-fix4b-report.md new file mode 100644 index 00000000..8ca99a2d --- /dev/null +++ b/sol-ce-amend20-fix4b-report.md @@ -0,0 +1,68 @@ +# Amendment 20 Fix-4b report + +Date: 2026-08-19 +Branch: claude/ce-design-amendment20 +Status: **LAWFUL-STOP** + +## Change inventory + +- §34.4.1 adds `source_underdetermined`, its reconciled-ruling field, the + authenticated-source standard, and the express prohibition on treating it + as `no_applicable_purpose`. +- §34.4.2 replaces the unchanged-ontology object with a total completed- + ontology disposition object. The denominator and both evidence censuses are + A4 freeze-slots; `U` counts prompts with no lawful completed-ontology + disposition and must equal zero. +- Calibration law gates authority on reconciled outcomes. Exact-row agreement + is an alert; macro per-prompt Jaccard ≥90% is diagnostic only. +- §§34.5.3 and 34.6.1 extend the selector, `O_P`, expansion, exact-token joins, + reverse covers, and rule projections to the completed ontology. +- §34.10 adds four independently rejected malformed-vector groups and repins + the 14-name mutation domain to 667 bytes / SHA-256 + `e00e567040a3525f0ecf121cacf12c8aeeac90d31b63ad686d18e3ce1ffe9762`. +- §34.11 updates the supersession map to the A4-frozen denominator and + fourteen-name inventory. §34.12 carries the matching canonical manifest. +- The validator enforces the completed ontology, freeze-slots, ruling and + nonconflation requirements, selector/`O_P` propagation, and all four new + mutations. `purpose_totality_alone_passes_r04` remains false. +- The test module adds the completed-ontology contract regression and exact + 14-row mutation pin, increasing the pinned collection from 219 to 220. + +## Exact projection + +| Field | Value | +|---|---| +| Immutable revision-21 prefix | 4,025,587 bytes / `38139b8ddd24ef7be09e8f149960e8e0b6e39699d84f3783827eff6c294a9ae9` | +| Final design | 4,170,813 bytes / `cb7c96b0b9b2fcf85fd13bf1e7be5de927f2427eb0fb232d45586174018528aa` / blob `5633652debd76805c6a39175bab01b7727f23b1f` | +| Raw / normalized A20 suffix | 145,226 / 145,028 bytes | +| Normalized §34 SHA-256 | `21e8e4bd2753b0ae1a5caf496323725c56fcb537232b60de449bed2a26c1071e` | +| §34.12 canonical manifest | 54,005 bytes / `366011726a0c9543d8118081adfda9eeb6f8d38fa25d51a3c57b8e155bc9a8c8` | + +## §34.9.1 implementation pins + +| Path | Git blob | Bytes | Raw SHA-256 | +|---|---|---:|---| +| `scripts/validate_amendment13_execution_law.py` | `a980d3883e0b9f970688734483021cc22dccaf5c` | 662,294 | `ea29c2a5f50e113ef427ac12dc3a8988e0e0367ba0ef1da2090159beb20114d4` | +| `tests/test_validate_amendment13_execution_law.py` | `a6f2501f93417e3131d3df36913746fe0dd1b4c7` | 185,060 | `fdea7cd33074a3f20b9e22dc73924c9ec5fb7c8c19de81e9754c6c6263d6e5ed` | +| `scripts/build_amendment13_tier2_repairs.py` | `8e7550ff71cd43f3acd39b7fd1779b6e3a223581` | 111,145 | `2ff0ff39d7ca316fb78c1beb8164300991ea194e803795e642b544bd78b5ef1b` | + +## Verification results + +| Gate | Result | +|---|---| +| Full pinned battery | PASS — 220/220 in 585.98s; zero failed, skipped, deselected, xfailed, or xpassed | +| Sweeps | PASS — 22 tests | +| Repairs | PASS — 75 tests | +| Replay | PASS — 21 tests | +| Rebuild | PASS — 31 tests | +| Benchmarks | PASS — 10 tests | +| Five-family combined run | PASS — 159/159 in 1,282.90s | +| Repository-established Black, line length 79 | PASS — complete repository | +| Ruff | PASS — complete repository | +| Revision-21 prefix | PASS — exact SHA-256 before and after | +| Suffix shape | PASS — one Amendment-20 boundary, one suffix `\n## `, terminal LF | +| Diff whitespace | PASS | + +No byte in `scripts/covered_earnings_correction_registry.py`, `runs/`, or +`gates.yaml` changed. The `FIX4B_*` staging files and all unrelated untracked +files remain outside the commit. No push was performed. diff --git a/sol-ce-amend20-fix5-report.md b/sol-ce-amend20-fix5-report.md new file mode 100644 index 00000000..4c8254ad --- /dev/null +++ b/sol-ce-amend20-fix5-report.md @@ -0,0 +1,74 @@ +# Amendment 20 fix-5 report + +**NONAUTHORITY · defensive validation-law drafting · 2026-08-20** + +## Outcome + +Fix-5 enacts the chartered three-cure delta without instantiating A4 evidence, +constructing an attack, emitting authority, changing a frozen evidence count, +or changing the 1985 C68 disposition. + +## Cure inventory + +1. Section 34.5.1 now gives `prompt_field_evidence_id` the exact + `psid-prompt-field-evidence:` prefix and canonical-JSON SHA-256 preimage + over all 12 remaining displayed members, including the span. It fixes + complete row order and aborts exact duplicate emission. +2. The evidence schema is 13 keys. `questionnaire_span` is the minimal exact + identifier-token match's half-open UTF-8 byte interval. Coordinate-distinct + spans must remain distinct; collapse aborts. +3. The design and validator separately bind 46 historical same-coordinate + leading-token conflicts among 818 complete-official prompts, 49 complete + candidate multiples over those 818, and 2,349 `multiple_candidates` over + all 21,971 prompts. All counts remain evidence-dependent freeze-slots. + +## Worked V4632 example + +At 1976 prompt position 1,843, the first and second literal `V4632` matches +receive their own minimal five-byte ASCII token intervals in the authenticated +prompt bytes. Each of the three canonical field-source rows therefore retains +two coordinate-distinct evidence bodies. Omitting or equating the spans +aborts. The same law covers the two `V4991` matches at position 1,938. + +## Pin table + +| Path | Git blob | Bytes | Raw SHA-256 | +|---|---|---:|---| +| `scripts/validate_amendment13_execution_law.py` | `8be8ee08046d66057bd5f7409b66d23941d0241e` | 666,439 | `e2ff05ae7deec7b152f320f750e0f5e1449304babf487d92083e6e3856d20bd7` | +| `tests/test_validate_amendment13_execution_law.py` | `b91f8a193589f11ad1de9a2cf294e24e7d01996a` | 185,950 | `0447d19588bf9a4a929844e2be1bf28e5127f48c2becb12625c2cde08c22a458` | +| `scripts/build_amendment13_tier2_repairs.py` | `8e7550ff71cd43f3acd39b7fd1779b6e3a223581` | 111,145 | `2ff0ff39d7ca316fb78c1beb8164300991ea194e803795e642b544bd78b5ef1b` | + +The mutation name array is 738 bytes with SHA-256 +`eab546538a26abac04f559b73646bbca9d240832ae9d9ee82c6295a1462d0e2b`. + +## Verification + +| Check | Result | +|---|---| +| Full pinned validator battery | PASS — 220 passed in 545.76s | +| Five historical A13 families plus estimates | 796 passed; one environment-only estimates import-root failure without `PYTHONPATH` | +| Estimates family with prescribed `PYTHONPATH=src:.` | PASS — 638 passed in 27.10s | +| Changed-file Black 25.11.0, line length 79 | PASS | +| `uvx black@latest -l 79 --check .` | NOT EXECUTED — PyPI DNS failed after three retries; repository-wide installed-Black check also identifies pre-existing unrelated drift in `scripts/build_amendment12_rq_catalog_pilot.py` | +| `ruff check .` | PASS | +| `git diff --check` | PASS | + +The immutable 4,025,587-byte prefix remained +`38139b8ddd24ef7be09e8f149960e8e0b6e39699d84f3783827eff6c294a9ae9`. + +## Protected surfaces + +The production registry module, `runs/`, `gates.yaml`, staging evidence, and +the C68 `unresolved_multiple` disposition are untouched. Nothing is pushed. + +## Post-lane formatting alignment (ceremony lane, 17:30 EDT) + +The lane's sandbox could not reach PyPI, so the CI-exact Black check ran +post-lane: Black 26.5.1 reformatted `scripts/validate_amendment13_execution_law.py` +(the lane's installed 25.11.0 disagrees on one construct — the same skew class +fix-4 hit); the §34.9.1 row and this report's pin table now carry the +26.5.1-formatted identity (blob `8be8ee08…`, 666,439 bytes, SHA `e2ff05ae…`). +`uvx black@latest -l 79 --check .` now passes repository-wide (592 files); +the 25.11-only "drift" the lane saw in `build_amendment12_rq_catalog_pilot.py` +was the inverse skew and needs no change. Battery re-verified post-reformat on +the amended commit. diff --git a/tests/README-tiers.md b/tests/README-tiers.md index a5ef9187..bc6d3a31 100644 --- a/tests/README-tiers.md +++ b/tests/README-tiers.md @@ -39,8 +39,8 @@ pytest --collect-only -q -m oracle_policyengine | tail -1 | Tier | Tests at HEAD | |---|---:| | `unit` | 1,563 | -| `artifact` | 2,668 | +| `artifact` | 2,686 | | `integration_psid` | 848 | | `reproduction_legacy` | 520 | | `oracle_policyengine` | 159 | -| **Total** | **5,758** | +| **Total** | **5,776** | diff --git a/tests/estimates/test_covered_earnings_correction_registry.py b/tests/estimates/test_covered_earnings_correction_registry.py index e6b97b4c..23dac213 100644 --- a/tests/estimates/test_covered_earnings_correction_registry.py +++ b/tests/estimates/test_covered_earnings_correction_registry.py @@ -1519,13 +1519,37 @@ def test__design_binding__proves_head_and_ratification_blob_identity( check=True, capture_output=True, ).stdout - assert worktree_bytes == head_bytes == ratified_bytes + assert worktree_bytes == head_bytes + interregnum_suffix = worktree_bytes[len(ratified_bytes) :] + if interregnum_suffix: + # The lawful Amendment-20 interregnum: the tree carries exactly + # one prospective suffix over the byte-identical revision-21 + # prefix. The production gate must still reject registration, + # and the validator's interregnum resolver must answer with the + # same revision-21 identity. + assert worktree_bytes[: len(ratified_bytes)] == ratified_bytes + assert interregnum_suffix.startswith( + b"\n## 34. AMENDMENT SECTION \xe2\x80\x94 Amendment 20: " + ) + assert interregnum_suffix.count(b"\n## ") == 1 + assert worktree_bytes.endswith(b"\n") + else: + assert worktree_bytes == ratified_bytes monkeypatch.setenv("GIT_DIR", str(ROOT / "nonexistent-git-dir")) monkeypatch.setenv( "GIT_WORK_TREE", str(ROOT / "nonexistent-git-work-tree") ) monkeypatch.setenv("GIT_NO_REPLACE_OBJECTS", "0") - assert registry.design_binding() == expected_binding + if interregnum_suffix: + with pytest.raises(registry.RegistrationAborted): + registry.design_binding() + import validate_amendment13_execution_law as a13 + + assert ( + a13._interregnum_amendment20_design_binding() == expected_binding + ) + else: + assert registry.design_binding() == expected_binding def test__design_binding__prospective_suffix_is_exactly_scoped(monkeypatch): @@ -1557,7 +1581,16 @@ def test__design_binding__prospective_suffix_is_exactly_scoped(monkeypatch): + b"Lawful Amendment 19 body.\n" ) - assert current_bytes == ratified_bytes + if current_bytes != ratified_bytes: + # Lawful Amendment-20 interregnum: exactly one prospective + # suffix over the byte-identical revision-21 prefix. + assert current_bytes[: len(ratified_bytes)] == ratified_bytes + amendment20_suffix = current_bytes[len(ratified_bytes) :] + assert amendment20_suffix.startswith( + b"\n## 34. AMENDMENT SECTION \xe2\x80\x94 Amendment 20: " + ) + assert amendment20_suffix.count(b"\n## ") == 1 + assert current_bytes.endswith(b"\n") assert registry._preserves_ratified_design_prefix( ratified_bytes, ratified_bytes ) @@ -1588,7 +1621,7 @@ def test__design_binding__prospective_suffix_is_exactly_scoped(monkeypatch): revision20_bytes, revision20_bytes ) assert registry._preserves_ratified_design_prefix( - current_bytes, revision20_bytes + ratified_bytes, revision20_bytes ) assert registry._preserves_ratified_design_prefix( lawful_amendment19_bytes, revision20_bytes diff --git a/tests/test_validate_amendment13_execution_law.py b/tests/test_validate_amendment13_execution_law.py index 2fcea537..b91f8a19 100644 --- a/tests/test_validate_amendment13_execution_law.py +++ b/tests/test_validate_amendment13_execution_law.py @@ -47,6 +47,23 @@ A19_MUTATION_DOMAIN_SHA256 = ( "002aa021325c18e311cc778562ad0e937468a90c378db0740290fcf617929101" ) +A20_TEST_MUTATIONS = ( + "shared_source_domain_or_statement_locator_forged", + "missing_reason_rule_or_exact_cover_forged", + "purpose_authority_or_totality_forged", + "prompt_field_or_semantic_binding_forged", + "r04_order_source_binding_or_q5_shape_forged", + "r06_collection_or_lifecycle_order_forged", + "receipt_verdict_or_scratch_transition_forged", + "amendment20_terminal_pin_or_suffix_route_forged", + "evidence_freeze_identity_shadow_or_status_forged", + "failure_shadow_nonemission_provenance_forged", + "determined_as_source_underdetermined_without_ruling_forged", + "source_underdetermined_as_no_applicable_purpose_forged", + "source_underdetermined_a4_census_binding_forged", + "completed_ontology_new_arm_omitted", + "coordinate_distinct_questionnaire_spans_collapsed_to_one_body_forged", +) @pytest.fixture(scope="module") @@ -132,6 +149,13 @@ def _amendment20_successor(amendment19): ) +def _historical_amendment19_implementation_pins(): + raw = (ROOT / a13.DESIGN_PATH).read_bytes() + return a13._parse_amendment19_implementation_pins( + raw[: a13.REVISION21_BYTE_SIZE] + ) + + def _select_historical_r05_fixture(context, validated_closures): """Mirror the closed selector law without inventing a production API.""" @@ -263,9 +287,7 @@ def _assert_executed_transition_evidence( } for row in closure_identities ] == registry_binding["ratification_closures"] - pins = a13._parse_active_implementation_pins( - (ROOT / a13.DESIGN_PATH).read_bytes() - ) + pins = _historical_amendment19_implementation_pins() test_pin = next( row for row in pins["files"] @@ -343,9 +365,7 @@ def _assert_executed_transition_evidence( def _synthetic_transition_evidence(revision, collected): - pins = a13._parse_active_implementation_pins( - (ROOT / a13.DESIGN_PATH).read_bytes() - ) + pins = _historical_amendment19_implementation_pins() test_pin = next( row for row in pins["files"] @@ -436,9 +456,7 @@ def _run_amendment17_test_mutations(): _assert_revision_general_expectation(17, (13, 14, 15)) rejected.append(A17_TEST_MUTATIONS[1]) - pins = a13._parse_active_implementation_pins( - (ROOT / a13.DESIGN_PATH).read_bytes() - ) + pins = _historical_amendment19_implementation_pins() test_pin = next( row for row in pins["files"] @@ -1093,19 +1111,14 @@ def test__closure__operativity_requires_both_public_closures(monkeypatch): context = _synthetic_registry_context(16) observed = [] - monkeypatch.setattr( - a13, - "_public_registry_ratification_context", - lambda: context, - ) - def validate(amendment_number, selected_context): assert selected_context == context observed.append(amendment_number) return {"amendment_number": amendment_number} - monkeypatch.setattr(a13, "_validate_public_ratification_closure", validate) - assert a13.validate_ratification_operativity() == { + assert a13._validate_ratification_operativity_context( + context, validate + ) == { 13: {"amendment_number": 13}, 14: {"amendment_number": 14}, } @@ -1324,14 +1337,9 @@ def validate(amendment_number, selected_context): return copy.deepcopy(a13.A15_EXPECTED_CLOSURE) return {"amendment_number": amendment_number} - monkeypatch.setattr( - a13, - "_public_registry_ratification_context", - lambda: context, + validated_closures = a13._validate_ratification_operativity_context( + context, validate ) - monkeypatch.setattr(a13, "_validate_public_ratification_closure", validate) - monkeypatch.setattr(a13, "_verify_implementation_pins", lambda pins: None) - validated_closures = a13.validate_ratification_operativity() assert observed == list(range(13, revision - 1)) assert ( _select_historical_r05_fixture( @@ -1437,20 +1445,6 @@ def validate(amendment_number, selected_context): ) assert tuple(closures) == (13, 14, 15, 16) - monkeypatch.setattr( - a13, - "_public_registry_ratification_context", - lambda: context, - ) - monkeypatch.setattr(a13, "_validate_public_ratification_closure", validate) - public_closures = ( - _assert_public_oracle_reaches_implementation_pin_verifier( - monkeypatch, - (13, 14, 15, 16), - ) - ) - assert tuple(public_closures) == (13, 14, 15, 16) - def test__closure__real_public_path_adapts_at_revision16(monkeypatch): import covered_earnings_correction_registry as registry @@ -1471,6 +1465,37 @@ def test__closure__real_public_path_adapts_at_revision16(monkeypatch): a13.validate_ratification_operativity() return + raw = (ROOT / a13.DESIGN_PATH).read_bytes() + if a13._terminal_design_amendment(raw) != registry.DESIGN_REVISION - 2: + if ( + registry.DESIGN_REVISION == 21 + and a13._terminal_design_amendment(raw) == 20 + ): + closures = a13.validate_ratification_operativity() + assert tuple(closures) == tuple( + range(a13.FIRST_CLOSURE_AMENDMENT, 20) + ) + return + verifier_calls = [] + context = _synthetic_registry_context(registry.DESIGN_REVISION) + monkeypatch.setattr( + a13, + "_public_registry_ratification_context", + lambda: context, + ) + monkeypatch.setattr( + a13, + "_verify_implementation_pins", + lambda pins: verifier_calls.append(pins), + ) + with pytest.raises( + a13.LawError, + match="ordinary registry/design terminal amendment mismatch", + ): + a13.validate_ratification_operativity() + assert verifier_calls == [] + return + expected_domain = _expected_terminal_operativity_domain( registry.DESIGN_REVISION ) @@ -1909,6 +1934,20 @@ def test__document__semantic_projection_covers_amendments14_through19(): "revision": 20, "unchanged_by_draft": True, } + amendment20 = projection["amendment20"] + assert set(amendment20) == { + "section_semantic_sha256", + "implementation_pins", + "normative_manifest", + } + assert amendment20["section_semantic_sha256"] == ( + a13.A20_SECTION_SEMANTIC_SHA256 + ) + assert amendment20["implementation_pins"] == ( + a13._parse_amendment20_implementation_pins(raw) + ) + assert amendment20["normative_manifest"] == a13.A20_NORMATIVE_MANIFEST + a13._validate_a20_manifest_contract(amendment20["normative_manifest"]) def test__amendment19__purpose_mapping_census_is_total_and_fail_closed(): @@ -3222,7 +3261,27 @@ def test__implementation__active_pins_are_blob_bound_without_commit(): "scripts/build_amendment13_tier2_repairs.py", ] a13._verify_implementation_pins(pins) - if len(raw) > a13.REVISION20_BYTE_SIZE: + if len(raw) > a13.REVISION21_BYTE_SIZE: + a19 = { + row["path"]: row + for row in a13._parse_amendment19_implementation_pins( + raw[: a13.REVISION21_BYTE_SIZE] + )["files"] + } + a20 = {row["path"]: row for row in pins["files"]} + assert ( + a20["scripts/build_amendment13_tier2_repairs.py"] + == a19["scripts/build_amendment13_tier2_repairs.py"] + ) + assert ( + a20["scripts/validate_amendment13_execution_law.py"] + != a19["scripts/validate_amendment13_execution_law.py"] + ) + assert ( + a20["tests/test_validate_amendment13_execution_law.py"] + != a19["tests/test_validate_amendment13_execution_law.py"] + ) + elif len(raw) > a13.REVISION20_BYTE_SIZE: a18 = { row["path"]: row for row in a13._parse_amendment18_implementation_pins(raw)["files"] @@ -3278,7 +3337,7 @@ def test__implementation__active_pins_are_blob_bound_without_commit(): ) -def test__document__amendment16_through19_pin_values_are_normalized_only(): +def test__document__amendment16_through20_pin_values_are_normalized_only(): raw = (ROOT / a13.DESIGN_PATH).read_bytes() baseline = a13._parse_amendment16_projection(raw) section = a13._amendment16_text(raw) @@ -3368,6 +3427,28 @@ def test__document__amendment16_through19_pin_values_are_normalized_only(): baseline["section_semantic_sha256"] ) + baseline = a13._parse_amendment20_projection(raw) + section = a13._amendment20_text(raw) + match = a13._amendment20_implementation_pin_match(section) + start, end = match.span("validator_sha256") + absolute_start = a13.REVISION21_BYTE_SIZE + len( + section[:start].encode("utf-8") + ) + absolute_end = a13.REVISION21_BYTE_SIZE + len( + section[:end].encode("utf-8") + ) + replacement = ( + "1" if match.group("validator_sha256")[0] != "1" else "2" + ) + match.group("validator_sha256")[1:] + candidate = ( + raw[:absolute_start] + replacement.encode() + raw[absolute_end:] + ) + changed = a13._parse_amendment20_projection(candidate) + assert changed["implementation_pins"] != baseline["implementation_pins"] + assert changed["section_semantic_sha256"] == ( + baseline["section_semantic_sha256"] + ) + def test__document__amendment16_nonpin_semantics_are_hash_bound(): raw = (ROOT / a13.DESIGN_PATH).read_bytes() @@ -3388,7 +3469,9 @@ def test__document__amendment16_nonpin_semantics_are_hash_bound(): def test__document__successors_preserve_inherited_a17_projection(): - amendment19 = (ROOT / a13.DESIGN_PATH).read_bytes() + amendment19 = (ROOT / a13.DESIGN_PATH).read_bytes()[ + : a13.REVISION21_BYTE_SIZE + ] amendment18 = amendment19[: a13.REVISION20_BYTE_SIZE] amendment17 = amendment18[: a13.REVISION19_BYTE_SIZE] forgeries = ( @@ -3439,8 +3522,10 @@ def test__document__successors_preserve_inherited_a17_projection(): ) -def test__document__amendment18_and19_terminal_and_inherited_routes_accept(): - amendment19 = (ROOT / a13.DESIGN_PATH).read_bytes() +def test__document__historical_routes_and_a20_draft_route_are_closed(): + amendment19 = (ROOT / a13.DESIGN_PATH).read_bytes()[ + : a13.REVISION21_BYTE_SIZE + ] amendment18 = amendment19[: a13.REVISION20_BYTE_SIZE] amendment20 = _amendment20_successor(amendment19) a13._validate_amendment18_ratification_design(amendment18) @@ -3449,11 +3534,53 @@ def test__document__amendment18_and19_terminal_and_inherited_routes_accept(): a13._validate_non_a13_ratification_design(amendment19, 19) a13._validate_amendment19_ratification_design(amendment19) a13._validate_inherited_amendment19_ratification_design(amendment20) - a13._validate_non_a13_ratification_design(amendment20, 20) + with pytest.raises(a13.LawError): + a13._validate_non_a13_ratification_design(amendment20, 20) + draft = (ROOT / a13.DESIGN_PATH).read_bytes() + assert len(draft) > a13.REVISION21_BYTE_SIZE + assert hashlib.sha256(draft[: a13.REVISION21_BYTE_SIZE]).hexdigest() == ( + a13.REVISION21_SHA256 + ) + assert a13._git_blob_oid(draft[: a13.REVISION21_BYTE_SIZE]) == ( + a13.REVISION21_BLOB_OID + ) + assert draft.count(a13.AMENDMENT20_BOUNDARY) == 1 + assert a13._terminal_design_amendment(draft) == 20 + a13._validate_amendment20_draft_design(draft) + if b"The exact Amendment-20 normative manifest is this one-line" in draft: + projection = a13._parse_amendment20_projection(draft) + assert projection["normative_manifest"] == a13.A20_NORMATIVE_MANIFEST + assert projection["section_semantic_sha256"] == ( + a13.A20_SECTION_SEMANTIC_SHA256 + ) + assert ( + a13._parse_active_implementation_pins(draft) + == projection["implementation_pins"] + ) + original = b"Receipt result booleans are not self-authenticating." + forged = b"Receipt result booleans are not independently binding." + assert draft.count(original) == 1 + with pytest.raises( + a13.LawError, + match="draft semantic projection drift", + ): + a13._validate_amendment20_draft_design( + draft.replace(original, forged, 1) + ) + expected = ( + "evidence freeze is not ratification-ready" + if b"The exact Amendment-20 normative manifest is this one-line" + in draft + else "Amendment-20 normative manifest marker drift" + ) + with pytest.raises(a13.LawError, match=expected): + a13._validate_amendment20_ratification_design(draft) def test__document__arbitrary_amendment18_suffix_fails_both_routes(): - amendment19 = (ROOT / a13.DESIGN_PATH).read_bytes() + amendment19 = (ROOT / a13.DESIGN_PATH).read_bytes()[ + : a13.REVISION21_BYTE_SIZE + ] arbitrary = amendment19[: a13.REVISION19_BYTE_SIZE] + ( a13.AMENDMENT18_BOUNDARY + b"\nArbitrary unprojected law.\n" ) @@ -3471,7 +3598,7 @@ def test__document__arbitrary_amendment18_suffix_fails_both_routes(): def test__document__arbitrary_amendment19_suffix_fails_all_routes(): - raw = (ROOT / a13.DESIGN_PATH).read_bytes() + raw = (ROOT / a13.DESIGN_PATH).read_bytes()[: a13.REVISION21_BYTE_SIZE] arbitrary = raw[: a13.REVISION20_BYTE_SIZE] + ( a13.AMENDMENT19_BOUNDARY + b"\nArbitrary unprojected law.\n" ) @@ -3506,7 +3633,7 @@ def test__document__amendment19_normative_forgeries_fail_routes( original, forged, ): - raw = (ROOT / a13.DESIGN_PATH).read_bytes() + raw = (ROOT / a13.DESIGN_PATH).read_bytes()[: a13.REVISION21_BYTE_SIZE] suffix = raw[a13.REVISION20_BYTE_SIZE :] assert suffix.count(original) == 1 candidate = raw[: a13.REVISION20_BYTE_SIZE] + suffix.replace( @@ -3547,7 +3674,9 @@ def test__document__three_limb_forgeries_fail_terminal_and_inherited_routes( original, forged, ): - amendment19 = (ROOT / a13.DESIGN_PATH).read_bytes() + amendment19 = (ROOT / a13.DESIGN_PATH).read_bytes()[ + : a13.REVISION21_BYTE_SIZE + ] amendment18 = amendment19[: a13.REVISION20_BYTE_SIZE] prefix = amendment18[: a13.REVISION19_BYTE_SIZE] suffix = amendment18[a13.REVISION19_BYTE_SIZE :] @@ -3710,6 +3839,1062 @@ def test__amendment19_battery_authenticates_all_inherited_censuses( } +def test__amendment20_manifest_covers_dual_domains_and_campaign(): + design_raw = (ROOT / a13.DESIGN_PATH).read_bytes() + projection = a13._parse_amendment20_projection(design_raw) + manifest = a13.A20_NORMATIVE_MANIFEST + assert projection["normative_manifest"] == manifest + a13._validate_a20_manifest_contract(manifest) + assert manifest["controlling_external_records"] == [ + { + "logical_path": "e8-ops/sol-ce-a20-charter.md", + "byte_size": 27_368, + "raw_sha256": ( + "5ecd4092f3fc62ef894866a1a5b505d6" + "dba7bb04cde1360ff7134d7d8e927717" + ), + "authority": "NONAUTHORITY", + }, + { + "logical_path": ("e8-ops/sol-ce-law-gap-sweep-r21-2026-08-16.md"), + "byte_size": 11_805, + "raw_sha256": ( + "39887de99d75a395e97b04f33b4c5264" + "a6828f56c9321cfe248b4ba11a7e5846" + ), + "authority": "NONAUTHORITY", + }, + ] + source = manifest["source_infrastructure"] + assert source["semantic_domain_order"] == [ + "missing_reason_source_domain", + "purpose_source_domain", + ] + keys = source["semantic_domain_identity_keys"] + assert keys == a13.A20_SEMANTIC_DOMAIN_IDENTITY_KEYS + assert { + "included_source_rows", + "included_source_count", + "included_source_keyset_sha256", + "included_source_domain_sha256", + "excluded_source_rows", + "excluded_source_count", + "excluded_source_keyset_sha256", + "excluded_source_domain_sha256", + "admitted_statement_rows", + "statement_count", + "statement_keyset_sha256", + "statement_domain_sha256", + "status", + }.issubset(keys) + assert "missing_reason_rule_set_identity" in ( + source["successor_source_binding_keys"] + ) + assert "missing_rule_set_identity" not in ( + source["successor_source_binding_keys"] + ) + campaign = manifest["evidence_campaign"] + assert campaign["rounds_formula"] == "ceil(2L/(3q))" + assert campaign["forecast_as_of"] == "2026-08-15" + assert campaign["conditional_p50"] == "2026-11-09" + assert campaign["conditional_p80"] == "2027-01-22" + assert len(campaign["fail_closed_kill_categories"]) == 15 + assert len(manifest["supersession_coverage"]) == 30 + assert any("30.2.2" in row for row in manifest["supersession_coverage"]) + fifteen_name_disposition = b"then its own fifteen-name inventory." + assert design_raw.count(fifteen_name_disposition) == 1 + with pytest.raises( + a13.LawError, + match="mutation inventory prose disposition drift", + ): + a13._parse_amendment20_projection( + design_raw.replace( + fifteen_name_disposition, + b"then its own fourteen-name inventory.", + 1, + ) + ) + identifiers = manifest["new_identifiers"] + assert "a20_prompt_field_candidate_sets.v1" in identifiers["schema"] + assert "a20_semantic_bindings.v1" not in identifiers["schema"] + assert identifiers["identity_prefix"] == [ + "psid-prompt-field-evidence:", + "psid-prompt-field-candidate-set:", + "psid-zero-candidate-positive-group:", + "a20-lifecycle-output:", + ] + + +def test__amendment20_evidence_freeze_is_exactly_unready_not_failed(): + freeze = a13.A20_NORMATIVE_MANIFEST["amendment20_evidence_freeze"] + assert freeze == a13.A20_EVIDENCE_FREEZE + assert freeze["schema_version"] == "a20_evidence_freeze.v1" + assert freeze["amendment20_evidence_freeze_status"] == ( + "not_instantiated_a4_required_before_ratify" + ) + assert freeze["missing_reason_authority_status"] is None + assert freeze["purpose_authority_status"] is None + assert freeze["prompt_field_semantic_binding_status"] is None + assert list(freeze["expected_identity_bindings"]) == ( + a13.A20_EXPECTED_IDENTITY_NAMES + ) + assert len(a13.A20_EXPECTED_IDENTITY_NAMES) == 21 + assert set( + contract["failure_shadow_identity_name"] + for contract in a13.A20_ARM_IDENTITY_CONTRACTS.values() + ) == { + "missing_reason_failure_shadow_identity", + "purpose_failure_shadow_identity", + "prompt_field_semantic_failure_shadow_identity", + } + assert all( + value is None + for value in freeze["expected_identity_bindings"].values() + ) + assert freeze["amendment20_ratification_ready"] is False + assert ( + a13.A20_EVIDENCE_FREEZE_CONTRACT[ + "semantic_arm_pass_required_for_ratification" + ] + is False + ) + identity_contract = a13.A20_EVIDENCE_FREEZE_CONTRACT["identity_contract"] + assert identity_contract["pass_identity_keys"] == ( + a13.A20_PASS_IDENTITY_KEYS + ) + assert identity_contract["failure_shadow_identity_keys"] == ( + a13.A20_FAILURE_SHADOW_IDENTITY_KEYS + ) + assert identity_contract["nonemission_complement_identity_keys"] == ( + a13.A20_NONEMISSION_COMPLEMENT_IDENTITY_KEYS + ) + assert identity_contract["failure_nonemission_evidence_keys"] == ( + a13.A20_FAILURE_NONEMISSION_EVIDENCE_KEYS + ) + assert { + "repository_read_only", + "network_disabled", + "captured_streams", + }.isdisjoint(identity_contract["failure_nonemission_evidence_keys"]) + assert identity_contract["repository_manifest_row_keys"] == ( + a13.A20_REPOSITORY_MANIFEST_ROW_KEYS + ) + assert all( + len(contract["pass_identity_names"]) + == len(contract["forbidden_output_paths"]) + for contract in a13.A20_ARM_IDENTITY_CONTRACTS.values() + ) + assert all( + identifier in a13.A20_NEW_IDENTIFIERS["python"] + for identifier in ( + "_canonical_amendment20_repository_path", + "_read_amendment20_worktree_file", + "_reconstruct_amendment20_repository_manifest", + "_validate_amendment20_nonemission_evidence", + ) + ) + a13._validate_amendment20_evidence_freeze( + freeze, + a13.A20_EVIDENCE_FREEZE_CONTRACT, + require_ratification_ready=False, + ) + + +def test__amendment20_nonemission_provenance_mutation_is_pinned(): + mutation_raw = a13.canonical_json_bytes(list(A20_TEST_MUTATIONS)) + assert A20_TEST_MUTATIONS[-5:] == ( + "determined_as_source_underdetermined_without_ruling_forged", + "source_underdetermined_as_no_applicable_purpose_forged", + "source_underdetermined_a4_census_binding_forged", + "completed_ontology_new_arm_omitted", + "coordinate_distinct_questionnaire_spans_collapsed_to_one_body_forged", + ) + assert len(mutation_raw) == a13.A20_MUTATION_DOMAIN_BYTE_SIZE + assert hashlib.sha256(mutation_raw).hexdigest() == ( + a13.A20_MUTATION_DOMAIN_SHA256 + ) + + +def test__amendment20_completed_purpose_ontology_is_fail_closed(): + purpose = a13.A20_PURPOSE_AUTHORITY_CONTRACT + assert purpose["completed_ontology_order"] == [ + *a13.A19_OFFICIAL_PURPOSES, + "source_underdetermined", + ] + assert purpose["prompt_denominator_a4_freeze_slot"] is None + assert purpose["required_disposition_counts"] == { + "complete_official_mapping": None, + "source_underdetermined": None, + "U": 0, + } + assert purpose["source_underdetermined_count_a4_freeze_slot"] is None + assert purpose[ + "source_underdetermined_requires_reconciled_adjudication_ruling" + ] + assert purpose[ + "source_underdetermined_uses_determined_row_provenance_authentication" + ] + assert not purpose["source_underdetermined_is_no_applicable_purpose"] + assert purpose["source_backed_alternative_selected"] == ( + "ontology_projection" + ) + assert not purpose["exact_row_agreement_is_authority_gate"] + assert purpose[ + "macro_per_prompt_jaccard_minimum_calibration_diagnostic" + ] == ("90%") + r04 = a13.A20_R04_Q5_CONTRACT + assert not r04["purpose_totality_alone_passes_r04"] + assert r04["o_p_order"] == purpose["completed_ontology_order"] + assert r04["selector_purpose_domain"] == "completed_purpose_ontology" + + +def test__amendment20_c68_and_zero_candidate_probes_fail_closed(): + contract = a13.A20_PROMPT_FIELD_SEMANTIC_BINDING_CONTRACT + assert contract["collision_census"] == { + "domain": "historical_same_coordinate_leading_question_token_conflicts", + "complete_official_prompt_count": 818, + "multiple_count": 46, + } + assert ( + contract["complete_official_prompt_candidate_census"]["multiple_count"] + == 49 + ) + assert contract["full_prompt_candidate_census"] == { + "domain": "multiple_candidates_over_full_prompt_denominator", + "prompt_count": 21_971, + "multiple_count": 2_349, + } + assert contract["prompt_field_row_keys"][3] == "questionnaire_span" + assert contract["prompt_field_evidence_id_prefix"] == ( + "psid-prompt-field-evidence:" + ) + assert contract["coordinate_distinct_span_collapse_aborts"] + assert contract["c68_regression"] == { + "source_prompt_occurrence_id": ( + "psid-questionnaire-occurrence:" + "4cd66190a898d568dd20c27140f44f1dff53d229f664f537722624d00c9b4b67" + ), + "interview_wave": 1985, + "printed_direct_field_id": "V11804", + "question_token": "C68.", + "candidate_raw_field_ids": ["V11804", "V11805"], + "draft_disposition": "unresolved_multiple", + } + probe = contract["zero_candidate_grouping_probe"] + assert probe["sweep_zero_candidate_observation"] == 15_428 + assert probe["diagnostic_zero_candidate_observation"] == 14_450 + assert probe["difference_explained"] is False + assert contract["direct_identifier_priority_forbidden"] is True + assert contract["attachment_dispositions"] == [ + "accepted_exact_source_identifier", + "accepted_expressly_admitted_official_alias", + "unresolved_multiple", + ] + assert contract["prompt_field_candidate_set_row_keys"] == [ + "prompt_field_candidate_set_id", + "source_prompt_occurrence_id", + "interview_wave", + "candidate_prompt_field_evidence_ids", + "candidate_raw_field_ids", + "candidate_count", + "candidate_disposition", + ] + assert contract["prompt_field_candidate_set_dispositions"] == [ + "zero_candidates", + "one_candidate", + "multiple_candidates", + ] + assert contract["candidate_arrays_complete_stable_unique_source_order"] + assert contract["candidate_disposition_is_iff_count_partition"] + assert contract[ + "candidate_set_id_is_sha256_of_canonical_remaining_members" + ] + assert contract["candidate_set_row_ids_and_prompt_ids_unique"] + assert contract["zero_candidate_positive_group_row_keys"] == [ + "zero_candidate_positive_group_id", + "positive_occurrence_id", + "zero_candidate_source_prompt_occurrence_ids", + "all_source_prompt_occurrence_ids", + "complete_reference_union_ids", + "empty_reference_union", + "group_disposition", + ] + assert contract["zero_candidate_positive_group_dispositions"] == [ + "complete_nonempty_reference_union", + "fail_empty_reference_union", + ] + assert contract[ + "zero_candidate_group_one_per_qualifying_positive_occurrence" + ] + assert contract[ + "zero_candidate_prompt_arrays_complete_positive_row_projections" + ] + assert contract["zero_candidate_reference_union_complete_stable_unique"] + assert contract["zero_candidate_group_disposition_is_iff_empty_boolean"] + assert contract["semantic_binding_serialization"] == ( + "near_match_source_annotation_rows" + ) + assert ( + contract["separate_semantic_binding_rows_serialization_permitted"] + is False + ) + + +def test__amendment20_r06_and_lifecycle_bind_six_files_223_nodes_26_rows(): + contract = a13.A20_R06_LIFECYCLE_CONTRACT + assert ( + contract["interpreter_selector"] == "executing_process_sys.executable" + ) + assert contract["test_command_after_interpreter"][:2] == ["-m", "pytest"] + assert len(contract["test_file_identities"]) == 6 + assert contract["collected_node_id_count"] == 223 + assert contract["collection_command_after_interpreter"] == [ + "-m", + "pytest", + "--collect-only", + "-q", + *[row["path"] for row in a13.A20_R06_FILE_IDENTITIES], + ] + binding = a13._validate_amendment20_r06_collection_binding() + assert binding["command"][0] == sys.executable + assert len(binding["node_ids"]) == 223 + assert binding["node_id_array_canonical_byte_size"] == 28_268 + assert binding["node_id_array_raw_sha256"] == ( + "09071bf4d9a9a5ee8b9ccc4d8d5c0bd91705c04d3c7c99d6ef155dfdc0dfdf05" + ) + assert contract["collected_node_id_array_canonical_byte_size"] == 28_268 + assert contract["collected_node_id_array_raw_sha256"] == ( + "09071bf4d9a9a5ee8b9ccc4d8d5c0bd91705c04d3c7c99d6ef155dfdc0dfdf05" + ) + rows = contract["dormant_lifecycle_rows"] + assert len(rows) == contract["dormant_lifecycle_row_count"] == 26 + assert [row["first_add_index"] for row in rows] == list(range(1, 27)) + assert all(row["output_identity_id"] is None for row in rows) + assert all(row["selection_enabled"] is False for row in rows) + assert all(row["status"] == "dormant_definition" for row in rows) + assert rows[0]["input_identity_ids"] == [ + "revision22_registry_repin_identity", + "a20_successor_source_binding_identity", + "dormant_lifecycle_definition_identity", + ] + assert rows[3]["input_identity_ids"] == [ + "a20_r05_certificate_identity", + "r06_six_module_identity", + "r06_collected_node_id_identity", + "historical_a11_replay_identity", + ] + assert rows[4]["lifecycle_stage_id"] == ( + "A20_MISSING_REASON_SUCCESSOR_ACTIVE" + ) + assert rows[4]["input_identity_ids"] == [ + "a20_historical_r06_identity", + "missing_reason_successor_relation_identity", + ] + consumed_freeze_identities = set( + a13.A20_SOURCE_INFRASTRUCTURE_CONTRACT["successor_source_binding_keys"] + ) | {identity for row in rows for identity in row["input_identity_ids"]} + assert set(a13.A20_EXPECTED_IDENTITY_NAMES) <= consumed_freeze_identities + + +def test__amendment20_q5_shapes_replace_a19_purpose_rows_exactly(): + contract = a13.A20_R04_Q5_CONTRACT + assert contract["source_document_manifest_additions"] == [ + "a20_successor_source_binding_identity", + "missing_reason_source_domain_identity", + "purpose_source_domain_identity", + "missing_reason_rule_set_identity", + "purpose_rule_set_identity", + "prompt_field_evidence_identity", + "semantic_binding_identity", + ] + assert contract["replaced_a19_effective_header_members"] == [ + "purpose_mapping_row_count", + "purpose_mapping_keyset_sha256", + "purpose_mapping_domain_sha256", + "purpose_mapping_disposition_counts", + ] + assert contract["normal_era_successor_sequence"] == [ + "hierarchy_rows", + "purpose_authority_mapping_rows", + "prompt_field_evidence_rows", + "prompt_field_candidate_set_rows", + "zero_candidate_positive_group_rows", + "positive_occurrence_rows", + ] + assert contract["inherited_semantic_relation_member"] == ( + "near_match_source_annotation_rows" + ) + assert contract["inherited_semantic_relation_position"] == ( + "after_expanded_disposition_rows" + ) + assert ( + contract[ + "a19_purpose_mapping_is_historical_nonconsumable_on_a20_normal_path" + ] + is True + ) + + +def _a20_qualifying_verdict(design_size="1,234", receipt_size="5,678"): + return ( + "# RATIFY\n" + f"attested_design_byte_size: {design_size}\n" + f"attested_design_raw_sha256: {'a' * 64}\n" + f"attested_design_blob_oid: {'b' * 40}\n" + f"executed_transition_receipt_byte_size: {receipt_size}\n" + f"executed_transition_receipt_raw_sha256: {'c' * 64}\n" + "executed_transition_receipt_schema: executed_transition_state.v2\n" + "---\n" + ).encode() + + +def test__amendment20_qualifying_verdict_accepts_both_decimal_forms(): + for design_size, receipt_size in (("1234", "5678"), ("1,234", "5,678")): + parsed = a13.validate_amendment20_qualifying_verdict( + _a20_qualifying_verdict(design_size, receipt_size), + design_byte_size=1_234, + design_raw_sha256="a" * 64, + design_blob_oid="b" * 40, + receipt_byte_size=5_678, + receipt_raw_sha256="c" * 64, + ) + assert parsed["receipt_schema"] == "executed_transition_state.v2" + + +@pytest.mark.parametrize( + ("original", "forged"), + ( + (b"1,234", b"01,234"), + (b"1,234", b"12,34"), + (b"executed_transition_state.v2", b"executed_transition_state.v1"), + (b"# RATIFY\n", b"preface\n# RATIFY\n"), + (b"---\n", b"---\nextra\n"), + (b"a" * 64, b"A" * 64), + ), +) +def test__amendment20_qualifying_verdict_variants_fail_closed( + original, + forged, +): + raw = _a20_qualifying_verdict() + assert raw.count(original) == 1 + with pytest.raises(a13.LawError): + a13.validate_amendment20_qualifying_verdict( + raw.replace(original, forged, 1), + design_byte_size=1_234, + design_raw_sha256="a" * 64, + design_blob_oid="b" * 40, + receipt_byte_size=5_678, + receipt_raw_sha256="c" * 64, + ) + + +def test__amendment20_historical_receipt_uses_a20_design_at_revision23( + monkeypatch, +): + historical_design = (ROOT / a13.DESIGN_PATH).read_bytes() + historical_sha256 = hashlib.sha256(historical_design).hexdigest() + historical_blob_oid = a13._git_blob_oid(historical_design) + historical_commit = "c" * 40 + receipt = { + "simulated_state_manifest": { + "candidate_commit_identity": {"commit": historical_commit} + } + } + receipt_raw = a13.canonical_json_bytes(receipt) + verdict_raw = ( + "# RATIFY\n" + f"attested_design_byte_size: {len(historical_design)}\n" + f"attested_design_raw_sha256: {historical_sha256}\n" + f"attested_design_blob_oid: {historical_blob_oid}\n" + f"executed_transition_receipt_byte_size: {len(receipt_raw)}\n" + "executed_transition_receipt_raw_sha256: " + f"{hashlib.sha256(receipt_raw).hexdigest()}\n" + "executed_transition_receipt_schema: executed_transition_state.v2\n" + "---\n" + ).encode() + verdict_paths = [ + "docs/analysis/amendment_20_ratification/" + "sol-ce-amend20-r1-verdict.md", + "docs/analysis/amendment_20_ratification/" + "sol-ce-amend20-r1b-verdict.md", + ] + closure = { + "amendment_number": 20, + "attested_candidate_design_blob_oid": historical_blob_oid, + "attested_candidate_design_byte_size": len(historical_design), + "attested_candidate_design_raw_sha256": historical_sha256, + "operator_merge_commit": historical_commit, + "ratification_commit": historical_commit, + "ratification_commit_sole_parent": "d" * 40, + "verdict_artifacts": [ + { + "path": path, + "byte_size": len(verdict_raw), + "raw_sha256": hashlib.sha256(verdict_raw).hexdigest(), + } + for path in verdict_paths + ], + } + closure_raw = a13.canonical_json_bytes(closure) + closure_binding = a13._closure_binding( + a13._ratification_closure_path(20), closure_raw + ) + revision23_context = _synthetic_registry_context(23) + revision23_context["ratification_closures"][20 - 13] = closure_binding + assert revision23_context["ratification_commit"] != historical_commit + assert revision23_context["blob_sha256"] != historical_sha256 + + receipt_validations = [] + design_validations = [] + monkeypatch.setattr( + a13, + "_validate_amendment20_transition_receipt", + lambda value: receipt_validations.append(copy.deepcopy(value)) + or value, + ) + monkeypatch.setattr( + a13, + "_validate_amendment20_ratification_design", + lambda raw: design_validations.append(raw), + ) + + def fake_git(*arguments, text=False): + assert arguments == ( + "show", + f"{historical_commit}:{a13.DESIGN_PATH}", + ) + assert text is False + return historical_design + + monkeypatch.setattr(a13, "_git", fake_git) + validated = a13._validate_ratification_closure( + closure_raw, + closure_binding, + {path: verdict_raw for path in verdict_paths}, + 20, + verify_git=False, + ratification_design_raw=historical_design, + registry_design_binding=revision23_context, + amendment20_transition_receipt_raw=receipt_raw, + ) + assert validated == closure + assert receipt_validations == [receipt] + assert design_validations == [historical_design] + + +def test__amendment20_standin_is_distinct_and_never_qualifying(monkeypatch): + standin = ( + "# RATIFY\n" + "attested_design_byte_size: 1,234\n" + f"attested_design_raw_sha256: {'a' * 64}\n" + f"attested_design_blob_oid: {'b' * 40}\n" + "executed_transition_receipt_status: pending_same_state_execution\n" + "simulation_context: amendment20_same_state_nonauthority_v1\n" + "---\n" + ).encode() + parsed = a13._validate_amendment20_simulated_standin( + standin, + design_byte_size=1_234, + design_raw_sha256="a" * 64, + design_blob_oid="b" * 40, + ) + assert parsed["executed_transition_receipt_status"] == ( + "pending_same_state_execution" + ) + with pytest.raises(a13.LawError): + a13.validate_amendment20_qualifying_verdict( + standin, + design_byte_size=1_234, + design_raw_sha256="a" * 64, + design_blob_oid="b" * 40, + receipt_byte_size=5_678, + receipt_raw_sha256="c" * 64, + ) + + verdict_paths = a13.A20_RECEIPT_SCHEMA["expected_changed_paths"][:2] + closure = { + "amendment_number": 20, + "attested_candidate_design_blob_oid": "b" * 40, + "attested_candidate_design_byte_size": 1_234, + "attested_candidate_design_raw_sha256": "a" * 64, + "operator_merge_commit": "d" * 40, + "ratification_commit": "d" * 40, + "ratification_commit_sole_parent": "e" * 40, + "verdict_artifacts": [ + { + "path": path, + "byte_size": len(standin), + "raw_sha256": hashlib.sha256(standin).hexdigest(), + } + for path in verdict_paths + ], + } + closure_raw = a13.canonical_json_bytes(closure) + context = _synthetic_registry_context(22) + context["ratification_closures"][-1] = { + "path": a13._ratification_closure_path(20), + "raw_byte_size": len(closure_raw), + "raw_sha256": hashlib.sha256(closure_raw).hexdigest(), + } + reads = { + a13._ratification_closure_path(20): closure_raw, + **{path: standin for path in verdict_paths}, + } + monkeypatch.setattr( + a13, + "_read_public_repository_file", + lambda path, label, require_regular_mode: reads[path], + ) + calls = [] + monkeypatch.setattr( + a13, + "_validate_amendment20_scratch_transition_context", + lambda verdicts: calls.append(dict(verdicts)) + or {"registry_binding": context, "closure": closure}, + ) + assert a13._validate_public_ratification_closure(20, context) == closure + assert calls == [{path: standin for path in verdict_paths}] + + +def test__amendment20_receipt_v2_changed_path_identity_is_exact(): + paths = a13.A20_RECEIPT_SCHEMA["expected_changed_paths"] + raw = a13.canonical_json_bytes(paths) + assert len(paths) == 4 + assert len(raw) == 260 + assert hashlib.sha256(raw).hexdigest() == ( + "5a7912498c4d959fef337f2a1d1cf85a2f254fa29d825d365ccf4fe214ad48a7" + ) + assert a13.A20_RECEIPT_SCHEMA["manifest_schema_version"] == ( + "executed_transition_state.v2" + ) + assert "candidate_or_scratch_HEAD" not in ( + a13.A20_RECEIPT_SCHEMA["manifest_keys"] + ) + receipt_contract = a13.A20_RATIFICATION_RECEIPT_CONTRACT + assert receipt_contract["amendment20_external_receipt_path"] == ( + "docs/analysis/amendment_20_ratification/" + "executed_transition_receipt_v2.json" + ) + assert receipt_contract["external_receipt_mode"] == "100644" + assert receipt_contract["external_receipt_candidate_ancestry_not_required"] + assert receipt_contract[ + "receipt_candidate_design_exactly_cross_binds_historical_a20_closure_and_verdicts" + ] + assert receipt_contract[ + "current_terminal_registry_cross_binding_required_iff_a20_terminal_revision22" + ] + assert receipt_contract[ + "later_revision_authenticates_historical_a20_design_under_30_2_3" + ] + + +def _synthetic_a20_receipt_v2(): + candidate = "c" * 40 + scratch = "d" * 40 + paths = list(a13.A20_RECEIPT_SCHEMA["expected_changed_paths"]) + candidate_raw = b"synthetic Amendment-20 candidate\n" + test_path = "tests/test_validate_amendment13_execution_law.py" + test_raw = b"synthetic pinned test\n" + test_blob = a13._git_blob_oid(test_raw) + pins = { + "mode": "100644", + "files": [ + { + "path": test_path, + "blob_oid": test_blob, + "byte_size": len(test_raw), + "sha256": hashlib.sha256(test_raw).hexdigest(), + } + ], + } + standin = ( + "# RATIFY\n" + f"attested_design_byte_size: {len(candidate_raw)}\n" + "attested_design_raw_sha256: " + f"{hashlib.sha256(candidate_raw).hexdigest()}\n" + f"attested_design_blob_oid: {a13._git_blob_oid(candidate_raw)}\n" + "executed_transition_receipt_status: pending_same_state_execution\n" + "simulation_context: amendment20_same_state_nonauthority_v1\n" + "---\n" + ).encode() + closure_raws = { + a13._ratification_closure_path(amendment_number): ( + f"synthetic closure {amendment_number}\n".encode() + ) + for amendment_number in range(13, 20) + } + synthetic_closure = { + "amendment_number": 20, + "attested_candidate_design_blob_oid": a13._git_blob_oid(candidate_raw), + "attested_candidate_design_byte_size": len(candidate_raw), + "attested_candidate_design_raw_sha256": hashlib.sha256( + candidate_raw + ).hexdigest(), + "ratification_commit": candidate, + "ratification_commit_sole_parent": "e" * 40, + "operator_merge_commit": candidate, + "verdict_artifacts": [ + { + "path": path, + "byte_size": len(standin), + "raw_sha256": hashlib.sha256(standin).hexdigest(), + } + for path in paths[:2] + ], + } + closure_raws[a13._ratification_closure_path(20)] = ( + a13.canonical_json_bytes(synthetic_closure) + ) + closure_identities = [ + { + "path": path, + "raw_byte_size": len(raw), + "raw_sha256": hashlib.sha256(raw).hexdigest(), + "git_blob": a13._git_blob_oid(raw), + } + for path, raw in closure_raws.items() + ] + registry_binding = { + "path": a13.DESIGN_PATH, + "ratification_commit": candidate, + "revision": 22, + "blob_sha256": hashlib.sha256(candidate_raw).hexdigest(), + "ratification_closures": [ + { + "path": row["path"], + "raw_byte_size": row["raw_byte_size"], + "raw_sha256": row["raw_sha256"], + } + for row in closure_identities + ], + } + registry_behavior = ( + "\ndef design_binding():\n" + " return {\n" + " 'path': DESIGN_PATH,\n" + " 'ratification_commit': DESIGN_RATIFICATION_COMMIT,\n" + " 'revision': DESIGN_REVISION,\n" + " 'blob_sha256': DESIGN_BLOB_SHA256,\n" + " 'ratification_closures': [\n" + " dict(row) for row in RATIFICATION_CLOSURE_BINDINGS\n" + " ],\n" + " }\n" + ) + candidate_registry_raw = ( + f"DESIGN_PATH = {a13.DESIGN_PATH!r}\n" + "DESIGN_RATIFICATION_COMMIT = 'production-revision-21'\n" + "DESIGN_REVISION = 21\n" + "DESIGN_BYTE_SIZE = 1\n" + "DESIGN_BLOB_SHA256 = 'production-revision-21'\n" + "RATIFICATION_CLOSURE_BINDINGS = ()\n" + f"{registry_behavior}" + ).encode() + scratch_registry_raw = ( + f"DESIGN_PATH = {a13.DESIGN_PATH!r}\n" + f"DESIGN_RATIFICATION_COMMIT = {candidate!r}\n" + "DESIGN_REVISION = 22\n" + f"DESIGN_BYTE_SIZE = {len(candidate_raw)}\n" + "DESIGN_BLOB_SHA256 = " + f"{hashlib.sha256(candidate_raw).hexdigest()!r}\n" + "RATIFICATION_CLOSURE_BINDINGS = " + f"{tuple(registry_binding['ratification_closures'])!r}\n" + "SIMULATED_STATE_AUTHORITY = 'NONAUTHORITY'\n" + "SIMULATION_CONTEXT = " + "'amendment20_same_state_nonauthority_v1'\n" + f"{registry_behavior}" + ).encode() + scratch_raws = { + paths[0]: standin, + paths[1]: standin, + paths[3]: scratch_registry_raw, + } + test_identity = { + "path": test_path, + "mode": "100644", + "git_blob": test_blob, + "raw_byte_size": len(test_raw), + "raw_sha256": hashlib.sha256(test_raw).hexdigest(), + } + manifest = { + "schema_version": "executed_transition_state.v2", + "simulated_state_authority": "NONAUTHORITY", + "candidate_commit_identity": { + "commit": candidate, + "tree": "a" * 40, + "sole_parent": "e" * 40, + }, + "scratch_transition": { + "commit": scratch, + "tree": "b" * 40, + "sole_parent": candidate, + "changed_paths": paths, + "changed_path_domain_sha256": ( + a13.A20_RECEIPT_SCHEMA["expected_changed_path_domain_sha256"] + ), + }, + "terminal_revision": 22, + "canonical_registry_binding": registry_binding, + "ordered_closure_identities": closure_identities, + "full_pinned_battery_test_identity": test_identity, + } + state_identity = hashlib.sha256( + a13.canonical_json_bytes(manifest) + ).hexdigest() + receipt = { + "simulated_state_authority": "NONAUTHORITY", + "simulated_state_identity_sha256": state_identity, + "simulated_state_manifest": manifest, + "terminal_revision": 22, + "public_oracle": { + "entrypoint": "validate_ratification_operativity", + "executed": True, + "exit_code": 0, + "operative_amendments": list(range(13, 21)), + "simulated_state_identity_sha256": state_identity, + }, + "full_pinned_battery": { + "executed": True, + "exit_code": 0, + "test_path": test_path, + "test_mode_blob_bytes_sha256": test_identity, + "exact_command": a13.A20_FULL_PINNED_BATTERY_COMMAND, + "collected": a13.A20_FULL_PINNED_BATTERY_COLLECTED, + "passed": a13.A20_FULL_PINNED_BATTERY_COLLECTED, + "failed": 0, + "skipped": 0, + "deselected": 0, + "xfailed": 0, + "xpassed": 0, + "simulated_state_identity_sha256": state_identity, + }, + } + return ( + receipt, + candidate_raw, + test_raw, + pins, + closure_raws, + candidate_registry_raw, + scratch_raws, + ) + + +def test__amendment20_receipt_v2_rederives_both_git_identities(monkeypatch): + ( + receipt, + candidate_raw, + test_raw, + pins, + closure_raws, + candidate_registry_raw, + scratch_raws, + ) = _synthetic_a20_receipt_v2() + candidate = "c" * 40 + scratch = "d" * 40 + paths = a13.A20_RECEIPT_SCHEMA["expected_changed_paths"] + monkeypatch.setattr( + a13, + "A20_PRODUCTION_REGISTRY_IDENTITY", + { + "path": "scripts/covered_earnings_correction_registry.py", + "mode": "100644", + "git_blob": a13._git_blob_oid(candidate_registry_raw), + "byte_size": len(candidate_registry_raw), + "raw_sha256": hashlib.sha256(candidate_registry_raw).hexdigest(), + }, + ) + + def fake_git(*arguments, text=False): + if arguments[:3] == ("rev-list", "--parents", "-n"): + assert text is True + commit = arguments[-1] + if commit == candidate: + return f"{candidate} {'e' * 40}\n" + return f"{scratch} {candidate}\n" + if arguments[:1] == ("rev-parse",): + assert text is True + return ( + ("a" * 40 + "\n") + if candidate in arguments[1] + else ("b" * 40 + "\n") + ) + if arguments[:1] == ("diff-tree",): + assert text is True + return "\n".join(reversed(paths)) + "\n" + if arguments[:1] == ("for-each-ref",): + assert text is True + return "" + if arguments[:1] == ("log",): + assert text is True + path = arguments[-1] + return ( + ("1" * 40 + "\n") + if path == a13.A20_EXECUTED_TRANSITION_RECEIPT_PATH + else ("2" * 40 + "\n") + ) + if arguments[:1] == ("show",): + assert text is False + specification = arguments[1] + _, path = specification.split(":", 1) + if path == a13.DESIGN_PATH: + return candidate_raw + if path == "tests/test_validate_amendment13_execution_law.py": + return test_raw + if ( + path == "scripts/covered_earnings_correction_registry.py" + and specification.startswith(f"{candidate}:") + ): + return candidate_registry_raw + if path in closure_raws: + return closure_raws[path] + return scratch_raws[path] + if arguments[:1] == ("ls-tree",): + assert text is True + commit, path = arguments[1], arguments[-1] + if commit == candidate: + if path == a13.DESIGN_PATH: + return ( + f"100644 blob {a13._git_blob_oid(candidate_raw)}" + f"\t{path}\n" + ) + row = pins["files"][0] + if path == row["path"]: + return f"100644 blob {row['blob_oid']}\t{path}\n" + return ( + "100644 blob " + f"{a13._git_blob_oid(candidate_registry_raw)}\t{path}\n" + ) + raw = closure_raws.get(path, scratch_raws.get(path)) + assert raw is not None + return f"100644 blob {a13._git_blob_oid(raw)}\t{path}\n" + raise AssertionError(arguments) + + monkeypatch.setattr(a13, "_git", fake_git) + + def fake_run_git(*arguments, **kwargs): + return_code = 1 + if arguments[:2] == ("merge-base", "--is-ancestor") and arguments[ + -2: + ] == ("1" * 40, "2" * 40): + return_code = 0 + return subprocess.CompletedProcess( + arguments, + return_code, + stdout=b"", + stderr=b"", + ) + + monkeypatch.setattr(a13, "_run_git", fake_run_git) + monkeypatch.setattr( + a13, + "_read_public_repository_file", + lambda path, label, require_regular_mode: a13.canonical_json_bytes( + receipt + ), + ) + monkeypatch.setattr( + a13, + "_validate_registry_ratification_context", + lambda binding: dict(binding), + ) + monkeypatch.setattr( + a13, + "_validate_amendment20_ratification_design", + lambda raw: None, + ) + monkeypatch.setattr( + a13, + "_parse_amendment20_implementation_pins", + lambda raw: pins, + ) + assert a13._validate_amendment20_transition_receipt(receipt) == receipt + registry_path = "scripts/covered_earnings_correction_registry.py" + valid_scratch_registry = scratch_raws[registry_path] + scratch_raws[registry_path] = valid_scratch_registry.replace( + b" 'revision': DESIGN_REVISION,\n", + b" 'revision': 999,\n", + 1, + ) + with pytest.raises( + a13.LawError, + match="scratch registry behavior differs from candidate", + ): + a13._validate_amendment20_transition_receipt(receipt) + scratch_raws[registry_path] = valid_scratch_registry + for forged_candidate_registry in ( + candidate_registry_raw + b"DESIGN_REVISION = 21\n", + candidate_registry_raw.replace( + b"DESIGN_REVISION = 21\n", + b"DESIGN_REVISION = int('21')\n", + 1, + ), + ): + with pytest.raises( + a13.LawError, + match="scratch registry behavior differs from candidate", + ): + a13._parse_amendment20_scratch_registry_binding( + valid_scratch_registry, + candidate_raw=forged_candidate_registry, + ) + with pytest.raises( + a13.LawError, + match="mutates a closed binding name", + ): + a13._parse_amendment20_scratch_registry_binding( + valid_scratch_registry + b"DESIGN_REVISION += 1\n", + candidate_raw=candidate_registry_raw + b"DESIGN_REVISION += 1\n", + ) + forged = copy.deepcopy(receipt) + forged["simulated_state_manifest"]["candidate_commit_identity"]["tree"] = ( + "f" * 40 + ) + forged["simulated_state_identity_sha256"] = hashlib.sha256( + a13.canonical_json_bytes(forged["simulated_state_manifest"]) + ).hexdigest() + monkeypatch.setattr( + a13, + "_read_public_repository_file", + lambda path, label, require_regular_mode: a13.canonical_json_bytes( + forged + ), + ) + with pytest.raises( + a13.LawError, + match="Git-resolved C/S identity drift", + ): + a13._validate_amendment20_transition_receipt(forged) + + +def test__amendment20_mutations_run_only_after_inherited_116(monkeypatch): + calls = [] + + def inherited(): + calls.append("inherited") + return a13.A19_EXPECTED_MUTATIONS + + monkeypatch.setattr( + a13, + "run_amendment19_member_law_mutation_tests", + inherited, + ) + monkeypatch.setattr( + a13, + "_validate_amendment20_r06_collection_binding", + lambda: calls.append("r06") or {}, + ) + rejected = a13.run_amendment20_contract_mutation_tests() + assert calls == ["inherited", "r06"] + assert rejected == a13.A20_EXPECTED_MUTATIONS == A20_TEST_MUTATIONS + assert ( + sum(row["count"] for row in a13.A20_INHERITED_MUTATION_CENSUSES) == 116 + ) + raw = a13.canonical_json_bytes(list(rejected)) + assert len(raw) == a13.A20_MUTATION_DOMAIN_BYTE_SIZE + assert hashlib.sha256(raw).hexdigest() == (a13.A20_MUTATION_DOMAIN_SHA256) + + def test__mutation_inventory__is_separate_and_exact( rejected_mutations, rejected_enforcement_mutations, @@ -3786,7 +4971,7 @@ def test__document__preserves_revision19_as_exact_prefix(): assert raw.count(a13.AMENDMENT18_BOUNDARY) == 1 -def test__document__preserves_revision20_a18_prefix_and_exact_a19_suffix(): +def test__document__preserves_revision20_and_exact_revision21_prefix(): raw = (ROOT / a13.DESIGN_PATH).read_bytes() revision20 = raw[: a13.REVISION20_BYTE_SIZE] enacted_revision20 = a13._git("cat-file", "blob", a13.REVISION20_BLOB_OID) @@ -3802,12 +4987,18 @@ def test__document__preserves_revision20_a18_prefix_and_exact_a19_suffix(): assert len(revision20) == a13.REVISION20_BYTE_SIZE assert hashlib.sha256(revision20).hexdigest() == a13.REVISION20_SHA256 assert a13._git_blob_oid(revision20) == a13.REVISION20_BLOB_OID - suffix = raw[a13.REVISION20_BYTE_SIZE :] + revision21 = raw[: a13.REVISION21_BYTE_SIZE] + suffix = revision21[a13.REVISION20_BYTE_SIZE :] assert suffix.startswith(a13.AMENDMENT19_BOUNDARY) assert raw.count(a13.AMENDMENT19_BOUNDARY) == 1 assert suffix.endswith(b"\n") - assert a13._terminal_design_amendment(raw) == 19 - projection = a13._parse_amendment19_projection(raw) + assert len(revision21) == 4_025_587 == a13.REVISION21_BYTE_SIZE + assert hashlib.sha256(revision21).hexdigest() == a13.REVISION21_SHA256 + assert a13._git_blob_oid(revision21) == a13.REVISION21_BLOB_OID + assert raw[a13.REVISION21_BYTE_SIZE :].startswith(a13.AMENDMENT20_BOUNDARY) + assert raw.count(a13.AMENDMENT20_BOUNDARY) == 1 + assert a13._terminal_design_amendment(raw) == 20 + projection = a13._parse_amendment19_projection(revision21) assert projection["section_semantic_sha256"] == ( a13.A19_SECTION_SEMANTIC_SHA256 ) diff --git a/tests/tier_counts.json b/tests/tier_counts.json index 71769153..7f49c590 100644 --- a/tests/tier_counts.json +++ b/tests/tier_counts.json @@ -2,7 +2,7 @@ "schema_version": 1, "counts": { "unit": 1563, - "artifact": 2668, + "artifact": 2687, "integration_psid": 848, "reproduction_legacy": 520, "oracle_policyengine": 159