Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,9 @@ ts/node_modules/
.env
infra/node_modules/
infra/cdk.out/

# Aperant data directory
.auto-claude/

# Git worktrees
.worktrees/
29 changes: 29 additions & 0 deletions migrations/012_slo_config.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
-- SLO definitions and alerts (F3: SLO Dashboard)

CREATE TABLE IF NOT EXISTS slo_definitions (
id TEXT PRIMARY KEY,
org_id TEXT NOT NULL,
name TEXT NOT NULL,
metric TEXT NOT NULL, -- p50_latency, p95_latency, p99_latency, hit_rate
operator TEXT NOT NULL, -- lt, gt
threshold DOUBLE PRECISION NOT NULL,
window_minutes INTEGER NOT NULL DEFAULT 60,
enabled BOOLEAN NOT NULL DEFAULT TRUE,
alert_channels JSONB DEFAULT '[]'::jsonb,
created_at TIMESTAMPTZ DEFAULT now(),
updated_at TIMESTAMPTZ DEFAULT now()
);

CREATE TABLE IF NOT EXISTS slo_alerts (
id BIGSERIAL PRIMARY KEY,
org_id TEXT NOT NULL,
slo_id TEXT NOT NULL REFERENCES slo_definitions(id) ON DELETE CASCADE,
metric_value DOUBLE PRECISION NOT NULL,
threshold DOUBLE PRECISION NOT NULL,
status TEXT NOT NULL, -- firing, resolved
dispatched_to JSONB DEFAULT '[]'::jsonb,
created_at TIMESTAMPTZ DEFAULT now()
);

CREATE INDEX IF NOT EXISTS idx_slo_alerts_slo_id ON slo_alerts(slo_id);
CREATE INDEX IF NOT EXISTS idx_slo_alerts_created ON slo_alerts(created_at DESC);
26 changes: 26 additions & 0 deletions migrations/013_retrieval_profiles.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
-- Retrieval profiles (F4: Adaptive Retrieval Profiles)

CREATE TABLE IF NOT EXISTS retrieval_profiles (
id TEXT PRIMARY KEY,
org_id TEXT NOT NULL,
name TEXT NOT NULL,
semantic_weight REAL NOT NULL DEFAULT 1.0,
graph_weight REAL NOT NULL DEFAULT 1.0,
recency_bias REAL NOT NULL DEFAULT 30.0,
tier_filters TEXT[] DEFAULT NULL,
min_score REAL NOT NULL DEFAULT 0.3,
max_results INT NOT NULL DEFAULT 10,
is_preset BOOLEAN NOT NULL DEFAULT FALSE,
created_at TIMESTAMPTZ DEFAULT now(),
updated_at TIMESTAMPTZ DEFAULT now(),
UNIQUE(org_id, name)
);

INSERT INTO retrieval_profiles (id, org_id, name, semantic_weight, graph_weight, recency_bias, tier_filters, min_score, max_results, is_preset)
VALUES
('preset-coding', '__global__', 'coding', 1.0, 0.5, 7.0, ARRAY['short','long'], 0.4, 10, TRUE),
('preset-incident', '__global__', 'incident-response', 0.8, 1.5, 1.0, NULL, 0.2, 20, TRUE),
('preset-research', '__global__', 'research', 1.2, 1.0, 90.0, ARRAY['long'], 0.3, 15, TRUE)
ON CONFLICT DO NOTHING;

ALTER TABLE api_keys ADD COLUMN IF NOT EXISTS default_profile_id TEXT;
13 changes: 13 additions & 0 deletions migrations/014_review_decisions.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
-- Review decisions audit trail (F5: Graph Approval Inbox)

CREATE TABLE IF NOT EXISTS review_decisions (
id TEXT PRIMARY KEY,
relationship_id TEXT NOT NULL,
action TEXT NOT NULL CHECK (action IN ('approve', 'reject')),
reviewer_id TEXT,
notes TEXT,
decided_at TIMESTAMPTZ DEFAULT now()
);

CREATE INDEX IF NOT EXISTS idx_review_decisions_rel ON review_decisions(relationship_id);
CREATE INDEX IF NOT EXISTS idx_review_decisions_time ON review_decisions(decided_at DESC);
41 changes: 41 additions & 0 deletions migrations/015_retention_policies.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
-- Retention policies and restore drills (F6: Policy-Based Retention)

