db: agent enrollment schema (M4-4a, migration 0021) #1482

Merged
fred merged 1 commits from feat/m4-4a-enrollment-schema into next 2026-08-30 01:47:06 +00:00
Collaborator

Second M4-4 slice, implementing the merged design doc's §4 schema delta (docs/plans/2026-08-29-agent-enrollment-command-design.md, PR #1481 / ee815a72). Additive-only DDL:

  • agents: nullable harness + enrolled_at (no backfill — NULL marks a legacy row).
  • agent_audit_events: append-only, seq identity for per-agent ordering, FK-free agent linkage (snapshot id — audit survives legacy CRUD DELETE), causation self-FK RESTRICT, closed event-type CHECK (agent.enrolled, agent.enrollment.replayed).
  • agent_outbox: hierarchy-outbox shape, one row per event, closed status enum. No idempotency-key column — the fence owns idempotency for this family.
  • agent_idempotency_fence: contract 3 §4.3 shape — UNIQUE (operation, key), actor/scope/digest/replay-mode columns, mode CHECK (actor-bound/shared; only actor-bound is ever recorded, shared is refused at validation per the design), FK-free outcome reference.

Witnesses (packages/db/src/agent-enrollment.witness.test.ts, PGlite leg + real-PostgreSQL leg on DATABASE_URL): nullable enrollment columns, event-type CHECK both-codes, per-agent seq ordering, information_schema FK probes proving deletion-safe linkage, causation/outbox RESTRICT, fence (operation, key) uniqueness incl. same-key-different-operation, replay-mode default + CHECK.

Command-level witnesses (never-echo, same-tx atomicity, replay, correlation, CLI parity, fail-closed) land with M4-4b per the design's witness split.

Second M4-4 slice, implementing the merged design doc's §4 schema delta (docs/plans/2026-08-29-agent-enrollment-command-design.md, PR #1481 / ee815a72). Additive-only DDL: - agents: nullable harness + enrolled_at (no backfill — NULL marks a legacy row). - agent_audit_events: append-only, seq identity for per-agent ordering, FK-free agent linkage (snapshot id — audit survives legacy CRUD DELETE), causation self-FK RESTRICT, closed event-type CHECK (agent.enrolled, agent.enrollment.replayed). - agent_outbox: hierarchy-outbox shape, one row per event, closed status enum. No idempotency-key column — the fence owns idempotency for this family. - agent_idempotency_fence: contract 3 §4.3 shape — UNIQUE (operation, key), actor/scope/digest/replay-mode columns, mode CHECK (actor-bound/shared; only actor-bound is ever recorded, shared is refused at validation per the design), FK-free outcome reference. Witnesses (packages/db/src/agent-enrollment.witness.test.ts, PGlite leg + real-PostgreSQL leg on DATABASE_URL): nullable enrollment columns, event-type CHECK both-codes, per-agent seq ordering, information_schema FK probes proving deletion-safe linkage, causation/outbox RESTRICT, fence (operation, key) uniqueness incl. same-key-different-operation, replay-mode default + CHECK. Command-level witnesses (never-echo, same-tx atomicity, replay, correlation, CLI parity, fail-closed) land with M4-4b per the design's witness split.
fred added 1 commit 2026-08-30 01:26:45 +00:00
db: agent enrollment schema (M4-4a, migration 0021)
ci/woodpecker/pr/ci Pipeline was successful
e4d5fa54b4
Additive-only DDL per the merged design (docs/plans/
2026-08-29-agent-enrollment-command-design.md SS4): agents gains
nullable harness + enrolled_at (no backfill); new agent_audit_events
(append-only, seq identity, FK-free agent linkage, causation self-FK,
closed event-type CHECK), agent_outbox (hierarchy shape, one row per
event, closed status enum), agent_idempotency_fence (contract 3 SS4.3
shape: UNIQUE (operation, key), replay-mode CHECK, FK-free outcome
reference).

Schema-level witnesses in agent-enrollment.witness.test.ts (PGlite +
real-PostgreSQL legs): nullable enrollment columns, event-type CHECK,
per-agent seq ordering, deletion-safe linkage (events and fence rows
survive agent deletion; information_schema FK probes), causation and
outbox RESTRICT, fence uniqueness and mode CHECK. Command-level
witnesses land with M4-4b.
rev-code-02 approved these changes 2026-08-30 01:41:39 +00:00
rev-code-02 left a comment
Member

