@asm-agent/postgres 0.8.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,87 @@
1
+ export interface OwnerRecord {
2
+ id: string;
3
+ handle: string;
4
+ }
5
+ export interface ProjectRecord {
6
+ id: string;
7
+ ownerId: string;
8
+ key: string;
9
+ rootPath: string;
10
+ }
11
+ export type SessionStatus = "active" | "archived" | "crash";
12
+ export interface SessionRecord {
13
+ id: string;
14
+ projectId: string;
15
+ parentSessionId?: string;
16
+ status: SessionStatus;
17
+ cwd: string;
18
+ name?: string;
19
+ rlmDepth: number;
20
+ transcriptRevision: number;
21
+ createdAt: Date;
22
+ updatedAt: Date;
23
+ }
24
+ export interface SessionMessageInput {
25
+ entryId: string;
26
+ parentEntryId?: string;
27
+ entryType: string;
28
+ payload: unknown;
29
+ createdAt: Date;
30
+ }
31
+ export interface SessionMessageRecord extends SessionMessageInput {
32
+ sequence: number;
33
+ }
34
+ export type GoalStatus = "active" | "paused" | "budget_limited" | "complete" | "error";
35
+ export interface GoalRecord {
36
+ id: string;
37
+ sessionId: string;
38
+ status: GoalStatus;
39
+ objective: string;
40
+ tokenBudget?: number;
41
+ tokensUsed: number;
42
+ timeUsedSeconds: number;
43
+ continuationsUsed: number;
44
+ lastReason?: string;
45
+ lastError?: string;
46
+ }
47
+ export type ScheduleStatus = "active" | "paused" | "completed" | "cancelled";
48
+ export type ScheduleKind = "once" | "cron" | "interval";
49
+ export interface ScheduleRecord {
50
+ id: string;
51
+ sessionId: string;
52
+ status: ScheduleStatus;
53
+ source: string;
54
+ scheduleKind: ScheduleKind;
55
+ expression: string;
56
+ intervalMs?: number;
57
+ prompt: string;
58
+ metadata: unknown;
59
+ nextRunAt?: Date;
60
+ lastRunAt?: Date;
61
+ runCount: number;
62
+ }
63
+ export interface LeaseRecord {
64
+ resourceType: string;
65
+ resourceId: string;
66
+ ownerId: string;
67
+ fencingToken: number;
68
+ expiresAt: Date;
69
+ }
70
+ export interface OutboxEvent {
71
+ id: string;
72
+ topic: string;
73
+ aggregateType: string;
74
+ aggregateId: string;
75
+ payload: unknown;
76
+ headers: unknown;
77
+ attempts: number;
78
+ }
79
+ export type IdempotencyStartResult = {
80
+ status: "started";
81
+ } | {
82
+ status: "in_progress";
83
+ } | {
84
+ status: "replayed";
85
+ response: unknown;
86
+ };
87
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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","sourcesContent":["export interface OwnerRecord {\n\tid: string;\n\thandle: string;\n}\n\nexport interface ProjectRecord {\n\tid: string;\n\townerId: string;\n\tkey: string;\n\trootPath: string;\n}\n\nexport type SessionStatus = \"active\" | \"archived\" | \"crash\";\n\nexport interface SessionRecord {\n\tid: string;\n\tprojectId: string;\n\tparentSessionId?: string;\n\tstatus: SessionStatus;\n\tcwd: string;\n\tname?: string;\n\trlmDepth: number;\n\ttranscriptRevision: number;\n\tcreatedAt: Date;\n\tupdatedAt: Date;\n}\n\nexport interface SessionMessageInput {\n\tentryId: string;\n\tparentEntryId?: string;\n\tentryType: string;\n\tpayload: unknown;\n\tcreatedAt: Date;\n}\n\nexport interface SessionMessageRecord extends SessionMessageInput {\n\tsequence: number;\n}\n\nexport type GoalStatus = \"active\" | \"paused\" | \"budget_limited\" | \"complete\" | \"error\";\n\nexport interface GoalRecord {\n\tid: string;\n\tsessionId: string;\n\tstatus: GoalStatus;\n\tobjective: string;\n\ttokenBudget?: number;\n\ttokensUsed: number;\n\ttimeUsedSeconds: number;\n\tcontinuationsUsed: number;\n\tlastReason?: string;\n\tlastError?: string;\n}\n\nexport type ScheduleStatus = \"active\" | \"paused\" | \"completed\" | \"cancelled\";\nexport type ScheduleKind = \"once\" | \"cron\" | \"interval\";\n\nexport interface ScheduleRecord {\n\tid: string;\n\tsessionId: string;\n\tstatus: ScheduleStatus;\n\tsource: string;\n\tscheduleKind: ScheduleKind;\n\texpression: string;\n\tintervalMs?: number;\n\tprompt: string;\n\tmetadata: unknown;\n\tnextRunAt?: Date;\n\tlastRunAt?: Date;\n\trunCount: number;\n}\n\nexport interface LeaseRecord {\n\tresourceType: string;\n\tresourceId: string;\n\townerId: string;\n\tfencingToken: number;\n\texpiresAt: Date;\n}\n\nexport interface OutboxEvent {\n\tid: string;\n\ttopic: string;\n\taggregateType: string;\n\taggregateId: string;\n\tpayload: unknown;\n\theaders: unknown;\n\tattempts: number;\n}\n\nexport type IdempotencyStartResult =\n\t| { status: \"started\" }\n\t| { status: \"in_progress\" }\n\t| { status: \"replayed\"; response: unknown };\n"]}
package/dist/types.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"","sourcesContent":["export interface OwnerRecord {\n\tid: string;\n\thandle: string;\n}\n\nexport interface ProjectRecord {\n\tid: string;\n\townerId: string;\n\tkey: string;\n\trootPath: string;\n}\n\nexport type SessionStatus = \"active\" | \"archived\" | \"crash\";\n\nexport interface SessionRecord {\n\tid: string;\n\tprojectId: string;\n\tparentSessionId?: string;\n\tstatus: SessionStatus;\n\tcwd: string;\n\tname?: string;\n\trlmDepth: number;\n\ttranscriptRevision: number;\n\tcreatedAt: Date;\n\tupdatedAt: Date;\n}\n\nexport interface SessionMessageInput {\n\tentryId: string;\n\tparentEntryId?: string;\n\tentryType: string;\n\tpayload: unknown;\n\tcreatedAt: Date;\n}\n\nexport interface SessionMessageRecord extends SessionMessageInput {\n\tsequence: number;\n}\n\nexport type GoalStatus = \"active\" | \"paused\" | \"budget_limited\" | \"complete\" | \"error\";\n\nexport interface GoalRecord {\n\tid: string;\n\tsessionId: string;\n\tstatus: GoalStatus;\n\tobjective: string;\n\ttokenBudget?: number;\n\ttokensUsed: number;\n\ttimeUsedSeconds: number;\n\tcontinuationsUsed: number;\n\tlastReason?: string;\n\tlastError?: string;\n}\n\nexport type ScheduleStatus = \"active\" | \"paused\" | \"completed\" | \"cancelled\";\nexport type ScheduleKind = \"once\" | \"cron\" | \"interval\";\n\nexport interface ScheduleRecord {\n\tid: string;\n\tsessionId: string;\n\tstatus: ScheduleStatus;\n\tsource: string;\n\tscheduleKind: ScheduleKind;\n\texpression: string;\n\tintervalMs?: number;\n\tprompt: string;\n\tmetadata: unknown;\n\tnextRunAt?: Date;\n\tlastRunAt?: Date;\n\trunCount: number;\n}\n\nexport interface LeaseRecord {\n\tresourceType: string;\n\tresourceId: string;\n\townerId: string;\n\tfencingToken: number;\n\texpiresAt: Date;\n}\n\nexport interface OutboxEvent {\n\tid: string;\n\ttopic: string;\n\taggregateType: string;\n\taggregateId: string;\n\tpayload: unknown;\n\theaders: unknown;\n\tattempts: number;\n}\n\nexport type IdempotencyStartResult =\n\t| { status: \"started\" }\n\t| { status: \"in_progress\" }\n\t| { status: \"replayed\"; response: unknown };\n"]}
@@ -0,0 +1,143 @@
1
+ CREATE SCHEMA IF NOT EXISTS asm_agent;
2
+
3
+ CREATE TABLE asm_agent.schema_migrations (
4
+ version integer PRIMARY KEY,
5
+ name text NOT NULL UNIQUE,
6
+ checksum text NOT NULL,
7
+ applied_at timestamptz NOT NULL DEFAULT clock_timestamp()
8
+ );
9
+
10
+ CREATE TABLE asm_agent.owners (
11
+ id uuid PRIMARY KEY,
12
+ handle text NOT NULL UNIQUE,
13
+ created_at timestamptz NOT NULL DEFAULT clock_timestamp(),
14
+ updated_at timestamptz NOT NULL DEFAULT clock_timestamp()
15
+ );
16
+
17
+ CREATE TABLE asm_agent.projects (
18
+ id uuid PRIMARY KEY,
19
+ owner_id uuid NOT NULL REFERENCES asm_agent.owners(id) ON DELETE CASCADE,
20
+ key text NOT NULL,
21
+ root_path text NOT NULL,
22
+ created_at timestamptz NOT NULL DEFAULT clock_timestamp(),
23
+ updated_at timestamptz NOT NULL DEFAULT clock_timestamp(),
24
+ UNIQUE (owner_id, key),
25
+ UNIQUE (owner_id, root_path)
26
+ );
27
+
28
+ CREATE TABLE asm_agent.sessions (
29
+ id uuid PRIMARY KEY,
30
+ project_id uuid NOT NULL REFERENCES asm_agent.projects(id) ON DELETE CASCADE,
31
+ parent_session_id uuid REFERENCES asm_agent.sessions(id) ON DELETE SET NULL,
32
+ status text NOT NULL DEFAULT 'active' CHECK (status IN ('active', 'archived', 'crash')),
33
+ cwd text NOT NULL,
34
+ name text,
35
+ rlm_depth integer NOT NULL DEFAULT 0 CHECK (rlm_depth >= 0),
36
+ transcript_revision bigint NOT NULL DEFAULT 0 CHECK (transcript_revision >= 0),
37
+ created_at timestamptz NOT NULL DEFAULT clock_timestamp(),
38
+ updated_at timestamptz NOT NULL DEFAULT clock_timestamp()
39
+ );
40
+
41
+ CREATE INDEX sessions_project_updated_idx ON asm_agent.sessions(project_id, updated_at DESC);
42
+ CREATE INDEX sessions_parent_idx ON asm_agent.sessions(parent_session_id) WHERE parent_session_id IS NOT NULL;
43
+
44
+ CREATE TABLE asm_agent.agent_messages (
45
+ session_id uuid NOT NULL REFERENCES asm_agent.sessions(id) ON DELETE CASCADE,
46
+ sequence bigint NOT NULL CHECK (sequence > 0),
47
+ entry_id uuid NOT NULL,
48
+ parent_entry_id uuid,
49
+ entry_type text NOT NULL,
50
+ payload jsonb NOT NULL,
51
+ created_at timestamptz NOT NULL,
52
+ PRIMARY KEY (session_id, sequence),
53
+ UNIQUE (session_id, entry_id)
54
+ );
55
+
56
+ CREATE INDEX agent_messages_session_created_idx ON asm_agent.agent_messages(session_id, created_at);
57
+
58
+ CREATE TABLE asm_agent.goals (
59
+ id uuid PRIMARY KEY,
60
+ session_id uuid NOT NULL REFERENCES asm_agent.sessions(id) ON DELETE CASCADE,
61
+ status text NOT NULL CHECK (status IN ('active', 'paused', 'budget_limited', 'complete', 'error')),
62
+ objective text NOT NULL CHECK (length(btrim(objective)) > 0),
63
+ token_budget bigint CHECK (token_budget > 0),
64
+ tokens_used bigint NOT NULL DEFAULT 0 CHECK (tokens_used >= 0),
65
+ time_used_seconds bigint NOT NULL DEFAULT 0 CHECK (time_used_seconds >= 0),
66
+ continuations_used integer NOT NULL DEFAULT 0 CHECK (continuations_used >= 0),
67
+ last_reason text,
68
+ last_error text,
69
+ created_at timestamptz NOT NULL DEFAULT clock_timestamp(),
70
+ updated_at timestamptz NOT NULL DEFAULT clock_timestamp()
71
+ );
72
+
73
+ CREATE UNIQUE INDEX goals_one_live_per_session_idx ON asm_agent.goals(session_id)
74
+ WHERE status IN ('active', 'paused', 'budget_limited');
75
+
76
+ CREATE TABLE asm_agent.schedules (
77
+ id uuid PRIMARY KEY,
78
+ session_id uuid NOT NULL REFERENCES asm_agent.sessions(id) ON DELETE CASCADE,
79
+ status text NOT NULL CHECK (status IN ('active', 'paused', 'completed', 'cancelled')),
80
+ source text NOT NULL,
81
+ schedule_kind text NOT NULL CHECK (schedule_kind IN ('once', 'cron', 'interval')),
82
+ expression text NOT NULL,
83
+ interval_ms bigint CHECK (interval_ms > 0),
84
+ prompt text NOT NULL,
85
+ metadata jsonb NOT NULL DEFAULT '{}'::jsonb,
86
+ next_run_at timestamptz,
87
+ last_run_at timestamptz,
88
+ run_count bigint NOT NULL DEFAULT 0 CHECK (run_count >= 0),
89
+ created_at timestamptz NOT NULL DEFAULT clock_timestamp(),
90
+ updated_at timestamptz NOT NULL DEFAULT clock_timestamp()
91
+ );
92
+
93
+ CREATE INDEX schedules_due_idx ON asm_agent.schedules(next_run_at, id) WHERE status = 'active';
94
+
95
+ CREATE SEQUENCE asm_agent.lease_fencing_token_seq AS bigint;
96
+
97
+ CREATE TABLE asm_agent.leases (
98
+ resource_type text NOT NULL,
99
+ resource_id text NOT NULL,
100
+ owner_id text NOT NULL,
101
+ fencing_token bigint NOT NULL DEFAULT nextval('asm_agent.lease_fencing_token_seq'),
102
+ acquired_at timestamptz NOT NULL DEFAULT clock_timestamp(),
103
+ expires_at timestamptz NOT NULL,
104
+ PRIMARY KEY (resource_type, resource_id),
105
+ CHECK (expires_at > acquired_at)
106
+ );
107
+
108
+ CREATE INDEX leases_expiry_idx ON asm_agent.leases(expires_at);
109
+
110
+ CREATE TABLE asm_agent.idempotency_records (
111
+ scope text NOT NULL,
112
+ key text NOT NULL,
113
+ request_hash text NOT NULL,
114
+ status text NOT NULL CHECK (status IN ('started', 'completed', 'failed')),
115
+ response jsonb,
116
+ error jsonb,
117
+ created_at timestamptz NOT NULL DEFAULT clock_timestamp(),
118
+ updated_at timestamptz NOT NULL DEFAULT clock_timestamp(),
119
+ expires_at timestamptz,
120
+ PRIMARY KEY (scope, key)
121
+ );
122
+
123
+ CREATE INDEX idempotency_expiry_idx ON asm_agent.idempotency_records(expires_at)
124
+ WHERE expires_at IS NOT NULL;
125
+
126
+ CREATE TABLE asm_agent.outbox_events (
127
+ id uuid PRIMARY KEY,
128
+ topic text NOT NULL,
129
+ aggregate_type text NOT NULL,
130
+ aggregate_id text NOT NULL,
131
+ payload jsonb NOT NULL,
132
+ headers jsonb NOT NULL DEFAULT '{}'::jsonb,
133
+ available_at timestamptz NOT NULL DEFAULT clock_timestamp(),
134
+ attempts integer NOT NULL DEFAULT 0 CHECK (attempts >= 0),
135
+ locked_by text,
136
+ locked_until timestamptz,
137
+ published_at timestamptz,
138
+ last_error text,
139
+ created_at timestamptz NOT NULL DEFAULT clock_timestamp()
140
+ );
141
+
142
+ CREATE INDEX outbox_available_idx ON asm_agent.outbox_events(available_at, id)
143
+ WHERE published_at IS NULL;
@@ -0,0 +1,160 @@
1
+ CREATE TABLE asm_agent.evidence_snapshots (
2
+ id uuid PRIMARY KEY,
3
+ owner_id uuid NOT NULL REFERENCES asm_agent.owners(id) ON DELETE CASCADE,
4
+ project_id uuid NOT NULL REFERENCES asm_agent.projects(id) ON DELETE CASCADE,
5
+ source_type text NOT NULL CHECK (source_type IN ('user', 'tool', 'document', 'system')),
6
+ source_uri text,
7
+ content_type text NOT NULL,
8
+ content_text text,
9
+ content_json jsonb,
10
+ digest text NOT NULL CHECK (digest ~ '^[a-f0-9]{64}$'),
11
+ captured_at timestamptz NOT NULL,
12
+ revoked_at timestamptz,
13
+ metadata jsonb NOT NULL DEFAULT '{}'::jsonb,
14
+ CHECK ((content_text IS NOT NULL)::integer + (content_json IS NOT NULL)::integer = 1),
15
+ UNIQUE (owner_id, project_id, digest)
16
+ );
17
+
18
+ CREATE INDEX evidence_project_captured_idx
19
+ ON asm_agent.evidence_snapshots(project_id, captured_at DESC);
20
+
21
+ CREATE TABLE asm_agent.evidence_claims (
22
+ id uuid PRIMARY KEY,
23
+ evidence_id uuid NOT NULL REFERENCES asm_agent.evidence_snapshots(id) ON DELETE CASCADE,
24
+ claim text NOT NULL CHECK (length(btrim(claim)) > 0),
25
+ locator jsonb NOT NULL DEFAULT '{}'::jsonb,
26
+ created_at timestamptz NOT NULL DEFAULT clock_timestamp()
27
+ );
28
+
29
+ CREATE TABLE asm_agent.memory_records (
30
+ id uuid PRIMARY KEY,
31
+ owner_id uuid NOT NULL REFERENCES asm_agent.owners(id) ON DELETE CASCADE,
32
+ project_id uuid NOT NULL REFERENCES asm_agent.projects(id) ON DELETE CASCADE,
33
+ session_id uuid REFERENCES asm_agent.sessions(id) ON DELETE SET NULL,
34
+ kind text NOT NULL CHECK (kind IN ('observation', 'fact', 'instruction')),
35
+ current_revision integer NOT NULL DEFAULT 1 CHECK (current_revision > 0),
36
+ expires_at timestamptz,
37
+ tombstoned_at timestamptz,
38
+ revocation_reason text,
39
+ created_at timestamptz NOT NULL DEFAULT clock_timestamp(),
40
+ updated_at timestamptz NOT NULL DEFAULT clock_timestamp()
41
+ );
42
+
43
+ CREATE INDEX memory_records_scope_idx
44
+ ON asm_agent.memory_records(owner_id, project_id, session_id, updated_at DESC)
45
+ WHERE tombstoned_at IS NULL;
46
+ CREATE INDEX memory_records_expiry_idx
47
+ ON asm_agent.memory_records(expires_at) WHERE expires_at IS NOT NULL AND tombstoned_at IS NULL;
48
+
49
+ CREATE TABLE asm_agent.memory_revisions (
50
+ memory_id uuid NOT NULL REFERENCES asm_agent.memory_records(id) ON DELETE CASCADE,
51
+ revision integer NOT NULL CHECK (revision > 0),
52
+ content text NOT NULL CHECK (length(btrim(content)) > 0),
53
+ metadata jsonb NOT NULL DEFAULT '{}'::jsonb,
54
+ correction_reason text,
55
+ created_at timestamptz NOT NULL DEFAULT clock_timestamp(),
56
+ PRIMARY KEY (memory_id, revision)
57
+ );
58
+
59
+ CREATE TABLE asm_agent.memory_revision_evidence (
60
+ memory_id uuid NOT NULL,
61
+ revision integer NOT NULL,
62
+ evidence_id uuid NOT NULL REFERENCES asm_agent.evidence_snapshots(id) ON DELETE RESTRICT,
63
+ PRIMARY KEY (memory_id, revision, evidence_id),
64
+ FOREIGN KEY (memory_id, revision)
65
+ REFERENCES asm_agent.memory_revisions(memory_id, revision) ON DELETE CASCADE
66
+ );
67
+
68
+ CREATE TABLE asm_agent.memory_reader_scopes (
69
+ memory_id uuid NOT NULL REFERENCES asm_agent.memory_records(id) ON DELETE CASCADE,
70
+ reader_type text NOT NULL CHECK (reader_type IN ('owner', 'project', 'session', 'agent')),
71
+ reader_id text NOT NULL,
72
+ created_at timestamptz NOT NULL DEFAULT clock_timestamp(),
73
+ PRIMARY KEY (memory_id, reader_type, reader_id)
74
+ );
75
+
76
+ CREATE TABLE asm_agent.memory_links (
77
+ source_memory_id uuid NOT NULL REFERENCES asm_agent.memory_records(id) ON DELETE CASCADE,
78
+ target_memory_id uuid NOT NULL REFERENCES asm_agent.memory_records(id) ON DELETE CASCADE,
79
+ relation text NOT NULL,
80
+ created_at timestamptz NOT NULL DEFAULT clock_timestamp(),
81
+ PRIMARY KEY (source_memory_id, target_memory_id, relation),
82
+ CHECK (source_memory_id <> target_memory_id)
83
+ );
84
+
85
+ CREATE TABLE asm_agent.memory_lexical_projections (
86
+ memory_id uuid PRIMARY KEY REFERENCES asm_agent.memory_records(id) ON DELETE CASCADE,
87
+ revision integer NOT NULL,
88
+ document tsvector NOT NULL,
89
+ projected_at timestamptz NOT NULL DEFAULT clock_timestamp(),
90
+ FOREIGN KEY (memory_id, revision)
91
+ REFERENCES asm_agent.memory_revisions(memory_id, revision) ON DELETE CASCADE
92
+ );
93
+
94
+ CREATE INDEX memory_lexical_document_idx
95
+ ON asm_agent.memory_lexical_projections USING gin(document);
96
+
97
+ CREATE TABLE asm_agent.memory_vector_projections (
98
+ memory_id uuid PRIMARY KEY REFERENCES asm_agent.memory_records(id) ON DELETE CASCADE,
99
+ revision integer NOT NULL,
100
+ model text NOT NULL,
101
+ dimensions integer NOT NULL CHECK (dimensions > 0),
102
+ embedding real[] NOT NULL,
103
+ projected_at timestamptz NOT NULL DEFAULT clock_timestamp(),
104
+ CHECK (cardinality(embedding) = dimensions),
105
+ FOREIGN KEY (memory_id, revision)
106
+ REFERENCES asm_agent.memory_revisions(memory_id, revision) ON DELETE CASCADE
107
+ );
108
+
109
+ CREATE TABLE asm_agent.retrieval_decisions (
110
+ id uuid PRIMARY KEY,
111
+ owner_id uuid NOT NULL REFERENCES asm_agent.owners(id) ON DELETE CASCADE,
112
+ project_id uuid NOT NULL REFERENCES asm_agent.projects(id) ON DELETE CASCADE,
113
+ session_id uuid REFERENCES asm_agent.sessions(id) ON DELETE SET NULL,
114
+ reader_type text NOT NULL CHECK (reader_type IN ('owner', 'project', 'session', 'agent')),
115
+ reader_id text NOT NULL,
116
+ query text NOT NULL,
117
+ algorithm text NOT NULL,
118
+ algorithm_version text NOT NULL,
119
+ query_embedding real[],
120
+ latency_ms integer NOT NULL CHECK (latency_ms >= 0),
121
+ reason_codes text[] NOT NULL DEFAULT '{}',
122
+ created_at timestamptz NOT NULL DEFAULT clock_timestamp()
123
+ );
124
+
125
+ CREATE TABLE asm_agent.retrieval_candidates (
126
+ decision_id uuid NOT NULL REFERENCES asm_agent.retrieval_decisions(id) ON DELETE CASCADE,
127
+ memory_id uuid NOT NULL REFERENCES asm_agent.memory_records(id) ON DELETE CASCADE,
128
+ revision integer NOT NULL,
129
+ rank integer NOT NULL CHECK (rank > 0),
130
+ score double precision NOT NULL CHECK (score >= 0 AND score <= 1),
131
+ selected boolean NOT NULL,
132
+ eligible boolean NOT NULL DEFAULT true,
133
+ reason_codes text[] NOT NULL DEFAULT '{}',
134
+ PRIMARY KEY (decision_id, memory_id),
135
+ UNIQUE (decision_id, rank),
136
+ FOREIGN KEY (memory_id, revision)
137
+ REFERENCES asm_agent.memory_revisions(memory_id, revision) ON DELETE CASCADE
138
+ );
139
+
140
+ CREATE TABLE asm_agent.retrieval_feedback (
141
+ id uuid PRIMARY KEY,
142
+ decision_id uuid NOT NULL REFERENCES asm_agent.retrieval_decisions(id) ON DELETE CASCADE,
143
+ target_memory_id uuid REFERENCES asm_agent.memory_records(id) ON DELETE SET NULL,
144
+ rating text NOT NULL CHECK (rating IN ('positive', 'negative', 'correction')),
145
+ comment text,
146
+ created_at timestamptz NOT NULL DEFAULT clock_timestamp()
147
+ );
148
+
149
+ CREATE TABLE asm_agent.memory_erasure_jobs (
150
+ id uuid PRIMARY KEY,
151
+ memory_id uuid NOT NULL,
152
+ status text NOT NULL DEFAULT 'pending' CHECK (status IN ('pending', 'running', 'completed', 'failed')),
153
+ attempts integer NOT NULL DEFAULT 0 CHECK (attempts >= 0),
154
+ requested_at timestamptz NOT NULL DEFAULT clock_timestamp(),
155
+ completed_at timestamptz,
156
+ last_error text
157
+ );
158
+
159
+ CREATE UNIQUE INDEX memory_erasure_one_open_idx ON asm_agent.memory_erasure_jobs(memory_id)
160
+ WHERE status IN ('pending', 'running');
@@ -0,0 +1,6 @@
1
+ ALTER TABLE asm_agent.memory_revision_evidence
2
+ DROP CONSTRAINT memory_revision_evidence_evidence_id_fkey;
3
+
4
+ ALTER TABLE asm_agent.memory_revision_evidence
5
+ ADD CONSTRAINT memory_revision_evidence_evidence_id_fkey
6
+ FOREIGN KEY (evidence_id) REFERENCES asm_agent.evidence_snapshots(id) ON DELETE CASCADE;
@@ -0,0 +1,61 @@
1
+ CREATE TABLE asm_agent.parsed_intents (
2
+ id uuid PRIMARY KEY,
3
+ owner_id uuid NOT NULL REFERENCES asm_agent.owners(id) ON DELETE CASCADE,
4
+ project_id uuid NOT NULL REFERENCES asm_agent.projects(id) ON DELETE CASCADE,
5
+ session_id uuid REFERENCES asm_agent.sessions(id) ON DELETE SET NULL,
6
+ contract_major integer NOT NULL,
7
+ contract_minor integer NOT NULL,
8
+ operation text NOT NULL CHECK (operation IN ('diagnose','read','write','execute','communicate','deploy','purchase','delete')),
9
+ resources text[] NOT NULL,
10
+ external_effect boolean NOT NULL,
11
+ idempotency_key text,
12
+ arguments jsonb NOT NULL,
13
+ parser_id text NOT NULL,
14
+ parser_version text NOT NULL,
15
+ model_provider text,
16
+ model_id text,
17
+ requested_at timestamptz NOT NULL,
18
+ created_at timestamptz NOT NULL DEFAULT clock_timestamp(),
19
+ CHECK (NOT external_effect OR idempotency_key IS NOT NULL)
20
+ );
21
+
22
+ CREATE TABLE asm_agent.policy_decisions (
23
+ id uuid PRIMARY KEY,
24
+ intent_id uuid NOT NULL REFERENCES asm_agent.parsed_intents(id) ON DELETE CASCADE,
25
+ outcome text NOT NULL CHECK (outcome IN ('allow','deny','require_approval')),
26
+ reason_codes text[] NOT NULL,
27
+ required_approvals text[] NOT NULL DEFAULT '{}',
28
+ policy_version text NOT NULL,
29
+ decided_at timestamptz NOT NULL,
30
+ CHECK (cardinality(reason_codes) > 0)
31
+ );
32
+
33
+ CREATE TABLE asm_agent.approval_grants (
34
+ id uuid PRIMARY KEY,
35
+ decision_id uuid NOT NULL REFERENCES asm_agent.policy_decisions(id) ON DELETE CASCADE,
36
+ approval_type text NOT NULL,
37
+ granted_by text NOT NULL,
38
+ scope_hash text NOT NULL CHECK (scope_hash ~ '^[a-f0-9]{64}$'),
39
+ granted_at timestamptz NOT NULL DEFAULT clock_timestamp(),
40
+ expires_at timestamptz,
41
+ consumed_at timestamptz,
42
+ UNIQUE (decision_id, approval_type)
43
+ );
44
+
45
+ CREATE TABLE asm_agent.governed_executions (
46
+ id uuid PRIMARY KEY,
47
+ intent_id uuid NOT NULL REFERENCES asm_agent.parsed_intents(id) ON DELETE CASCADE,
48
+ decision_id uuid NOT NULL REFERENCES asm_agent.policy_decisions(id) ON DELETE RESTRICT,
49
+ idempotency_scope text NOT NULL,
50
+ idempotency_key text NOT NULL,
51
+ request_hash text NOT NULL CHECK (request_hash ~ '^[a-f0-9]{64}$'),
52
+ status text NOT NULL CHECK (status IN ('started','completed','failed','unknown_external_outcome')),
53
+ result jsonb,
54
+ error jsonb,
55
+ started_at timestamptz NOT NULL DEFAULT clock_timestamp(),
56
+ completed_at timestamptz,
57
+ UNIQUE (idempotency_scope, idempotency_key)
58
+ );
59
+
60
+ CREATE INDEX parsed_intents_project_created_idx ON asm_agent.parsed_intents(project_id, created_at DESC);
61
+ CREATE INDEX policy_decisions_intent_idx ON asm_agent.policy_decisions(intent_id, decided_at DESC);
@@ -0,0 +1,64 @@
1
+ CREATE TABLE asm_agent.inference_manifests (
2
+ id uuid PRIMARY KEY,
3
+ project_id uuid NOT NULL REFERENCES asm_agent.projects(id) ON DELETE CASCADE,
4
+ backend text NOT NULL CHECK (backend IN ('deterministic','vector','causal_head','dual_asm')),
5
+ model_id text NOT NULL,
6
+ model_version text NOT NULL,
7
+ artifact_digest text CHECK (artifact_digest ~ '^[a-f0-9]{64}$'),
8
+ contract_majors jsonb NOT NULL,
9
+ parameters jsonb NOT NULL,
10
+ created_at timestamptz NOT NULL,
11
+ UNIQUE (project_id, model_id, model_version)
12
+ );
13
+
14
+ CREATE TABLE asm_agent.model_state_snapshots (
15
+ id uuid PRIMARY KEY,
16
+ project_id uuid NOT NULL REFERENCES asm_agent.projects(id) ON DELETE CASCADE,
17
+ session_id uuid NOT NULL REFERENCES asm_agent.sessions(id) ON DELETE CASCADE,
18
+ manifest_id uuid REFERENCES asm_agent.inference_manifests(id) ON DELETE RESTRICT,
19
+ backend text NOT NULL CHECK (backend IN ('causal_head','dual_asm')),
20
+ sequence bigint NOT NULL CHECK (sequence >= 0),
21
+ state jsonb NOT NULL,
22
+ digest text NOT NULL CHECK (digest ~ '^[a-f0-9]{64}$'),
23
+ created_at timestamptz NOT NULL DEFAULT clock_timestamp(),
24
+ UNIQUE (session_id, backend, sequence),
25
+ UNIQUE (session_id, backend, digest)
26
+ );
27
+
28
+ CREATE TABLE asm_agent.retrieval_experiments (
29
+ id uuid PRIMARY KEY,
30
+ project_id uuid NOT NULL REFERENCES asm_agent.projects(id) ON DELETE CASCADE,
31
+ manifest_id uuid NOT NULL REFERENCES asm_agent.inference_manifests(id) ON DELETE RESTRICT,
32
+ baseline_backend text NOT NULL CHECK (baseline_backend IN ('lexical-v1','vector-l2-v1')),
33
+ candidate_backend text NOT NULL CHECK (candidate_backend IN ('causal-head-v1','dual-asm-v1')),
34
+ mode text NOT NULL DEFAULT 'shadow' CHECK (mode IN ('shadow','candidate','promoted','rejected')),
35
+ fixture_digest text NOT NULL CHECK (fixture_digest ~ '^[a-f0-9]{64}$'),
36
+ created_at timestamptz NOT NULL DEFAULT clock_timestamp(),
37
+ updated_at timestamptz NOT NULL DEFAULT clock_timestamp()
38
+ );
39
+
40
+ CREATE TABLE asm_agent.retrieval_evaluations (
41
+ id uuid PRIMARY KEY,
42
+ experiment_id uuid NOT NULL REFERENCES asm_agent.retrieval_experiments(id) ON DELETE CASCADE,
43
+ metrics jsonb NOT NULL,
44
+ thresholds jsonb NOT NULL,
45
+ passed boolean NOT NULL,
46
+ evaluated_at timestamptz NOT NULL DEFAULT clock_timestamp()
47
+ );
48
+
49
+ CREATE TABLE asm_agent.retrieval_configurations (
50
+ project_id uuid PRIMARY KEY REFERENCES asm_agent.projects(id) ON DELETE CASCADE,
51
+ primary_backend text NOT NULL DEFAULT 'lexical-v1',
52
+ primary_manifest_id uuid REFERENCES asm_agent.inference_manifests(id) ON DELETE RESTRICT,
53
+ shadow_backend text,
54
+ shadow_manifest_id uuid REFERENCES asm_agent.inference_manifests(id) ON DELETE RESTRICT,
55
+ previous_backend text,
56
+ previous_manifest_id uuid REFERENCES asm_agent.inference_manifests(id) ON DELETE RESTRICT,
57
+ revision bigint NOT NULL DEFAULT 1 CHECK (revision > 0),
58
+ updated_at timestamptz NOT NULL DEFAULT clock_timestamp()
59
+ );
60
+
61
+ CREATE INDEX model_state_session_latest_idx
62
+ ON asm_agent.model_state_snapshots(session_id, backend, sequence DESC);
63
+ CREATE INDEX retrieval_experiments_project_idx
64
+ ON asm_agent.retrieval_experiments(project_id, created_at DESC);
@@ -0,0 +1,82 @@
1
+ CREATE TABLE asm_agent.knowledge_sources (
2
+ id uuid PRIMARY KEY,
3
+ owner_id uuid NOT NULL REFERENCES asm_agent.owners(id) ON DELETE CASCADE,
4
+ project_id uuid NOT NULL REFERENCES asm_agent.projects(id) ON DELETE CASCADE,
5
+ kind text NOT NULL CHECK (kind IN ('document','website','api')),
6
+ uri text NOT NULL,
7
+ host text,
8
+ status text NOT NULL CHECK (status IN ('pending_approval','approved','paused','revoked')),
9
+ crawl_policy jsonb NOT NULL DEFAULT '{}',
10
+ approved_by text,
11
+ approved_at timestamptz,
12
+ created_at timestamptz NOT NULL DEFAULT clock_timestamp(),
13
+ UNIQUE (project_id, uri)
14
+ );
15
+
16
+ CREATE TABLE asm_agent.ingestion_items (
17
+ id uuid PRIMARY KEY,
18
+ source_id uuid NOT NULL REFERENCES asm_agent.knowledge_sources(id) ON DELETE CASCADE,
19
+ evidence_id uuid REFERENCES asm_agent.evidence_snapshots(id) ON DELETE SET NULL,
20
+ memory_id uuid REFERENCES asm_agent.memory_records(id) ON DELETE SET NULL,
21
+ source_uri text NOT NULL,
22
+ content_digest text NOT NULL CHECK (content_digest ~ '^[a-f0-9]{64}$'),
23
+ status text NOT NULL CHECK (status IN ('pending_moderation','accepted','rejected','revoked')),
24
+ moderation_reason text,
25
+ metadata jsonb NOT NULL DEFAULT '{}',
26
+ created_at timestamptz NOT NULL DEFAULT clock_timestamp(),
27
+ moderated_at timestamptz,
28
+ UNIQUE (source_id, content_digest)
29
+ );
30
+
31
+ CREATE TABLE asm_agent.durable_workflows (
32
+ id uuid PRIMARY KEY,
33
+ owner_id uuid NOT NULL REFERENCES asm_agent.owners(id) ON DELETE CASCADE,
34
+ project_id uuid NOT NULL REFERENCES asm_agent.projects(id) ON DELETE CASCADE,
35
+ session_id uuid REFERENCES asm_agent.sessions(id) ON DELETE SET NULL,
36
+ kind text NOT NULL CHECK (kind IN ('ingestion','research','evaluation','learning')),
37
+ status text NOT NULL CHECK (status IN ('pending','waiting_approval','running','completed','failed','cancelled')),
38
+ input jsonb NOT NULL,
39
+ result jsonb,
40
+ approval_scope_hash text CHECK (approval_scope_hash IS NULL OR approval_scope_hash ~ '^[a-f0-9]{64}$'),
41
+ approved_by text,
42
+ approved_at timestamptz,
43
+ available_at timestamptz NOT NULL DEFAULT clock_timestamp(),
44
+ locked_by text,
45
+ locked_until timestamptz,
46
+ fencing_token bigint NOT NULL DEFAULT 0,
47
+ attempts integer NOT NULL DEFAULT 0 CHECK (attempts >= 0),
48
+ created_at timestamptz NOT NULL DEFAULT clock_timestamp(),
49
+ completed_at timestamptz
50
+ );
51
+
52
+ CREATE TABLE asm_agent.workflow_events (
53
+ workflow_id uuid NOT NULL REFERENCES asm_agent.durable_workflows(id) ON DELETE CASCADE,
54
+ sequence bigint GENERATED ALWAYS AS IDENTITY,
55
+ event_type text NOT NULL,
56
+ payload jsonb NOT NULL DEFAULT '{}',
57
+ created_at timestamptz NOT NULL DEFAULT clock_timestamp(),
58
+ PRIMARY KEY (workflow_id, sequence)
59
+ );
60
+
61
+ CREATE TABLE asm_agent.local_agent_handoffs (
62
+ id uuid PRIMARY KEY,
63
+ owner_id uuid NOT NULL REFERENCES asm_agent.owners(id) ON DELETE CASCADE,
64
+ project_id uuid NOT NULL REFERENCES asm_agent.projects(id) ON DELETE CASCADE,
65
+ from_session_id uuid NOT NULL REFERENCES asm_agent.sessions(id) ON DELETE CASCADE,
66
+ to_session_id uuid NOT NULL REFERENCES asm_agent.sessions(id) ON DELETE CASCADE,
67
+ from_agent_id text NOT NULL,
68
+ to_agent_id text NOT NULL,
69
+ status text NOT NULL CHECK (status IN ('offered','accepted','rejected','completed','cancelled')),
70
+ objective text NOT NULL,
71
+ payload jsonb NOT NULL DEFAULT '{}',
72
+ evidence_ids uuid[] NOT NULL DEFAULT '{}',
73
+ created_at timestamptz NOT NULL DEFAULT clock_timestamp(),
74
+ accepted_at timestamptz,
75
+ completed_at timestamptz,
76
+ CHECK (from_session_id <> to_session_id)
77
+ );
78
+
79
+ CREATE INDEX knowledge_sources_scope_idx ON asm_agent.knowledge_sources(owner_id, project_id, status);
80
+ CREATE INDEX ingestion_items_source_status_idx ON asm_agent.ingestion_items(source_id, status, created_at);
81
+ CREATE INDEX durable_workflows_claim_idx ON asm_agent.durable_workflows(status, available_at, locked_until);
82
+ CREATE INDEX local_agent_handoffs_target_idx ON asm_agent.local_agent_handoffs(project_id, to_agent_id, status);
@@ -0,0 +1,28 @@
1
+ ALTER TABLE asm_agent.inference_manifests
2
+ DROP CONSTRAINT inference_manifests_backend_check,
3
+ ADD CONSTRAINT inference_manifests_backend_check
4
+ CHECK (backend IN ('deterministic','vector','causal_head','dual_asm','asm_cm'));
5
+
6
+ ALTER TABLE asm_agent.retrieval_experiments
7
+ DROP CONSTRAINT retrieval_experiments_candidate_backend_check,
8
+ ADD CONSTRAINT retrieval_experiments_candidate_backend_check
9
+ CHECK (candidate_backend IN ('causal-head-v1','dual-asm-v1','asm-cm-v1'));
10
+
11
+ CREATE TABLE asm_agent.asm_runtime_observations (
12
+ id uuid PRIMARY KEY,
13
+ owner_id uuid NOT NULL REFERENCES asm_agent.owners(id) ON DELETE CASCADE,
14
+ project_id uuid NOT NULL REFERENCES asm_agent.projects(id) ON DELETE CASCADE,
15
+ session_id uuid NOT NULL REFERENCES asm_agent.sessions(id) ON DELETE CASCADE,
16
+ manifest_id uuid NOT NULL REFERENCES asm_agent.inference_manifests(id) ON DELETE RESTRICT,
17
+ mode text NOT NULL DEFAULT 'shadow' CHECK (mode = 'shadow'),
18
+ input_digest text NOT NULL CHECK (input_digest ~ '^[a-f0-9]{64}$'),
19
+ vector_count integer NOT NULL CHECK (vector_count > 0),
20
+ dimensions integer NOT NULL CHECK (dimensions > 0),
21
+ latency_ms integer NOT NULL CHECK (latency_ms >= 0),
22
+ succeeded boolean NOT NULL,
23
+ error_code text,
24
+ created_at timestamptz NOT NULL DEFAULT clock_timestamp()
25
+ );
26
+
27
+ CREATE INDEX asm_runtime_observations_session_idx
28
+ ON asm_agent.asm_runtime_observations(session_id, created_at DESC);
@@ -0,0 +1,8 @@
1
+ ALTER TABLE asm_agent.retrieval_evaluations
2
+ ADD COLUMN seed integer,
3
+ ADD COLUMN workload_digest text
4
+ CHECK (workload_digest IS NULL OR workload_digest ~ '^[a-f0-9]{64}$');
5
+
6
+ CREATE INDEX retrieval_evaluations_confirmation_idx
7
+ ON asm_agent.retrieval_evaluations(experiment_id, passed, workload_digest)
8
+ WHERE seed IS NOT NULL AND workload_digest IS NOT NULL;