CREATE TABLE IF NOT EXISTS retention_policies (
id TEXT PRIMARY KEY,
org_id TEXT NOT NULL,
name TEXT NOT NULL,
retention_window JSONB NOT NULL DEFAULT '{"working": 3600, "short": 604800, "long": null}',
snapshot_schedule TEXT,
encryption_required BOOLEAN DEFAULT FALSE,
max_snapshots INT DEFAULT 50,
is_active BOOLEAN DEFAULT TRUE,
created_at TIMESTAMPTZ DEFAULT now(),
updated_at TIMESTAMPTZ DEFAULT now(),
UNIQUE(org_id, name)
);

CREATE TABLE IF NOT EXISTS snapshot_metadata (
id TEXT PRIMARY KEY,
org_id TEXT NOT NULL,
policy_id TEXT REFERENCES retention_policies(id),
name TEXT NOT NULL,
path TEXT NOT NULL,
size_bytes BIGINT,
memory_count INT,
encrypted BOOLEAN DEFAULT FALSE,
created_at TIMESTAMPTZ DEFAULT now()
);

CREATE TABLE IF NOT EXISTS restore_drill_results (
id TEXT PRIMARY KEY,
org_id TEXT NOT NULL,
snapshot_id TEXT REFERENCES snapshot_metadata(id),
snapshot_name TEXT NOT NULL,
started_at TIMESTAMPTZ NOT NULL,
completed_at TIMESTAMPTZ,
recovery_time_ms BIGINT,
memories_restored INT,
status TEXT DEFAULT 'running',
error TEXT,
created_at TIMESTAMPTZ DEFAULT now()
);
41 changes: 41 additions & 0 deletions migrations/016_workspaces.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
-- Workspaces and audit log (F7: Multi-Tenant Workspace Isolation)

CREATE TABLE IF NOT EXISTS workspaces (
id TEXT PRIMARY KEY,
org_id TEXT NOT NULL,
name TEXT NOT NULL,
slug TEXT NOT NULL,
settings JSONB DEFAULT '{}',
created_at TIMESTAMPTZ DEFAULT now(),
archived_at TIMESTAMPTZ,
UNIQUE(org_id, slug)
);

CREATE TABLE IF NOT EXISTS workspace_members (
id TEXT PRIMARY KEY,
workspace_id TEXT NOT NULL REFERENCES workspaces(id),
user_id TEXT,
role TEXT NOT NULL DEFAULT 'writer',
invited_at TIMESTAMPTZ DEFAULT now(),
accepted_at TIMESTAMPTZ
);

CREATE TABLE IF NOT EXISTS audit_log (
id BIGSERIAL PRIMARY KEY,
org_id TEXT NOT NULL,
workspace_id TEXT,
actor_id TEXT NOT NULL,
actor_type TEXT NOT NULL,
action TEXT NOT NULL,
resource_type TEXT,
resource_id TEXT,
metadata JSONB DEFAULT '{}',
ip_address INET,
created_at TIMESTAMPTZ DEFAULT now()
);

CREATE INDEX IF NOT EXISTS idx_audit_org_time ON audit_log(org_id, created_at DESC);
CREATE INDEX IF NOT EXISTS idx_audit_workspace ON audit_log(workspace_id, created_at DESC);

ALTER TABLE memories ADD COLUMN IF NOT EXISTS workspace_id TEXT;
ALTER TABLE api_keys ADD COLUMN IF NOT EXISTS workspace_id TEXT;
28 changes: 28 additions & 0 deletions migrations/017_recommendations.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
-- Proactive recommendations (F9: Proactive Memory Recommendations)

CREATE TABLE IF NOT EXISTS recommendation_feedback (
id TEXT PRIMARY KEY,
org_id TEXT NOT NULL,
workspace_id TEXT,
memory_id TEXT NOT NULL,
actor_id TEXT NOT NULL,
signal TEXT DEFAULT 'manual',
feedback TEXT NOT NULL,
context_hash TEXT,
created_at TIMESTAMPTZ DEFAULT now()
);

CREATE INDEX IF NOT EXISTS idx_rec_feedback_memory ON recommendation_feedback(memory_id);
CREATE INDEX IF NOT EXISTS idx_rec_feedback_actor ON recommendation_feedback(actor_id, created_at DESC);

CREATE TABLE IF NOT EXISTS recommendation_config (
id TEXT PRIMARY KEY,
workspace_id TEXT,
agent_id TEXT,
aggressiveness REAL DEFAULT 0.5,
enabled BOOLEAN DEFAULT true,
max_suggestions INTEGER DEFAULT 3,
cooldown_minutes INTEGER DEFAULT 15,
updated_at TIMESTAMPTZ DEFAULT now(),
UNIQUE(workspace_id, agent_id)
);
Loading
Loading