@cavelang/store 0.4.0 → 0.12.0

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.
package/README.md CHANGED
@@ -38,17 +38,32 @@ store.exportText({ current: true }) // canonical CAVE text back out
38
38
  (`@ 0%`) rows; opt back in with `{ negated: true, retracted: true }`.
39
39
  Contradictions still coexist as rows (§9.4) — resolution belongs to the
40
40
  query layer.
41
+ - **Alias closure is opt-in** (§13.6): `{ aliases: true }` on traversal
42
+ (and on `claimsAbout`) matches the entity through every name linked by
43
+ current positive `ALIAS` claims, read as undirected edges;
44
+ `aliasesOf(entity)` returns the closure itself. Union-of-rows semantics:
45
+ matching widens, stored names come back untouched, and disagreeing
46
+ belief series surface side by side rather than merging silently. Unmerge
47
+ is retraction — `dupe ALIAS canonical @ 0%`.
48
+ - **Actor provenance is caller-supplied** (§9.5): `ingest`/`insertResult`
49
+ accept `{ source }` and stamp `@src:<source>` on every appended claim
50
+ that carries no `src:` context — *before* the claim key is computed, so
51
+ the stamp is part of claim identity and the same fact asserted by
52
+ different actors keeps separate belief series (§9.4). A written `@src:`
53
+ always wins; `raw_line` stays as authored. Interchange replay (`cave
54
+ import`) passes no source, preserving exported keys.
41
55
 
42
56
  ## API
43
57
 
44
58
  | Method | Spec | Purpose |
45
59
  |---|---|---|
46
- | `ingest(text, {strict})` | §13.4 | parse → canonicalize → append; lenient by default |
47
- | `insertResult(result)` | | append a pre-canonicalized `@cavelang/canonical` result |
60
+ | `ingest(text, {strict, source})` | §13.4 | parse → canonicalize → append; lenient by default |
61
+ | `insertResult(result, {source})` | | append a pre-canonicalized `@cavelang/canonical` result |
48
62
  | `currentBeliefs({minConf})` | §13.5 | latest row per key |
49
63
  | `currentBelief(key)` / `history(key)` | §9.1 | one fact's belief series |
50
- | `claimsAbout(entity)` | §13.5 | both directions, all rows |
64
+ | `claimsAbout(entity, {aliases})` | §13.5 | both directions, all rows |
51
65
  | `forward(entity)` / `reverse(entity)` | §13.3 | named traversal, inverse-aware |
66
+ | `aliasesOf(entity)` | §13.6 | the entity's alias closure |
52
67
  | `byTag(key, value?)` | §13.5 | flat (`value` omitted → `IS NULL`) or scoped |
53
68
  | `byContext(ctx)` | §13.5 | context filter |
54
69
  | `topicMembers(t)` / `topicsOf(e)` | §11.2 | topic layer over `CONTAINS` |
@@ -86,6 +101,9 @@ pnpm --filter @cavelang/store test
86
101
 
87
102
  Covers the §9.1 belief series, §5.5 one-fact-two-names invariants
88
103
  (unified belief through either name, negation riding the row, no
89
- materialized inverses), every §13.5 query, the §11.2 topic reads, edge
90
- persistence, registry rebuild across reopen, transactional strict ingest
91
- and export round-trips.
104
+ materialized inverses), every §13.5 query, the §13.6 alias closure
105
+ (merge, unmerge by retraction, opt-in traversal, union semantics), the
106
+ §9.5 provenance stamping (written `@src:` wins, per-actor series,
107
+ cross-actor retraction, stamped round-trips), the §11.2 topic reads,
108
+ edge persistence, registry rebuild across reopen, transactional strict
109
+ ingest and export round-trips.
@@ -14,5 +14,5 @@
14
14
  export * as Row from './row.ts';
15
15
  export * as Schema from './schema.ts';
16
16
  export { defaultDbPath, open } from './store.ts';
17
- export type { ForwardFact, IngestResult, ReverseFact, Store, TraverseOptions } from './store.ts';
17
+ export type { AppendOptions, ForwardFact, IngestResult, ReverseFact, Store, TraverseOptions } from './store.ts';
18
18
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,GAAG,MAAM,UAAU,CAAA;AAC/B,OAAO,KAAK,MAAM,MAAM,aAAa,CAAA;AACrC,OAAO,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,YAAY,CAAA;AAChD,YAAY,EAAE,WAAW,EAAE,YAAY,EAAE,WAAW,EAAE,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,GAAG,MAAM,UAAU,CAAA;AAC/B,OAAO,KAAK,MAAM,MAAM,aAAa,CAAA;AACrC,OAAO,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,YAAY,CAAA;AAChD,YAAY,EAAE,aAAa,EAAE,WAAW,EAAE,YAAY,EAAE,WAAW,EAAE,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA"}
@@ -8,7 +8,10 @@
8
8
  * - the verb registry is rebuilt from stored in-band declaration claims on
9
9
  * open, so a reopened database keeps its inverse vocabulary;
10
10
  * - full-text search over subjects, objects, values, comments and raw
11
- * lines via FTS5.
11
+ * lines via FTS5;
12
+ * - appends can stamp actor provenance (spec §9.5): pass `source` and every
13
+ * claim without a `src:` context gets `@src:<actor>` — applied before the
14
+ * claim key is computed, so different actors keep separate belief series.
12
15
  */
13
16
  import { DatabaseSync } from 'node:sqlite';
14
17
  import { Claim } from '@cavelang/core';
@@ -20,6 +23,17 @@ export type IngestResult = {
20
23
  readonly edges: number;
21
24
  readonly problems: readonly Canonical.Problem[];
22
25
  };
26
+ export type AppendOptions = {
27
+ /**
28
+ * Actor provenance (spec §9.5): stamp `@src:<source>` on every appended
29
+ * claim that carries no `src:` context — e.g. `cli`, `agent/claude-code`,
30
+ * `ingest/93a01c626b3f`. Applied before the claim key is computed, so the
31
+ * stamp is part of claim identity; claims that already name a source keep
32
+ * it untouched. Omit for interchange replay (`cave import`), which must
33
+ * preserve claim keys as exported.
34
+ */
35
+ readonly source?: string;
36
+ };
23
37
  export type ForwardFact = {
24
38
  /** Canonical (primary) verb. */
25
39
  readonly verb: string;
@@ -39,6 +53,12 @@ export type TraverseOptions = {
39
53
  readonly negated?: boolean;
40
54
  /** Include rows whose current belief is `@ 0%` (default `false`). */
41
55
  readonly retracted?: boolean;
56
+ /**
57
+ * Match the entity through its alias closure — every name linked by
58
+ * current positive `ALIAS` claims (spec §13.6, default `false`).
59
+ * Union-of-rows: matching widens, returned rows keep their stored names.
60
+ */
61
+ readonly aliases?: boolean;
42
62
  };
43
63
  export type Store = ReturnType<typeof open>;
44
64
  /**
@@ -61,16 +81,24 @@ export declare const open: (path?: string, options?: {
61
81
  db: DatabaseSync;
62
82
  /** Current verb registry (input registry + stored + ingested declarations). */
63
83
  registry: () => Canonical.Registry.t;
84
+ /**
85
+ * Runs `body` atomically; throwing rolls everything back, including
86
+ * nested appends and their registry declarations. Nestable
87
+ * (savepoints) — the write gate wraps ingest + check in one of these
88
+ * (spec §20.3).
89
+ */
90
+ transaction: <T>(body: () => T) => T;
64
91
  /**
65
92
  * Parses, canonicalizes and appends CAVE text. Lenient by default —
66
93
  * problems are returned, valid lines still land (spec §1.6); pass
67
- * `strict` to throw instead.
94
+ * `strict` to throw instead, `source` to stamp actor provenance
95
+ * (spec §9.5).
68
96
  */
69
97
  ingest(text: string, options_?: {
70
98
  strict?: boolean;
71
- }): IngestResult;
99
+ } & AppendOptions): IngestResult;
72
100
  /** Appends an already-canonicalized result. */
73
- insertResult: (result: Canonical.Result) => IngestResult;
101
+ insertResult: (result: Canonical.Result, options_?: AppendOptions) => IngestResult;
74
102
  /** Latest row per claim key (spec §13.5), oldest first. */
75
103
  currentBeliefs(options_?: {
76
104
  minConf?: number;
@@ -79,8 +107,17 @@ export declare const open: (path?: string, options?: {
79
107
  currentBelief(claimKey: string): undefined | Row.t;
80
108
  /** Full belief series of one claim key, oldest first (spec §9.1). */
81
109
  history(claimKey: string): Row.t[];
110
+ /**
111
+ * The alias closure of an entity (spec §13.6): the entity itself plus
112
+ * every name reachable through current positive `ALIAS` claims, read as
113
+ * undirected edges. Unmerge is retraction — appending `a ALIAS b @ 0%`
114
+ * removes that link. The queried name first, the rest sorted.
115
+ */
116
+ aliasesOf(entity: string): string[];
82
117
  /** All rows about an entity, both directions, newest first (spec §13.5). */
83
- claimsAbout(entity: string): Row.t[];
118
+ claimsAbout(entity: string, options_?: {
119
+ aliases?: boolean;
120
+ }): Row.t[];
84
121
  /** Forward reads: current relational facts with `entity` as subject (spec §13.3). */
85
122
  forward(entity: string, options_?: TraverseOptions): ForwardFact[];
86
123
  /**
@@ -106,6 +143,19 @@ export declare const open: (path?: string, options?: {
106
143
  search(query: string, options_?: {
107
144
  raw?: boolean;
108
145
  }): Row.t[];
146
+ /**
147
+ * Appends edges between *existing* claim rows (spec §13.2) — the
148
+ * derivation-lineage path (§24.3): a derived row points `BECAUSE` at
149
+ * the specific premise rows that fired and `VIA` at the rule's
150
+ * declaration row. `insertResult` covers edges within one appended
151
+ * batch; this covers edges into rows that are already stored. Foreign
152
+ * keys reject unknown ids.
153
+ */
154
+ appendEdges(edges: readonly {
155
+ parentId: string;
156
+ role: Canonical.EdgeRole;
157
+ childId: string;
158
+ }[]): void;
109
159
  /** Qualifier/grouping edges of a claim row (spec §13.2). */
110
160
  edgesOf(parentId: string): {
111
161
  role: string;
@@ -1 +1 @@
1
- {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/store.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/store.ts"],"names":[],"mappings":"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"}
package/dist/src/store.js CHANGED
@@ -8,10 +8,13 @@
8
8
  * - the verb registry is rebuilt from stored in-band declaration claims on
9
9
  * open, so a reopened database keeps its inverse vocabulary;
10
10
  * - full-text search over subjects, objects, values, comments and raw
11
- * lines via FTS5.
11
+ * lines via FTS5;
12
+ * - appends can stamp actor provenance (spec §9.5): pass `source` and every
13
+ * claim without a `src:` context gets `@src:<actor>` — applied before the
14
+ * claim key is computed, so different actors keep separate belief series.
12
15
  */
13
16
  import { DatabaseSync } from 'node:sqlite';
14
- import { Claim, Key, Uuidv7, Verb } from '@cavelang/core';
17
+ import { Claim, Context, Key, Uuidv7, Verb } from '@cavelang/core';
15
18
  import * as Canonical from '@cavelang/canonical';
16
19
  import * as Row from "./row.js";
17
20
  import * as Schema from "./schema.js";
@@ -22,6 +25,30 @@ JOIN (
22
25
  FROM cave_claim GROUP BY claim_key
23
26
  ) latest ON c.claim_key = latest.claim_key AND c.tx = latest.max_tx
24
27
  `;
28
+ /**
29
+ * Alias closure (spec §13.6): current positive `ALIAS` claims as undirected
30
+ * edges (`ALIAS` has no `REVERSE`, so each written direction is its own
31
+ * claim key — both assert the same link), walked recursively from a seed
32
+ * entity. Retraction unmerges: `a ALIAS b @ 0%` drops that direction's edge.
33
+ * The seed is the query's single positional parameter.
34
+ */
35
+ const aliasClosureSql = `
36
+ WITH RECURSIVE alias_edge(a, b) AS (
37
+ SELECT c.subject, c.object FROM (${currentSql}) c
38
+ WHERE c.verb = 'ALIAS' AND c.negated = 0 AND c.conf > 0 AND c.object IS NOT NULL
39
+ UNION
40
+ SELECT c.object, c.subject FROM (${currentSql}) c
41
+ WHERE c.verb = 'ALIAS' AND c.negated = 0 AND c.conf > 0 AND c.object IS NOT NULL
42
+ ), alias_closure(name) AS (
43
+ SELECT ?
44
+ UNION
45
+ SELECT e.b FROM alias_closure s JOIN alias_edge e ON e.a = s.name
46
+ )
47
+ `;
48
+ /** Stamps `@src:<source>` on a claim without a source context (spec §9.5). */
49
+ const stampSource = (claim, source) => source === undefined || Context.hasSource(claim.contexts) ?
50
+ claim :
51
+ { ...claim, contexts: [...claim.contexts, Context.source(source)] };
25
52
  /**
26
53
  * Database path used by CLI surfaces when `--db` is omitted: the `CAVE_DB`
27
54
  * environment variable, falling back to `cave.db` in the current directory.
@@ -83,23 +110,39 @@ export const open = (path = ':memory:', options = {}) => {
83
110
  }
84
111
  };
85
112
  rebuildRegistry();
113
+ /**
114
+ * Savepoint-based, so transactions nest: a caller can wrap several
115
+ * appends — or an append plus checks against the appended state — and
116
+ * roll the whole group back by throwing (spec §20.3 write gating).
117
+ * Rollback also restores the in-memory verb registry, so declarations
118
+ * from rolled-back claims don't outlive their rows.
119
+ */
120
+ let transactionDepth = 0;
86
121
  const transaction = (body) => {
87
- db.exec('BEGIN');
122
+ const savepoint = `cave_tx_${transactionDepth}`;
123
+ transactionDepth += 1;
124
+ const savedRegistry = registry;
125
+ db.exec(`SAVEPOINT ${savepoint}`);
88
126
  try {
89
127
  const result = body();
90
- db.exec('COMMIT');
128
+ db.exec(`RELEASE ${savepoint}`);
91
129
  return result;
92
130
  }
93
131
  catch (error) {
94
- db.exec('ROLLBACK');
132
+ db.exec(`ROLLBACK TO ${savepoint}`);
133
+ db.exec(`RELEASE ${savepoint}`);
134
+ registry = savedRegistry;
95
135
  throw error;
96
136
  }
137
+ finally {
138
+ transactionDepth -= 1;
139
+ }
97
140
  };
98
141
  /** Appends a canonicalization result — one row per claim, per-row tx. */
99
- const insertResult = (result) => transaction(() => {
142
+ const insertResult = (result, options_ = {}) => transaction(() => {
100
143
  const ids = [];
101
144
  for (const entry of result.claims) {
102
- const claim = entry.claim;
145
+ const claim = stampSource(entry.claim, options_.source);
103
146
  const id = Uuidv7.next();
104
147
  const columns = Row.toColumns(claim);
105
148
  const rawLine = columns.rawLine === '' ? Canonical.emitClaim(claim) : columns.rawLine;
@@ -126,15 +169,31 @@ export const open = (path = ':memory:', options = {}) => {
126
169
  const toClaim = (row) => Row.toClaim(row, contextsOf(row.id), tagsOf(row.id));
127
170
  const traversalFilter = (options) => (options.negated === true ? '' : ' AND negated = 0') +
128
171
  (options.retracted === true ? '' : ' AND conf > 0');
172
+ /**
173
+ * Entity-matching fragment for one traversal endpoint: exact by default,
174
+ * `IN` the alias closure when opted in. Either form consumes exactly one
175
+ * positional parameter — the closure seeds from it (`aliasClosureSql`
176
+ * must be prepended when `aliases` is set).
177
+ */
178
+ const entityMatch = (column, options) => options.aliases === true ? `${column} IN (SELECT name FROM alias_closure)` : `${column} = ?`;
179
+ const withAliases = (options) => options.aliases === true ? aliasClosureSql : '';
129
180
  return {
130
181
  /** Raw database handle — used by `@cavelang/query`; treat as read-only. */
131
182
  db,
132
183
  /** Current verb registry (input registry + stored + ingested declarations). */
133
184
  registry: () => registry,
185
+ /**
186
+ * Runs `body` atomically; throwing rolls everything back, including
187
+ * nested appends and their registry declarations. Nestable
188
+ * (savepoints) — the write gate wraps ingest + check in one of these
189
+ * (spec §20.3).
190
+ */
191
+ transaction,
134
192
  /**
135
193
  * Parses, canonicalizes and appends CAVE text. Lenient by default —
136
194
  * problems are returned, valid lines still land (spec §1.6); pass
137
- * `strict` to throw instead.
195
+ * `strict` to throw instead, `source` to stamp actor provenance
196
+ * (spec §9.5).
138
197
  */
139
198
  ingest(text, options_ = {}) {
140
199
  const result = Canonical.canonicalizeText(text, registry);
@@ -142,7 +201,7 @@ export const open = (path = ':memory:', options = {}) => {
142
201
  const detail = result.problems.map(problem => ` line ${problem.line}: ${problem.message}`).join('\n');
143
202
  throw new Error(`CAVE ingest failed with ${result.problems.length} problem(s):\n${detail}`);
144
203
  }
145
- return insertResult(result);
204
+ return insertResult(result, options_);
146
205
  },
147
206
  /** Appends an already-canonicalized result. */
148
207
  insertResult,
@@ -161,13 +220,28 @@ export const open = (path = ':memory:', options = {}) => {
161
220
  history(claimKey) {
162
221
  return rows('SELECT * FROM cave_claim WHERE claim_key = ? ORDER BY tx', claimKey);
163
222
  },
223
+ /**
224
+ * The alias closure of an entity (spec §13.6): the entity itself plus
225
+ * every name reachable through current positive `ALIAS` claims, read as
226
+ * undirected edges. Unmerge is retraction — appending `a ALIAS b @ 0%`
227
+ * removes that link. The queried name first, the rest sorted.
228
+ */
229
+ aliasesOf(entity) {
230
+ const names = db.prepare(`${aliasClosureSql} SELECT name FROM alias_closure WHERE name <> ? ORDER BY name`)
231
+ .all(entity, entity);
232
+ return [entity, ...names.map(row => row.name)];
233
+ },
164
234
  /** All rows about an entity, both directions, newest first (spec §13.5). */
165
- claimsAbout(entity) {
166
- return rows('SELECT * FROM cave_claim WHERE subject = ? OR object = ? ORDER BY tx DESC', entity, entity);
235
+ claimsAbout(entity, options_ = {}) {
236
+ return options_.aliases === true ?
237
+ rows(`${aliasClosureSql} SELECT * FROM cave_claim
238
+ WHERE subject IN (SELECT name FROM alias_closure) OR object IN (SELECT name FROM alias_closure)
239
+ ORDER BY tx DESC`, entity) :
240
+ rows('SELECT * FROM cave_claim WHERE subject = ? OR object = ? ORDER BY tx DESC', entity, entity);
167
241
  },
168
242
  /** Forward reads: current relational facts with `entity` as subject (spec §13.3). */
169
243
  forward(entity, options_ = {}) {
170
- return rows(`SELECT * FROM (${currentSql}) WHERE subject = ? AND object IS NOT NULL${traversalFilter(options_)} ORDER BY tx`, entity).map(row => ({ verb: row.verb, target: row.object, row }));
244
+ return rows(`${withAliases(options_)} SELECT * FROM (${currentSql}) WHERE ${entityMatch('subject', options_)} AND object IS NOT NULL${traversalFilter(options_)} ORDER BY tx`, entity).map(row => ({ verb: row.verb, target: row.object, row }));
171
245
  },
172
246
  /**
173
247
  * Inverse reads (spec §13.3): current relational facts
@@ -175,7 +249,7 @@ export const open = (path = ':memory:', options = {}) => {
175
249
  * when one is declared.
176
250
  */
177
251
  reverse(entity, options_ = {}) {
178
- return rows(`SELECT * FROM (${currentSql}) WHERE object = ? AND object IS NOT NULL${traversalFilter(options_)} ORDER BY tx`, entity).map(row => {
252
+ return rows(`${withAliases(options_)} SELECT * FROM (${currentSql}) WHERE ${entityMatch('object', options_)} AND object IS NOT NULL${traversalFilter(options_)} ORDER BY tx`, entity).map(row => {
179
253
  const rel = Canonical.Registry.inverseOf(registry, row.verb);
180
254
  return { verb: row.verb, ...rel === undefined ? {} : { rel }, source: row.subject, row };
181
255
  });
@@ -198,11 +272,11 @@ export const open = (path = ':memory:', options = {}) => {
198
272
  },
199
273
  /** Members of a topic — forward `CONTAINS` traversal (spec §11.2). */
200
274
  topicMembers(topic, options_ = {}) {
201
- return rows(`SELECT * FROM (${currentSql}) WHERE subject = ? AND verb = 'CONTAINS' AND object IS NOT NULL${traversalFilter(options_)} ORDER BY tx`, topic).map(row => row.object);
275
+ return rows(`${withAliases(options_)} SELECT * FROM (${currentSql}) WHERE ${entityMatch('subject', options_)} AND verb = 'CONTAINS' AND object IS NOT NULL${traversalFilter(options_)} ORDER BY tx`, topic).map(row => row.object);
202
276
  },
203
277
  /** Topics containing an entity — the inverse `CONTAINS` read (spec §11.2). */
204
278
  topicsOf(entity, options_ = {}) {
205
- return rows(`SELECT * FROM (${currentSql}) WHERE object = ? AND verb = 'CONTAINS'${traversalFilter(options_)} ORDER BY tx`, entity).map(row => row.subject);
279
+ return rows(`${withAliases(options_)} SELECT * FROM (${currentSql}) WHERE ${entityMatch('object', options_)} AND verb = 'CONTAINS'${traversalFilter(options_)} ORDER BY tx`, entity).map(row => row.subject);
206
280
  },
207
281
  /**
208
282
  * Full-text search, newest first. The query is treated as a literal
@@ -216,6 +290,21 @@ export const open = (path = ':memory:', options = {}) => {
216
290
  SELECT c.* FROM cave_claim c JOIN cave_fts f ON c.id = f.claim_id
217
291
  WHERE cave_fts MATCH ? ORDER BY c.tx DESC`, match);
218
292
  },
293
+ /**
294
+ * Appends edges between *existing* claim rows (spec §13.2) — the
295
+ * derivation-lineage path (§24.3): a derived row points `BECAUSE` at
296
+ * the specific premise rows that fired and `VIA` at the rule's
297
+ * declaration row. `insertResult` covers edges within one appended
298
+ * batch; this covers edges into rows that are already stored. Foreign
299
+ * keys reject unknown ids.
300
+ */
301
+ appendEdges(edges) {
302
+ transaction(() => {
303
+ for (const edge of edges) {
304
+ insertEdge.run(edge.parentId, edge.role, edge.childId);
305
+ }
306
+ });
307
+ },
219
308
  /** Qualifier/grouping edges of a claim row (spec §13.2). */
220
309
  edgesOf(parentId) {
221
310
  return db.prepare(`
@@ -1 +1 @@
1
- {"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/store.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/store.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cavelang/store",
3
- "version": "0.4.0",
3
+ "version": "0.12.0",
4
4
  "type": "module",
5
5
  "description": "CAVE persistence on node:sqlite — §13 storage model, append-only belief series, inverse-aware reads.",
6
6
  "license": "CC0-1.0",
@@ -32,8 +32,8 @@
32
32
  "access": "public"
33
33
  },
34
34
  "dependencies": {
35
- "@cavelang/core": "0.4.0",
36
- "@cavelang/canonical": "0.4.0"
35
+ "@cavelang/core": "0.12.0",
36
+ "@cavelang/canonical": "0.12.0"
37
37
  },
38
38
  "scripts": {
39
39
  "build": "tsc -b",
package/src/index.ts CHANGED
@@ -15,4 +15,4 @@
15
15
  export * as Row from './row.ts'
16
16
  export * as Schema from './schema.ts'
17
17
  export { defaultDbPath, open } from './store.ts'
18
- export type { ForwardFact, IngestResult, ReverseFact, Store, TraverseOptions } from './store.ts'
18
+ export type { AppendOptions, ForwardFact, IngestResult, ReverseFact, Store, TraverseOptions } from './store.ts'
package/src/store.ts CHANGED
@@ -8,11 +8,14 @@
8
8
  * - the verb registry is rebuilt from stored in-band declaration claims on
9
9
  * open, so a reopened database keeps its inverse vocabulary;
10
10
  * - full-text search over subjects, objects, values, comments and raw
11
- * lines via FTS5.
11
+ * lines via FTS5;
12
+ * - appends can stamp actor provenance (spec §9.5): pass `source` and every
13
+ * claim without a `src:` context gets `@src:<actor>` — applied before the
14
+ * claim key is computed, so different actors keep separate belief series.
12
15
  */
13
16
 
14
17
  import { DatabaseSync } from 'node:sqlite'
15
- import { Claim, Key, Uuidv7, Verb } from '@cavelang/core'
18
+ import { Claim, Context, Key, Uuidv7, Verb } from '@cavelang/core'
16
19
  import * as Canonical from '@cavelang/canonical'
17
20
  import * as Row from './row.ts'
18
21
  import * as Schema from './schema.ts'
@@ -25,6 +28,27 @@ JOIN (
25
28
  ) latest ON c.claim_key = latest.claim_key AND c.tx = latest.max_tx
26
29
  `
27
30
 
31
+ /**
32
+ * Alias closure (spec §13.6): current positive `ALIAS` claims as undirected
33
+ * edges (`ALIAS` has no `REVERSE`, so each written direction is its own
34
+ * claim key — both assert the same link), walked recursively from a seed
35
+ * entity. Retraction unmerges: `a ALIAS b @ 0%` drops that direction's edge.
36
+ * The seed is the query's single positional parameter.
37
+ */
38
+ const aliasClosureSql = `
39
+ WITH RECURSIVE alias_edge(a, b) AS (
40
+ SELECT c.subject, c.object FROM (${currentSql}) c
41
+ WHERE c.verb = 'ALIAS' AND c.negated = 0 AND c.conf > 0 AND c.object IS NOT NULL
42
+ UNION
43
+ SELECT c.object, c.subject FROM (${currentSql}) c
44
+ WHERE c.verb = 'ALIAS' AND c.negated = 0 AND c.conf > 0 AND c.object IS NOT NULL
45
+ ), alias_closure(name) AS (
46
+ SELECT ?
47
+ UNION
48
+ SELECT e.b FROM alias_closure s JOIN alias_edge e ON e.a = s.name
49
+ )
50
+ `
51
+
28
52
  export type IngestResult = {
29
53
  /** ids of inserted claim rows, in document order. */
30
54
  readonly ids: readonly string[]
@@ -32,6 +56,24 @@ export type IngestResult = {
32
56
  readonly problems: readonly Canonical.Problem[]
33
57
  }
34
58
 
59
+ export type AppendOptions = {
60
+ /**
61
+ * Actor provenance (spec §9.5): stamp `@src:<source>` on every appended
62
+ * claim that carries no `src:` context — e.g. `cli`, `agent/claude-code`,
63
+ * `ingest/93a01c626b3f`. Applied before the claim key is computed, so the
64
+ * stamp is part of claim identity; claims that already name a source keep
65
+ * it untouched. Omit for interchange replay (`cave import`), which must
66
+ * preserve claim keys as exported.
67
+ */
68
+ readonly source?: string
69
+ }
70
+
71
+ /** Stamps `@src:<source>` on a claim without a source context (spec §9.5). */
72
+ const stampSource = (claim: Claim.t, source: undefined | string): Claim.t =>
73
+ source === undefined || Context.hasSource(claim.contexts) ?
74
+ claim :
75
+ { ...claim, contexts: [...claim.contexts, Context.source(source)] }
76
+
35
77
  export type ForwardFact = {
36
78
  /** Canonical (primary) verb. */
37
79
  readonly verb: string
@@ -53,6 +95,12 @@ export type TraverseOptions = {
53
95
  readonly negated?: boolean
54
96
  /** Include rows whose current belief is `@ 0%` (default `false`). */
55
97
  readonly retracted?: boolean
98
+ /**
99
+ * Match the entity through its alias closure — every name linked by
100
+ * current positive `ALIAS` claims (spec §13.6, default `false`).
101
+ * Union-of-rows: matching widens, returned rows keep their stored names.
102
+ */
103
+ readonly aliases?: boolean
56
104
  }
57
105
 
58
106
  export type Store = ReturnType<typeof open>
@@ -123,24 +171,39 @@ export const open = (path: string = ':memory:', options: { registry?: Canonical.
123
171
  }
124
172
  rebuildRegistry()
125
173
 
174
+ /**
175
+ * Savepoint-based, so transactions nest: a caller can wrap several
176
+ * appends — or an append plus checks against the appended state — and
177
+ * roll the whole group back by throwing (spec §20.3 write gating).
178
+ * Rollback also restores the in-memory verb registry, so declarations
179
+ * from rolled-back claims don't outlive their rows.
180
+ */
181
+ let transactionDepth = 0
126
182
  const transaction = <T>(body: () => T): T => {
127
- db.exec('BEGIN')
183
+ const savepoint = `cave_tx_${transactionDepth}`
184
+ transactionDepth += 1
185
+ const savedRegistry = registry
186
+ db.exec(`SAVEPOINT ${savepoint}`)
128
187
  try {
129
188
  const result = body()
130
- db.exec('COMMIT')
189
+ db.exec(`RELEASE ${savepoint}`)
131
190
  return result
132
191
  } catch (error) {
133
- db.exec('ROLLBACK')
192
+ db.exec(`ROLLBACK TO ${savepoint}`)
193
+ db.exec(`RELEASE ${savepoint}`)
194
+ registry = savedRegistry
134
195
  throw error
196
+ } finally {
197
+ transactionDepth -= 1
135
198
  }
136
199
  }
137
200
 
138
201
  /** Appends a canonicalization result — one row per claim, per-row tx. */
139
- const insertResult = (result: Canonical.Result): IngestResult =>
202
+ const insertResult = (result: Canonical.Result, options_: AppendOptions = {}): IngestResult =>
140
203
  transaction(() => {
141
204
  const ids: string[] = []
142
205
  for (const entry of result.claims) {
143
- const claim = entry.claim
206
+ const claim = stampSource(entry.claim, options_.source)
144
207
  const id = Uuidv7.next()
145
208
  const columns = Row.toColumns(claim)
146
209
  const rawLine = columns.rawLine === '' ? Canonical.emitClaim(claim) : columns.rawLine
@@ -189,6 +252,18 @@ export const open = (path: string = ':memory:', options: { registry?: Canonical.
189
252
  (options.negated === true ? '' : ' AND negated = 0') +
190
253
  (options.retracted === true ? '' : ' AND conf > 0')
191
254
 
255
+ /**
256
+ * Entity-matching fragment for one traversal endpoint: exact by default,
257
+ * `IN` the alias closure when opted in. Either form consumes exactly one
258
+ * positional parameter — the closure seeds from it (`aliasClosureSql`
259
+ * must be prepended when `aliases` is set).
260
+ */
261
+ const entityMatch = (column: string, options: TraverseOptions): string =>
262
+ options.aliases === true ? `${column} IN (SELECT name FROM alias_closure)` : `${column} = ?`
263
+
264
+ const withAliases = (options: TraverseOptions): string =>
265
+ options.aliases === true ? aliasClosureSql : ''
266
+
192
267
  return {
193
268
  /** Raw database handle — used by `@cavelang/query`; treat as read-only. */
194
269
  db,
@@ -196,18 +271,27 @@ export const open = (path: string = ':memory:', options: { registry?: Canonical.
196
271
  /** Current verb registry (input registry + stored + ingested declarations). */
197
272
  registry: (): Canonical.Registry.t => registry,
198
273
 
274
+ /**
275
+ * Runs `body` atomically; throwing rolls everything back, including
276
+ * nested appends and their registry declarations. Nestable
277
+ * (savepoints) — the write gate wraps ingest + check in one of these
278
+ * (spec §20.3).
279
+ */
280
+ transaction,
281
+
199
282
  /**
200
283
  * Parses, canonicalizes and appends CAVE text. Lenient by default —
201
284
  * problems are returned, valid lines still land (spec §1.6); pass
202
- * `strict` to throw instead.
285
+ * `strict` to throw instead, `source` to stamp actor provenance
286
+ * (spec §9.5).
203
287
  */
204
- ingest(text: string, options_: { strict?: boolean } = {}): IngestResult {
288
+ ingest(text: string, options_: { strict?: boolean } & AppendOptions = {}): IngestResult {
205
289
  const result = Canonical.canonicalizeText(text, registry)
206
290
  if (options_.strict === true && result.problems.length > 0) {
207
291
  const detail = result.problems.map(problem => ` line ${problem.line}: ${problem.message}`).join('\n')
208
292
  throw new Error(`CAVE ingest failed with ${result.problems.length} problem(s):\n${detail}`)
209
293
  }
210
- return insertResult(result)
294
+ return insertResult(result, options_)
211
295
  },
212
296
 
213
297
  /** Appends an already-canonicalized result. */
@@ -233,15 +317,34 @@ export const open = (path: string = ':memory:', options: { registry?: Canonical.
233
317
  return rows('SELECT * FROM cave_claim WHERE claim_key = ? ORDER BY tx', claimKey)
234
318
  },
235
319
 
320
+ /**
321
+ * The alias closure of an entity (spec §13.6): the entity itself plus
322
+ * every name reachable through current positive `ALIAS` claims, read as
323
+ * undirected edges. Unmerge is retraction — appending `a ALIAS b @ 0%`
324
+ * removes that link. The queried name first, the rest sorted.
325
+ */
326
+ aliasesOf(entity: string): string[] {
327
+ const names = db.prepare(`${aliasClosureSql} SELECT name FROM alias_closure WHERE name <> ? ORDER BY name`)
328
+ .all(entity, entity) as { name: string }[]
329
+ return [entity, ...names.map(row => row.name)]
330
+ },
331
+
236
332
  /** All rows about an entity, both directions, newest first (spec §13.5). */
237
- claimsAbout(entity: string): Row.t[] {
238
- return rows('SELECT * FROM cave_claim WHERE subject = ? OR object = ? ORDER BY tx DESC', entity, entity)
333
+ claimsAbout(entity: string, options_: { aliases?: boolean } = {}): Row.t[] {
334
+ return options_.aliases === true ?
335
+ rows(
336
+ `${aliasClosureSql} SELECT * FROM cave_claim
337
+ WHERE subject IN (SELECT name FROM alias_closure) OR object IN (SELECT name FROM alias_closure)
338
+ ORDER BY tx DESC`,
339
+ entity
340
+ ) :
341
+ rows('SELECT * FROM cave_claim WHERE subject = ? OR object = ? ORDER BY tx DESC', entity, entity)
239
342
  },
240
343
 
241
344
  /** Forward reads: current relational facts with `entity` as subject (spec §13.3). */
242
345
  forward(entity: string, options_: TraverseOptions = {}): ForwardFact[] {
243
346
  return rows(
244
- `SELECT * FROM (${currentSql}) WHERE subject = ? AND object IS NOT NULL${traversalFilter(options_)} ORDER BY tx`,
347
+ `${withAliases(options_)} SELECT * FROM (${currentSql}) WHERE ${entityMatch('subject', options_)} AND object IS NOT NULL${traversalFilter(options_)} ORDER BY tx`,
245
348
  entity
246
349
  ).map(row => ({ verb: row.verb, target: row.object!, row }))
247
350
  },
@@ -253,7 +356,7 @@ export const open = (path: string = ':memory:', options: { registry?: Canonical.
253
356
  */
254
357
  reverse(entity: string, options_: TraverseOptions = {}): ReverseFact[] {
255
358
  return rows(
256
- `SELECT * FROM (${currentSql}) WHERE object = ? AND object IS NOT NULL${traversalFilter(options_)} ORDER BY tx`,
359
+ `${withAliases(options_)} SELECT * FROM (${currentSql}) WHERE ${entityMatch('object', options_)} AND object IS NOT NULL${traversalFilter(options_)} ORDER BY tx`,
257
360
  entity
258
361
  ).map(row => {
259
362
  const rel = Canonical.Registry.inverseOf(registry, row.verb)
@@ -282,7 +385,7 @@ export const open = (path: string = ':memory:', options: { registry?: Canonical.
282
385
  /** Members of a topic — forward `CONTAINS` traversal (spec §11.2). */
283
386
  topicMembers(topic: string, options_: TraverseOptions = {}): string[] {
284
387
  return rows(
285
- `SELECT * FROM (${currentSql}) WHERE subject = ? AND verb = 'CONTAINS' AND object IS NOT NULL${traversalFilter(options_)} ORDER BY tx`,
388
+ `${withAliases(options_)} SELECT * FROM (${currentSql}) WHERE ${entityMatch('subject', options_)} AND verb = 'CONTAINS' AND object IS NOT NULL${traversalFilter(options_)} ORDER BY tx`,
286
389
  topic
287
390
  ).map(row => row.object!)
288
391
  },
@@ -290,7 +393,7 @@ export const open = (path: string = ':memory:', options: { registry?: Canonical.
290
393
  /** Topics containing an entity — the inverse `CONTAINS` read (spec §11.2). */
291
394
  topicsOf(entity: string, options_: TraverseOptions = {}): string[] {
292
395
  return rows(
293
- `SELECT * FROM (${currentSql}) WHERE object = ? AND verb = 'CONTAINS'${traversalFilter(options_)} ORDER BY tx`,
396
+ `${withAliases(options_)} SELECT * FROM (${currentSql}) WHERE ${entityMatch('object', options_)} AND verb = 'CONTAINS'${traversalFilter(options_)} ORDER BY tx`,
294
397
  entity
295
398
  ).map(row => row.subject)
296
399
  },
@@ -308,6 +411,22 @@ export const open = (path: string = ':memory:', options: { registry?: Canonical.
308
411
  WHERE cave_fts MATCH ? ORDER BY c.tx DESC`, match)
309
412
  },
310
413
 
414
+ /**
415
+ * Appends edges between *existing* claim rows (spec §13.2) — the
416
+ * derivation-lineage path (§24.3): a derived row points `BECAUSE` at
417
+ * the specific premise rows that fired and `VIA` at the rule's
418
+ * declaration row. `insertResult` covers edges within one appended
419
+ * batch; this covers edges into rows that are already stored. Foreign
420
+ * keys reject unknown ids.
421
+ */
422
+ appendEdges(edges: readonly { parentId: string, role: Canonical.EdgeRole, childId: string }[]): void {
423
+ transaction(() => {
424
+ for (const edge of edges) {
425
+ insertEdge.run(edge.parentId, edge.role, edge.childId)
426
+ }
427
+ })
428
+ },
429
+
311
430
  /** Qualifier/grouping edges of a claim row (spec §13.2). */
312
431
  edgesOf(parentId: string): { role: string, child: Row.t }[] {
313
432
  return (db.prepare(`
package/License.md DELETED
@@ -1,6 +0,0 @@
1
- # CC0 1.0 Universal (CC0 1.0) Public Domain Dedication
2
-
3
- To the extent possible under law, the authors listed in [Authors.md](./Authors.md) have waived all copyright and related or neighboring rights to this software and associated documentation files (the "Software").
4
-
5
- For more information, please see:
6
- https://creativecommons.org/publicdomain/zero/1.0/