Independent review by rev-code-02 (gate 16; author fred). Head reviewed: e4d5fa54b4 (verified current PR head == fetched ref == reviewed tree; base ee815a72 is the #1481 design merge, squash-verified by content — the design doc is present in the base; one additive commit, no rewrite). Detached terra round-1 APPROVE was context; everything below is measured by me.

Migration 0021 vs the merged design doc §4, item by item (I reviewed the design itself as review 383, so the cross-check is against the same text that just merged):

  • agents gains exactly harness (text, NULL) and enrolled_at (timestamptz, NULL); no backfill, no other column touched; custody-schema §5.2's live-agents-table FK binding is untouched (table extended, not replaced).
  • agent_audit_events: event-type CHECK closed to exactly the two designed events (agent.enrolled + the non-mutation agent.enrollment.replayed); agent_id carries NO FK (deletion-safe snapshot linkage, per design §3.1 rule 6); causation is a self-FK with RESTRICT; per-agent ordering index on (agent_id, seq) plus global seq identity and correlation index.
  • agent_outbox mirrors the hierarchy outbox shape exactly (unique one-row-per-event, closed status enum, status+created claim index).
  • agent_idempotency_fence carries contract 3 §4.3's full recorded set — operation, key, acting principal, authorization scope, payload digest (input excludes credential material per design rule 5), replay mode (CHECK allows actor-bound|shared; the column exists for envelope fidelity and mode-mismatch collision checks, exactly as the design states), committed-outcome agent id (no FK — replays must keep answering after a legacy DELETE) — with UNIQUE (operation, key).
  • SQL, schema.ts, 0021_snapshot, and journal idx 21 are mutually consistent (verified programmatically: column sets, nullability, FK inventory, unique index, CHECKs).

Witness suite, run by me at this head: 10/10 on the PGlite leg; the real-PostgreSQL leg (binding, ci-postgres) skips locally and runs in CI — the same two-leg lane standard the hierarchy schema witnesses use. Every constraint witness pairs a refusal with a control (both event types accepted before the undeclared one is refused; same key under a different operation allowed before the duplicate is refused). The header honestly maps the split: schema-level guarantees here; never-echo, same-tx atomicity (which names the gateway-side credential write and cannot be witnessed from packages/db), replay semantics, correlation, CLI parity, and fail-closed are owed by the M4-4b command slice per the design's §5 list.

Mutation control: removing the fence unique index from the shipped migration SQL turns the (operation, key) uniqueness witness red; restored, 10/10 green, tree byte-clean.

Regression and mechanical: full db suite 73 passed / 44 skipped (PG legs; up ten from the new PGlite witnesses); tsc --noEmit and eslint clean; Prettier 3.8.1 green on both TS files (drizzle/ generated files are correctly under .prettierignore). CI pipeline 3030 is the PR pipeline at exactly e4d5fa54 and was still running at review time — terminal green remains the merge gate's.

Verdict: APPROVED at e4d5fa54b4. An amend or rebase voids this approval.

Independent review by rev-code-02 (gate 16; author fred). Head reviewed: e4d5fa54b444ef63c0e17eced1711ba24526f8e5 (verified current PR head == fetched ref == reviewed tree; base ee815a72 is the #1481 design merge, squash-verified by content — the design doc is present in the base; one additive commit, no rewrite). Detached terra round-1 APPROVE was context; everything below is measured by me. Migration 0021 vs the merged design doc §4, item by item (I reviewed the design itself as review 383, so the cross-check is against the same text that just merged): - agents gains exactly harness (text, NULL) and enrolled_at (timestamptz, NULL); no backfill, no other column touched; custody-schema §5.2's live-agents-table FK binding is untouched (table extended, not replaced). - agent_audit_events: event-type CHECK closed to exactly the two designed events (agent.enrolled + the non-mutation agent.enrollment.replayed); agent_id carries NO FK (deletion-safe snapshot linkage, per design §3.1 rule 6); causation is a self-FK with RESTRICT; per-agent ordering index on (agent_id, seq) plus global seq identity and correlation index. - agent_outbox mirrors the hierarchy outbox shape exactly (unique one-row-per-event, closed status enum, status+created claim index). - agent_idempotency_fence carries contract 3 §4.3's full recorded set — operation, key, acting principal, authorization scope, payload digest (input excludes credential material per design rule 5), replay mode (CHECK allows actor-bound|shared; the column exists for envelope fidelity and mode-mismatch collision checks, exactly as the design states), committed-outcome agent id (no FK — replays must keep answering after a legacy DELETE) — with UNIQUE (operation, key). - SQL, schema.ts, 0021_snapshot, and journal idx 21 are mutually consistent (verified programmatically: column sets, nullability, FK inventory, unique index, CHECKs). Witness suite, run by me at this head: 10/10 on the PGlite leg; the real-PostgreSQL leg (binding, ci-postgres) skips locally and runs in CI — the same two-leg lane standard the hierarchy schema witnesses use. Every constraint witness pairs a refusal with a control (both event types accepted before the undeclared one is refused; same key under a different operation allowed before the duplicate is refused). The header honestly maps the split: schema-level guarantees here; never-echo, same-tx atomicity (which names the gateway-side credential write and cannot be witnessed from packages/db), replay semantics, correlation, CLI parity, and fail-closed are owed by the M4-4b command slice per the design's §5 list. Mutation control: removing the fence unique index from the shipped migration SQL turns the (operation, key) uniqueness witness red; restored, 10/10 green, tree byte-clean. Regression and mechanical: full db suite 73 passed / 44 skipped (PG legs; up ten from the new PGlite witnesses); tsc --noEmit and eslint clean; Prettier 3.8.1 green on both TS files (drizzle/ generated files are correctly under .prettierignore). CI pipeline 3030 is the PR pipeline at exactly e4d5fa54 and was still running at review time — terminal green remains the merge gate's. Verdict: APPROVED at e4d5fa54b444ef63c0e17eced1711ba24526f8e5. An amend or rebase voids this approval.
fred merged commit 143ba0f57a into next 2026-08-30 01:47:06 +00:00
Sign in to join this conversation.