Major additions: - marketplace/: Agent template registry with FTS5 search, ratings, versioning - observability/: Prometheus metrics, distributed tracing, structured logging - ledger/migrations/: Database migration scripts for multi-tenant support - tests/governance/: 15 new test files for phases 6-12 (295 total tests) - bin/validate-phases: Full 12-phase validation script New features: - Multi-tenant support with tenant isolation and quota enforcement - Agent marketplace with semantic versioning and search - Observability with metrics, tracing, and log correlation - Tier-1 agent bootstrap scripts Updated components: - ledger/api.py: Extended API for tenants, marketplace, observability - ledger/schema.sql: Added tenant, project, marketplace tables - testing/framework.ts: Enhanced test framework - checkpoint/checkpoint.py: Improved checkpoint management Archived: - External integrations (Slack/GitHub/PagerDuty) moved to .archive/ - Old checkpoint files cleaned up Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
224 lines
7.8 KiB
SQL
224 lines
7.8 KiB
SQL
-- Agent Governance Ledger Schema
|
|
-- Version 2.0: Multi-Tenant Support (Phase 10)
|
|
|
|
-- ============================================================
|
|
-- MULTI-TENANT CORE TABLES
|
|
-- ============================================================
|
|
|
|
-- Tenants (organizations/customers)
|
|
CREATE TABLE IF NOT EXISTS tenants (
|
|
tenant_id TEXT PRIMARY KEY,
|
|
name TEXT NOT NULL,
|
|
slug TEXT UNIQUE NOT NULL,
|
|
owner_email TEXT,
|
|
subscription_tier TEXT DEFAULT 'free', -- free, pro, enterprise
|
|
is_active INTEGER DEFAULT 1,
|
|
settings TEXT, -- JSON
|
|
created_at TEXT DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TEXT DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
|
|
-- Projects (workspaces within a tenant)
|
|
CREATE TABLE IF NOT EXISTS projects (
|
|
project_id TEXT PRIMARY KEY,
|
|
tenant_id TEXT NOT NULL,
|
|
name TEXT NOT NULL,
|
|
slug TEXT NOT NULL,
|
|
description TEXT,
|
|
is_active INTEGER DEFAULT 1,
|
|
settings TEXT, -- JSON
|
|
created_at TEXT DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TEXT DEFAULT CURRENT_TIMESTAMP,
|
|
FOREIGN KEY (tenant_id) REFERENCES tenants(tenant_id) ON DELETE CASCADE,
|
|
UNIQUE(tenant_id, slug)
|
|
);
|
|
|
|
-- Tenant quotas and limits
|
|
CREATE TABLE IF NOT EXISTS tenant_quotas (
|
|
tenant_id TEXT PRIMARY KEY,
|
|
max_projects INTEGER DEFAULT 3,
|
|
max_agents_per_project INTEGER DEFAULT 5,
|
|
max_concurrent_executions INTEGER DEFAULT 2,
|
|
max_storage_bytes INTEGER DEFAULT 1073741824, -- 1GB
|
|
max_api_calls_per_day INTEGER DEFAULT 10000,
|
|
max_tokens_per_day INTEGER DEFAULT 1000000,
|
|
cost_budget_cents INTEGER DEFAULT 10000, -- $100
|
|
updated_at TEXT DEFAULT CURRENT_TIMESTAMP,
|
|
FOREIGN KEY (tenant_id) REFERENCES tenants(tenant_id) ON DELETE CASCADE
|
|
);
|
|
|
|
-- Tenant usage tracking
|
|
CREATE TABLE IF NOT EXISTS tenant_usage (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
tenant_id TEXT NOT NULL,
|
|
period_start TEXT NOT NULL, -- YYYY-MM-DD
|
|
api_calls INTEGER DEFAULT 0,
|
|
tokens_used INTEGER DEFAULT 0,
|
|
storage_bytes INTEGER DEFAULT 0,
|
|
executions INTEGER DEFAULT 0,
|
|
cost_cents INTEGER DEFAULT 0,
|
|
updated_at TEXT DEFAULT CURRENT_TIMESTAMP,
|
|
FOREIGN KEY (tenant_id) REFERENCES tenants(tenant_id) ON DELETE CASCADE,
|
|
UNIQUE(tenant_id, period_start)
|
|
);
|
|
|
|
-- Project membership and roles
|
|
CREATE TABLE IF NOT EXISTS project_members (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
project_id TEXT NOT NULL,
|
|
user_id TEXT NOT NULL,
|
|
role TEXT NOT NULL DEFAULT 'viewer', -- viewer, editor, admin, owner
|
|
invited_by TEXT,
|
|
created_at TEXT DEFAULT CURRENT_TIMESTAMP,
|
|
FOREIGN KEY (project_id) REFERENCES projects(project_id) ON DELETE CASCADE,
|
|
UNIQUE(project_id, user_id)
|
|
);
|
|
|
|
-- API keys for programmatic access
|
|
CREATE TABLE IF NOT EXISTS api_keys (
|
|
key_id TEXT PRIMARY KEY,
|
|
tenant_id TEXT NOT NULL,
|
|
project_id TEXT,
|
|
key_hash TEXT NOT NULL,
|
|
name TEXT NOT NULL,
|
|
permissions TEXT, -- JSON
|
|
rate_limit_per_minute INTEGER DEFAULT 60,
|
|
expires_at TEXT,
|
|
last_used_at TEXT,
|
|
is_active INTEGER DEFAULT 1,
|
|
created_at TEXT DEFAULT CURRENT_TIMESTAMP,
|
|
FOREIGN KEY (tenant_id) REFERENCES tenants(tenant_id) ON DELETE CASCADE,
|
|
FOREIGN KEY (project_id) REFERENCES projects(project_id) ON DELETE SET NULL
|
|
);
|
|
|
|
-- ============================================================
|
|
-- AGENT GOVERNANCE TABLES
|
|
-- ============================================================
|
|
|
|
CREATE TABLE IF NOT EXISTS agent_actions (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
tenant_id TEXT DEFAULT 'default',
|
|
project_id TEXT DEFAULT 'default',
|
|
timestamp TEXT NOT NULL,
|
|
agent_id TEXT NOT NULL,
|
|
agent_version TEXT NOT NULL,
|
|
tier INTEGER NOT NULL,
|
|
action TEXT NOT NULL,
|
|
decision TEXT NOT NULL,
|
|
confidence REAL NOT NULL,
|
|
target TEXT,
|
|
side_effects TEXT, -- JSON array
|
|
success INTEGER NOT NULL, -- 0 or 1
|
|
error_type TEXT,
|
|
error_message TEXT,
|
|
vault_token_accessor TEXT,
|
|
session_id TEXT,
|
|
created_at TEXT DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS agent_metrics (
|
|
agent_id TEXT PRIMARY KEY,
|
|
tenant_id TEXT DEFAULT 'default',
|
|
project_id TEXT DEFAULT 'default',
|
|
current_tier INTEGER DEFAULT 0,
|
|
compliant_runs INTEGER DEFAULT 0,
|
|
consecutive_compliant INTEGER DEFAULT 0,
|
|
total_runs INTEGER DEFAULT 0,
|
|
last_violation_at TEXT,
|
|
last_active_at TEXT,
|
|
promotion_eligible INTEGER DEFAULT 0,
|
|
updated_at TEXT DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS violations (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
tenant_id TEXT DEFAULT 'default',
|
|
project_id TEXT DEFAULT 'default',
|
|
timestamp TEXT NOT NULL,
|
|
agent_id TEXT NOT NULL,
|
|
violation_type TEXT NOT NULL,
|
|
severity TEXT NOT NULL, -- low, medium, high, critical
|
|
description TEXT NOT NULL,
|
|
triggering_action TEXT,
|
|
evidence TEXT, -- JSON
|
|
remediation TEXT,
|
|
acknowledged INTEGER DEFAULT 0,
|
|
acknowledged_by TEXT,
|
|
created_at TEXT DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS promotions (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
tenant_id TEXT DEFAULT 'default',
|
|
project_id TEXT DEFAULT 'default',
|
|
timestamp TEXT NOT NULL,
|
|
agent_id TEXT NOT NULL,
|
|
from_tier INTEGER NOT NULL,
|
|
to_tier INTEGER NOT NULL,
|
|
approved_by TEXT NOT NULL,
|
|
rationale TEXT,
|
|
evidence TEXT, -- JSON
|
|
created_at TEXT DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
|
|
-- ============================================================
|
|
-- ORCHESTRATION TABLES
|
|
-- ============================================================
|
|
|
|
CREATE TABLE IF NOT EXISTS orchestration_log (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
tenant_id TEXT DEFAULT 'default',
|
|
project_id TEXT DEFAULT 'default',
|
|
timestamp TEXT NOT NULL,
|
|
model TEXT NOT NULL,
|
|
instruction TEXT NOT NULL,
|
|
response TEXT,
|
|
tokens_used INTEGER,
|
|
success INTEGER NOT NULL,
|
|
error_message TEXT,
|
|
checkpoint_before TEXT,
|
|
checkpoint_after TEXT,
|
|
created_at TEXT DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
|
|
-- ============================================================
|
|
-- INDEXES
|
|
-- ============================================================
|
|
|
|
-- Multi-tenant indexes
|
|
CREATE INDEX IF NOT EXISTS idx_projects_tenant ON projects(tenant_id);
|
|
CREATE INDEX IF NOT EXISTS idx_tenant_usage_tenant ON tenant_usage(tenant_id);
|
|
CREATE INDEX IF NOT EXISTS idx_project_members_project ON project_members(project_id);
|
|
CREATE INDEX IF NOT EXISTS idx_project_members_user ON project_members(user_id);
|
|
CREATE INDEX IF NOT EXISTS idx_api_keys_tenant ON api_keys(tenant_id);
|
|
|
|
-- Agent table indexes
|
|
CREATE INDEX IF NOT EXISTS idx_actions_agent ON agent_actions(agent_id);
|
|
CREATE INDEX IF NOT EXISTS idx_actions_timestamp ON agent_actions(timestamp);
|
|
CREATE INDEX IF NOT EXISTS idx_actions_tenant ON agent_actions(tenant_id);
|
|
CREATE INDEX IF NOT EXISTS idx_actions_project ON agent_actions(project_id);
|
|
CREATE INDEX IF NOT EXISTS idx_metrics_tenant ON agent_metrics(tenant_id);
|
|
CREATE INDEX IF NOT EXISTS idx_metrics_project ON agent_metrics(project_id);
|
|
CREATE INDEX IF NOT EXISTS idx_violations_agent ON violations(agent_id);
|
|
CREATE INDEX IF NOT EXISTS idx_violations_severity ON violations(severity);
|
|
CREATE INDEX IF NOT EXISTS idx_violations_tenant ON violations(tenant_id);
|
|
CREATE INDEX IF NOT EXISTS idx_promotions_tenant ON promotions(tenant_id);
|
|
|
|
-- ============================================================
|
|
-- DEFAULT DATA
|
|
-- ============================================================
|
|
|
|
INSERT OR IGNORE INTO tenants (tenant_id, name, slug, subscription_tier)
|
|
VALUES ('default', 'Default Tenant', 'default', 'enterprise');
|
|
|
|
INSERT OR IGNORE INTO projects (project_id, tenant_id, name, slug)
|
|
VALUES ('default', 'default', 'Default Project', 'default');
|
|
|
|
INSERT OR IGNORE INTO tenant_quotas (
|
|
tenant_id, max_projects, max_agents_per_project,
|
|
max_concurrent_executions, max_storage_bytes,
|
|
max_api_calls_per_day, max_tokens_per_day, cost_budget_cents
|
|
) VALUES (
|
|
'default', 100, 100, 50, 107374182400, 1000000, 100000000, 1000000
|
|
);
|