Phase 13: integrations (research folder, git, Prometheus, signed webhooks)
Adds the integration layer that turns external sources into provenance-tagged observations without ever executing what it reads. - research folder poller: os.OpenRoot, text allowlist, binary/archive/symlink rejection, content fingerprints, duplicate tracking - git poller: bare shallow mirror with hooks disabled and ext protocol refused, commit observations, co-change pairs - Prometheus poller: threshold crossings and relative-change detection - webhooks: HMAC over timestamp.body, +/-300s window, replay cache, 256 KiB cap, per-IP rate limit; refused entirely without a secret - capabilities read_metrics (allow) and repository.read (ask), scoped to the invoking mind's integrations - migrations 0013, API, UI pages, noemactl integrations, docs/integrations.md
This commit is contained in:
@@ -0,0 +1,3 @@
|
||||
DROP TABLE IF EXISTS ingested_documents;
|
||||
DROP TABLE IF EXISTS integration_runs;
|
||||
DROP TABLE IF EXISTS integrations;
|
||||
@@ -0,0 +1,53 @@
|
||||
-- Integrations: configured external sources, their runs and ingested documents.
|
||||
|
||||
CREATE TABLE integrations (
|
||||
id uuid PRIMARY KEY,
|
||||
mind_id uuid NOT NULL REFERENCES minds(id),
|
||||
kind text NOT NULL CHECK (kind IN ('research_folder','git','prometheus','webhook')),
|
||||
name text NOT NULL,
|
||||
config jsonb NOT NULL DEFAULT '{}'::jsonb, -- never contains secrets
|
||||
secret_ref text NOT NULL DEFAULT '', -- env:/file:/enc: reference
|
||||
trust text NOT NULL DEFAULT 'source',
|
||||
enabled boolean NOT NULL DEFAULT true,
|
||||
status text NOT NULL DEFAULT 'new' CHECK (status IN ('new','ok','stale','error','disabled')),
|
||||
state jsonb NOT NULL DEFAULT '{}'::jsonb, -- poller bookkeeping (last commit, last values)
|
||||
last_run_at timestamptz,
|
||||
last_ok_at timestamptz,
|
||||
last_error text NOT NULL DEFAULT '',
|
||||
ingested_count integer NOT NULL DEFAULT 0,
|
||||
created_at timestamptz NOT NULL DEFAULT now(),
|
||||
updated_at timestamptz NOT NULL DEFAULT now()
|
||||
);
|
||||
CREATE UNIQUE INDEX integrations_mind_name_idx ON integrations (mind_id, lower(name));
|
||||
|
||||
CREATE TABLE integration_runs (
|
||||
id uuid PRIMARY KEY,
|
||||
integration_id uuid NOT NULL REFERENCES integrations(id) ON DELETE CASCADE,
|
||||
started_at timestamptz NOT NULL DEFAULT now(),
|
||||
finished_at timestamptz,
|
||||
items integer NOT NULL DEFAULT 0,
|
||||
observations integer NOT NULL DEFAULT 0,
|
||||
errors integer NOT NULL DEFAULT 0,
|
||||
notes jsonb NOT NULL DEFAULT '[]'::jsonb,
|
||||
error text NOT NULL DEFAULT ''
|
||||
);
|
||||
CREATE INDEX integration_runs_idx ON integration_runs (integration_id, started_at DESC);
|
||||
|
||||
CREATE TABLE ingested_documents (
|
||||
id uuid PRIMARY KEY,
|
||||
mind_id uuid NOT NULL REFERENCES minds(id),
|
||||
integration_id uuid NOT NULL REFERENCES integrations(id) ON DELETE CASCADE,
|
||||
fingerprint text NOT NULL,
|
||||
reference text NOT NULL,
|
||||
title text NOT NULL DEFAULT '',
|
||||
content_type text NOT NULL DEFAULT '',
|
||||
size_bytes bigint NOT NULL DEFAULT 0,
|
||||
extracted_chars integer NOT NULL DEFAULT 0,
|
||||
excerpt text NOT NULL DEFAULT '',
|
||||
status text NOT NULL CHECK (status IN ('ingested','duplicate','rejected','failed')),
|
||||
error text NOT NULL DEFAULT '',
|
||||
event_id uuid,
|
||||
created_at timestamptz NOT NULL DEFAULT now(),
|
||||
UNIQUE (mind_id, fingerprint)
|
||||
);
|
||||
CREATE INDEX ingested_documents_integration_idx ON ingested_documents (integration_id, created_at DESC);
|
||||
Reference in New Issue
Block a user