Repository navigation
fix(organization): reject same-instant datetime replacement after hierarchy-review issuance #291
Description
Finding
Canonical owner is PR #96 (feat/organization-hierarchy-change-review). Exact predecessor under review: 70212e6e00e0e3c0104b2444aadd7ac01880847b on protected develop@eb9757f8649aaad026a9865508d9aad50c1a7a4f.
#290 correctly rejects caller-defined nested tzinfo before Python datetime equality can execute attacker-controlled behavior. A narrower representation-integrity gap remains for exact built-in datetimes: Python aware-datetime equality compares instants, so 2026-08-23T16:00:00+09:00 == 2026-08-23T07:00:00+00:00. Both values have exact built-in datetime and exact built-in timezone runtime types. After issuance, low-level object.__setattr__ can therefore replace the retained recorded_at with a different built-in datetime object representing the same instant. The current #96 state_matches_issuance(...) accepts that replacement because its nested timezone-type guard passes and current_value != issuance_value is false, after which canonical_json() returns the original sealed bytes.
This contradicts ADR 0096's current process-local contract that canonical export rejects changed live state against the closure-private issuance state. It does not create a different canonical instant or execute caller code; it is a narrower structural representation substitution within the already-claimed post-issuance integrity boundary.
Required repair
- Add a test-first regression issuing a valid fixed-offset
recorded_at, replacing it after issuance with a different exact built-in datetime object for the same instant under another exact built-in fixed offset, and requiringcanonical_json()to fail closed. - Apply the minimum causal repair inside the closure-bound state comparison. For
datetime, after the existing exact type and nested built-in-timezone check, require the retained object to be the exact immutable datetime object captured at issuance rather than using instant-based datetime equality. Do not broaden this into arbitrary object-identity semantics for other inert primitives. - Preserve fix(organization): reject nested timezone behavior before hierarchy-review export comparison #290's zero-callback guarantee for caller-defined
tzinfo, all fix(organization): seal post-issuance export representation and snapshot consistency #279–fix(organization): reject nested timezone behavior before hierarchy-review export comparison #290 invariants, valid fixed-offset construction/canonical UTC export, and exact owned statement/branch coverage at 100%. - Keep ADR 0096, hierarchy-review TRACEABILITY, package README and CHANGELOG code-current. Hand the durable representation principle to docs: maintain durable product-technical gap baseline #100 instead of competing for
docs/product-technical-gap-baseline.md. - Reacquire exact-head Foundation/security/SAST/CodeQL/model-backed evidence. Predecessor verdicts do not transfer.
- feat(core): apply reviewed Organization hierarchy changes #119 remains the durable authority for same-tenant hierarchy re-resolution, concurrency, authoritative system/audit clock, immutable persistence, audit/outbox and mutation after normal feat(core): add governed Organization hierarchy-change review #96 protected integration.
No force push, destructive rebase, self-approval, routine administrator bypass, gate weakening, mutable sibling-source copy, premature Close, or merge is authorized.
Activity
seonghobae commentedon Sep 10, 2026
Execution evidence for the canonical #96 lane:
70212e6e00e0e3c0104b2444aadd7ac01880847b:state_matches_issuance(...)accepts exact built-in datetime/timezone types and then uses aware-datetime value inequality. Python treats2026-08-23T16:00:00+09:00and2026-08-23T07:00:00+00:00as equal instants, so a low-level post-issuance replacement by the second distinct built-in datetime escapes the existing live-state comparison even though ADR 0096 says changed retained state must fail closed.4bf2c1411d19ce60099948ec9ce9d97c31af6ab8addstest_datetime_representation_integrity.py::test_export_rejects_same_instant_different_datetime_representation. No hosted RED is claimed: no PR workflow had materialized for that test-only head before the causal source commit.1d5f423f3ff3c654dc6dfc6d896ab024c92b9045changes onlystate_matches_issuance(...). After exact-type and fix(organization): reject nested timezone behavior before hierarchy-review export comparison #290 nested-timezone validation, exact built-in datetimes must be the same immutable object captured in closure-private issuance state; the comparison thencontinues without entering Python datetime instant equality. Other inert primitive values retain exact-type/value comparison.4bf2c14... → 1d5f423...is one ordinary commit changing onlyreview.py(+11/-8).60d203d9..., README5e35c3ab..., TRACEABILITY70615f59..., and ADR 0096f2c6e70e...now describe the same narrow representation boundary and keep feat(core): apply reviewed Organization hierarchy changes #119's durable clock/mutation authority unchanged.Current #96 exact head is
f2c6e70edcf5c62ae0f848c29efd7bd3b8d45b97. Predecessor workflow conclusions do not transfer. Keep #291 open until exact-head hosted evidence is admissible and #96 integrates normally.seonghobae commentedon Sep 10, 2026
Current-owner acceptance update: canonical PR #96 is exact
f2c6e70edcf5c62ae0f848c29efd7bd3b8d45b97. Foundation34441833963/102758308481completed SUCCESS on this exact head, including the installed-artifact hierarchy-review contract, owned unit/service contracts, isolated PostgreSQL contracts and read-only validation. SAST34441834059is also SUCCESS. The same-instant datetime representation repair and its docs therefore have current-head hosted owner-code evidence; predecessor GREEN is not being transferred.Issue #291 remains open because full integration acceptance is not satisfied. Security
34441833987is FAILURE only on the central public Dependency Review HTTP-403 availability incident (.github#810, current canary5613994010). CodeQL34441833995is non-passing because both compatibility consumers have already failed while its producer-dispatch job remains queued (.github#2040, current canary5613996039). Current-head Noema and Strix remain in progress at contextual-orchestrator sidecar provisioning. There is still no qualifying independentAPPROVEDreview. Do not close until the unchanged integrating head has admissible required-workflow evidence and normal protected integration (or a verified successor completely inherits this delta).seonghobae commentedon Sep 10, 2026
Fresh current-owner acceptance correction for unchanged canonical
#96@f2c6e70edcf5c62ae0f848c29efd7bd3b8d45b97on protecteddevelop@eb9757f8649aaad026a9865508d9aad50c1a7a4f:34441833963/102758308481: SUCCESS on the exact head.34441834059: SUCCESS.34441832326/102761043453: SUCCESS; the review job completed at2026-09-10T06:10:30Zafter exact-head admission and contextual-orchestrator provisioning.34441832410/102760977777: workflow/job SUCCESS, completed at2026-09-10T06:21:12Z, but the uploaded terminal evidence is non-authorizing under canonical.github#891: the exact-head artifact regressed to a generic/template no-finding report and lacks the machine-readable repository/PR/head/live-base/materialized-scope/finding-set terminal receipt required by that owner contract. GitHub success conclusion alone is not clean-security evidence.34441833987: FAILURE at the central public Dependency Review HTTP-403 availability boundary;.github#810remains open and explicitly requires a future unchanged-head HTTP-200 comparison plus actual pinned Dependency Review execution.34441833995: FAILURE on the central producer/consumer settlement-ordering defect;.github#2040remains open and its actual owner branch is still based on stale central protected truth.APPROVEDreview.The #291 source/docs repair therefore has exact-head Foundation/SAST/Noema evidence, but the integrating head is still not admissible for merge because Security, CodeQL, Strix provenance, and independent-review governance remain unsatisfied. Keep #291 open through normal protected integration; do not transfer predecessor evidence, self-approve, use routine administrator bypass, or add a leaf workflow workaround.