lockwire 0.1.22 → 0.1.24

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/values.js ADDED
@@ -0,0 +1,167 @@
1
+ /**
2
+ * Value anchors: a claim bound to a value in a data file rather than to code.
3
+ *
4
+ * <!-- lockwire results/metrics.json#ci.canon.cve.lo value -->
5
+ * The lower bound of the canonical CVE interval is 0.18.
6
+ *
7
+ * <!-- lockwire paper/numbers.tex#ciCanonCVELo value -->
8
+ *
9
+ * The `value` tier fingerprints the value itself (not the file, so re-serialising a JSON file with
10
+ * its keys in a different order changes nothing). And because a number in a sentence can be checked
11
+ * against the number it came from, a value anchor is a real truth check: the claim is compared with
12
+ * the current value, rounded to the precision the sentence shows.
13
+ */
14
+ import { canonicalJson } from "./hash.js";
15
+ const DATA_EXTENSIONS = {
16
+ ".json": "json",
17
+ ".tex": "tex",
18
+ ".sty": "tex",
19
+ ".ltx": "tex",
20
+ };
21
+ export function dataFormatOf(path) {
22
+ const dot = path.lastIndexOf(".");
23
+ return dot < 0 ? undefined : DATA_EXTENSIONS[path.slice(dot).toLowerCase()];
24
+ }
25
+ /** `a.b[0].c`, `a.b.0.c`, or a JSON Pointer (`/a/b/0/c`, for keys that contain dots). */
26
+ function jsonPath(key) {
27
+ if (key.startsWith("/"))
28
+ return key
29
+ .slice(1)
30
+ .split("/")
31
+ .map((s) => s.replace(/~1/g, "/").replace(/~0/g, "~"));
32
+ return key
33
+ .replace(/\[(\d+)\]/g, ".$1")
34
+ .split(".")
35
+ .filter((s) => s !== "");
36
+ }
37
+ /** LaTeX: `\newcommand{\name}{body}`, `\renewcommand`, `\providecommand`, `\def\name{body}`. */
38
+ function texMacros(text) {
39
+ const out = new Map();
40
+ const re = /\\(?:(?:re)?newcommand|providecommand)\*?\s*\{?\s*\\([A-Za-z@]+)\s*\}?\s*(?:\[\d\])?\s*\{|\\def\s*\\([A-Za-z@]+)\s*\{/g;
41
+ for (let m = re.exec(text); m; m = re.exec(text)) {
42
+ const name = m[1] ?? m[2];
43
+ if (!name)
44
+ continue;
45
+ // read the balanced-brace body that starts right after the match
46
+ let depth = 1;
47
+ let i = re.lastIndex;
48
+ for (; i < text.length && depth > 0; i++) {
49
+ const c = text[i];
50
+ if (c === "\\")
51
+ i++;
52
+ else if (c === "{")
53
+ depth++;
54
+ else if (c === "}")
55
+ depth--;
56
+ }
57
+ out.set(name, text.slice(re.lastIndex, i - 1));
58
+ re.lastIndex = i;
59
+ }
60
+ return out;
61
+ }
62
+ /** Strip the LaTeX that typically wraps a generated number: `\num{0.18}`, `$0.18$`, `0.18\%`, `\SI{3}{ms}`. */
63
+ function texValue(body) {
64
+ let s = body.trim();
65
+ for (;;) {
66
+ const unwrapped = s
67
+ .replace(/^\\(?:num|ensuremath|text|mathrm|textrm)\s*\{([\s\S]*)\}$/, "$1")
68
+ .replace(/^\\SI\s*\{([^}]*)\}\s*\{[^}]*\}$/, "$1")
69
+ .replace(/^\$([\s\S]*)\$$/, "$1")
70
+ .trim();
71
+ if (unwrapped === s)
72
+ break;
73
+ s = unwrapped;
74
+ }
75
+ const percent = /^(.*?)\s*\\%$/.exec(s);
76
+ const core = (percent?.[1] ?? s).replace(/\{,\}/g, "").replace(/\\,/g, "");
77
+ if (/^[-+]?(?:\d+\.?\d*|\.\d+)(?:[eE][-+]?\d+)?$/.test(core))
78
+ return Number(core);
79
+ return s;
80
+ }
81
+ /** Looks up `key` in the data file's text. Throws only on a file that can't be parsed at all. */
82
+ export function resolveValue(text, format, key) {
83
+ if (format === "tex") {
84
+ const macros = texMacros(text);
85
+ const name = key.replace(/^\\/, "");
86
+ if (!macros.has(name))
87
+ return { found: false };
88
+ const value = texValue(macros.get(name) ?? "");
89
+ return { found: true, value, display: displayValue(value) };
90
+ }
91
+ let node = JSON.parse(text);
92
+ for (const seg of jsonPath(key)) {
93
+ if (Array.isArray(node) && /^\d+$/.test(seg))
94
+ node = node[Number(seg)];
95
+ else if (node && typeof node === "object" && Object.hasOwn(node, seg))
96
+ node = node[seg];
97
+ else
98
+ return { found: false };
99
+ if (node === undefined)
100
+ return { found: false };
101
+ }
102
+ return { found: true, value: node, display: displayValue(node) };
103
+ }
104
+ /** A stable serialisation of the value for fingerprinting: key order never matters. */
105
+ export function valueFingerprintInput(value) {
106
+ return canonicalJson(value ?? null);
107
+ }
108
+ /** The whole data file as content, insensitive to JSON key order and to line endings. */
109
+ export function wholeFileContent(text, format) {
110
+ if (format === "json")
111
+ return canonicalJson(JSON.parse(text));
112
+ return text.replace(/\r\n?/g, "\n");
113
+ }
114
+ export function displayValue(value) {
115
+ if (typeof value === "string")
116
+ return JSON.stringify(value);
117
+ if (typeof value === "number" || typeof value === "boolean" || value === null)
118
+ return String(value);
119
+ const s = JSON.stringify(value);
120
+ return s.length > 60 ? `${s.slice(0, 59)}…` : s;
121
+ }
122
+ /** Numbers a sentence states, skipping digits that are part of a word or identifier (`v2`, `x86`, `h264`). */
123
+ export function claimNumbers(text) {
124
+ const out = [];
125
+ const re = /(?<![\w.])([-−]?(?:\d{1,3}(?:,\d{3})+|\d+)(?:\.\d+)?|[-−]?\.\d+)(?:[eE]([-+]?\d+))?(?![\w])(\s*(?:%|\\%|percent\b))?/g;
126
+ for (let m = re.exec(text); m; m = re.exec(text)) {
127
+ const literal = (m[1] ?? "").replace("−", "-");
128
+ const exp = m[2];
129
+ const n = Number(literal.replace(/,/g, "")) * (exp ? 10 ** Number(exp) : 1);
130
+ if (!Number.isFinite(n))
131
+ continue;
132
+ const frac = /\.(\d+)$/.exec(literal);
133
+ const decimals = Math.max(0, (frac?.[1]?.length ?? 0) - (exp ? Number(exp) : 0));
134
+ out.push({ text: m[0].trim(), value: n, decimals, percent: Boolean(m[3]) });
135
+ }
136
+ return out;
137
+ }
138
+ /** Whether `stated` is `actual` at the precision the sentence shows (0.18 matches 0.1834, not 0.19). */
139
+ function sameAtPrecision(stated, decimals, actual) {
140
+ const half = 0.5 * 10 ** -decimals;
141
+ return Math.abs(actual - stated) <= half + 1e-9 * Math.max(1, Math.abs(actual));
142
+ }
143
+ /**
144
+ * Does the claim state this value? A number value matches if any number in the sentence equals it at
145
+ * the sentence's own precision (a percentage also matches the value × 100). A string value matches
146
+ * if the sentence contains it. Other values (objects, booleans, null) aren't checked against prose.
147
+ */
148
+ export function checkClaimAgainstValue(claimText, value) {
149
+ const numeric = typeof value === "number"
150
+ ? value
151
+ : typeof value === "string" && /^\s*[-+]?(?:\d+\.?\d*|\.\d+)(?:[eE][-+]?\d+)?\s*$/.test(value)
152
+ ? Number(value)
153
+ : undefined;
154
+ if (numeric !== undefined && Number.isFinite(numeric)) {
155
+ const nums = claimNumbers(claimText);
156
+ if (nums.length === 0)
157
+ return { checkable: false, matches: true, claimed: [] };
158
+ const matches = nums.some((n) => sameAtPrecision(n.value, n.decimals, numeric) ||
159
+ (n.percent && sameAtPrecision(n.value, n.decimals, numeric * 100)));
160
+ return { checkable: true, matches, claimed: nums.map((n) => n.text) };
161
+ }
162
+ if (typeof value === "string" && value.trim() !== "") {
163
+ return { checkable: true, matches: claimText.includes(value), claimed: [] };
164
+ }
165
+ return { checkable: false, matches: true, claimed: [] };
166
+ }
167
+ //# sourceMappingURL=values.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"values.js","sourceRoot":"","sources":["../src/values.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lockwire",
3
- "version": "0.1.22",
3
+ "version": "0.1.24",
4
4
  "description": "Bind documentation claims to code fingerprints. Catch stale CLAUDE.md, AGENTS.md and docs at write time inside Claude Code and Codex, with a tamper-evident history.",
5
5
  "license": "MIT",
6
6
  "type": "module",