-- shepherd v6.5.7 — authoritative native singleton ownership claims.
-- One Engineer owns a run; one Conductor owns each run/lane. The row survives
-- stop so a new identity can enter only through an exact native resume.
PRAGMA foreign_keys = ON;

BEGIN;

CREATE TABLE dispatch_singleton_claims (
  project_id            TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE ON UPDATE CASCADE,
  run_id                TEXT NOT NULL CHECK(length(run_id) BETWEEN 1 AND 64 AND run_id NOT GLOB '*[^a-z0-9-]*'),
  role                  TEXT NOT NULL CHECK(role IN ('engineer', 'conductor')),
  lane_key              TEXT NOT NULL CHECK(length(lane_key) BETWEEN 1 AND 64 AND lane_key NOT GLOB '*[^a-z0-9_-]*'),
  lane_id               TEXT CHECK(lane_id IS NULL OR (length(lane_id) BETWEEN 1 AND 64 AND lane_id NOT GLOB '*[^a-z0-9-]*')),
  agent_id              TEXT NOT NULL CHECK(length(agent_id) BETWEEN 1 AND 128 AND agent_id NOT GLOB '*[^A-Za-z0-9._:-]*'),
  harness               TEXT NOT NULL CHECK(harness IN ('claude', 'codex', 'pi', 'prime_agent')),
  agent_type            TEXT NOT NULL CHECK(length(agent_type) BETWEEN 1 AND 128 AND agent_type NOT GLOB '*[^A-Za-z0-9._:-]*'),
  parent_agent_id       TEXT CHECK(parent_agent_id IS NULL OR (length(parent_agent_id) BETWEEN 1 AND 128 AND parent_agent_id NOT GLOB '*[^A-Za-z0-9._:-]*')),
  session_id            TEXT NOT NULL CHECK(length(session_id) BETWEEN 1 AND 128 AND session_id NOT GLOB '*[^A-Za-z0-9._:-]*'),
  identity_fingerprint  TEXT NOT NULL CHECK(
    length(identity_fingerprint) = 64 AND
    identity_fingerprint NOT GLOB '*[^0-9a-f]*'
  ),
  write_scope           TEXT NOT NULL CHECK(json_valid(write_scope) AND json_type(write_scope) = 'array'),
  claimed_at            INTEGER NOT NULL CHECK(claimed_at >= 0),
  resumed_from_agent_id TEXT CHECK(resumed_from_agent_id IS NULL OR (length(resumed_from_agent_id) BETWEEN 1 AND 128 AND resumed_from_agent_id NOT GLOB '*[^A-Za-z0-9._:-]*')),
  PRIMARY KEY (project_id, run_id, role, lane_key),
  CHECK (
    (role = 'engineer' AND lane_key = '__run__') OR
    (role = 'conductor' AND lane_key <> '__run__' AND lane_id = lane_key)
  )
) WITHOUT ROWID;

COMMIT;
