Skip to content

records(packet): bind signoffs and phase events to the pin timeline in verification #52

Description

@TusanHomichi

Context

#50 (trainee packets, ADR 0015) verifies each packet's documents against the enrollment's pin history: the lifecycle events' version changes define which versions were ever pinned, each signoff and phase event names a pinned version with the packet's label for it, and each phase event's version is the one its named epoch reached (docs/formats/trainee-packet.md, verification check 8). Codex's review of c19460a raised two findings that these checks are set membership over the history, not position on its timeline:

  1. Signoffs. A rehashed packet can relabel a signoff recorded under version 1 as a version-2 task when the enrollment later moved to version 2, because version 2 appears somewhere in the pin history. task_signoff stores no epoch; the trigger task_signoff_takes_a_pinned_task (migration 0013) binds the task to the pin current at insert, so the property to verify is temporal: the signoff's version was the pin at signed_at.
  2. Phase events. A phase event naming a recorded epoch verifies even when its effective_at and recorded_at precede that version change's occurred_at. Production refuses this (lifecycle::record_phase_event: "a phase event cannot take effect before its epoch opened", effective < epoch_opened is refused); the verifier does not mirror it.

Proposed design

Extend PinHistory in packet_verify.rs with each version change's occurred_at, and check position on the timeline with second-granularity tolerance, since every instant the packet carries is a unix second and a change and an act in the same second are legitimately unordered:

  • pinned_during(t): the pin after all changes with occurred_at < t, plus the target of every change with occurred_at == t. A signoff's program_version must be in pinned_during(signed_at).
  • A phase event under epoch E (a version change at instant o, closed by the next change at n if any) must have recorded_at >= o, effective_at >= o, and recorded_at <= n; a phase event under the original pin (null epoch) must have recorded_at <= o of the first change.
  • Findings are DocumentPinHistory; the format document's pin-history paragraph and check 8 state the timeline rules.

Tests: forge a signoff relabelled to a version pinned only later, a phase event effective before its epoch opened, and one recorded under the original pin after the first change; the genuine packet, including a same-second change and act, must still verify.

Raised by Codex on #50 (review threads r3909122078 and r3909122081) after the set-membership checks landed in c19460a; tracked here so #50 merges with the format's stated checks complete. Refs #48, #44.

Activity

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

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions