@cavelang/core 0.28.1 → 0.29.1

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/dist/src/value.js CHANGED
@@ -19,16 +19,17 @@
19
19
  * with their kind already known; use {@link ofText} / {@link ofCode}.
20
20
  */
21
21
  import * as Multiplier from "./multiplier.js";
22
+ import { parsePeriod } from "./time.js";
22
23
  const numberRe = /^(-?\d+(?:\.\d+)?)([A-Za-z%]*)$/;
23
24
  const unitRe = /^[A-Za-z%$][A-Za-z0-9%$]*(?:\/[A-Za-z0-9%$]+)*$/;
24
- const dateRe = /^\d{4}-(?:H[1-2]|Q[1-4]|W\d{1,2}|\d{2})(?:-\d{2})?$/;
25
25
  /** @returns `true` if `s` is a valid unit expression (`USD/yr`, `ms`, `%`). */
26
26
  export const isUnit = (s) => unitRe.test(s);
27
27
  /**
28
28
  * @returns `true` if `s` is date-like (spec §16 `date_like`): `2026-H2`,
29
- * `2026-Q1`, `2026-04`, `2026-04-10`. A bare year parses as a number instead.
29
+ * `2026-Q1`, `2026-04`, `2026-04-10`. Calendar validity is shared with
30
+ * {@link parsePeriod}; a bare year parses as a number instead.
30
31
  */
31
- export const isDateLike = (s) => dateRe.test(s);
32
+ export const isDateLike = (s) => s.includes('-') && parsePeriod(s) !== undefined;
32
33
  /**
33
34
  * Parses `body` as number [multiplier] [unit] where the unit is either glued
34
35
  * (`30ms`, `94.5%`) or space-separated (`20B USD/yr`, `20 conn`).
@@ -1 +1 @@
1
- {"version":3,"file":"value.js","sourceRoot":"","sources":["../../src/value.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"value.js","sourceRoot":"","sources":["../../src/value.ts"],"names":[],"mappings":"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"}
@@ -18,12 +18,16 @@ export declare const causation: readonly ["CAUSE", "FIX", "BECOMES"];
18
18
  /** Dependency and production (spec §5.2). */
19
19
  export declare const dependency: readonly ["NEEDS", "USES", "YIELDS", "ENABLES", "BLOCKS"];
20
20
  /** Structure and ordering (spec §5.2). */
21
- export declare const structure: readonly ["CONTAINS", "PRECEDES", "EXCEEDS", "VS"];
21
+ export declare const structure: readonly ["CONTAINS", "PRECEDES", "VS"];
22
+ /** Canonical verbs for qualifier comparisons (spec §8.2). */
23
+ export declare const comparison: readonly ["EXCEEDS", "IS-BELOW", "IS-AT-LEAST", "IS-AT-MOST", "EQUALS", "DIFFERS-FROM"];
22
24
  /** Qualifier verbs — appear indented under another claim (spec §5.2, §8.2). */
23
25
  export declare const qualifiers: readonly ["WHEN", "UNLESS", "VIA", "BECAUSE"];
24
26
  export type Qualifier = (typeof qualifiers)[number];
25
27
  /** The inverse-declaration verb (spec §5.5). */
26
28
  export declare const REVERSE = "REVERSE";
29
+ /** The verb-lifecycle declaration (spec §5.8). */
30
+ export declare const RENAMED_TO = "RENAMED-TO";
27
31
  /** The shape-expectation meta-verb (spec §20.1). */
28
32
  export declare const EXPECTS = "EXPECTS";
29
33
  /** The standard inverse names (spec §5.5's declaration block). */
@@ -32,7 +36,8 @@ export declare const standardInverses: readonly ["PART-OF", "CAUSED-BY", "FOLLOW
32
36
  export declare const standard: readonly Verb[];
33
37
  /**
34
38
  * @returns `true` if `s` has the lexical shape of a verb — an uppercase atom:
35
- * uppercase letters and internal `-` (spec §16 `uppercase_atom`).
39
+ * an uppercase letter followed by uppercase letters or `-` (spec §16
40
+ * `uppercase_atom`, which permits a trailing hyphen).
36
41
  */
37
42
  export declare const isVerbToken: (s: string) => boolean;
38
43
  /** @returns `true` if `v` is one of the standard relational verbs. */
@@ -41,7 +46,7 @@ export declare const isStandard: (v: string) => boolean;
41
46
  export declare const isQualifier: (v: string) => v is Qualifier;
42
47
  /**
43
48
  * @returns `true` if `v` belongs to the known standard vocabulary —
44
- * standard verbs, `HAS`, `REVERSE`, `EXPECTS`, and the standard §5.5
49
+ * standard verbs, `HAS`, `REVERSE`, `RENAMED-TO`, `EXPECTS`, and the standard §5.5
45
50
  * inverse names.
46
51
  * Used by the parser's indentation tiebreak: `USES JWT` is a continuation
47
52
  * (JWT is not a known verb) while `API NEEDS auth` is a full triple.
@@ -1 +1 @@
1
- {"version":3,"file":"verb.d.ts","sourceRoot":"","sources":["../../src/verb.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,MAAM,MAAM,IAAI,GAAG,MAAM,CAAA;AAEzB,MAAM,MAAM,CAAC,GAAG,IAAI,CAAA;AAEpB,mCAAmC;AACnC,eAAO,MAAM,SAAS,wBAAyB,CAAA;AAE/C,yCAAyC;AACzC,eAAO,MAAM,QAAQ,uDAAwD,CAAA;AAE7E,wCAAwC;AACxC,eAAO,MAAM,SAAS,sCAAuC,CAAA;AAE7D,6CAA6C;AAC7C,eAAO,MAAM,UAAU,2DAA4D,CAAA;AAEnF,0CAA0C;AAC1C,eAAO,MAAM,SAAS,oDAAqD,CAAA;AAE3E,+EAA+E;AAC/E,eAAO,MAAM,UAAU,+CAAgD,CAAA;AAEvE,MAAM,MAAM,SAAS,GAAG,CAAC,OAAO,UAAU,CAAC,CAAC,MAAM,CAAC,CAAA;AAEnD,gDAAgD;AAChD,eAAO,MAAM,OAAO,YAAY,CAAA;AAEhC,oDAAoD;AACpD,eAAO,MAAM,OAAO,YAAY,CAAA;AAEhC,kEAAkE;AAClE,eAAO,MAAM,gBAAgB,iHAGnB,CAAA;AAEV,2DAA2D;AAC3D,eAAO,MAAM,QAAQ,EAAE,SAAS,IAAI,EAKnC,CAAA;AAMD;;;GAGG;AACH,eAAO,MAAM,WAAW,GAAI,GAAG,MAAM,KAAG,OACJ,CAAA;AAEpC,sEAAsE;AACtE,eAAO,MAAM,UAAU,GAAI,GAAG,MAAM,KAAG,OACnB,CAAA;AAEpB,uFAAuF;AACvF,eAAO,MAAM,WAAW,GAAI,GAAG,MAAM,KAAG,CAAC,IAAI,SACxB,CAAA;AAErB;;;;;;GAMG;AACH,eAAO,MAAM,OAAO,GAAI,GAAG,MAAM,KAAG,OACnB,CAAA"}
1
+ {"version":3,"file":"verb.d.ts","sourceRoot":"","sources":["../../src/verb.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,MAAM,MAAM,IAAI,GAAG,MAAM,CAAA;AAEzB,MAAM,MAAM,CAAC,GAAG,IAAI,CAAA;AAEpB,mCAAmC;AACnC,eAAO,MAAM,SAAS,wBAAyB,CAAA;AAE/C,yCAAyC;AACzC,eAAO,MAAM,QAAQ,uDAAwD,CAAA;AAE7E,wCAAwC;AACxC,eAAO,MAAM,SAAS,sCAAuC,CAAA;AAE7D,6CAA6C;AAC7C,eAAO,MAAM,UAAU,2DAA4D,CAAA;AAEnF,0CAA0C;AAC1C,eAAO,MAAM,SAAS,yCAA0C,CAAA;AAEhE,6DAA6D;AAC7D,eAAO,MAAM,UAAU,yFAEb,CAAA;AAEV,+EAA+E;AAC/E,eAAO,MAAM,UAAU,+CAAgD,CAAA;AAEvE,MAAM,MAAM,SAAS,GAAG,CAAC,OAAO,UAAU,CAAC,CAAC,MAAM,CAAC,CAAA;AAEnD,gDAAgD;AAChD,eAAO,MAAM,OAAO,YAAY,CAAA;AAEhC,kDAAkD;AAClD,eAAO,MAAM,UAAU,eAAe,CAAA;AAEtC,oDAAoD;AACpD,eAAO,MAAM,OAAO,YAAY,CAAA;AAEhC,kEAAkE;AAClE,eAAO,MAAM,gBAAgB,iHAGnB,CAAA;AAEV,2DAA2D;AAC3D,eAAO,MAAM,QAAQ,EAAE,SAAS,IAAI,EAMnC,CAAA;AAMD;;;;GAIG;AACH,eAAO,MAAM,WAAW,GAAI,GAAG,MAAM,KAAG,OACd,CAAA;AAE1B,sEAAsE;AACtE,eAAO,MAAM,UAAU,GAAI,GAAG,MAAM,KAAG,OACnB,CAAA;AAEpB,uFAAuF;AACvF,eAAO,MAAM,WAAW,GAAI,GAAG,MAAM,KAAG,CAAC,IAAI,SACxB,CAAA;AAErB;;;;;;GAMG;AACH,eAAO,MAAM,OAAO,GAAI,GAAG,MAAM,KAAG,OACnB,CAAA"}
package/dist/src/verb.js CHANGED
@@ -16,11 +16,17 @@ export const causation = ['CAUSE', 'FIX', 'BECOMES'];
16
16
  /** Dependency and production (spec §5.2). */
17
17
  export const dependency = ['NEEDS', 'USES', 'YIELDS', 'ENABLES', 'BLOCKS'];
18
18
  /** Structure and ordering (spec §5.2). */
19
- export const structure = ['CONTAINS', 'PRECEDES', 'EXCEEDS', 'VS'];
19
+ export const structure = ['CONTAINS', 'PRECEDES', 'VS'];
20
+ /** Canonical verbs for qualifier comparisons (spec §8.2). */
21
+ export const comparison = [
22
+ 'EXCEEDS', 'IS-BELOW', 'IS-AT-LEAST', 'IS-AT-MOST', 'EQUALS', 'DIFFERS-FROM'
23
+ ];
20
24
  /** Qualifier verbs — appear indented under another claim (spec §5.2, §8.2). */
21
25
  export const qualifiers = ['WHEN', 'UNLESS', 'VIA', 'BECAUSE'];
22
26
  /** The inverse-declaration verb (spec §5.5). */
23
27
  export const REVERSE = 'REVERSE';
28
+ /** The verb-lifecycle declaration (spec §5.8). */
29
+ export const RENAMED_TO = 'RENAMED-TO';
24
30
  /** The shape-expectation meta-verb (spec §20.1). */
25
31
  export const EXPECTS = 'EXPECTS';
26
32
  /** The standard inverse names (spec §5.5's declaration block). */
@@ -33,23 +39,25 @@ export const standard = [
33
39
  ...identity,
34
40
  ...causation,
35
41
  ...dependency,
36
- ...structure
42
+ ...structure,
43
+ ...comparison
37
44
  ];
38
45
  const standardSet = new Set(standard);
39
46
  const qualifierSet = new Set(qualifiers);
40
- const knownSet = new Set([...standard, 'HAS', REVERSE, EXPECTS, ...standardInverses]);
47
+ const knownSet = new Set([...standard, 'HAS', REVERSE, RENAMED_TO, EXPECTS, ...standardInverses]);
41
48
  /**
42
49
  * @returns `true` if `s` has the lexical shape of a verb — an uppercase atom:
43
- * uppercase letters and internal `-` (spec §16 `uppercase_atom`).
50
+ * an uppercase letter followed by uppercase letters or `-` (spec §16
51
+ * `uppercase_atom`, which permits a trailing hyphen).
44
52
  */
45
- export const isVerbToken = (s) => /^[A-Z](?:[A-Z-]*[A-Z])?$/.test(s);
53
+ export const isVerbToken = (s) => /^[A-Z][A-Z-]*$/.test(s);
46
54
  /** @returns `true` if `v` is one of the standard relational verbs. */
47
55
  export const isStandard = (v) => standardSet.has(v);
48
56
  /** @returns `true` if `v` is a qualifier verb (`WHEN`, `UNLESS`, `VIA`, `BECAUSE`). */
49
57
  export const isQualifier = (v) => qualifierSet.has(v);
50
58
  /**
51
59
  * @returns `true` if `v` belongs to the known standard vocabulary —
52
- * standard verbs, `HAS`, `REVERSE`, `EXPECTS`, and the standard §5.5
60
+ * standard verbs, `HAS`, `REVERSE`, `RENAMED-TO`, `EXPECTS`, and the standard §5.5
53
61
  * inverse names.
54
62
  * Used by the parser's indentation tiebreak: `USES JWT` is a continuation
55
63
  * (JWT is not a known verb) while `API NEEDS auth` is a full triple.
@@ -1 +1 @@
1
- {"version":3,"file":"verb.js","sourceRoot":"","sources":["../../src/verb.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAMH,mCAAmC;AACnC,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,IAAI,EAAE,KAAK,CAAU,CAAA;AAE/C,yCAAyC;AACzC,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAU,CAAA;AAE7E,wCAAwC;AACxC,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,OAAO,EAAE,KAAK,EAAE,SAAS,CAAU,CAAA;AAE7D,6CAA6C;AAC7C,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,CAAU,CAAA;AAEnF,0CAA0C;AAC1C,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,UAAU,EAAE,UAAU,EAAE,SAAS,EAAE,IAAI,CAAU,CAAA;AAE3E,+EAA+E;AAC/E,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,SAAS,CAAU,CAAA;AAIvE,gDAAgD;AAChD,MAAM,CAAC,MAAM,OAAO,GAAG,SAAS,CAAA;AAEhC,oDAAoD;AACpD,MAAM,CAAC,MAAM,OAAO,GAAG,SAAS,CAAA;AAEhC,kEAAkE;AAClE,MAAM,CAAC,MAAM,gBAAgB,GAAG;IAC9B,SAAS,EAAE,WAAW,EAAE,SAAS,EAAE,SAAS;IAC5C,WAAW,EAAE,YAAY,EAAE,YAAY,EAAE,aAAa;CAC9C,CAAA;AAEV,2DAA2D;AAC3D,MAAM,CAAC,MAAM,QAAQ,GAAoB;IACvC,GAAG,QAAQ;IACX,GAAG,SAAS;IACZ,GAAG,UAAU;IACb,GAAG,SAAS;CACb,CAAA;AAED,MAAM,WAAW,GAAG,IAAI,GAAG,CAAS,QAAQ,CAAC,CAAA;AAC7C,MAAM,YAAY,GAAG,IAAI,GAAG,CAAS,UAAU,CAAC,CAAA;AAChD,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAS,CAAC,GAAG,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,gBAAgB,CAAC,CAAC,CAAA;AAE7F;;;GAGG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,CAAS,EAAW,EAAE,CAChD,0BAA0B,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;AAEpC,sEAAsE;AACtE,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,CAAS,EAAW,EAAE,CAC/C,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,CAAA;AAEpB,uFAAuF;AACvF,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,CAAS,EAAkB,EAAE,CACvD,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,CAAA;AAErB;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,CAAS,EAAW,EAAE,CAC5C,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAA"}
1
+ {"version":3,"file":"verb.js","sourceRoot":"","sources":["../../src/verb.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAMH,mCAAmC;AACnC,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,IAAI,EAAE,KAAK,CAAU,CAAA;AAE/C,yCAAyC;AACzC,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAU,CAAA;AAE7E,wCAAwC;AACxC,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,OAAO,EAAE,KAAK,EAAE,SAAS,CAAU,CAAA;AAE7D,6CAA6C;AAC7C,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,CAAU,CAAA;AAEnF,0CAA0C;AAC1C,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,UAAU,EAAE,UAAU,EAAE,IAAI,CAAU,CAAA;AAEhE,6DAA6D;AAC7D,MAAM,CAAC,MAAM,UAAU,GAAG;IACxB,SAAS,EAAE,UAAU,EAAE,aAAa,EAAE,YAAY,EAAE,QAAQ,EAAE,cAAc;CACpE,CAAA;AAEV,+EAA+E;AAC/E,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,SAAS,CAAU,CAAA;AAIvE,gDAAgD;AAChD,MAAM,CAAC,MAAM,OAAO,GAAG,SAAS,CAAA;AAEhC,kDAAkD;AAClD,MAAM,CAAC,MAAM,UAAU,GAAG,YAAY,CAAA;AAEtC,oDAAoD;AACpD,MAAM,CAAC,MAAM,OAAO,GAAG,SAAS,CAAA;AAEhC,kEAAkE;AAClE,MAAM,CAAC,MAAM,gBAAgB,GAAG;IAC9B,SAAS,EAAE,WAAW,EAAE,SAAS,EAAE,SAAS;IAC5C,WAAW,EAAE,YAAY,EAAE,YAAY,EAAE,aAAa;CAC9C,CAAA;AAEV,2DAA2D;AAC3D,MAAM,CAAC,MAAM,QAAQ,GAAoB;IACvC,GAAG,QAAQ;IACX,GAAG,SAAS;IACZ,GAAG,UAAU;IACb,GAAG,SAAS;IACZ,GAAG,UAAU;CACd,CAAA;AAED,MAAM,WAAW,GAAG,IAAI,GAAG,CAAS,QAAQ,CAAC,CAAA;AAC7C,MAAM,YAAY,GAAG,IAAI,GAAG,CAAS,UAAU,CAAC,CAAA;AAChD,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAS,CAAC,GAAG,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,GAAG,gBAAgB,CAAC,CAAC,CAAA;AAEzG;;;;GAIG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,CAAS,EAAW,EAAE,CAChD,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;AAE1B,sEAAsE;AACtE,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,CAAS,EAAW,EAAE,CAC/C,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,CAAA;AAEpB,uFAAuF;AACvF,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,CAAS,EAAkB,EAAE,CACvD,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,CAAA;AAErB;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,CAAS,EAAW,EAAE,CAC5C,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAA"}
package/package.json CHANGED
@@ -1,8 +1,18 @@
1
1
  {
2
2
  "name": "@cavelang/core",
3
- "version": "0.28.1",
3
+ "version": "0.29.1",
4
4
  "type": "module",
5
5
  "description": "CAVE domain model — claims, values, units, uncertainty, claim keys, UUIDv7 transactions.",
6
+ "keywords": [
7
+ "cave",
8
+ "knowledge-graph",
9
+ "knowledge-representation",
10
+ "typescript"
11
+ ],
12
+ "homepage": "https://github.com/mirek/cave#readme",
13
+ "bugs": {
14
+ "url": "https://github.com/mirek/cave/issues"
15
+ },
6
16
  "license": "CC0-1.0",
7
17
  "author": "Mirek Rusin (https://github.com/mirek)",
8
18
  "repository": {
@@ -26,14 +36,15 @@
26
36
  "src",
27
37
  "!src/**/*.test.ts",
28
38
  "README.md",
29
- "License.md"
39
+ "License.md",
40
+ "Authors.md"
30
41
  ],
31
42
  "publishConfig": {
32
43
  "access": "public"
33
44
  },
34
45
  "scripts": {
35
46
  "build": "tsc -b",
36
- "test": "node --disable-warning=ExperimentalWarning --test 'test/*.test.ts'",
47
+ "test": "node --disable-warning=ExperimentalWarning --test \"test/*.test.ts\"",
37
48
  "typecheck": "tsc -b"
38
49
  }
39
50
  }
package/src/claim.ts CHANGED
@@ -15,6 +15,7 @@ import * as Value from './value.ts'
15
15
  import * as Tag from './tag.ts'
16
16
  import * as Context from './context.ts'
17
17
  import * as Confidence from './confidence.ts'
18
+ import * as Uncertainty from './uncertainty.ts'
18
19
 
19
20
  /** Subject or object term (spec §16: atom, literal or code literal). */
20
21
  export type TermKind = 'entity' | 'text' | 'code'
@@ -106,20 +107,24 @@ export type Init = {
106
107
  }
107
108
 
108
109
  /** @returns claim with defaults applied (spec §6: all suffixes optional). */
109
- export const of = (init: Init): Claim => ({
110
- subject: init.subject,
111
- verb: init.verb,
112
- negated: init.negated ?? false,
113
- payload: init.payload,
114
- contexts: Context.dedupe(init.contexts ?? []),
115
- tags: init.tags ?? [],
116
- conf: init.conf ?? Confidence.defaultConfidence,
117
- importance: init.importance ?? false,
118
- ...init.delta !== undefined ? { delta: init.delta } : {},
119
- ...init.sigmaLevel !== undefined ? { sigmaLevel: init.sigmaLevel } : {},
120
- ...init.comment !== undefined ? { comment: init.comment } : {},
121
- raw: init.raw ?? ''
122
- })
110
+ export const of = (init: Init): Claim => {
111
+ if (init.delta !== undefined) Uncertainty.validateDelta(init.delta.num)
112
+ if (init.sigmaLevel !== undefined) Uncertainty.validateSigmaLevel(init.sigmaLevel)
113
+ return {
114
+ subject: init.subject,
115
+ verb: init.verb,
116
+ negated: init.negated ?? false,
117
+ payload: init.payload,
118
+ contexts: Context.dedupe(init.contexts ?? []),
119
+ tags: init.tags ?? [],
120
+ conf: init.conf ?? Confidence.defaultConfidence,
121
+ importance: init.importance ?? false,
122
+ ...init.delta !== undefined ? { delta: init.delta } : {},
123
+ ...init.sigmaLevel !== undefined ? { sigmaLevel: init.sigmaLevel } : {},
124
+ ...init.comment !== undefined ? { comment: init.comment } : {},
125
+ raw: init.raw ?? ''
126
+ }
127
+ }
123
128
 
124
129
  /** @returns relational claim payload. */
125
130
  export const relation = (object: Term): Payload =>
@@ -145,4 +150,4 @@ export const none: Payload =
145
150
  export const sigmaOf = (claim: Claim): undefined | number =>
146
151
  claim.delta?.num === undefined ?
147
152
  undefined :
148
- claim.delta.num / (claim.sigmaLevel ?? 2)
153
+ Uncertainty.sigma(claim.delta.num, claim.sigmaLevel)
package/src/index.ts CHANGED
@@ -16,6 +16,7 @@ export * as Context from './context.ts'
16
16
  export * as Entity from './entity.ts'
17
17
  export * as Key from './key.ts'
18
18
  export * as Multiplier from './multiplier.ts'
19
+ export * as SourceSpan from './source-span.ts'
19
20
  export * as Tag from './tag.ts'
20
21
  export * as Time from './time.ts'
21
22
  export * as Uncertainty from './uncertainty.ts'
@@ -23,3 +24,4 @@ export * as Uuidv7 from './uuidv7.ts'
23
24
  export * as Value from './value.ts'
24
25
  export * as Verb from './verb.ts'
25
26
  export * as Version from './version.ts'
27
+ export type { LineSpan, Reference as SourceReference } from './source-span.ts'
@@ -0,0 +1,98 @@
1
+ /** Stable source-line provenance carried by `src:` contexts (spec §9.8). */
2
+
3
+ import type { Context } from './context.ts'
4
+
5
+ export type LineSpan = {
6
+ /** One-based first source line. */
7
+ readonly startLine: number
8
+ /** One-based inclusive last source line. */
9
+ readonly endLine: number
10
+ }
11
+
12
+ export type Reference = {
13
+ /** Canonical stored context, without the leading `@`. */
14
+ readonly context: Context
15
+ /** Decoded underlying source identity, without the line fragment. */
16
+ readonly source: string
17
+ readonly span?: LineSpan
18
+ /** Human-facing source plus line fragment. */
19
+ readonly location: string
20
+ /** Navigable location when the source is an HTTP(S) URL. */
21
+ readonly href?: string
22
+ }
23
+
24
+ const lineFragment = (span: LineSpan): string =>
25
+ span.startLine === span.endLine ? `L${span.startLine}` : `L${span.startLine}-L${span.endLine}`
26
+
27
+ const validSpan = (span: LineSpan): boolean =>
28
+ Number.isInteger(span.startLine) && Number.isInteger(span.endLine) &&
29
+ span.startLine >= 1 && span.endLine >= span.startLine
30
+
31
+ /** Percent-escape a source while keeping readable path and URL separators. */
32
+ export const escape = (source: string): string =>
33
+ encodeURIComponent(source)
34
+ .replace(/[!'()*]/g, char => `%${char.charCodeAt(0).toString(16).toUpperCase()}`)
35
+ .replaceAll('%2F', '/')
36
+ .replaceAll('%3A', ':')
37
+
38
+ /** Reverse {@link escape}; malformed percent encodings are rejected. */
39
+ export const unescape = (source: string): undefined | string => {
40
+ try {
41
+ return decodeURIComponent(source)
42
+ } catch {
43
+ return undefined
44
+ }
45
+ }
46
+
47
+ /** Build a canonical `src:` context from a source and optional line span. */
48
+ export const context = (source: string, span?: LineSpan): Context => {
49
+ if (source === '') {
50
+ throw new Error('source must not be empty')
51
+ }
52
+ if (span !== undefined && !validSpan(span)) {
53
+ throw new Error(`invalid source line span ${JSON.stringify(span)}`)
54
+ }
55
+ return `src:${escape(source)}${span === undefined ? '' : `#${lineFragment(span)}`}`
56
+ }
57
+
58
+ /** Parse one canonical source context, preserving an unspanned source too. */
59
+ export const parse = (value: Context): undefined | Reference => {
60
+ if (!value.startsWith('src:')) {
61
+ return undefined
62
+ }
63
+ const payload = value.slice(4)
64
+ const hashAt = payload.indexOf('#')
65
+ const encodedSource = hashAt === -1 ? payload : payload.slice(0, hashAt)
66
+ const fragment = hashAt === -1 ? undefined : payload.slice(hashAt + 1)
67
+ const match = fragment === undefined ? undefined : /^L([1-9]\d*)(?:-L([1-9]\d*))?$/.exec(fragment)
68
+ if (encodedSource === '' || (fragment !== undefined && match === null)) {
69
+ return undefined
70
+ }
71
+ const source = unescape(encodedSource)
72
+ if (source === undefined || escape(source) !== encodedSource) {
73
+ return undefined
74
+ }
75
+ const start = match == null ? undefined : Number(match[1])
76
+ const end = start === undefined || match == null ? undefined : Number(match[2] ?? match[1])
77
+ const span = start === undefined ? undefined : { startLine: start, endLine: end! }
78
+ if (span !== undefined && !validSpan(span)) {
79
+ return undefined
80
+ }
81
+ const location = `${source}${span === undefined ? '' : `#${lineFragment(span)}`}`
82
+ const href = /^https?:\/\//i.test(source) && !source.includes('#') ?
83
+ `${encodeURI(source)}${span === undefined ? '' : `#${lineFragment(span)}`}` : undefined
84
+ return {
85
+ context: value,
86
+ source,
87
+ ...span === undefined ? {} : { span },
88
+ location,
89
+ ...href === undefined ? {} : { href }
90
+ }
91
+ }
92
+
93
+ /** Parse every valid `src:` context, in authored order. */
94
+ export const ofContexts = (contexts: readonly Context[]): Reference[] =>
95
+ contexts.flatMap(value => {
96
+ const reference = parse(value)
97
+ return reference === undefined ? [] : [reference]
98
+ })
package/src/time.ts CHANGED
@@ -24,6 +24,9 @@ export type Period = {
24
24
 
25
25
  export type t = Period
26
26
 
27
+ /** A query boundary as a UTC half-open interval. */
28
+ export type Boundary = Period
29
+
27
30
  /** How a context reads as time: a point period, or a `..` range. */
28
31
  export type TimeContext =
29
32
  | { readonly kind: 'point', readonly period: Period }
@@ -31,8 +34,14 @@ export type TimeContext =
31
34
 
32
35
  const dayMs = 86_400_000
33
36
 
34
- const utcDay = (year: number, month: number, day: number): number =>
35
- Date.UTC(year, month - 1, day)
37
+ const utcDay = (year: number, month: number, day: number): number => {
38
+ // Date.UTC treats years 0..99 as 1900..1999. Setting the full year on an
39
+ // existing date preserves the four-digit year written in the CAVE value.
40
+ const date = new Date(0)
41
+ date.setUTCHours(0, 0, 0, 0)
42
+ date.setUTCFullYear(year, month - 1, day)
43
+ return date.getTime()
44
+ }
36
45
 
37
46
  /** Monday starting ISO week `week` of `year` (ISO 8601: week 1 contains Jan 4). */
38
47
  const isoWeekStart = (year: number, week: number): number => {
@@ -70,6 +79,10 @@ export const parsePeriod = (text: string): undefined | Period => {
70
79
  return undefined
71
80
  }
72
81
  const start = isoWeekStart(year, w)
82
+ // Only years whose next ISO week-year starts after week 53 have one.
83
+ if (start >= isoWeekStart(year + 1, 1)) {
84
+ return undefined
85
+ }
73
86
  return { start, end: start + 7 * dayMs }
74
87
  }
75
88
  if (month !== undefined) {
@@ -154,6 +167,40 @@ export const ofContext = (context: string): undefined | TimeContext => {
154
167
  return period === undefined ? undefined : { kind: 'point', period }
155
168
  }
156
169
 
170
+ const timestampRe = /^(\d{4}-\d{2}-\d{2})T(\d{2}):(\d{2}):(\d{2})(?:\.(\d+))?([zZ]|[+-]\d{2}:\d{2})?$/
171
+
172
+ /**
173
+ * Parses an ISO timestamp into a UTC instant. An omitted offset means UTC,
174
+ * never the host's local timezone; explicit `Z` and numeric offsets retain
175
+ * their usual ISO meaning. Date and clock fields are validated before the
176
+ * platform parser can normalize them.
177
+ */
178
+ export const parseTimestamp = (text: string): undefined | number => {
179
+ const match = timestampRe.exec(text)
180
+ if (match === null) return undefined
181
+ const [, date, hour, minute, second, , zone] = match
182
+ if (parsePeriod(date!) === undefined || Number(hour) > 23 || Number(minute) > 59 || Number(second) > 59) {
183
+ return undefined
184
+ }
185
+ if (zone !== undefined && zone !== 'Z' && zone !== 'z') {
186
+ const [offsetHour, offsetMinute] = zone.slice(1).split(':').map(Number)
187
+ if (offsetHour! > 23 || offsetMinute! > 59) return undefined
188
+ }
189
+ const parsed = Date.parse(zone === undefined ? `${text}Z` : text)
190
+ return Number.isNaN(parsed) ? undefined : parsed
191
+ }
192
+
193
+ /**
194
+ * Parses the shared query-time boundary: a date-like period keeps its whole
195
+ * UTC interval, while a timestamp covers one second from its exact instant.
196
+ */
197
+ export const parseBoundary = (text: string): undefined | Boundary => {
198
+ const period = parsePeriod(text)
199
+ if (period !== undefined) return period
200
+ const start = parseTimestamp(text)
201
+ return start === undefined ? undefined : { start, end: start + 1_000 }
202
+ }
203
+
157
204
  /**
158
205
  * Parses a query anchor into an instant (ms since epoch): a date-like
159
206
  * period reads as its *start* instant (`2026` is 2026-01-01T00:00:00Z —
@@ -161,15 +208,7 @@ export const ofContext = (context: string): undefined | TimeContext => {
161
208
  * exactly. @returns `undefined` when `text` is neither.
162
209
  */
163
210
  export const parseInstant = (text: string): undefined | number => {
164
- const period = parsePeriod(text)
165
- if (period !== undefined) {
166
- return period.start
167
- }
168
- if (!text.includes('T')) {
169
- return undefined
170
- }
171
- const parsed = Date.parse(text)
172
- return Number.isNaN(parsed) ? undefined : parsed
211
+ return parseBoundary(text)?.start
173
212
  }
174
213
 
175
214
  /** @returns whether a time context covers the instant (spec §32.4). */
@@ -16,12 +16,43 @@
16
16
  /** Default σ level when `(Nσ)` is omitted (spec §7.2). */
17
17
  export const defaultSigmaLevel = 2
18
18
 
19
+ export type Field = 'uncertainty delta' | 'sigma level' | 'sigma'
20
+
21
+ /** Typed failure for uncertainty values that cannot define a finite distribution. */
22
+ export class InvalidUncertaintyError extends RangeError {
23
+ readonly field: Field
24
+ readonly value: unknown
25
+
26
+ constructor(field: Field, value: unknown) {
27
+ super(`Expected positive finite ${field}, got ${String(value)}.`)
28
+ this.name = 'InvalidUncertaintyError'
29
+ this.field = field
30
+ this.value = value
31
+ }
32
+ }
33
+
34
+ const positiveFinite = (field: Field, value: unknown): number => {
35
+ if (typeof value !== 'number' || !Number.isFinite(value) || !(value > 0)) {
36
+ throw new InvalidUncertaintyError(field, value)
37
+ }
38
+ return value
39
+ }
40
+
41
+ /** Validates a `+/-` interval half-width. */
42
+ export const validateDelta = (value: unknown): number =>
43
+ positiveFinite('uncertainty delta', value)
44
+
45
+ /** Validates the `N` in an `(Nσ)` override. */
46
+ export const validateSigmaLevel = (value: unknown): number =>
47
+ positiveFinite('sigma level', value)
48
+
49
+ /** Validates a directly supplied standard deviation. */
50
+ export const validateSigma = (value: unknown): number =>
51
+ positiveFinite('sigma', value)
52
+
19
53
  /** @returns σ from an interval `delta` given at `level`σ: σ = Δ / k. */
20
54
  export const sigma = (delta: number, level: number = defaultSigmaLevel): number => {
21
- if (!(level > 0)) {
22
- throw new Error(`Expected positive sigma level, got ${level}.`)
23
- }
24
- return delta / level
55
+ return validateSigma(validateDelta(delta) / validateSigmaLevel(level))
25
56
  }
26
57
 
27
58
  /** @returns symmetric `[low, high]` interval around `mean`. */
package/src/uuidv7.ts CHANGED
@@ -104,3 +104,19 @@ export const observe = (id: string): void => {
104
104
  lastSeq = seq
105
105
  }
106
106
  }
107
+
108
+ /**
109
+ * Runs synchronous speculative work without retaining UUID generator state.
110
+ * Database dry-runs use this alongside transaction rollback so explicit-id
111
+ * observations and locally minted rows are both absent after the preview.
112
+ */
113
+ export const withStatePreserved = <T>(body: () => T): T => {
114
+ const savedMs = lastMs
115
+ const savedSeq = lastSeq
116
+ try {
117
+ return body()
118
+ } finally {
119
+ lastMs = savedMs
120
+ lastSeq = savedSeq
121
+ }
122
+ }
package/src/value.ts CHANGED
@@ -20,6 +20,7 @@
20
20
  */
21
21
 
22
22
  import * as Multiplier from './multiplier.ts'
23
+ import { parsePeriod } from './time.ts'
23
24
 
24
25
  /** How the value text was classified. */
25
26
  export type Kind =
@@ -54,18 +55,17 @@ export type t = Value
54
55
 
55
56
  const numberRe = /^(-?\d+(?:\.\d+)?)([A-Za-z%]*)$/
56
57
  const unitRe = /^[A-Za-z%$][A-Za-z0-9%$]*(?:\/[A-Za-z0-9%$]+)*$/
57
- const dateRe = /^\d{4}-(?:H[1-2]|Q[1-4]|W\d{1,2}|\d{2})(?:-\d{2})?$/
58
-
59
58
  /** @returns `true` if `s` is a valid unit expression (`USD/yr`, `ms`, `%`). */
60
59
  export const isUnit = (s: string): boolean =>
61
60
  unitRe.test(s)
62
61
 
63
62
  /**
64
63
  * @returns `true` if `s` is date-like (spec §16 `date_like`): `2026-H2`,
65
- * `2026-Q1`, `2026-04`, `2026-04-10`. A bare year parses as a number instead.
64
+ * `2026-Q1`, `2026-04`, `2026-04-10`. Calendar validity is shared with
65
+ * {@link parsePeriod}; a bare year parses as a number instead.
66
66
  */
67
67
  export const isDateLike = (s: string): boolean =>
68
- dateRe.test(s)
68
+ s.includes('-') && parsePeriod(s) !== undefined
69
69
 
70
70
  type Numeric = { num: number, unit?: string }
71
71
 
package/src/verb.ts CHANGED
@@ -25,7 +25,12 @@ export const causation = ['CAUSE', 'FIX', 'BECOMES'] as const
25
25
  export const dependency = ['NEEDS', 'USES', 'YIELDS', 'ENABLES', 'BLOCKS'] as const
26
26
 
27
27
  /** Structure and ordering (spec §5.2). */
28
- export const structure = ['CONTAINS', 'PRECEDES', 'EXCEEDS', 'VS'] as const
28
+ export const structure = ['CONTAINS', 'PRECEDES', 'VS'] as const
29
+
30
+ /** Canonical verbs for qualifier comparisons (spec §8.2). */
31
+ export const comparison = [
32
+ 'EXCEEDS', 'IS-BELOW', 'IS-AT-LEAST', 'IS-AT-MOST', 'EQUALS', 'DIFFERS-FROM'
33
+ ] as const
29
34
 
30
35
  /** Qualifier verbs — appear indented under another claim (spec §5.2, §8.2). */
31
36
  export const qualifiers = ['WHEN', 'UNLESS', 'VIA', 'BECAUSE'] as const
@@ -35,6 +40,9 @@ export type Qualifier = (typeof qualifiers)[number]
35
40
  /** The inverse-declaration verb (spec §5.5). */
36
41
  export const REVERSE = 'REVERSE'
37
42
 
43
+ /** The verb-lifecycle declaration (spec §5.8). */
44
+ export const RENAMED_TO = 'RENAMED-TO'
45
+
38
46
  /** The shape-expectation meta-verb (spec §20.1). */
39
47
  export const EXPECTS = 'EXPECTS'
40
48
 
@@ -49,19 +57,21 @@ export const standard: readonly Verb[] = [
49
57
  ...identity,
50
58
  ...causation,
51
59
  ...dependency,
52
- ...structure
60
+ ...structure,
61
+ ...comparison
53
62
  ]
54
63
 
55
64
  const standardSet = new Set<string>(standard)
56
65
  const qualifierSet = new Set<string>(qualifiers)
57
- const knownSet = new Set<string>([...standard, 'HAS', REVERSE, EXPECTS, ...standardInverses])
66
+ const knownSet = new Set<string>([...standard, 'HAS', REVERSE, RENAMED_TO, EXPECTS, ...standardInverses])
58
67
 
59
68
  /**
60
69
  * @returns `true` if `s` has the lexical shape of a verb — an uppercase atom:
61
- * uppercase letters and internal `-` (spec §16 `uppercase_atom`).
70
+ * an uppercase letter followed by uppercase letters or `-` (spec §16
71
+ * `uppercase_atom`, which permits a trailing hyphen).
62
72
  */
63
73
  export const isVerbToken = (s: string): boolean =>
64
- /^[A-Z](?:[A-Z-]*[A-Z])?$/.test(s)
74
+ /^[A-Z][A-Z-]*$/.test(s)
65
75
 
66
76
  /** @returns `true` if `v` is one of the standard relational verbs. */
67
77
  export const isStandard = (v: string): boolean =>
@@ -73,7 +83,7 @@ export const isQualifier = (v: string): v is Qualifier =>
73
83
 
74
84
  /**
75
85
  * @returns `true` if `v` belongs to the known standard vocabulary —
76
- * standard verbs, `HAS`, `REVERSE`, `EXPECTS`, and the standard §5.5
86
+ * standard verbs, `HAS`, `REVERSE`, `RENAMED-TO`, `EXPECTS`, and the standard §5.5
77
87
  * inverse names.
78
88
  * Used by the parser's indentation tiebreak: `USES JWT` is a continuation
79
89
  * (JWT is not a known verb) while `API NEEDS auth` is a full triple.