Finding
Canonical Selection Outcome Monitoring evidence is issuance-sealed by HMAC over canonical JSON, but the current export path treats equality of serialized bytes as sufficient post-issuance runtime integrity.
At exact owner head ec35dc87d6be4f44a2c7b44311fa8c89bb080fb3, construction correctly rejects caller-defined str subclasses. After issuance, however, object.__setattr__ can replace an exact built-in text field with a behavior-bearing str subclass carrying the same underlying text. _canonical_plan_json_unchecked(...) serializes that subclass to the same JSON bytes, so the HMAC comparison can still succeed. The live packet therefore retains executable caller-owned runtime state even though the canonical bytes are unchanged. The same class of representation-preserving alias applies to exact date evidence if a post-issuance subclass can reach .isoformat() before an exact-type gate.
This is distinct from the already-covered value-changing tamper case: changing population_snapshot_digest from a…a to f…f changes bytes and is rejected today. The missing regression is same canonical value, different executable runtime type.
Canonical owner / constraints
PR #42 (feat/selection-outcome-monitoring-plan) is the existing Selection Monitoring writer and is already based on protected develop@eb9757f8649aaad026a9865508d9aad50c1a7a4f. Repair there; do not create a second package owner.
Preserve aggregate-only scope, protected-attribute/small-sample/statistical-plan provenance, human-only consequential authority, exact 100% statement/branch coverage, current #258/#259 Foundation dependency order, and all existing privacy/issuance regressions. Do not weaken the process-local seal or accept mutable/subclass evidence merely because canonical bytes are unchanged.
Test-first acceptance
- Add an immutable RED regression that issues a valid plan, replaces at least one trust-bearing exact string with a
str subclass carrying identical text, and proves current canonical_json() incorrectly succeeds before repair.
- The repaired canonical export must fail closed on representation-preserving runtime aliases before invoking caller-controlled methods/comparisons.
- Cover exact-string trust fields and exact
date/UTC datetime/integer/boolean runtime types consumed by canonical export; valid issued plans must preserve byte-for-byte canonical JSON and SHA-256 behavior.
- Keep serialization output/schema and public builder contract unchanged for valid inputs.
- Obtain exact-head Foundation/Selection Monitoring coverage/security/review evidence on the successor; predecessor checks do not transfer.
This is a runtime-integrity repair, not a statistical-method or employment-decision authority expansion.
Finding
Canonical Selection Outcome Monitoring evidence is issuance-sealed by HMAC over canonical JSON, but the current export path treats equality of serialized bytes as sufficient post-issuance runtime integrity.
At exact owner head
ec35dc87d6be4f44a2c7b44311fa8c89bb080fb3, construction correctly rejects caller-definedstrsubclasses. After issuance, however,object.__setattr__can replace an exact built-in text field with a behavior-bearingstrsubclass carrying the same underlying text._canonical_plan_json_unchecked(...)serializes that subclass to the same JSON bytes, so the HMAC comparison can still succeed. The live packet therefore retains executable caller-owned runtime state even though the canonical bytes are unchanged. The same class of representation-preserving alias applies to exactdateevidence if a post-issuance subclass can reach.isoformat()before an exact-type gate.This is distinct from the already-covered value-changing tamper case: changing
population_snapshot_digestfroma…atof…fchanges bytes and is rejected today. The missing regression is same canonical value, different executable runtime type.Canonical owner / constraints
PR #42 (
feat/selection-outcome-monitoring-plan) is the existing Selection Monitoring writer and is already based on protecteddevelop@eb9757f8649aaad026a9865508d9aad50c1a7a4f. Repair there; do not create a second package owner.Preserve aggregate-only scope, protected-attribute/small-sample/statistical-plan provenance, human-only consequential authority, exact 100% statement/branch coverage, current #258/#259 Foundation dependency order, and all existing privacy/issuance regressions. Do not weaken the process-local seal or accept mutable/subclass evidence merely because canonical bytes are unchanged.
Test-first acceptance
strsubclass carrying identical text, and proves currentcanonical_json()incorrectly succeeds before repair.date/UTCdatetime/integer/boolean runtime types consumed by canonical export; valid issued plans must preserve byte-for-byte canonical JSON and SHA-256 behavior.This is a runtime-integrity repair, not a statistical-method or employment-decision authority expansion.