mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-15 07:04:01 -06:00
14940edf15
* feat(skills): add lifecycle hook contracts * feat(plugins): expose skill hook contracts * feat(plugins): identify skill evaluators * feat(skills): persist proposal evaluation lifecycle * feat(skills): add agent evaluation action * feat(skills): emit committed skill lifecycle changes * feat(gateway): expose skill proposal evaluation lifecycle * feat(ui): add Skill Workshop evaluations * fix(skills): bind lifecycle state to proposal revisions * fix(skills): preserve lifecycle events without artifacts * feat(cli): evaluate skill proposals * fix(ui): bind evaluations to proposal revisions * docs(skills): document lifecycle hook primitives * chore(plugin-sdk): refresh skill hook surface * fix(skills): harden proposal evaluator execution * fix(plugins): isolate skill evaluator inputs * fix(cli): align skill lifecycle deadlines * fix(skills): preserve evaluation replay invariants * test(ui): capture Skill Workshop evaluation proof * fix(skills): bind apply to evaluated target tree * fix(skills): preserve evaluation contract edges * fix(skills): bound evaluation event storage * chore(skills): keep lifecycle helpers internal * refactor(skills): isolate evaluation persistence * fix(skills): satisfy lifecycle validation gates * chore(protocol): refresh Skill Workshop clients * docs: refresh Skill Workshop map * chore: keep release notes in PR metadata * docs: refresh merged docs map * fix(ci): type Code Mode catch errors * fix(skills): freeze lifecycle observation payloads * fix(protocol): keep proposal inspect backward-decodable * fix(skills): enforce final evaluator bundle limits * fix(skills): preserve lifecycle caller attribution * chore: drop subsumed Code Mode formatting * test(plugins): adapt lifecycle hook mocks
2192 lines
69 KiB
SQL
2192 lines
69 KiB
SQL
CREATE TABLE IF NOT EXISTS auth_profile_stores (
|
|
store_key TEXT NOT NULL PRIMARY KEY,
|
|
store_json TEXT NOT NULL,
|
|
updated_at INTEGER NOT NULL
|
|
) STRICT;
|
|
|
|
CREATE TABLE IF NOT EXISTS auth_profile_state (
|
|
store_key TEXT NOT NULL PRIMARY KEY,
|
|
state_json TEXT NOT NULL,
|
|
updated_at INTEGER NOT NULL
|
|
) STRICT;
|
|
|
|
CREATE TABLE IF NOT EXISTS mcp_oauth_stores (
|
|
store_key TEXT NOT NULL PRIMARY KEY,
|
|
format_version INTEGER NOT NULL CHECK (format_version = 1),
|
|
store_json TEXT NOT NULL,
|
|
updated_at INTEGER NOT NULL
|
|
) STRICT;
|
|
|
|
CREATE TABLE IF NOT EXISTS diagnostic_events (
|
|
scope TEXT NOT NULL,
|
|
event_key TEXT NOT NULL,
|
|
payload_json TEXT NOT NULL,
|
|
created_at INTEGER NOT NULL,
|
|
sequence INTEGER NOT NULL DEFAULT 0,
|
|
PRIMARY KEY (scope, event_key)
|
|
) STRICT;
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_diagnostic_events_scope_sequence
|
|
ON diagnostic_events(scope, sequence, event_key);
|
|
|
|
CREATE TABLE IF NOT EXISTS skill_usage (
|
|
skill_file TEXT NOT NULL PRIMARY KEY,
|
|
skill_key TEXT NOT NULL,
|
|
skill_name TEXT NOT NULL,
|
|
skill_source TEXT NOT NULL,
|
|
first_used_at_ms INTEGER NOT NULL,
|
|
last_used_at_ms INTEGER NOT NULL,
|
|
use_count INTEGER NOT NULL,
|
|
last_agent_id TEXT
|
|
) STRICT;
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_skill_usage_key
|
|
ON skill_usage(skill_key, skill_file);
|
|
|
|
CREATE TABLE IF NOT EXISTS skill_lifecycle (
|
|
skill_file TEXT NOT NULL PRIMARY KEY,
|
|
skill_key TEXT NOT NULL,
|
|
skill_name TEXT NOT NULL,
|
|
state TEXT NOT NULL CHECK (state IN ('active', 'stale', 'archived')),
|
|
pinned INTEGER NOT NULL DEFAULT 0,
|
|
state_changed_at_ms INTEGER NOT NULL,
|
|
created_at_ms INTEGER NOT NULL,
|
|
archived_reason TEXT
|
|
) STRICT;
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_skill_lifecycle_key
|
|
ON skill_lifecycle(skill_key, skill_file);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_skill_lifecycle_state
|
|
ON skill_lifecycle(state, skill_file);
|
|
|
|
CREATE TABLE IF NOT EXISTS skill_curator_state (
|
|
id INTEGER NOT NULL PRIMARY KEY CHECK (id = 1),
|
|
last_attempt_at_ms INTEGER NOT NULL,
|
|
last_success_at_ms INTEGER,
|
|
last_error TEXT,
|
|
last_result_json TEXT NOT NULL
|
|
) STRICT;
|
|
|
|
CREATE TABLE IF NOT EXISTS skill_workshop_proposals (
|
|
proposal_id TEXT NOT NULL PRIMARY KEY,
|
|
record_json TEXT NOT NULL,
|
|
owner_agent_id TEXT,
|
|
workspace_dir TEXT NOT NULL,
|
|
kind TEXT NOT NULL CHECK (kind IN ('create', 'update')),
|
|
status TEXT NOT NULL CHECK (status IN ('pending', 'applied', 'rejected', 'quarantined', 'stale')),
|
|
created_at TEXT NOT NULL,
|
|
updated_at TEXT NOT NULL,
|
|
draft_hash TEXT NOT NULL,
|
|
origin_agent_id TEXT,
|
|
origin_session_key TEXT,
|
|
origin_run_id TEXT,
|
|
origin_message_id TEXT,
|
|
applied_at TEXT,
|
|
rejected_at TEXT,
|
|
quarantined_at TEXT,
|
|
stale_at TEXT,
|
|
status_reason TEXT
|
|
) STRICT;
|
|
|
|
CREATE TABLE IF NOT EXISTS skill_workshop_proposal_origin_runs (
|
|
proposal_id TEXT NOT NULL,
|
|
run_id TEXT NOT NULL,
|
|
position INTEGER NOT NULL,
|
|
mutation_count INTEGER NOT NULL CHECK (mutation_count > 0),
|
|
PRIMARY KEY (proposal_id, run_id),
|
|
FOREIGN KEY (proposal_id) REFERENCES skill_workshop_proposals(proposal_id) ON DELETE CASCADE
|
|
) STRICT;
|
|
|
|
CREATE TABLE IF NOT EXISTS skill_workshop_proposal_rollbacks (
|
|
proposal_id TEXT NOT NULL PRIMARY KEY,
|
|
written_at TEXT NOT NULL,
|
|
target_skill_file TEXT NOT NULL,
|
|
action TEXT NOT NULL CHECK (action IN ('create', 'update')),
|
|
previous_content_hash TEXT,
|
|
previous_content TEXT,
|
|
support_files_json TEXT,
|
|
FOREIGN KEY (proposal_id) REFERENCES skill_workshop_proposals(proposal_id) ON DELETE CASCADE
|
|
) STRICT;
|
|
|
|
CREATE TABLE IF NOT EXISTS skill_workshop_proposal_events (
|
|
sequence INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
event_id TEXT NOT NULL UNIQUE,
|
|
proposal_id TEXT NOT NULL,
|
|
proposed_version TEXT NOT NULL,
|
|
revision_hash TEXT NOT NULL,
|
|
event_type TEXT NOT NULL CHECK (event_type IN (
|
|
'created',
|
|
'revised',
|
|
'evaluation_completed',
|
|
'applied',
|
|
'rejected',
|
|
'quarantined',
|
|
'stale'
|
|
)),
|
|
occurred_at TEXT NOT NULL,
|
|
actor_json TEXT NOT NULL,
|
|
correlation_id TEXT,
|
|
payload_json TEXT,
|
|
FOREIGN KEY (proposal_id) REFERENCES skill_workshop_proposals(proposal_id) ON DELETE CASCADE
|
|
) STRICT;
|
|
|
|
CREATE TABLE IF NOT EXISTS audit_events (
|
|
sequence INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
event_id TEXT NOT NULL UNIQUE,
|
|
source_id TEXT NOT NULL UNIQUE,
|
|
schema_version INTEGER NOT NULL DEFAULT 1,
|
|
source_sequence INTEGER NOT NULL,
|
|
occurred_at INTEGER NOT NULL,
|
|
kind TEXT NOT NULL,
|
|
action TEXT NOT NULL,
|
|
status TEXT NOT NULL,
|
|
error_code TEXT,
|
|
actor_type TEXT NOT NULL,
|
|
actor_id TEXT NOT NULL,
|
|
agent_id TEXT,
|
|
session_key TEXT,
|
|
session_id TEXT,
|
|
run_id TEXT,
|
|
tool_call_id TEXT,
|
|
tool_name TEXT,
|
|
direction TEXT,
|
|
channel TEXT,
|
|
conversation_kind TEXT,
|
|
message_outcome TEXT,
|
|
reason_code TEXT,
|
|
delivery_kind TEXT,
|
|
failure_stage TEXT,
|
|
duration_ms INTEGER,
|
|
result_count INTEGER,
|
|
account_ref TEXT,
|
|
conversation_ref TEXT,
|
|
message_ref TEXT,
|
|
target_ref TEXT
|
|
) STRICT;
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_audit_events_time
|
|
ON audit_events(occurred_at DESC, sequence DESC);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_audit_events_agent_sequence
|
|
ON audit_events(agent_id, sequence DESC);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_audit_events_session_sequence
|
|
ON audit_events(session_key, sequence DESC);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_audit_events_run_sequence
|
|
ON audit_events(run_id, sequence DESC);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_audit_events_kind_sequence
|
|
ON audit_events(kind, sequence DESC);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_audit_events_status_sequence
|
|
ON audit_events(status, sequence DESC);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_audit_events_channel_sequence
|
|
ON audit_events(channel, sequence DESC);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_audit_events_direction_sequence
|
|
ON audit_events(direction, sequence DESC);
|
|
|
|
CREATE TABLE IF NOT EXISTS audit_identity_keys (
|
|
id INTEGER NOT NULL PRIMARY KEY CHECK (id = 1),
|
|
key_id TEXT NOT NULL,
|
|
key BLOB NOT NULL,
|
|
created_at INTEGER NOT NULL
|
|
) STRICT;
|
|
|
|
CREATE TABLE IF NOT EXISTS session_state_events (
|
|
sequence INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
dedupe_key TEXT UNIQUE,
|
|
session_key TEXT NOT NULL,
|
|
session_id TEXT,
|
|
agent_id TEXT NOT NULL,
|
|
kind TEXT NOT NULL,
|
|
actor_type TEXT NOT NULL,
|
|
actor_id TEXT,
|
|
run_id TEXT,
|
|
occurred_at INTEGER NOT NULL,
|
|
summary TEXT NOT NULL,
|
|
payload_json TEXT
|
|
) STRICT;
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_session_state_events_session_sequence
|
|
ON session_state_events(session_key, sequence DESC);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_session_state_events_time
|
|
ON session_state_events(occurred_at DESC, sequence DESC);
|
|
|
|
CREATE TABLE IF NOT EXISTS session_state_heads (
|
|
session_key TEXT NOT NULL,
|
|
agent_id TEXT NOT NULL,
|
|
last_sequence INTEGER NOT NULL,
|
|
pruned_max_sequence INTEGER NOT NULL DEFAULT 0,
|
|
updated_at INTEGER NOT NULL,
|
|
PRIMARY KEY (session_key, agent_id)
|
|
) STRICT;
|
|
|
|
-- Notifiable watcher identity is the bare session key, matching the process-local
|
|
-- system-event queue it feeds. Provenance distinguishes explicit immediate-wake
|
|
-- watches from ambient queue-only group watches. Other bare keys
|
|
-- (session.scope="global") are ambiguous across agents and excluded until watcher
|
|
-- identity is agent-scoped end-to-end.
|
|
CREATE TABLE IF NOT EXISTS session_watch_cursors (
|
|
watcher_session_key TEXT NOT NULL,
|
|
target_session_key TEXT NOT NULL,
|
|
last_seen_sequence INTEGER NOT NULL DEFAULT 0,
|
|
notified_sequence INTEGER NOT NULL DEFAULT 0,
|
|
material_sequence INTEGER NOT NULL DEFAULT 0,
|
|
provenance TEXT NOT NULL DEFAULT 'explicit' CHECK (provenance IN ('explicit', 'ambient-group')),
|
|
updated_at INTEGER NOT NULL,
|
|
PRIMARY KEY (watcher_session_key, target_session_key)
|
|
) STRICT;
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_session_watch_cursors_target
|
|
ON session_watch_cursors(target_session_key);
|
|
|
|
CREATE TABLE IF NOT EXISTS session_upstream_links (
|
|
session_key TEXT NOT NULL,
|
|
agent_id TEXT NOT NULL,
|
|
catalog_id TEXT NOT NULL,
|
|
host_id TEXT NOT NULL,
|
|
thread_id TEXT NOT NULL,
|
|
upstream_kind TEXT NOT NULL,
|
|
upstream_ref_json TEXT,
|
|
last_marker_json TEXT,
|
|
last_scanned_at INTEGER,
|
|
created_at INTEGER NOT NULL,
|
|
updated_at INTEGER NOT NULL,
|
|
-- (session_key, agent_id) composite identity: under session.scope="global" agents
|
|
-- share bare keys; a key-only row would let one agent overwrite another's upstream.
|
|
PRIMARY KEY (session_key, agent_id)
|
|
) STRICT;
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_session_upstream_links_catalog_id
|
|
ON session_upstream_links(catalog_id);
|
|
|
|
CREATE TABLE IF NOT EXISTS diagnostic_stability_bundles (
|
|
bundle_key TEXT NOT NULL PRIMARY KEY,
|
|
reason TEXT NOT NULL,
|
|
generated_at TEXT NOT NULL,
|
|
bundle_json TEXT NOT NULL,
|
|
created_at INTEGER NOT NULL
|
|
) STRICT;
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_diagnostic_stability_bundles_created
|
|
ON diagnostic_stability_bundles(created_at DESC, bundle_key);
|
|
|
|
CREATE TABLE IF NOT EXISTS state_leases (
|
|
scope TEXT NOT NULL,
|
|
lease_key TEXT NOT NULL,
|
|
owner TEXT NOT NULL,
|
|
expires_at INTEGER,
|
|
heartbeat_at INTEGER,
|
|
payload_json TEXT,
|
|
created_at INTEGER NOT NULL,
|
|
updated_at INTEGER NOT NULL,
|
|
PRIMARY KEY (scope, lease_key)
|
|
) STRICT;
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_state_leases_expiry
|
|
ON state_leases(expires_at, scope, lease_key)
|
|
WHERE expires_at IS NOT NULL;
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_state_leases_owner
|
|
ON state_leases(owner, updated_at DESC);
|
|
|
|
CREATE TABLE IF NOT EXISTS exec_approvals_config (
|
|
config_key TEXT NOT NULL PRIMARY KEY,
|
|
raw_json TEXT NOT NULL,
|
|
socket_path TEXT,
|
|
has_socket_token INTEGER NOT NULL,
|
|
default_security TEXT,
|
|
default_ask TEXT,
|
|
default_ask_fallback TEXT,
|
|
auto_allow_skills INTEGER,
|
|
agent_count INTEGER NOT NULL,
|
|
allowlist_count INTEGER NOT NULL,
|
|
updated_at_ms INTEGER NOT NULL
|
|
) STRICT;
|
|
|
|
CREATE TABLE IF NOT EXISTS operator_approvals (
|
|
approval_id TEXT NOT NULL PRIMARY KEY CHECK (
|
|
length(approval_id) > 0 AND approval_id NOT IN ('.', '..')
|
|
),
|
|
resolution_ref TEXT NOT NULL CHECK (
|
|
length(resolution_ref) = 43 AND resolution_ref NOT GLOB '*[^A-Za-z0-9_-]*'
|
|
),
|
|
kind TEXT NOT NULL CHECK (kind IN ('exec', 'plugin', 'system-agent')),
|
|
status TEXT NOT NULL CHECK (status IN ('pending', 'allowed', 'denied', 'expired', 'cancelled')),
|
|
presentation_json TEXT NOT NULL,
|
|
requested_by_device_id TEXT,
|
|
requested_by_client_id TEXT,
|
|
requested_by_device_token_auth INTEGER NOT NULL DEFAULT 0,
|
|
reviewer_device_ids_json TEXT NOT NULL,
|
|
source_agent_id TEXT,
|
|
source_session_key TEXT,
|
|
source_session_id TEXT,
|
|
source_run_id TEXT,
|
|
source_tool_call_id TEXT,
|
|
source_tool_name TEXT,
|
|
audience_session_keys_json TEXT NOT NULL,
|
|
runtime_epoch TEXT NOT NULL,
|
|
created_at_ms INTEGER NOT NULL,
|
|
expires_at_ms INTEGER NOT NULL,
|
|
updated_at_ms INTEGER NOT NULL,
|
|
decision TEXT CHECK (decision IN ('allow-once', 'allow-always', 'deny')),
|
|
terminal_reason TEXT CHECK (
|
|
terminal_reason IN (
|
|
'user',
|
|
'timeout',
|
|
'malformed-verdict',
|
|
'no-route',
|
|
'run-aborted',
|
|
'gateway-restart',
|
|
'storage-corrupt'
|
|
)
|
|
),
|
|
resolved_at_ms INTEGER,
|
|
resolver_kind TEXT CHECK (resolver_kind IN ('device', 'channel', 'runtime', 'system')),
|
|
resolver_id TEXT,
|
|
consumed_at_ms INTEGER,
|
|
consumed_by TEXT,
|
|
CHECK (expires_at_ms >= created_at_ms),
|
|
CHECK (updated_at_ms >= created_at_ms),
|
|
CHECK (resolved_at_ms IS NULL OR resolved_at_ms >= created_at_ms),
|
|
CHECK (resolved_at_ms IS NULL OR resolved_at_ms <= updated_at_ms),
|
|
CHECK (consumed_at_ms IS NULL OR consumed_at_ms >= resolved_at_ms),
|
|
CHECK (consumed_at_ms IS NULL OR consumed_at_ms <= updated_at_ms),
|
|
CHECK (requested_by_device_token_auth IN (0, 1)),
|
|
CHECK (
|
|
(
|
|
status = 'pending'
|
|
AND decision IS NULL
|
|
AND terminal_reason IS NULL
|
|
AND resolved_at_ms IS NULL
|
|
AND resolver_kind IS NULL
|
|
AND resolver_id IS NULL
|
|
AND consumed_at_ms IS NULL
|
|
AND consumed_by IS NULL
|
|
)
|
|
OR (
|
|
status = 'allowed'
|
|
AND decision IN ('allow-once', 'allow-always')
|
|
AND terminal_reason = 'user'
|
|
AND resolved_at_ms IS NOT NULL
|
|
AND resolver_kind IS NOT NULL
|
|
)
|
|
OR (
|
|
status = 'denied'
|
|
AND decision = 'deny'
|
|
AND terminal_reason IN ('user', 'malformed-verdict', 'no-route', 'storage-corrupt')
|
|
AND resolved_at_ms IS NOT NULL
|
|
AND resolver_kind IS NOT NULL
|
|
AND consumed_at_ms IS NULL
|
|
AND consumed_by IS NULL
|
|
)
|
|
OR (
|
|
status = 'expired'
|
|
AND decision = 'deny'
|
|
AND terminal_reason = 'timeout'
|
|
AND resolved_at_ms IS NOT NULL
|
|
AND resolver_kind IS NOT NULL
|
|
AND consumed_at_ms IS NULL
|
|
AND consumed_by IS NULL
|
|
)
|
|
OR (
|
|
status = 'cancelled'
|
|
AND decision = 'deny'
|
|
AND terminal_reason IN ('run-aborted', 'gateway-restart')
|
|
AND resolved_at_ms IS NOT NULL
|
|
AND resolver_kind IS NOT NULL
|
|
AND consumed_at_ms IS NULL
|
|
AND consumed_by IS NULL
|
|
)
|
|
),
|
|
CHECK (
|
|
(consumed_at_ms IS NULL AND consumed_by IS NULL)
|
|
OR (
|
|
status = 'allowed'
|
|
AND decision = 'allow-once'
|
|
AND consumed_at_ms IS NOT NULL
|
|
AND consumed_by IS NOT NULL
|
|
)
|
|
)
|
|
) STRICT;
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_operator_approvals_status_expiry
|
|
ON operator_approvals(status, expires_at_ms, approval_id);
|
|
|
|
CREATE UNIQUE INDEX IF NOT EXISTS idx_operator_approvals_resolution_ref
|
|
ON operator_approvals(resolution_ref);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_operator_approvals_source_session_created
|
|
ON operator_approvals(source_session_key, created_at_ms DESC, approval_id);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_operator_approvals_resolved
|
|
ON operator_approvals(resolved_at_ms, approval_id)
|
|
WHERE resolved_at_ms IS NOT NULL;
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_operator_approvals_runtime_pending
|
|
ON operator_approvals(runtime_epoch, approval_id)
|
|
WHERE status = 'pending';
|
|
|
|
CREATE TABLE IF NOT EXISTS schema_meta (
|
|
meta_key TEXT NOT NULL PRIMARY KEY,
|
|
role TEXT NOT NULL,
|
|
schema_version INTEGER NOT NULL,
|
|
agent_id TEXT,
|
|
app_version TEXT,
|
|
created_at INTEGER NOT NULL,
|
|
updated_at INTEGER NOT NULL
|
|
) STRICT;
|
|
|
|
CREATE TABLE IF NOT EXISTS config_machine_state (
|
|
state_key TEXT NOT NULL PRIMARY KEY,
|
|
value_json TEXT NOT NULL,
|
|
updated_at_ms INTEGER NOT NULL
|
|
) STRICT;
|
|
|
|
CREATE TABLE IF NOT EXISTS device_pairing_pending (
|
|
request_id TEXT NOT NULL PRIMARY KEY,
|
|
device_id TEXT NOT NULL,
|
|
public_key TEXT NOT NULL,
|
|
display_name TEXT,
|
|
platform TEXT,
|
|
device_family TEXT,
|
|
client_id TEXT,
|
|
client_mode TEXT,
|
|
browser_origin TEXT,
|
|
role TEXT,
|
|
roles_json TEXT,
|
|
scopes_json TEXT,
|
|
remote_ip TEXT,
|
|
silent INTEGER,
|
|
is_repair INTEGER,
|
|
ts INTEGER NOT NULL,
|
|
refreshed_at_ms INTEGER
|
|
) STRICT;
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_device_pairing_pending_device
|
|
ON device_pairing_pending(device_id, ts DESC);
|
|
|
|
CREATE TABLE IF NOT EXISTS device_pairing_paired (
|
|
device_id TEXT NOT NULL PRIMARY KEY,
|
|
public_key TEXT NOT NULL,
|
|
display_name TEXT,
|
|
operator_label TEXT,
|
|
platform TEXT,
|
|
device_family TEXT,
|
|
client_id TEXT,
|
|
client_mode TEXT,
|
|
browser_origin TEXT,
|
|
role TEXT,
|
|
roles_json TEXT,
|
|
scopes_json TEXT,
|
|
approved_scopes_json TEXT,
|
|
remote_ip TEXT,
|
|
tokens_json TEXT,
|
|
approved_via TEXT,
|
|
node_surface_json TEXT,
|
|
pending_node_surface_json TEXT,
|
|
created_at_ms INTEGER NOT NULL,
|
|
approved_at_ms INTEGER NOT NULL,
|
|
last_seen_at_ms INTEGER,
|
|
last_seen_reason TEXT
|
|
) STRICT;
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_device_pairing_paired_approved
|
|
ON device_pairing_paired(approved_at_ms DESC, device_id);
|
|
|
|
CREATE TABLE IF NOT EXISTS device_bootstrap_tokens (
|
|
token_key TEXT NOT NULL PRIMARY KEY,
|
|
token TEXT NOT NULL,
|
|
ts INTEGER NOT NULL,
|
|
device_id TEXT,
|
|
public_key TEXT,
|
|
profile_json TEXT,
|
|
redeemed_profile_json TEXT,
|
|
pending_profile_json TEXT,
|
|
issued_at_ms INTEGER NOT NULL,
|
|
last_used_at_ms INTEGER
|
|
) STRICT;
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_device_bootstrap_tokens_ts
|
|
ON device_bootstrap_tokens(ts);
|
|
|
|
CREATE TABLE IF NOT EXISTS device_identities (
|
|
identity_key TEXT NOT NULL PRIMARY KEY,
|
|
device_id TEXT NOT NULL,
|
|
public_key_pem TEXT NOT NULL,
|
|
private_key_pem TEXT NOT NULL,
|
|
created_at_ms INTEGER NOT NULL,
|
|
updated_at_ms INTEGER NOT NULL
|
|
) STRICT;
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_device_identities_device
|
|
ON device_identities(device_id, updated_at_ms DESC);
|
|
|
|
CREATE TABLE IF NOT EXISTS device_auth_tokens (
|
|
device_id TEXT NOT NULL,
|
|
role TEXT NOT NULL,
|
|
token TEXT NOT NULL,
|
|
scopes_json TEXT NOT NULL,
|
|
updated_at_ms INTEGER NOT NULL,
|
|
PRIMARY KEY (device_id, role)
|
|
) STRICT;
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_device_auth_tokens_updated
|
|
ON device_auth_tokens(updated_at_ms DESC, device_id, role);
|
|
|
|
CREATE TABLE IF NOT EXISTS android_notification_recent_packages (
|
|
package_name TEXT NOT NULL PRIMARY KEY,
|
|
sort_order INTEGER NOT NULL,
|
|
updated_at_ms INTEGER NOT NULL
|
|
) STRICT;
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_android_notification_recent_packages_order
|
|
ON android_notification_recent_packages(sort_order, package_name);
|
|
|
|
CREATE TABLE IF NOT EXISTS macos_port_guardian_records (
|
|
pid INTEGER NOT NULL PRIMARY KEY,
|
|
port INTEGER NOT NULL,
|
|
command TEXT NOT NULL,
|
|
mode TEXT NOT NULL,
|
|
timestamp REAL NOT NULL
|
|
) STRICT;
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_macos_port_guardian_records_port
|
|
ON macos_port_guardian_records(port, timestamp DESC);
|
|
|
|
CREATE TABLE IF NOT EXISTS onboarding_recommendations (
|
|
config_key TEXT NOT NULL PRIMARY KEY,
|
|
inventory_hash TEXT NOT NULL,
|
|
matches_json TEXT NOT NULL,
|
|
offered_at_ms INTEGER NOT NULL,
|
|
accepted_at_ms INTEGER,
|
|
updated_at_ms INTEGER NOT NULL
|
|
) STRICT;
|
|
|
|
CREATE TABLE IF NOT EXISTS workspace_setup_state (
|
|
workspace_key TEXT NOT NULL PRIMARY KEY,
|
|
workspace_path TEXT NOT NULL,
|
|
version INTEGER NOT NULL,
|
|
bootstrap_seeded_at TEXT,
|
|
setup_completed_at TEXT,
|
|
updated_at INTEGER NOT NULL
|
|
) STRICT;
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_workspace_setup_state_path
|
|
ON workspace_setup_state(workspace_path);
|
|
|
|
CREATE TABLE IF NOT EXISTS workspace_path_aliases (
|
|
alias_key TEXT NOT NULL PRIMARY KEY,
|
|
alias_path TEXT NOT NULL,
|
|
workspace_key TEXT NOT NULL,
|
|
workspace_path TEXT NOT NULL,
|
|
updated_at_ms INTEGER NOT NULL
|
|
) STRICT;
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_workspace_path_aliases_workspace
|
|
ON workspace_path_aliases(workspace_key);
|
|
|
|
CREATE TABLE IF NOT EXISTS workspace_attestations (
|
|
workspace_key TEXT NOT NULL PRIMARY KEY,
|
|
attested_at_ms INTEGER NOT NULL,
|
|
updated_at_ms INTEGER NOT NULL
|
|
) STRICT;
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_workspace_attestations_attested
|
|
ON workspace_attestations(attested_at_ms DESC, workspace_key);
|
|
|
|
CREATE TABLE IF NOT EXISTS workspace_generated_bootstrap_hashes (
|
|
workspace_key TEXT NOT NULL,
|
|
filename TEXT NOT NULL,
|
|
sha256 TEXT NOT NULL,
|
|
PRIMARY KEY (workspace_key, filename),
|
|
FOREIGN KEY (workspace_key) REFERENCES workspace_attestations(workspace_key) ON DELETE CASCADE
|
|
) STRICT;
|
|
|
|
CREATE TABLE IF NOT EXISTS native_hook_relay_bridges (
|
|
relay_id TEXT NOT NULL PRIMARY KEY,
|
|
pid INTEGER NOT NULL,
|
|
hostname TEXT NOT NULL,
|
|
port INTEGER NOT NULL,
|
|
token TEXT NOT NULL,
|
|
expires_at_ms INTEGER NOT NULL,
|
|
updated_at_ms INTEGER NOT NULL
|
|
) STRICT;
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_native_hook_relay_bridges_expires
|
|
ON native_hook_relay_bridges(expires_at_ms, relay_id);
|
|
|
|
CREATE TABLE IF NOT EXISTS model_capability_cache (
|
|
provider_id TEXT NOT NULL,
|
|
model_id TEXT NOT NULL,
|
|
name TEXT NOT NULL,
|
|
input_text INTEGER NOT NULL,
|
|
input_image INTEGER NOT NULL,
|
|
reasoning INTEGER NOT NULL,
|
|
supports_tools INTEGER,
|
|
context_window INTEGER NOT NULL,
|
|
max_tokens INTEGER NOT NULL,
|
|
cost_input REAL NOT NULL,
|
|
cost_output REAL NOT NULL,
|
|
cost_cache_read REAL NOT NULL,
|
|
cost_cache_write REAL NOT NULL,
|
|
updated_at_ms INTEGER NOT NULL,
|
|
PRIMARY KEY (provider_id, model_id)
|
|
) STRICT;
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_model_capability_cache_provider_updated
|
|
ON model_capability_cache(provider_id, updated_at_ms DESC, model_id);
|
|
|
|
CREATE TABLE IF NOT EXISTS agent_model_catalogs (
|
|
catalog_key TEXT NOT NULL PRIMARY KEY,
|
|
agent_dir TEXT NOT NULL,
|
|
raw_json TEXT NOT NULL,
|
|
updated_at INTEGER NOT NULL
|
|
) STRICT;
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_agent_model_catalogs_agent_dir
|
|
ON agent_model_catalogs(agent_dir, updated_at DESC);
|
|
|
|
CREATE TABLE IF NOT EXISTS managed_outgoing_image_records (
|
|
attachment_id TEXT NOT NULL PRIMARY KEY,
|
|
session_key TEXT NOT NULL,
|
|
agent_id TEXT,
|
|
message_id TEXT,
|
|
created_at TEXT NOT NULL,
|
|
updated_at TEXT,
|
|
retention_class TEXT,
|
|
alt TEXT NOT NULL,
|
|
original_media_root TEXT NOT NULL,
|
|
original_media_id TEXT NOT NULL,
|
|
original_media_subdir TEXT NOT NULL,
|
|
original_content_type TEXT NOT NULL,
|
|
original_width INTEGER,
|
|
original_height INTEGER,
|
|
original_size_bytes INTEGER,
|
|
original_filename TEXT,
|
|
record_json TEXT NOT NULL,
|
|
cleanup_pending INTEGER NOT NULL DEFAULT 0 CHECK (cleanup_pending IN (0, 1))
|
|
) STRICT;
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_managed_outgoing_images_session
|
|
ON managed_outgoing_image_records(session_key, created_at DESC, attachment_id);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_managed_outgoing_images_message
|
|
ON managed_outgoing_image_records(session_key, message_id, attachment_id)
|
|
WHERE message_id IS NOT NULL;
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_managed_outgoing_images_agent_session
|
|
ON managed_outgoing_image_records(session_key, agent_id, created_at DESC, attachment_id);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_managed_outgoing_images_agent_message
|
|
ON managed_outgoing_image_records(session_key, agent_id, message_id, attachment_id)
|
|
WHERE message_id IS NOT NULL;
|
|
|
|
CREATE TABLE IF NOT EXISTS channel_pairing_requests (
|
|
channel_key TEXT NOT NULL,
|
|
account_id TEXT NOT NULL,
|
|
request_id TEXT NOT NULL,
|
|
code TEXT NOT NULL,
|
|
created_at TEXT NOT NULL,
|
|
last_seen_at TEXT NOT NULL,
|
|
meta_json TEXT,
|
|
PRIMARY KEY (channel_key, account_id, request_id)
|
|
) STRICT;
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_channel_pairing_requests_code
|
|
ON channel_pairing_requests(channel_key, code);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_channel_pairing_requests_created
|
|
ON channel_pairing_requests(channel_key, created_at, request_id);
|
|
|
|
CREATE TABLE IF NOT EXISTS channel_pairing_allow_entries (
|
|
channel_key TEXT NOT NULL,
|
|
account_id TEXT NOT NULL,
|
|
entry TEXT NOT NULL,
|
|
sort_order INTEGER NOT NULL,
|
|
updated_at INTEGER NOT NULL,
|
|
PRIMARY KEY (channel_key, account_id, entry)
|
|
) STRICT;
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_channel_pairing_allow_account
|
|
ON channel_pairing_allow_entries(channel_key, account_id, sort_order, entry);
|
|
|
|
CREATE TABLE IF NOT EXISTS web_push_subscriptions (
|
|
endpoint_hash TEXT NOT NULL PRIMARY KEY,
|
|
subscription_id TEXT NOT NULL UNIQUE,
|
|
endpoint TEXT NOT NULL,
|
|
p256dh TEXT NOT NULL,
|
|
auth TEXT NOT NULL,
|
|
created_at_ms INTEGER NOT NULL,
|
|
updated_at_ms INTEGER NOT NULL
|
|
) STRICT;
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_web_push_subscriptions_updated
|
|
ON web_push_subscriptions(updated_at_ms DESC, subscription_id);
|
|
|
|
CREATE TABLE IF NOT EXISTS web_push_vapid_keys (
|
|
key_id TEXT NOT NULL PRIMARY KEY,
|
|
public_key TEXT NOT NULL,
|
|
private_key TEXT NOT NULL,
|
|
subject TEXT NOT NULL,
|
|
updated_at_ms INTEGER NOT NULL
|
|
) STRICT;
|
|
|
|
CREATE TABLE IF NOT EXISTS apns_registrations (
|
|
node_id TEXT NOT NULL PRIMARY KEY,
|
|
transport TEXT NOT NULL,
|
|
token TEXT,
|
|
relay_handle TEXT,
|
|
send_grant TEXT,
|
|
installation_id TEXT,
|
|
relay_origin TEXT,
|
|
topic TEXT NOT NULL,
|
|
environment TEXT NOT NULL,
|
|
distribution TEXT,
|
|
token_debug_suffix TEXT,
|
|
updated_at_ms INTEGER NOT NULL
|
|
) STRICT;
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_apns_registrations_updated
|
|
ON apns_registrations(updated_at_ms DESC, node_id);
|
|
|
|
CREATE TABLE IF NOT EXISTS apns_registration_tombstones (
|
|
node_id TEXT NOT NULL PRIMARY KEY,
|
|
deleted_at_ms INTEGER NOT NULL
|
|
) STRICT;
|
|
|
|
CREATE TABLE IF NOT EXISTS node_host_config (
|
|
config_key TEXT NOT NULL PRIMARY KEY,
|
|
version INTEGER NOT NULL,
|
|
node_id TEXT NOT NULL,
|
|
token TEXT,
|
|
display_name TEXT,
|
|
gateway_host TEXT,
|
|
gateway_port INTEGER,
|
|
gateway_tls INTEGER,
|
|
gateway_tls_fingerprint TEXT,
|
|
gateway_context_path TEXT,
|
|
installed_apps_sharing INTEGER NOT NULL DEFAULT 0,
|
|
updated_at_ms INTEGER NOT NULL
|
|
) STRICT;
|
|
|
|
CREATE TABLE IF NOT EXISTS voicewake_triggers (
|
|
config_key TEXT NOT NULL,
|
|
position INTEGER NOT NULL,
|
|
trigger TEXT NOT NULL,
|
|
updated_at_ms INTEGER NOT NULL,
|
|
PRIMARY KEY (config_key, position)
|
|
) STRICT;
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_voicewake_triggers_trigger
|
|
ON voicewake_triggers(config_key, trigger);
|
|
|
|
CREATE TABLE IF NOT EXISTS voicewake_routing_config (
|
|
config_key TEXT NOT NULL PRIMARY KEY,
|
|
version INTEGER NOT NULL,
|
|
default_target_mode TEXT NOT NULL,
|
|
default_target_agent_id TEXT,
|
|
default_target_session_key TEXT,
|
|
updated_at_ms INTEGER NOT NULL
|
|
) STRICT;
|
|
|
|
CREATE TABLE IF NOT EXISTS voicewake_routing_routes (
|
|
config_key TEXT NOT NULL,
|
|
position INTEGER NOT NULL,
|
|
trigger TEXT NOT NULL,
|
|
target_mode TEXT NOT NULL,
|
|
target_agent_id TEXT,
|
|
target_session_key TEXT,
|
|
updated_at_ms INTEGER NOT NULL,
|
|
PRIMARY KEY (config_key, position),
|
|
FOREIGN KEY (config_key) REFERENCES voicewake_routing_config(config_key) ON DELETE CASCADE
|
|
) STRICT;
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_voicewake_routing_routes_trigger
|
|
ON voicewake_routing_routes(config_key, trigger);
|
|
|
|
CREATE TABLE IF NOT EXISTS update_check_state (
|
|
state_key TEXT NOT NULL PRIMARY KEY,
|
|
last_checked_at TEXT,
|
|
last_notified_version TEXT,
|
|
last_notified_tag TEXT,
|
|
last_available_version TEXT,
|
|
last_available_tag TEXT,
|
|
auto_install_id TEXT,
|
|
auto_first_seen_version TEXT,
|
|
auto_first_seen_tag TEXT,
|
|
auto_first_seen_at TEXT,
|
|
auto_last_attempt_version TEXT,
|
|
auto_last_attempt_at TEXT,
|
|
auto_last_success_version TEXT,
|
|
auto_last_success_at TEXT,
|
|
updated_at_ms INTEGER NOT NULL
|
|
) STRICT;
|
|
|
|
CREATE TABLE IF NOT EXISTS config_health_entries (
|
|
config_path TEXT NOT NULL PRIMARY KEY,
|
|
last_known_good_json TEXT,
|
|
last_promoted_good_json TEXT,
|
|
last_observed_suspicious_signature TEXT,
|
|
updated_at_ms INTEGER NOT NULL
|
|
) STRICT;
|
|
|
|
CREATE TABLE IF NOT EXISTS clawhub_promotions_feed_state (
|
|
state_key TEXT NOT NULL PRIMARY KEY,
|
|
etag TEXT,
|
|
payload_json TEXT,
|
|
feed_sequence INTEGER,
|
|
last_checked_at_ms INTEGER,
|
|
notified_slugs_json TEXT NOT NULL DEFAULT '[]',
|
|
updated_at_ms INTEGER NOT NULL
|
|
) STRICT;
|
|
|
|
CREATE TABLE IF NOT EXISTS clawhub_promotion_claims (
|
|
slug TEXT NOT NULL PRIMARY KEY,
|
|
provider TEXT,
|
|
model_keys_json TEXT NOT NULL,
|
|
ends_at_ms INTEGER NOT NULL,
|
|
claimed_at_ms INTEGER NOT NULL
|
|
) STRICT;
|
|
|
|
CREATE TABLE IF NOT EXISTS installed_plugin_index (
|
|
index_key TEXT NOT NULL PRIMARY KEY,
|
|
version INTEGER NOT NULL,
|
|
host_contract_version TEXT NOT NULL,
|
|
compat_registry_version TEXT NOT NULL,
|
|
migration_version INTEGER NOT NULL,
|
|
policy_hash TEXT NOT NULL,
|
|
generated_at_ms INTEGER NOT NULL,
|
|
refresh_reason TEXT,
|
|
install_records_json TEXT NOT NULL,
|
|
plugins_json TEXT NOT NULL,
|
|
diagnostics_json TEXT NOT NULL,
|
|
warning TEXT,
|
|
updated_at_ms INTEGER NOT NULL
|
|
) STRICT;
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_installed_plugin_index_generated
|
|
ON installed_plugin_index(generated_at_ms DESC, index_key);
|
|
|
|
CREATE TABLE IF NOT EXISTS official_external_plugin_catalog_snapshots (
|
|
feed_url TEXT NOT NULL PRIMARY KEY,
|
|
body TEXT NOT NULL,
|
|
status INTEGER NOT NULL,
|
|
etag TEXT,
|
|
last_modified TEXT,
|
|
checksum TEXT NOT NULL,
|
|
saved_at TEXT NOT NULL,
|
|
trust_mode TEXT,
|
|
trust_key_id TEXT,
|
|
trust_signature_count INTEGER,
|
|
trust_threshold INTEGER,
|
|
trust_verified_at TEXT,
|
|
updated_at_ms INTEGER NOT NULL
|
|
) STRICT;
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_official_external_plugin_catalog_snapshots_updated
|
|
ON official_external_plugin_catalog_snapshots(updated_at_ms DESC, feed_url);
|
|
|
|
CREATE TABLE IF NOT EXISTS gateway_restart_sentinel (
|
|
sentinel_key TEXT NOT NULL PRIMARY KEY,
|
|
version INTEGER NOT NULL,
|
|
kind TEXT NOT NULL,
|
|
status TEXT NOT NULL,
|
|
ts INTEGER NOT NULL,
|
|
session_key TEXT,
|
|
thread_id TEXT,
|
|
delivery_channel TEXT,
|
|
delivery_to TEXT,
|
|
delivery_account_id TEXT,
|
|
message TEXT,
|
|
continuation_json TEXT,
|
|
doctor_hint TEXT,
|
|
stats_json TEXT,
|
|
payload_json TEXT NOT NULL,
|
|
updated_at_ms INTEGER NOT NULL
|
|
) STRICT;
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_gateway_restart_sentinel_ts
|
|
ON gateway_restart_sentinel(ts DESC, sentinel_key);
|
|
|
|
CREATE TABLE IF NOT EXISTS gateway_restart_intent (
|
|
intent_key TEXT NOT NULL PRIMARY KEY,
|
|
kind TEXT NOT NULL,
|
|
pid INTEGER NOT NULL,
|
|
created_at INTEGER NOT NULL,
|
|
reason TEXT,
|
|
force INTEGER,
|
|
wait_ms INTEGER,
|
|
updated_at_ms INTEGER NOT NULL
|
|
) STRICT;
|
|
|
|
CREATE TABLE IF NOT EXISTS gateway_restart_handoff (
|
|
handoff_key TEXT NOT NULL PRIMARY KEY,
|
|
kind TEXT NOT NULL,
|
|
version INTEGER NOT NULL,
|
|
intent_id TEXT NOT NULL,
|
|
pid INTEGER NOT NULL,
|
|
process_instance_id TEXT,
|
|
created_at INTEGER NOT NULL,
|
|
expires_at INTEGER NOT NULL,
|
|
reason TEXT,
|
|
restart_trace_started_at INTEGER,
|
|
restart_trace_last_at INTEGER,
|
|
source TEXT NOT NULL,
|
|
restart_kind TEXT NOT NULL,
|
|
supervisor_mode TEXT NOT NULL,
|
|
updated_at_ms INTEGER NOT NULL
|
|
) STRICT;
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_gateway_restart_handoff_expiry
|
|
ON gateway_restart_handoff(expires_at, pid);
|
|
|
|
CREATE TABLE IF NOT EXISTS gateway_boot_lifecycle (
|
|
boot_id TEXT NOT NULL PRIMARY KEY,
|
|
pid INTEGER NOT NULL,
|
|
started_at_ms INTEGER NOT NULL,
|
|
completed_at_ms INTEGER,
|
|
outcome TEXT,
|
|
startup_reason TEXT,
|
|
reason TEXT
|
|
) STRICT;
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_gateway_boot_lifecycle_started
|
|
ON gateway_boot_lifecycle(started_at_ms);
|
|
|
|
CREATE TABLE IF NOT EXISTS acp_sessions (
|
|
session_key TEXT NOT NULL PRIMARY KEY,
|
|
session_id TEXT,
|
|
backend TEXT NOT NULL,
|
|
agent TEXT NOT NULL,
|
|
runtime_session_name TEXT NOT NULL,
|
|
identity_json TEXT,
|
|
mode TEXT NOT NULL,
|
|
runtime_options_json TEXT,
|
|
cwd TEXT,
|
|
state TEXT NOT NULL,
|
|
last_activity_at INTEGER NOT NULL,
|
|
last_error TEXT,
|
|
updated_at INTEGER NOT NULL
|
|
) STRICT;
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_acp_sessions_state_activity
|
|
ON acp_sessions(state, last_activity_at DESC, session_key);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_acp_sessions_agent_activity
|
|
ON acp_sessions(agent, last_activity_at DESC, session_key);
|
|
|
|
CREATE TABLE IF NOT EXISTS acp_replay_sessions (
|
|
session_id TEXT NOT NULL PRIMARY KEY,
|
|
session_key TEXT NOT NULL,
|
|
cwd TEXT NOT NULL,
|
|
complete INTEGER NOT NULL,
|
|
created_at INTEGER NOT NULL,
|
|
updated_at INTEGER NOT NULL,
|
|
next_seq INTEGER NOT NULL,
|
|
-- Running estimate of this session's ledger footprint (row overhead plus
|
|
-- all event rows), maintained at insert/trim so budget checks never scan
|
|
-- acp_replay_events (#100622).
|
|
estimated_bytes INTEGER NOT NULL DEFAULT 0
|
|
) STRICT;
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_acp_replay_sessions_key_updated
|
|
ON acp_replay_sessions(session_key, complete, updated_at DESC, session_id);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_acp_replay_sessions_updated
|
|
ON acp_replay_sessions(updated_at DESC, session_id);
|
|
|
|
CREATE TABLE IF NOT EXISTS acp_replay_events (
|
|
session_id TEXT NOT NULL,
|
|
seq INTEGER NOT NULL,
|
|
at INTEGER NOT NULL,
|
|
session_key TEXT NOT NULL,
|
|
run_id TEXT,
|
|
update_json TEXT NOT NULL,
|
|
estimated_bytes INTEGER NOT NULL DEFAULT 0,
|
|
PRIMARY KEY (session_id, seq),
|
|
FOREIGN KEY (session_id) REFERENCES acp_replay_sessions(session_id) ON DELETE CASCADE
|
|
) STRICT;
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_acp_replay_events_session_seq
|
|
ON acp_replay_events(session_id, seq);
|
|
|
|
CREATE TABLE IF NOT EXISTS agent_databases (
|
|
agent_id TEXT NOT NULL,
|
|
path TEXT NOT NULL,
|
|
schema_version INTEGER NOT NULL,
|
|
last_seen_at INTEGER NOT NULL,
|
|
size_bytes INTEGER,
|
|
PRIMARY KEY (agent_id, path)
|
|
) STRICT;
|
|
|
|
CREATE TABLE IF NOT EXISTS agent_deletion_journal (
|
|
agent_id TEXT PRIMARY KEY,
|
|
operation_id TEXT NOT NULL DEFAULT '',
|
|
agent_dir TEXT NOT NULL,
|
|
workspace_dir TEXT NOT NULL,
|
|
sessions_dir TEXT NOT NULL,
|
|
database_paths_json TEXT NOT NULL DEFAULT '[]',
|
|
cleanup_paths_json TEXT NOT NULL DEFAULT '[]',
|
|
created_at INTEGER NOT NULL,
|
|
cleanup_completed INTEGER NOT NULL DEFAULT 0,
|
|
delete_files INTEGER NOT NULL DEFAULT 1
|
|
) STRICT;
|
|
|
|
CREATE TABLE IF NOT EXISTS agent_database_leases (
|
|
lease_id TEXT PRIMARY KEY,
|
|
agent_id TEXT NOT NULL,
|
|
path TEXT NOT NULL,
|
|
owner_pid INTEGER NOT NULL,
|
|
owner_start_time INTEGER,
|
|
opened_at INTEGER NOT NULL
|
|
) STRICT;
|
|
|
|
CREATE TABLE IF NOT EXISTS plugin_state_entries (
|
|
plugin_id TEXT NOT NULL,
|
|
namespace TEXT NOT NULL,
|
|
entry_key TEXT NOT NULL,
|
|
value_json TEXT NOT NULL,
|
|
created_at INTEGER NOT NULL,
|
|
expires_at INTEGER,
|
|
PRIMARY KEY (plugin_id, namespace, entry_key)
|
|
) STRICT;
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_plugin_state_expiry
|
|
ON plugin_state_entries(expires_at)
|
|
WHERE expires_at IS NOT NULL;
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_plugin_state_listing
|
|
ON plugin_state_entries(plugin_id, namespace, created_at, entry_key);
|
|
|
|
CREATE TABLE IF NOT EXISTS channel_ingress_events (
|
|
queue_name TEXT NOT NULL,
|
|
event_id TEXT NOT NULL,
|
|
channel_id TEXT NOT NULL,
|
|
account_id TEXT NOT NULL,
|
|
status TEXT NOT NULL,
|
|
lane_key TEXT,
|
|
payload_json TEXT NOT NULL,
|
|
metadata_json TEXT,
|
|
received_at INTEGER NOT NULL,
|
|
updated_at INTEGER NOT NULL,
|
|
claim_token TEXT,
|
|
claim_owner TEXT,
|
|
claimed_at INTEGER,
|
|
attempts INTEGER NOT NULL DEFAULT 0,
|
|
last_attempt_at INTEGER,
|
|
last_error TEXT,
|
|
failed_reason TEXT,
|
|
failed_at INTEGER,
|
|
completed_at INTEGER,
|
|
completed_metadata_json TEXT,
|
|
PRIMARY KEY (queue_name, event_id)
|
|
) STRICT;
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_channel_ingress_pending
|
|
ON channel_ingress_events(queue_name, status, received_at, event_id);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_channel_ingress_claims
|
|
ON channel_ingress_events(queue_name, status, claimed_at);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_channel_ingress_lane
|
|
ON channel_ingress_events(queue_name, status, lane_key);
|
|
|
|
CREATE TABLE IF NOT EXISTS plugin_blob_entries (
|
|
plugin_id TEXT NOT NULL,
|
|
namespace TEXT NOT NULL,
|
|
entry_key TEXT NOT NULL,
|
|
metadata_json TEXT NOT NULL,
|
|
blob BLOB NOT NULL,
|
|
created_at INTEGER NOT NULL,
|
|
expires_at INTEGER,
|
|
PRIMARY KEY (plugin_id, namespace, entry_key)
|
|
) STRICT;
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_plugin_blob_expiry
|
|
ON plugin_blob_entries(expires_at)
|
|
WHERE expires_at IS NOT NULL;
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_plugin_blob_listing
|
|
ON plugin_blob_entries(plugin_id, namespace, created_at, entry_key);
|
|
|
|
CREATE TABLE IF NOT EXISTS media_blobs (
|
|
subdir TEXT NOT NULL,
|
|
id TEXT NOT NULL,
|
|
content_type TEXT,
|
|
size_bytes INTEGER NOT NULL,
|
|
blob BLOB NOT NULL,
|
|
created_at INTEGER NOT NULL,
|
|
updated_at INTEGER NOT NULL,
|
|
PRIMARY KEY (subdir, id)
|
|
) STRICT;
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_media_blobs_created
|
|
ON media_blobs(created_at);
|
|
|
|
CREATE TABLE IF NOT EXISTS skill_uploads (
|
|
upload_id TEXT NOT NULL PRIMARY KEY,
|
|
kind TEXT NOT NULL,
|
|
slug TEXT NOT NULL,
|
|
force INTEGER NOT NULL,
|
|
size_bytes INTEGER NOT NULL,
|
|
sha256 TEXT,
|
|
actual_sha256 TEXT,
|
|
received_bytes INTEGER NOT NULL,
|
|
archive_blob BLOB NOT NULL,
|
|
created_at INTEGER NOT NULL,
|
|
expires_at INTEGER NOT NULL,
|
|
committed INTEGER NOT NULL,
|
|
committed_at INTEGER,
|
|
idempotency_key_hash TEXT UNIQUE
|
|
) STRICT;
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_skill_uploads_expiry
|
|
ON skill_uploads(expires_at);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_skill_uploads_idempotency
|
|
ON skill_uploads(idempotency_key_hash)
|
|
WHERE idempotency_key_hash IS NOT NULL;
|
|
|
|
CREATE TABLE IF NOT EXISTS skill_upload_chunks (
|
|
upload_id TEXT NOT NULL,
|
|
byte_offset INTEGER NOT NULL CHECK (byte_offset >= 0),
|
|
size_bytes INTEGER NOT NULL CHECK (size_bytes > 0),
|
|
chunk_blob BLOB NOT NULL,
|
|
PRIMARY KEY (upload_id, byte_offset),
|
|
FOREIGN KEY (upload_id) REFERENCES skill_uploads(upload_id) ON DELETE CASCADE,
|
|
CHECK (length(chunk_blob) = size_bytes)
|
|
) STRICT;
|
|
|
|
CREATE TABLE IF NOT EXISTS capture_sessions (
|
|
id TEXT NOT NULL PRIMARY KEY,
|
|
started_at INTEGER NOT NULL,
|
|
ended_at INTEGER,
|
|
mode TEXT NOT NULL,
|
|
source_scope TEXT NOT NULL,
|
|
source_process TEXT NOT NULL,
|
|
proxy_url TEXT
|
|
) STRICT;
|
|
|
|
CREATE TABLE IF NOT EXISTS capture_blobs (
|
|
blob_id TEXT NOT NULL PRIMARY KEY,
|
|
content_type TEXT,
|
|
encoding TEXT NOT NULL,
|
|
size_bytes INTEGER NOT NULL,
|
|
sha256 TEXT NOT NULL,
|
|
data BLOB NOT NULL,
|
|
created_at INTEGER NOT NULL
|
|
) STRICT;
|
|
|
|
CREATE TABLE IF NOT EXISTS capture_events (
|
|
id INTEGER NOT NULL PRIMARY KEY,
|
|
session_id TEXT NOT NULL,
|
|
ts INTEGER NOT NULL,
|
|
source_scope TEXT NOT NULL,
|
|
source_process TEXT NOT NULL,
|
|
protocol TEXT NOT NULL,
|
|
direction TEXT NOT NULL,
|
|
kind TEXT NOT NULL,
|
|
flow_id TEXT NOT NULL,
|
|
method TEXT,
|
|
host TEXT,
|
|
path TEXT,
|
|
status INTEGER,
|
|
close_code INTEGER,
|
|
content_type TEXT,
|
|
headers_json TEXT,
|
|
data_text TEXT,
|
|
data_blob_id TEXT,
|
|
data_sha256 TEXT,
|
|
error_text TEXT,
|
|
meta_json TEXT,
|
|
FOREIGN KEY (session_id) REFERENCES capture_sessions(id) ON DELETE CASCADE,
|
|
FOREIGN KEY (data_blob_id) REFERENCES capture_blobs(blob_id) ON DELETE SET NULL
|
|
) STRICT;
|
|
|
|
CREATE INDEX IF NOT EXISTS capture_events_session_ts_idx
|
|
ON capture_events(session_id, ts);
|
|
|
|
CREATE INDEX IF NOT EXISTS capture_events_flow_idx
|
|
ON capture_events(flow_id, ts);
|
|
|
|
CREATE TABLE IF NOT EXISTS sandbox_registry_entries (
|
|
registry_kind TEXT NOT NULL,
|
|
container_name TEXT NOT NULL,
|
|
session_key TEXT,
|
|
backend_id TEXT,
|
|
runtime_label TEXT,
|
|
image TEXT,
|
|
created_at_ms INTEGER,
|
|
last_used_at_ms INTEGER,
|
|
config_label_kind TEXT,
|
|
config_hash TEXT,
|
|
cdp_port INTEGER,
|
|
no_vnc_port INTEGER,
|
|
entry_json TEXT NOT NULL,
|
|
updated_at INTEGER NOT NULL,
|
|
PRIMARY KEY (registry_kind, container_name)
|
|
) STRICT;
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_sandbox_registry_updated
|
|
ON sandbox_registry_entries(registry_kind, updated_at DESC, container_name);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_sandbox_registry_session
|
|
ON sandbox_registry_entries(registry_kind, session_key, last_used_at_ms DESC, container_name)
|
|
WHERE session_key IS NOT NULL;
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_sandbox_registry_last_used
|
|
ON sandbox_registry_entries(registry_kind, last_used_at_ms DESC, container_name)
|
|
WHERE last_used_at_ms IS NOT NULL;
|
|
|
|
CREATE TABLE IF NOT EXISTS commitments (
|
|
id TEXT NOT NULL PRIMARY KEY,
|
|
agent_id TEXT NOT NULL,
|
|
session_key TEXT NOT NULL,
|
|
channel TEXT NOT NULL,
|
|
account_id TEXT,
|
|
recipient_id TEXT,
|
|
thread_id TEXT,
|
|
sender_id TEXT,
|
|
kind TEXT NOT NULL,
|
|
sensitivity TEXT NOT NULL,
|
|
source TEXT NOT NULL,
|
|
status TEXT NOT NULL,
|
|
reason TEXT NOT NULL,
|
|
suggested_text TEXT NOT NULL,
|
|
dedupe_key TEXT NOT NULL,
|
|
confidence REAL NOT NULL,
|
|
due_earliest_ms INTEGER NOT NULL,
|
|
due_latest_ms INTEGER NOT NULL,
|
|
due_timezone TEXT NOT NULL,
|
|
source_message_id TEXT,
|
|
source_run_id TEXT,
|
|
created_at_ms INTEGER NOT NULL,
|
|
updated_at_ms INTEGER NOT NULL,
|
|
attempts INTEGER NOT NULL,
|
|
last_attempt_at_ms INTEGER,
|
|
sent_at_ms INTEGER,
|
|
dismissed_at_ms INTEGER,
|
|
snoozed_until_ms INTEGER,
|
|
expired_at_ms INTEGER,
|
|
record_json TEXT NOT NULL
|
|
) STRICT;
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_commitments_scope_due
|
|
ON commitments(agent_id, session_key, status, due_earliest_ms, due_latest_ms);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_commitments_status_due
|
|
ON commitments(status, due_earliest_ms, due_latest_ms);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_commitments_scope_dedupe
|
|
ON commitments(agent_id, session_key, channel, dedupe_key, status);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_commitments_agent_due
|
|
ON commitments(agent_id, status, due_earliest_ms, due_latest_ms, session_key);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_commitments_agent_sent
|
|
ON commitments(agent_id, status, sent_at_ms, session_key);
|
|
|
|
CREATE TABLE IF NOT EXISTS cron_jobs (
|
|
store_key TEXT NOT NULL,
|
|
job_id TEXT NOT NULL,
|
|
declaration_key TEXT,
|
|
display_name TEXT,
|
|
owner_agent_id TEXT,
|
|
owner_session_key TEXT,
|
|
name TEXT NOT NULL,
|
|
description TEXT,
|
|
enabled INTEGER NOT NULL,
|
|
delete_after_run INTEGER,
|
|
created_at_ms INTEGER NOT NULL,
|
|
agent_id TEXT,
|
|
session_key TEXT,
|
|
schedule_kind TEXT NOT NULL,
|
|
schedule_expr TEXT,
|
|
schedule_tz TEXT,
|
|
every_ms INTEGER,
|
|
anchor_ms INTEGER,
|
|
at TEXT,
|
|
stagger_ms INTEGER,
|
|
session_target TEXT NOT NULL,
|
|
wake_mode TEXT NOT NULL,
|
|
trigger_script TEXT,
|
|
trigger_once INTEGER,
|
|
payload_kind TEXT NOT NULL,
|
|
payload_message TEXT,
|
|
payload_model TEXT,
|
|
payload_fallbacks_json TEXT,
|
|
payload_thinking TEXT,
|
|
payload_timeout_seconds INTEGER,
|
|
payload_allow_unsafe_external_content INTEGER,
|
|
payload_external_content_source_json TEXT,
|
|
payload_light_context INTEGER,
|
|
payload_tools_allow_json TEXT,
|
|
payload_tools_allow_is_default INTEGER,
|
|
delivery_mode TEXT,
|
|
delivery_channel TEXT,
|
|
delivery_to TEXT,
|
|
delivery_thread_id TEXT,
|
|
delivery_thread_id_type TEXT,
|
|
delivery_account_id TEXT,
|
|
delivery_best_effort INTEGER,
|
|
delivery_completion_mode TEXT,
|
|
delivery_completion_to TEXT,
|
|
failure_delivery_mode TEXT,
|
|
failure_delivery_channel TEXT,
|
|
failure_delivery_to TEXT,
|
|
failure_delivery_account_id TEXT,
|
|
failure_alert_disabled INTEGER,
|
|
failure_alert_after INTEGER,
|
|
failure_alert_channel TEXT,
|
|
failure_alert_to TEXT,
|
|
failure_alert_cooldown_ms INTEGER,
|
|
failure_alert_include_skipped INTEGER,
|
|
failure_alert_mode TEXT,
|
|
failure_alert_account_id TEXT,
|
|
next_run_at_ms INTEGER,
|
|
running_at_ms INTEGER,
|
|
last_run_at_ms INTEGER,
|
|
last_run_status TEXT,
|
|
last_error TEXT,
|
|
last_duration_ms INTEGER,
|
|
consecutive_errors INTEGER,
|
|
consecutive_skipped INTEGER,
|
|
schedule_error_count INTEGER,
|
|
last_delivery_status TEXT,
|
|
last_delivery_error TEXT,
|
|
last_delivered INTEGER,
|
|
last_failure_alert_at_ms INTEGER,
|
|
job_json TEXT NOT NULL,
|
|
state_json TEXT NOT NULL DEFAULT '{}',
|
|
runtime_updated_at_ms INTEGER,
|
|
schedule_identity TEXT,
|
|
sort_order INTEGER NOT NULL DEFAULT 0,
|
|
updated_at INTEGER NOT NULL,
|
|
PRIMARY KEY (store_key, job_id)
|
|
) STRICT;
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_cron_jobs_store_updated
|
|
ON cron_jobs(store_key, sort_order ASC, updated_at DESC, job_id);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_cron_jobs_store_order
|
|
ON cron_jobs(store_key, sort_order ASC, updated_at ASC, job_id);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_cron_jobs_enabled_next_run
|
|
ON cron_jobs(store_key, enabled, next_run_at_ms, job_id)
|
|
WHERE next_run_at_ms IS NOT NULL;
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_cron_jobs_agent_session
|
|
ON cron_jobs(agent_id, session_key, updated_at DESC, job_id)
|
|
WHERE agent_id IS NOT NULL OR session_key IS NOT NULL;
|
|
|
|
-- Scratch is separate from cron_jobs so scheduler state writes and downgraded
|
|
-- full-row replacement preserve it. New builds prune rows explicitly on job removal.
|
|
-- content NULL is a tombstone: it keeps the revision lineage monotonic across
|
|
-- unset/recreate so stale compare-and-swap writes cannot resurrect old content.
|
|
CREATE TABLE IF NOT EXISTS cron_job_scratch (
|
|
store_key TEXT NOT NULL,
|
|
job_id TEXT NOT NULL,
|
|
content TEXT,
|
|
revision INTEGER NOT NULL,
|
|
source_sha256 TEXT,
|
|
updated_at_ms INTEGER NOT NULL,
|
|
PRIMARY KEY (store_key, job_id),
|
|
CHECK (revision >= 1),
|
|
CHECK (content IS NULL OR length(CAST(content AS BLOB)) <= 262144)
|
|
) STRICT;
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_cron_job_scratch_store_updated
|
|
ON cron_job_scratch(store_key, updated_at_ms DESC, job_id);
|
|
|
|
CREATE TABLE IF NOT EXISTS command_log_entries (
|
|
id TEXT NOT NULL PRIMARY KEY,
|
|
timestamp_ms INTEGER NOT NULL,
|
|
action TEXT NOT NULL,
|
|
session_key TEXT NOT NULL,
|
|
sender_id TEXT NOT NULL,
|
|
source TEXT NOT NULL,
|
|
entry_json TEXT NOT NULL
|
|
) STRICT;
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_command_log_entries_timestamp
|
|
ON command_log_entries(timestamp_ms DESC, id);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_command_log_entries_session
|
|
ON command_log_entries(session_key, timestamp_ms DESC, id);
|
|
|
|
CREATE TABLE IF NOT EXISTS delivery_queue_entries (
|
|
queue_name TEXT NOT NULL,
|
|
id TEXT NOT NULL,
|
|
status TEXT NOT NULL,
|
|
entry_kind TEXT,
|
|
session_key TEXT,
|
|
channel TEXT,
|
|
target TEXT,
|
|
account_id TEXT,
|
|
retry_count INTEGER NOT NULL DEFAULT 0,
|
|
last_attempt_at INTEGER,
|
|
last_error TEXT,
|
|
recovery_state TEXT,
|
|
platform_send_started_at INTEGER,
|
|
entry_json TEXT NOT NULL,
|
|
enqueued_at INTEGER NOT NULL,
|
|
updated_at INTEGER NOT NULL,
|
|
failed_at INTEGER,
|
|
PRIMARY KEY (queue_name, id)
|
|
) STRICT;
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_delivery_queue_pending
|
|
ON delivery_queue_entries(queue_name, status, enqueued_at, id);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_delivery_queue_failed
|
|
ON delivery_queue_entries(queue_name, status, failed_at, id);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_delivery_queue_session
|
|
ON delivery_queue_entries(queue_name, status, session_key, enqueued_at, id)
|
|
WHERE session_key IS NOT NULL;
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_delivery_queue_target
|
|
ON delivery_queue_entries(queue_name, status, channel, target, enqueued_at, id)
|
|
WHERE channel IS NOT NULL AND target IS NOT NULL;
|
|
|
|
CREATE TABLE IF NOT EXISTS task_runs (
|
|
task_id TEXT NOT NULL PRIMARY KEY,
|
|
runtime TEXT NOT NULL,
|
|
task_kind TEXT,
|
|
source_id TEXT,
|
|
requester_session_key TEXT,
|
|
owner_key TEXT NOT NULL,
|
|
scope_kind TEXT NOT NULL,
|
|
child_session_key TEXT,
|
|
parent_flow_id TEXT,
|
|
parent_task_id TEXT,
|
|
agent_id TEXT,
|
|
requester_agent_id TEXT,
|
|
run_id TEXT,
|
|
label TEXT,
|
|
task TEXT NOT NULL,
|
|
status TEXT NOT NULL,
|
|
delivery_status TEXT NOT NULL,
|
|
notify_policy TEXT NOT NULL,
|
|
created_at INTEGER NOT NULL,
|
|
started_at INTEGER,
|
|
ended_at INTEGER,
|
|
last_event_at INTEGER,
|
|
cleanup_after INTEGER,
|
|
tool_use_count INTEGER,
|
|
last_tool_name TEXT,
|
|
error TEXT,
|
|
progress_summary TEXT,
|
|
terminal_summary TEXT,
|
|
terminal_outcome TEXT,
|
|
detail_json TEXT
|
|
) STRICT;
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_task_runs_run_id ON task_runs(run_id);
|
|
CREATE INDEX IF NOT EXISTS idx_task_runs_status ON task_runs(status);
|
|
CREATE INDEX IF NOT EXISTS idx_task_runs_runtime_status ON task_runs(runtime, status);
|
|
CREATE INDEX IF NOT EXISTS idx_task_runs_cleanup_after ON task_runs(cleanup_after);
|
|
CREATE INDEX IF NOT EXISTS idx_task_runs_last_event_at ON task_runs(last_event_at);
|
|
CREATE INDEX IF NOT EXISTS idx_task_runs_owner_key ON task_runs(owner_key);
|
|
CREATE INDEX IF NOT EXISTS idx_task_runs_parent_flow_id ON task_runs(parent_flow_id);
|
|
CREATE INDEX IF NOT EXISTS idx_task_runs_child_session_key ON task_runs(child_session_key);
|
|
CREATE INDEX IF NOT EXISTS idx_task_runs_runtime_source_ended
|
|
ON task_runs(runtime, source_id, ended_at, created_at, task_id);
|
|
CREATE INDEX IF NOT EXISTS idx_task_runs_runtime_ended
|
|
ON task_runs(runtime, ended_at, created_at, task_id);
|
|
|
|
CREATE TABLE IF NOT EXISTS subagent_runs (
|
|
run_id TEXT NOT NULL PRIMARY KEY,
|
|
child_session_key TEXT NOT NULL,
|
|
controller_session_key TEXT,
|
|
requester_session_key TEXT NOT NULL,
|
|
requester_display_key TEXT NOT NULL,
|
|
requester_origin_json TEXT,
|
|
task TEXT NOT NULL,
|
|
task_name TEXT,
|
|
cleanup TEXT NOT NULL,
|
|
label TEXT,
|
|
model TEXT,
|
|
agent_dir TEXT,
|
|
workspace_dir TEXT,
|
|
run_timeout_seconds INTEGER,
|
|
spawn_mode TEXT,
|
|
created_at INTEGER NOT NULL,
|
|
started_at INTEGER,
|
|
session_started_at INTEGER,
|
|
accumulated_runtime_ms INTEGER,
|
|
ended_at INTEGER,
|
|
outcome_json TEXT,
|
|
archive_at_ms INTEGER,
|
|
cleanup_completed_at INTEGER,
|
|
cleanup_handled INTEGER,
|
|
suppress_announce_reason TEXT,
|
|
expects_completion_message INTEGER,
|
|
announce_retry_count INTEGER,
|
|
last_announce_retry_at INTEGER,
|
|
last_announce_delivery_error TEXT,
|
|
ended_reason TEXT,
|
|
pause_reason TEXT,
|
|
wake_on_descendant_settle INTEGER,
|
|
requester_settle_wake_status TEXT,
|
|
requester_settle_wake_attempt_count INTEGER,
|
|
requester_settle_wake_replay_count INTEGER,
|
|
requester_settle_wake_next_attempt_at INTEGER,
|
|
requester_settle_wake_batch_run_ids_json TEXT,
|
|
requester_settle_wake_last_error TEXT,
|
|
requester_settle_wake_retire_after INTEGER,
|
|
frozen_result_text TEXT,
|
|
frozen_result_captured_at INTEGER,
|
|
fallback_frozen_result_text TEXT,
|
|
fallback_frozen_result_captured_at INTEGER,
|
|
ended_hook_emitted_at INTEGER,
|
|
pending_final_delivery INTEGER,
|
|
pending_final_delivery_created_at INTEGER,
|
|
pending_final_delivery_last_attempt_at INTEGER,
|
|
pending_final_delivery_attempt_count INTEGER,
|
|
pending_final_delivery_last_error TEXT,
|
|
pending_final_delivery_payload_json TEXT,
|
|
completion_announced_at INTEGER,
|
|
swarm_group_id TEXT,
|
|
swarm_collector INTEGER,
|
|
swarm_output_schema_json TEXT,
|
|
swarm_completion_status TEXT,
|
|
swarm_structured_json TEXT,
|
|
swarm_schema_error TEXT,
|
|
swarm_usage_json TEXT,
|
|
payload_json TEXT NOT NULL DEFAULT '{}'
|
|
) STRICT;
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_subagent_runs_child_session_key
|
|
ON subagent_runs(child_session_key, created_at DESC, run_id);
|
|
CREATE INDEX IF NOT EXISTS idx_subagent_runs_requester_session_key
|
|
ON subagent_runs(requester_session_key, created_at DESC, run_id);
|
|
CREATE INDEX IF NOT EXISTS idx_subagent_runs_controller_session_key
|
|
ON subagent_runs(controller_session_key, created_at DESC, run_id);
|
|
CREATE INDEX IF NOT EXISTS idx_subagent_runs_archive_at
|
|
ON subagent_runs(archive_at_ms, cleanup_handled, run_id);
|
|
CREATE INDEX IF NOT EXISTS idx_subagent_runs_ended_cleanup
|
|
ON subagent_runs(ended_at, cleanup_handled, run_id);
|
|
|
|
CREATE TABLE IF NOT EXISTS current_conversation_bindings (
|
|
binding_key TEXT NOT NULL PRIMARY KEY,
|
|
binding_id TEXT NOT NULL,
|
|
target_agent_id TEXT NOT NULL,
|
|
target_session_id TEXT,
|
|
target_session_key TEXT NOT NULL,
|
|
channel TEXT NOT NULL,
|
|
account_id TEXT NOT NULL,
|
|
conversation_kind TEXT NOT NULL,
|
|
parent_conversation_id TEXT,
|
|
conversation_id TEXT NOT NULL,
|
|
target_kind TEXT NOT NULL,
|
|
status TEXT NOT NULL,
|
|
bound_at INTEGER NOT NULL,
|
|
expires_at INTEGER,
|
|
metadata_json TEXT,
|
|
record_json TEXT NOT NULL,
|
|
updated_at INTEGER NOT NULL
|
|
) STRICT;
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_current_conversation_bindings_target
|
|
ON current_conversation_bindings(target_agent_id, target_session_key, updated_at DESC, binding_key);
|
|
CREATE INDEX IF NOT EXISTS idx_current_conversation_bindings_conversation
|
|
ON current_conversation_bindings(channel, account_id, conversation_kind, conversation_id);
|
|
CREATE INDEX IF NOT EXISTS idx_current_conversation_bindings_expires
|
|
ON current_conversation_bindings(expires_at, binding_key);
|
|
|
|
CREATE TABLE IF NOT EXISTS plugin_binding_approvals (
|
|
plugin_root TEXT NOT NULL,
|
|
channel TEXT NOT NULL,
|
|
account_id TEXT NOT NULL,
|
|
plugin_id TEXT NOT NULL,
|
|
plugin_name TEXT,
|
|
approved_at INTEGER NOT NULL,
|
|
PRIMARY KEY (plugin_root, channel, account_id)
|
|
) STRICT;
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_plugin_binding_approvals_plugin
|
|
ON plugin_binding_approvals(plugin_id, approved_at DESC);
|
|
|
|
CREATE TABLE IF NOT EXISTS tui_last_sessions (
|
|
scope_key TEXT NOT NULL PRIMARY KEY,
|
|
session_key TEXT NOT NULL,
|
|
updated_at INTEGER NOT NULL
|
|
) STRICT;
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_tui_last_sessions_session_key
|
|
ON tui_last_sessions(session_key, updated_at DESC, scope_key);
|
|
|
|
CREATE TABLE IF NOT EXISTS task_delivery_state (
|
|
task_id TEXT NOT NULL PRIMARY KEY,
|
|
requester_origin_json TEXT,
|
|
last_notified_event_at INTEGER,
|
|
FOREIGN KEY (task_id) REFERENCES task_runs(task_id) ON DELETE CASCADE
|
|
) STRICT;
|
|
|
|
CREATE TABLE IF NOT EXISTS flow_runs (
|
|
flow_id TEXT NOT NULL PRIMARY KEY,
|
|
shape TEXT,
|
|
sync_mode TEXT NOT NULL DEFAULT 'managed',
|
|
owner_key TEXT NOT NULL,
|
|
requester_origin_json TEXT,
|
|
controller_id TEXT,
|
|
revision INTEGER NOT NULL DEFAULT 0,
|
|
status TEXT NOT NULL,
|
|
notify_policy TEXT NOT NULL,
|
|
goal TEXT NOT NULL,
|
|
current_step TEXT,
|
|
blocked_task_id TEXT,
|
|
blocked_summary TEXT,
|
|
state_json TEXT,
|
|
wait_json TEXT,
|
|
cancel_requested_at INTEGER,
|
|
created_at INTEGER NOT NULL,
|
|
updated_at INTEGER NOT NULL,
|
|
ended_at INTEGER
|
|
) STRICT;
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_flow_runs_status ON flow_runs(status);
|
|
CREATE INDEX IF NOT EXISTS idx_flow_runs_owner_key ON flow_runs(owner_key);
|
|
CREATE INDEX IF NOT EXISTS idx_flow_runs_updated_at ON flow_runs(updated_at);
|
|
|
|
-- Durable meeting-capture sessions are gateway-global rather than agent-session
|
|
-- transcripts. JSON/JSONL files are doctor import inputs or explicit CLI exports.
|
|
CREATE TABLE IF NOT EXISTS meeting_transcript_sessions (
|
|
session_id TEXT NOT NULL,
|
|
started_at TEXT NOT NULL,
|
|
selector TEXT NOT NULL UNIQUE,
|
|
export_key TEXT NOT NULL,
|
|
session_slug TEXT NOT NULL,
|
|
provider_id TEXT NOT NULL,
|
|
title TEXT,
|
|
source_json TEXT NOT NULL,
|
|
stopped_at TEXT,
|
|
metadata_json TEXT,
|
|
export_manifest_json TEXT NOT NULL DEFAULT '{}',
|
|
export_pending_json TEXT NOT NULL DEFAULT '[]',
|
|
next_utterance_seq INTEGER NOT NULL DEFAULT 0 CHECK (next_utterance_seq >= 0),
|
|
created_at_ms INTEGER NOT NULL CHECK (created_at_ms >= 0),
|
|
updated_at_ms INTEGER NOT NULL CHECK (updated_at_ms >= 0),
|
|
PRIMARY KEY (session_id, started_at)
|
|
) STRICT;
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_meeting_transcript_sessions_started
|
|
ON meeting_transcript_sessions(started_at DESC, session_id);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_meeting_transcript_sessions_id
|
|
ON meeting_transcript_sessions(session_id, started_at DESC);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_meeting_transcript_sessions_slug
|
|
ON meeting_transcript_sessions(session_slug, started_at DESC);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_meeting_transcript_sessions_export_key
|
|
ON meeting_transcript_sessions(export_key);
|
|
|
|
CREATE TABLE IF NOT EXISTS meeting_transcript_utterances (
|
|
session_id TEXT NOT NULL,
|
|
session_started_at TEXT NOT NULL,
|
|
sequence INTEGER NOT NULL CHECK (sequence >= 0),
|
|
utterance_id TEXT,
|
|
started_at TEXT,
|
|
ended_at TEXT,
|
|
speaker_id TEXT,
|
|
speaker_label TEXT,
|
|
text TEXT NOT NULL,
|
|
final INTEGER CHECK (final IN (0, 1)),
|
|
metadata_json TEXT,
|
|
PRIMARY KEY (session_id, session_started_at, sequence),
|
|
FOREIGN KEY (session_id, session_started_at)
|
|
REFERENCES meeting_transcript_sessions(session_id, started_at)
|
|
ON DELETE CASCADE
|
|
) STRICT;
|
|
|
|
CREATE TABLE IF NOT EXISTS meeting_transcript_summaries (
|
|
session_id TEXT NOT NULL,
|
|
session_started_at TEXT NOT NULL,
|
|
generated_at TEXT,
|
|
summary_json TEXT,
|
|
markdown TEXT,
|
|
utterance_count INTEGER NOT NULL CHECK (utterance_count >= 0),
|
|
PRIMARY KEY (session_id, session_started_at),
|
|
FOREIGN KEY (session_id, session_started_at)
|
|
REFERENCES meeting_transcript_sessions(session_id, started_at)
|
|
ON DELETE CASCADE,
|
|
CHECK (summary_json IS NOT NULL OR markdown IS NOT NULL)
|
|
) STRICT;
|
|
|
|
CREATE TABLE IF NOT EXISTS migration_runs (
|
|
id TEXT NOT NULL PRIMARY KEY,
|
|
started_at INTEGER NOT NULL,
|
|
finished_at INTEGER,
|
|
status TEXT NOT NULL,
|
|
report_json TEXT NOT NULL
|
|
) STRICT;
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_migration_runs_started
|
|
ON migration_runs(started_at DESC, id);
|
|
|
|
CREATE TABLE IF NOT EXISTS migration_sources (
|
|
source_key TEXT NOT NULL PRIMARY KEY,
|
|
migration_kind TEXT NOT NULL,
|
|
source_path TEXT NOT NULL,
|
|
target_table TEXT NOT NULL,
|
|
source_sha256 TEXT,
|
|
source_size_bytes INTEGER,
|
|
source_record_count INTEGER,
|
|
last_run_id TEXT NOT NULL,
|
|
status TEXT NOT NULL,
|
|
imported_at INTEGER NOT NULL,
|
|
removed_source INTEGER NOT NULL DEFAULT 0,
|
|
report_json TEXT NOT NULL,
|
|
FOREIGN KEY (last_run_id) REFERENCES migration_runs(id) ON DELETE CASCADE
|
|
) STRICT;
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_migration_sources_path
|
|
ON migration_sources(source_path, migration_kind, target_table);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_migration_sources_run
|
|
ON migration_sources(last_run_id, source_path);
|
|
|
|
CREATE TABLE IF NOT EXISTS backup_runs (
|
|
id TEXT NOT NULL PRIMARY KEY,
|
|
created_at INTEGER NOT NULL,
|
|
archive_path TEXT NOT NULL,
|
|
status TEXT NOT NULL,
|
|
manifest_json TEXT NOT NULL
|
|
) STRICT;
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_backup_runs_created
|
|
ON backup_runs(created_at DESC, id);
|
|
|
|
CREATE TABLE IF NOT EXISTS worktrees (
|
|
id TEXT NOT NULL PRIMARY KEY,
|
|
repo_fingerprint TEXT NOT NULL,
|
|
repo_root TEXT NOT NULL,
|
|
path TEXT NOT NULL,
|
|
branch TEXT NOT NULL,
|
|
base_ref TEXT NOT NULL,
|
|
owner_kind TEXT NOT NULL CHECK (owner_kind IN ('manual', 'workboard', 'session')),
|
|
owner_id TEXT,
|
|
snapshot_ref TEXT,
|
|
provisioned_paths_json TEXT,
|
|
created_at INTEGER NOT NULL,
|
|
last_active_at INTEGER NOT NULL,
|
|
removed_at INTEGER
|
|
) STRICT;
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_worktrees_repo_fingerprint
|
|
ON worktrees(repo_fingerprint);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_worktrees_removed_at
|
|
ON worktrees(removed_at);
|
|
|
|
CREATE TABLE IF NOT EXISTS worktree_provisioned_file_chunks (
|
|
worktree_id TEXT NOT NULL,
|
|
path TEXT NOT NULL,
|
|
chunk_index INTEGER NOT NULL CHECK (chunk_index >= 0),
|
|
data BLOB NOT NULL,
|
|
PRIMARY KEY (worktree_id, path, chunk_index)
|
|
) STRICT;
|
|
|
|
-- Gateway-owned custom session group catalog (names + display order).
|
|
-- Membership stays on each session entry's category field; this table only
|
|
-- owns which groups exist and how operator UIs order them.
|
|
CREATE TABLE IF NOT EXISTS session_groups (
|
|
name TEXT NOT NULL PRIMARY KEY,
|
|
position INTEGER NOT NULL,
|
|
created_at INTEGER NOT NULL
|
|
) STRICT;
|
|
|
|
-- Gateway-owned sidebar section layout. IDs are ungrouped, groups, work, or
|
|
-- category:<name>; pinned sessions are ordered separately and never stored.
|
|
CREATE TABLE IF NOT EXISTS sidebar_sections (
|
|
section_id TEXT NOT NULL PRIMARY KEY,
|
|
position INTEGER NOT NULL
|
|
) STRICT;
|
|
|
|
-- Gateway-owned durable cloud worker lifecycle. Provider-specific execution
|
|
-- stays in plugins; this table records only core reconciliation facts.
|
|
CREATE TABLE IF NOT EXISTS worker_environments (
|
|
environment_id TEXT NOT NULL PRIMARY KEY,
|
|
provider_id TEXT NOT NULL,
|
|
profile_id TEXT NOT NULL,
|
|
profile_snapshot_json TEXT NOT NULL,
|
|
provision_operation_id TEXT NOT NULL UNIQUE,
|
|
lease_id TEXT,
|
|
ssh_host TEXT,
|
|
ssh_port INTEGER CHECK (ssh_port IS NULL OR (ssh_port >= 1 AND ssh_port <= 65535)),
|
|
ssh_user TEXT,
|
|
ssh_host_key TEXT,
|
|
ssh_key_ref_json TEXT,
|
|
state TEXT NOT NULL CHECK (
|
|
state IN (
|
|
'requested',
|
|
'provisioning',
|
|
'bootstrapping',
|
|
'ready',
|
|
'attached',
|
|
'idle',
|
|
'draining',
|
|
'destroying',
|
|
'destroyed',
|
|
'failed',
|
|
'orphaned'
|
|
)
|
|
),
|
|
bootstrap_bundle_hash TEXT,
|
|
bootstrap_openclaw_version TEXT,
|
|
bootstrap_protocol_features_json TEXT,
|
|
owner_epoch INTEGER NOT NULL DEFAULT 0 CHECK (owner_epoch >= 0),
|
|
teardown_terminal_state TEXT CHECK (teardown_terminal_state IN ('destroyed', 'failed')),
|
|
attached_session_ids_json TEXT NOT NULL DEFAULT '[]',
|
|
created_at_ms INTEGER NOT NULL,
|
|
updated_at_ms INTEGER NOT NULL,
|
|
state_changed_at_ms INTEGER NOT NULL,
|
|
idle_since_at_ms INTEGER,
|
|
destroy_requested_at_ms INTEGER,
|
|
last_error TEXT
|
|
) STRICT;
|
|
|
|
CREATE UNIQUE INDEX IF NOT EXISTS idx_worker_environments_provider_lease
|
|
ON worker_environments(provider_id, lease_id)
|
|
WHERE lease_id IS NOT NULL;
|
|
|
|
-- Session placement lives in the shared state database so local admission,
|
|
-- worker admission, and environment attachment use one durable authority.
|
|
CREATE TABLE IF NOT EXISTS worker_session_placements (
|
|
session_id TEXT NOT NULL PRIMARY KEY,
|
|
agent_id TEXT NOT NULL,
|
|
session_key TEXT NOT NULL,
|
|
state TEXT NOT NULL CHECK (
|
|
state IN (
|
|
'local',
|
|
'requested',
|
|
'provisioning',
|
|
'syncing',
|
|
'starting',
|
|
'active',
|
|
'draining',
|
|
'reconciling',
|
|
'reclaimed',
|
|
'failed'
|
|
)
|
|
),
|
|
environment_id TEXT,
|
|
transition_generation INTEGER NOT NULL DEFAULT 0 CHECK (transition_generation >= 0),
|
|
active_owner_epoch INTEGER CHECK (active_owner_epoch IS NULL OR active_owner_epoch >= 1),
|
|
workspace_base_manifest_ref TEXT,
|
|
remote_workspace_dir TEXT,
|
|
worker_bundle_hash TEXT,
|
|
last_transcript_ack_cursor INTEGER CHECK (
|
|
last_transcript_ack_cursor IS NULL OR last_transcript_ack_cursor >= 0
|
|
),
|
|
last_live_event_ack_cursor INTEGER CHECK (
|
|
last_live_event_ack_cursor IS NULL OR last_live_event_ack_cursor >= 0
|
|
),
|
|
recovery_error TEXT,
|
|
turn_claim_owner TEXT CHECK (turn_claim_owner IN ('local', 'worker')),
|
|
turn_claim_id TEXT,
|
|
turn_claim_run_id TEXT,
|
|
turn_claim_generation INTEGER CHECK (
|
|
turn_claim_generation IS NULL OR turn_claim_generation >= 0
|
|
),
|
|
turn_claim_owner_epoch INTEGER CHECK (
|
|
turn_claim_owner_epoch IS NULL OR turn_claim_owner_epoch >= 1
|
|
),
|
|
created_at_ms INTEGER NOT NULL,
|
|
updated_at_ms INTEGER NOT NULL,
|
|
state_changed_at_ms INTEGER NOT NULL,
|
|
CHECK (
|
|
(state IN ('local', 'requested')
|
|
AND environment_id IS NULL AND active_owner_epoch IS NULL
|
|
AND workspace_base_manifest_ref IS NULL AND remote_workspace_dir IS NULL
|
|
AND worker_bundle_hash IS NULL
|
|
AND last_transcript_ack_cursor IS NULL AND last_live_event_ack_cursor IS NULL
|
|
AND recovery_error IS NULL)
|
|
OR
|
|
(state IS 'provisioning'
|
|
AND active_owner_epoch IS NULL
|
|
AND workspace_base_manifest_ref IS NULL AND remote_workspace_dir IS NULL
|
|
AND worker_bundle_hash IS NULL
|
|
AND last_transcript_ack_cursor IS NULL AND last_live_event_ack_cursor IS NULL
|
|
AND recovery_error IS NULL)
|
|
OR
|
|
(state IS 'syncing'
|
|
AND environment_id IS NOT NULL AND active_owner_epoch IS NULL
|
|
AND workspace_base_manifest_ref IS NULL AND remote_workspace_dir IS NULL
|
|
AND worker_bundle_hash IS NOT NULL
|
|
AND last_transcript_ack_cursor IS NULL AND last_live_event_ack_cursor IS NULL
|
|
AND recovery_error IS NULL)
|
|
OR
|
|
(state IS 'starting'
|
|
AND environment_id IS NOT NULL AND active_owner_epoch IS NULL
|
|
AND workspace_base_manifest_ref IS NOT NULL AND remote_workspace_dir IS NOT NULL
|
|
AND worker_bundle_hash IS NOT NULL
|
|
AND last_transcript_ack_cursor IS NULL AND last_live_event_ack_cursor IS NULL
|
|
AND recovery_error IS NULL)
|
|
OR
|
|
(state IN ('active', 'draining', 'reconciling')
|
|
AND environment_id IS NOT NULL AND active_owner_epoch IS NOT NULL
|
|
AND workspace_base_manifest_ref IS NOT NULL AND remote_workspace_dir IS NOT NULL
|
|
AND worker_bundle_hash IS NOT NULL AND recovery_error IS NULL)
|
|
OR
|
|
(state IS 'reclaimed'
|
|
AND environment_id IS NOT NULL AND active_owner_epoch IS NOT NULL
|
|
AND workspace_base_manifest_ref IS NOT NULL AND remote_workspace_dir IS NOT NULL
|
|
AND worker_bundle_hash IS NOT NULL AND recovery_error IS NULL
|
|
AND turn_claim_owner IS NULL AND turn_claim_id IS NULL AND turn_claim_run_id IS NULL
|
|
AND turn_claim_generation IS NULL AND turn_claim_owner_epoch IS NULL)
|
|
OR
|
|
(state IS 'failed' AND recovery_error IS NOT NULL)
|
|
),
|
|
CHECK (
|
|
(turn_claim_owner IS NULL AND turn_claim_id IS NULL AND turn_claim_run_id IS NULL
|
|
AND turn_claim_generation IS NULL AND turn_claim_owner_epoch IS NULL)
|
|
OR
|
|
(turn_claim_owner IS 'local' AND turn_claim_id IS NOT NULL
|
|
AND turn_claim_run_id IS NOT NULL AND turn_claim_generation IS NOT NULL
|
|
AND turn_claim_owner_epoch IS NULL)
|
|
OR
|
|
(turn_claim_owner IS 'worker' AND turn_claim_id IS NOT NULL
|
|
AND turn_claim_run_id IS NOT NULL AND turn_claim_generation IS NOT NULL
|
|
AND turn_claim_owner_epoch IS NOT NULL)
|
|
),
|
|
CHECK (
|
|
turn_claim_owner IS NULL
|
|
OR
|
|
(turn_claim_owner IS 'local' AND state IN ('local', 'requested', 'failed'))
|
|
OR
|
|
(turn_claim_owner IS 'worker' AND state IN ('active', 'draining')
|
|
AND turn_claim_owner_epoch IS active_owner_epoch)
|
|
)
|
|
) STRICT;
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_worker_session_placements_session_key
|
|
ON worker_session_placements(agent_id, session_key);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_worker_session_placements_reconcile
|
|
ON worker_session_placements(updated_at_ms, session_id);
|
|
|
|
-- A reconciliation journal is written before managed-worktree mutation. The
|
|
-- bounded Git base snapshot repairs any subset left by an interrupted apply.
|
|
CREATE TABLE IF NOT EXISTS worker_workspace_reconciliations (
|
|
session_id TEXT NOT NULL PRIMARY KEY,
|
|
environment_id TEXT NOT NULL,
|
|
owner_epoch INTEGER NOT NULL CHECK (owner_epoch >= 1),
|
|
placement_generation INTEGER NOT NULL CHECK (placement_generation >= 0),
|
|
base_manifest_ref TEXT NOT NULL,
|
|
current_manifest_ref TEXT NOT NULL,
|
|
plan_json TEXT NOT NULL,
|
|
base_pack BLOB NOT NULL CHECK (length(base_pack) <= 268435456),
|
|
created_at_ms INTEGER NOT NULL,
|
|
FOREIGN KEY (session_id) REFERENCES worker_session_placements(session_id) ON DELETE CASCADE
|
|
) STRICT;
|
|
|
|
-- A completed remote turn is fenced from stale-claim teardown until its
|
|
-- workspace result is durably reconciled into the managed worktree.
|
|
CREATE TABLE IF NOT EXISTS worker_workspace_pending_results (
|
|
session_id TEXT NOT NULL PRIMARY KEY,
|
|
environment_id TEXT NOT NULL,
|
|
owner_epoch INTEGER NOT NULL CHECK (owner_epoch >= 1),
|
|
placement_generation INTEGER NOT NULL CHECK (placement_generation >= 0),
|
|
claim_id TEXT NOT NULL,
|
|
run_id TEXT NOT NULL,
|
|
gateway_instance_id TEXT NOT NULL,
|
|
recovery_requested_at_ms INTEGER,
|
|
workspace_accepted_at_ms INTEGER,
|
|
staged_result_ref TEXT,
|
|
created_at_ms INTEGER NOT NULL,
|
|
FOREIGN KEY (session_id) REFERENCES worker_session_placements(session_id) ON DELETE CASCADE
|
|
) STRICT;
|
|
|
|
-- One active, opaque admission credential per worker environment. Plaintext
|
|
-- may be retried until delivery acknowledgement but never enters durable state.
|
|
CREATE TABLE IF NOT EXISTS worker_environment_credentials (
|
|
environment_id TEXT NOT NULL PRIMARY KEY,
|
|
credential_hash TEXT NOT NULL UNIQUE,
|
|
bundle_hash TEXT NOT NULL,
|
|
session_id TEXT,
|
|
rpc_set_version INTEGER NOT NULL CHECK (rpc_set_version >= 1),
|
|
owner_epoch INTEGER NOT NULL CHECK (owner_epoch >= 0),
|
|
expires_at_ms INTEGER NOT NULL CHECK (expires_at_ms >= 0),
|
|
delivered_at_ms INTEGER CHECK (delivered_at_ms >= 0),
|
|
FOREIGN KEY (environment_id) REFERENCES worker_environments(environment_id) ON DELETE CASCADE
|
|
) STRICT;
|
|
|
|
-- One durable sequence cursor per attached session owner epoch. The environment
|
|
-- binding prevents independent workers with coincident epochs from sharing replay state.
|
|
CREATE TABLE IF NOT EXISTS worker_transcript_commit_heads (
|
|
session_id TEXT NOT NULL,
|
|
run_epoch INTEGER NOT NULL CHECK (run_epoch >= 0),
|
|
environment_id TEXT NOT NULL,
|
|
next_seq INTEGER NOT NULL CHECK (next_seq >= 1),
|
|
updated_at_ms INTEGER NOT NULL CHECK (updated_at_ms >= 0),
|
|
PRIMARY KEY (session_id, run_epoch)
|
|
) STRICT;
|
|
|
|
-- Pending rows preserve a claimed request across gateway restarts. Terminal rows
|
|
-- cache the exact result returned for deterministic at-least-once replay.
|
|
CREATE TABLE IF NOT EXISTS worker_transcript_commits (
|
|
session_id TEXT NOT NULL,
|
|
run_epoch INTEGER NOT NULL CHECK (run_epoch >= 0),
|
|
seq INTEGER NOT NULL CHECK (seq >= 1),
|
|
request_hash TEXT NOT NULL,
|
|
state TEXT NOT NULL CHECK (state IN ('pending', 'terminal')),
|
|
result_json TEXT,
|
|
created_at_ms INTEGER NOT NULL CHECK (created_at_ms >= 0),
|
|
updated_at_ms INTEGER NOT NULL CHECK (updated_at_ms >= 0),
|
|
PRIMARY KEY (session_id, run_epoch, seq),
|
|
FOREIGN KEY (session_id, run_epoch)
|
|
REFERENCES worker_transcript_commit_heads(session_id, run_epoch)
|
|
ON DELETE CASCADE,
|
|
CHECK (
|
|
(state = 'pending' AND result_json IS NULL) OR
|
|
(state = 'terminal' AND result_json IS NOT NULL)
|
|
)
|
|
) STRICT;
|
|
|
|
-- Pending rows preserve a claimed inference turn across gateway restarts.
|
|
-- Terminal rows cache the exact outcome returned for deterministic replay.
|
|
CREATE TABLE IF NOT EXISTS worker_inference_turns (
|
|
session_id TEXT NOT NULL,
|
|
run_epoch INTEGER NOT NULL CHECK (run_epoch >= 0),
|
|
run_id TEXT NOT NULL,
|
|
turn_id TEXT NOT NULL,
|
|
environment_id TEXT NOT NULL,
|
|
request_hash TEXT NOT NULL,
|
|
state TEXT NOT NULL CHECK (state IN ('pending', 'terminal')),
|
|
terminal_json TEXT,
|
|
created_at_ms INTEGER NOT NULL CHECK (created_at_ms >= 0),
|
|
updated_at_ms INTEGER NOT NULL CHECK (updated_at_ms >= 0),
|
|
PRIMARY KEY (session_id, run_epoch, run_id, turn_id),
|
|
FOREIGN KEY (environment_id) REFERENCES worker_environments(environment_id) ON DELETE CASCADE,
|
|
CHECK (
|
|
(state = 'pending' AND terminal_json IS NULL) OR
|
|
(state = 'terminal' AND terminal_json IS NOT NULL)
|
|
)
|
|
) STRICT;
|
|
|
|
CREATE UNIQUE INDEX IF NOT EXISTS idx_worker_inference_turns_pending_run
|
|
ON worker_inference_turns(session_id, run_epoch, run_id)
|
|
WHERE state = 'pending';
|
|
|
|
CREATE TABLE IF NOT EXISTS fleet_cells (
|
|
tenant_id TEXT NOT NULL PRIMARY KEY,
|
|
created_at_ms INTEGER NOT NULL,
|
|
image TEXT NOT NULL,
|
|
runtime TEXT NOT NULL,
|
|
host_port INTEGER NOT NULL,
|
|
container_name TEXT NOT NULL,
|
|
data_dir TEXT NOT NULL
|
|
) STRICT;
|
|
|
|
CREATE TABLE IF NOT EXISTS claw_installs (
|
|
agent_id TEXT NOT NULL PRIMARY KEY,
|
|
schema_version TEXT NOT NULL,
|
|
source_kind TEXT NOT NULL,
|
|
claw_name TEXT NOT NULL,
|
|
claw_version TEXT NOT NULL,
|
|
package_root TEXT NOT NULL,
|
|
manifest_path TEXT NOT NULL,
|
|
integrity_kind TEXT NOT NULL,
|
|
integrity TEXT NOT NULL,
|
|
source_byte_length INTEGER NOT NULL,
|
|
manifest_schema_version INTEGER NOT NULL,
|
|
plan_integrity TEXT NOT NULL,
|
|
workspace TEXT NOT NULL UNIQUE,
|
|
agent_config_digest TEXT NOT NULL,
|
|
agent_owned_paths_json TEXT NOT NULL,
|
|
status TEXT NOT NULL CHECK (
|
|
status IN ('pending', 'workspace_ready', 'config_committed', 'complete', 'partial')
|
|
),
|
|
added_at_ms INTEGER NOT NULL,
|
|
updated_at_ms INTEGER NOT NULL
|
|
) STRICT;
|
|
|
|
CREATE TABLE IF NOT EXISTS claw_workspace_files (
|
|
agent_id TEXT NOT NULL,
|
|
target_path TEXT NOT NULL,
|
|
schema_version TEXT NOT NULL,
|
|
workspace TEXT NOT NULL,
|
|
source_path TEXT NOT NULL,
|
|
content_digest TEXT NOT NULL,
|
|
status TEXT NOT NULL,
|
|
created_at_ms INTEGER NOT NULL,
|
|
updated_at_ms INTEGER NOT NULL,
|
|
PRIMARY KEY (agent_id, target_path)
|
|
) STRICT;
|
|
|
|
CREATE TABLE IF NOT EXISTS claw_package_refs (
|
|
agent_id TEXT NOT NULL,
|
|
package_kind TEXT NOT NULL,
|
|
package_source TEXT NOT NULL,
|
|
package_ref TEXT NOT NULL,
|
|
package_version TEXT NOT NULL,
|
|
package_integrity TEXT NOT NULL,
|
|
schema_version TEXT NOT NULL,
|
|
claw_name TEXT NOT NULL,
|
|
package_status TEXT NOT NULL,
|
|
relationship TEXT NOT NULL CHECK (relationship IN ('managed', 'referenced')),
|
|
origin TEXT NOT NULL CHECK (origin IN ('claw-introduced', 'pre-existing')),
|
|
independent_owner INTEGER NOT NULL CHECK (independent_owner IN (0, 1)),
|
|
installed_at_ms INTEGER NOT NULL,
|
|
updated_at_ms INTEGER NOT NULL,
|
|
PRIMARY KEY (agent_id, package_kind, package_source, package_ref, package_version)
|
|
) STRICT;
|
|
|
|
CREATE TABLE IF NOT EXISTS claw_cron_refs (
|
|
agent_id TEXT NOT NULL,
|
|
manifest_id TEXT NOT NULL,
|
|
schema_version TEXT NOT NULL,
|
|
declaration_key TEXT NOT NULL UNIQUE,
|
|
scheduler_job_id TEXT UNIQUE,
|
|
status TEXT NOT NULL,
|
|
job_json TEXT NOT NULL,
|
|
error TEXT,
|
|
created_at_ms INTEGER NOT NULL,
|
|
updated_at_ms INTEGER NOT NULL,
|
|
PRIMARY KEY (agent_id, manifest_id)
|
|
) STRICT;
|
|
|
|
CREATE TABLE IF NOT EXISTS claw_mcp_server_refs (
|
|
agent_id TEXT NOT NULL,
|
|
name TEXT NOT NULL,
|
|
schema_version TEXT NOT NULL,
|
|
config_digest TEXT NOT NULL,
|
|
relationship TEXT NOT NULL CHECK (relationship IN ('managed', 'referenced')),
|
|
origin TEXT NOT NULL CHECK (origin IN ('claw-introduced', 'pre-existing')),
|
|
independent_owner INTEGER NOT NULL DEFAULT 0 CHECK (independent_owner IN (0, 1)),
|
|
status TEXT NOT NULL,
|
|
error TEXT,
|
|
created_at_ms INTEGER NOT NULL,
|
|
updated_at_ms INTEGER NOT NULL,
|
|
PRIMARY KEY (agent_id, name)
|
|
) STRICT;
|
|
|
|
CREATE TABLE IF NOT EXISTS outbound_media_provenance (
|
|
realpath TEXT NOT NULL PRIMARY KEY,
|
|
kind TEXT NOT NULL,
|
|
version INTEGER NOT NULL,
|
|
sha256 TEXT NOT NULL,
|
|
size_bytes INTEGER NOT NULL,
|
|
created_at_ms INTEGER NOT NULL
|
|
) STRICT;
|
|
|
|
CREATE TABLE IF NOT EXISTS model_catalog_remote (
|
|
id INTEGER PRIMARY KEY CHECK (id = 1),
|
|
bundle_json TEXT NOT NULL,
|
|
generated_at INTEGER NOT NULL,
|
|
min_version TEXT,
|
|
source_url TEXT NOT NULL,
|
|
etag TEXT,
|
|
last_modified TEXT,
|
|
checked_at INTEGER NOT NULL
|
|
) STRICT;
|