Skip to content

fix(organization): reject nested timezone behavior before hierarchy-review export comparison #290

Open

Description

@seonghobae

Finding

Canonical owner is PR #96 (feat/organization-hierarchy-change-review). Exact predecessor under review: 6573a6293db49632c525f0979973377869b4817c on protected develop@eb9757f8649aaad026a9865508d9aad50c1a7a4f.

The process-local post-issuance integrity check still has one narrower nested-runtime gap. canonical_json() captures direct slot values and state_matches_issuance(...) verifies that each outer runtime type matches the issuance snapshot before evaluating current_value != issuance_value. For recorded_at, however, an exact built-in datetime may retain a caller-defined tzinfo. After issuance, low-level object.__setattr__ can replace recorded_at with another exact built-in datetime whose nested timezone object has executable utcoffset() behavior. The outer type check passes and Python datetime equality invokes that nested caller-owned behavior before the export boundary fails closed.

A source-level counterexample against the predecessor confirms that comparing such a substituted datetime with the issued built-in-UTC datetime executes the custom utcoffset() implementation. This is not a durable authorization or Python-sandbox claim; it is a checked-versus-used nested representation defect inside #96's stated process-local defense-in-depth boundary.

Required repair

  1. Add a test-first regression that substitutes an exact built-in datetime carrying an executable custom tzinfo after issuance, calls canonical_json(), requires the packet to fail closed, and proves the custom timezone callback was never invoked.
  2. Apply the minimum causal source fix in the closure-bound export comparison: before datetime equality, require both current and issued tzinfo objects to have the exact built-in fixed-offset timezone runtime type captured by the packet runtime. Do not reopen mutable module bindings and do not claim protection against deliberate closure/default/global/native-memory mutation.
  3. Preserve valid canonical JSON behavior, one-snapshot issuance/export, single-use issuance, digest verification, all fix(organization): seal post-issuance export representation and snapshot consistency #279–fix(organization): bind hierarchy-review transitive validation authority #289 invariants, and exact owned statement/branch coverage at 100%.
  4. Keep ADR 0096, hierarchy-review TRACEABILITY, package README and CHANGELOG code-current. Hand the durable nested-runtime principle to docs: maintain durable product-technical gap baseline #100 rather than editing docs/product-technical-gap-baseline.md from this lane.
  5. Reacquire exact-head Foundation/security/SAST/CodeQL/model-backed evidence after the repair. Predecessor checks do not transfer.
  6. feat(core): apply reviewed Organization hierarchy changes #119 continues to own durable same-tenant re-resolution, concurrency, authoritative system/audit clock, immutable persistence, audit/outbox and mutation authority 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 or premature Close/merge is authorized.

Activity

  1. seonghobae commented on Sep 10, 2026

    @seonghobae
    ContributorAuthor

    Execution evidence for the canonical #96 lane:

    • Source-level RED was reproduced against predecessor 6573a6293db49632c525f0979973377869b4817c: an exact built-in datetime carrying caller-defined tzinfo passes the outer type check and Python datetime inequality invokes the custom utcoffset() before the export verifier can fail closed.
    • Test-first commit d2969bb118a4e79d6e36353e31d83018a259cd7e adds test_export_rejects_nested_timezone_substitution_before_datetime_comparison, requiring canonical_json() to reject the changed packet and proving the substituted timezone callback count remains zero. No hosted RED is claimed for this superseded test-only head; no pull-request workflow run materialized before the causal source commit.
    • Minimal production repair 03b0d865741372084f7b11eca85932767a3e14a6 captures the built-in datetime and fixed-offset timezone runtime types inside _build_packet_runtime() and checks nested timezone type before datetime equality. The repair is one ordinary descendant commit of the test-only head and changes only review.py (+11/-4).
    • Local causal verification of the repaired comparison returns fail-closed False with zero calls into the executable custom timezone object. This is not substituted for hosted acceptance.
    • Package CHANGELOG 50bc0d12..., README 6114624d..., TRACEABILITY 625a39db..., and ADR 0096 81ed7555... now document the same narrow nested-runtime boundary and preserve feat(core): apply reviewed Organization hierarchy changes #119's durable authority.

    Current #96 exact head is 81ed7555fd030967356c5ff9d1c698b6070e2e8a. Fresh Foundation 34439908483, Security 34439908493, SAST 34439908512, and CodeQL 34439908521 exist but are queued. Predecessor GREEN/RED evidence does not transfer. Keep this issue open until the exact current head has admissible hosted evidence and #96 integrates normally.

  2. seonghobae commented on Sep 10, 2026

    @seonghobae
    ContributorAuthor

    Current-head correction after coverage-path review: the first causal source repair 03b0d865741372084f7b11eca85932767a3e14a6 checked nested timezone type on both the mutable retained datetime and the closure-private issuance datetime. The issuance-side true branch is unreachable under this package contract because _validate_issuance_timestamp already requires an exact built-in datetime with built-in fixed-offset tzinfo before that immutable issuance value is stored. Rather than manufacture a closure-tampering test merely to cover an impossible branch, ordinary descendant 5ffdf0dbe2c6445aa5b115af24b3ae33951b9e21 removes only that duplicate issuance-state recheck. The current guard still inspects the mutable retained recorded_at nested timezone before equality, so the #290 counterexample remains fail-closed without executing caller utcoffset().

    CHANGELOG d25b4244..., README b0457426..., TRACEABILITY ee2358bb..., and ADR 0096 70212e6e... now document that reachable authority boundary. Current #96 exact head is 70212e6e00e0e3c0104b2444aadd7ac01880847b; fresh Foundation 34440405579, Security 34440405530, SAST 34440405543, and CodeQL 34440405532 remain queued. No predecessor verdict transfers and no current-head GREEN is claimed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions