-- The seen-set for continuous missions. -- -- Every "continuous X" mission has the same failure mode: it runs again and -- redoes work it already did. Research resurfaces papers it already read; a -- security scan re-reports findings already triaged. Orchestration does not -- fix that — a record of what has already been covered does. -- -- This repository already tried continuous research once. Migrations 0030-0044 -- built `research_topics`, `research_outcomes` and `loops`; 0053 dropped them -- all. `research_topics` carried a status lifecycle but no seen-set, so it -- could run forever and never know what it had covered. That is the gap this -- table exists to close, and it is the reason it lands before any scheduling. -- -- Authoritative here rather than in the runtime's memory: ZeroClaw memory is -- scoped per agent, and mission agents are ephemeral `claw_` aliases -- minted per mission (measured: ~100 of them already). A seen-set that -- disappears with the agent that wrote it is not a seen-set. CREATE TABLE corpus_items ( id UUID PRIMARY KEY, workspace_id UUID NOT NULL REFERENCES workspaces (id) ON DELETE CASCADE, -- Which corpus this belongs to, e.g. 'valhalla-vault'. A workspace can -- track several (a vault, a findings ledger, a paper collection). corpus_id TEXT NOT NULL, -- 'note' = something already in the corpus (a vault file). Establishes -- coverage: what has this vault already got? -- 'source' = an external thing a mission consumed (a paper, an advisory). -- This is the dedupe key that stops re-reading. -- -- Both are needed and they answer different questions. Measured against -- the real vault: 416 notes, and ZERO carry an arxiv/doi/url key — so an -- ingester keyed only on external identity would index nothing at all. kind TEXT NOT NULL CHECK (kind IN ('note', 'source')), -- Stable identity within the corpus. For notes, 'note:'; for sources, a natural id like 'arxiv:2401.12345', 'doi:10...' -- or 'url:'. Uniqueness is on this, which is what makes -- re-ingestion idempotent. source_id TEXT NOT NULL, title TEXT, -- Vault-relative path for notes; NULL for external sources. path TEXT, url TEXT, -- SHA-256 of the content at last sight. Lets a re-index distinguish -- "unchanged" from "edited" without diffing, so an unchanged vault is a -- genuine no-op rather than 416 pointless updates. content_hash TEXT NOT NULL, first_seen_at TIMESTAMPTZ NOT NULL DEFAULT now(), last_seen_at TIMESTAMPTZ NOT NULL DEFAULT now(), -- Which mission first recorded this. NULL for the initial vault index, -- which is derived from files nobody's mission wrote. mission_id UUID REFERENCES missions (id) ON DELETE SET NULL, UNIQUE (workspace_id, corpus_id, source_id) ); -- The hot query is "have I seen this?", which the UNIQUE index already covers. -- This one serves "what does this corpus contain?" for briefing assembly. CREATE INDEX corpus_items_corpus_idx ON corpus_items (workspace_id, corpus_id, kind, last_seen_at DESC); -- "What did this mission add?" — the verification predicate for a continuous -- run is that it contributed at least one NEW source. CREATE INDEX corpus_items_mission_idx ON corpus_items (mission_id) WHERE mission_id IS NOT NULL;