Skip to Content
EngineeringDecisions (ADRs)ADR 0023 Hand-offs as records; event triggers from the audit stream

ADR 0023: Hand-offs as records; event triggers from the audit stream

Status
Accepted
Date
Deciders
Founder

Context

Twins of different personas must pass work to each other (an entry ready for an SOP check, a supply slip that blocks a study) without an agent-to-agent channel, and twins must start work when something happens without polling every table.

Decision

  • handoff_requests are created sent only when the sending person approves the proposal (program.handoffs.manage); statuses sent, accepted, declined, done, withdrawn; acceptance opens a program-visible thread pinned to the linked record and fires the receiving twin (twin_handoff); duplicates refused (409 handoff_exists), self-addressing refused, routes scoped by party.
  • Event triggers match a closed TRIGGERABLE_ACTIONS tuple (connector_object.update, hypothesis.decision, sop_version.update, milestone.update, handoff.accept, experiment.update, approval.create) inside a post-flush hook of write_audit that runs in a savepoint (a hook failure never fails the record write), coalesces per trigger and interval, honours backpressure, and enqueues twin_cycle runs with on_conflict_do_nothing; an AUDIT_ACTIONS registry pins every action name; PAUSE_ACTIONS (role_assignment.delete, user.deactivate) pause twins in the same hook; an hourly reconcile job catches anything missed.

Consequences

  • Mentions never start a twin; the mentioned person clicks “Let my twin look at this”.
  • The hook is structural: no notification, run, interrupt, twin, inbox or sync action can trigger anything (catalogue-style test).

Alternatives considered

  • Message bus between agents: invisible to the record; rejected.
  • Polling tables for changes: cost and latency; rejected in favour of the audit hook plus reconcile.

Follow-ups

  • Cross-program hand-offs (R5).
Last updated on