@getbourdon/conformance 0.2.2 → 0.3.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 +26 -4
- package/dist/index.cjs +30 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +20 -1
- package/dist/index.d.ts +28 -11
- package/dist/index.js +51 -29
- package/dist/index.js.map +1 -1
- package/fixtures/README.md +11 -3
- package/fixtures/l5_manifests/invalid/entity-impossible-calendar-date.json +14 -0
- package/fixtures/l5_manifests/invalid/reasons.json +52 -0
- package/fixtures/l5_manifests/invalid/session-impossible-calendar-date.json +13 -0
- package/fixtures/l5_manifests/invalid/session-impossible-feb-30.json +13 -0
- package/fixtures/l5_manifests/valid/session-empty-date.json +16 -0
- package/fixtures/l5_schema.json +137 -38
- package/fixtures/manifest.json +97 -7
- package/fixtures/mcp_snapshots/_normalizer.json +1 -0
- package/fixtures/mcp_snapshots/commit_to_federation.res.json +1 -0
- package/fixtures/mcp_snapshots/explain_memory_change.req.json +7 -0
- package/fixtures/mcp_snapshots/explain_memory_change.res.json +15 -0
- package/fixtures/mcp_snapshots/list_memory_versions.req.json +6 -0
- package/fixtures/mcp_snapshots/list_memory_versions.res.json +13 -0
- package/fixtures/mcp_snapshots/prepare_recognition_context_drifting.req.json +8 -0
- package/fixtures/mcp_snapshots/prepare_recognition_context_drifting.res.json +26 -0
- package/fixtures/mcp_snapshots/resource_agent_memory.req.json +6 -0
- package/fixtures/mcp_snapshots/resource_agent_memory.res.json +80 -0
- package/fixtures/mcp_snapshots/resource_agents.req.json +4 -0
- package/fixtures/mcp_snapshots/resource_agents.res.json +4 -0
- package/fixtures/mcp_snapshots/resource_entity.req.json +6 -0
- package/fixtures/mcp_snapshots/resource_entity.res.json +19 -0
- package/fixtures/mcp_snapshots/rollback_agent_memory.req.json +7 -0
- package/fixtures/mcp_snapshots/rollback_agent_memory.res.json +7 -0
- package/fixtures/mcp_snapshots/seed_library.json +67 -3
- package/fixtures.pin.json +5 -0
- package/package.json +6 -4
package/README.md
CHANGED
|
@@ -6,8 +6,13 @@ Python (`pip install bourdon`) is the **oracle**. The `@getbourdon/*` TypeScript
|
|
|
6
6
|
reproduces the oracle's output on these exact fixtures — byte-for-byte where the contract is bytes (redaction,
|
|
7
7
|
recognition strings, MCP wire), value-for-value where it's structured (F1, schema validity, tool I/O).
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
## Who mints fixtures
|
|
10
|
+
|
|
11
|
+
**The Python repository mints fixtures; this package is a runner and consumer, never a producer.** Every
|
|
12
|
+
fixture is generated by the Python repo's `tools/gen_conformance.py` (the single writer, which imports the
|
|
13
|
+
live oracle and emits its actual output). This package vendors a reviewed snapshot of that output under
|
|
14
|
+
`fixtures/` and ships it with typed loaders. No fixture is ever authored or edited here — a change always
|
|
15
|
+
starts oracle-side and arrives through the re-pin ritual below.
|
|
11
16
|
|
|
12
17
|
```ts
|
|
13
18
|
import { loadRedactionBattery, assembleSecret } from "@getbourdon/conformance";
|
|
@@ -19,8 +24,25 @@ for (const secret of battery.secrets) {
|
|
|
19
24
|
}
|
|
20
25
|
```
|
|
21
26
|
|
|
22
|
-
|
|
23
|
-
|
|
27
|
+
## The pin
|
|
28
|
+
|
|
29
|
+
`fixtures.pin.json` records which contract the vendored snapshot is (`conformance_version`) and the sha256
|
|
30
|
+
`fixtures/manifest.json` must hash to. The test suite asserts both and prints them, and separately verifies
|
|
31
|
+
every fixture file against the sha256 its manifest stamps — so a stale, partial, or hand-edited fixture tree
|
|
32
|
+
cannot pass quietly. A mutation test corrupts a temp copy and asserts the hash gate goes red, proving the
|
|
33
|
+
gate itself is live.
|
|
34
|
+
|
|
35
|
+
## Re-pin ritual (per contract bump)
|
|
36
|
+
|
|
37
|
+
1. Oracle side: regenerate (`python tools/gen_conformance.py`), review the diff, land it there first.
|
|
38
|
+
2. Here: `BOURDON_CONFORMANCE_DIR=<oracle>/conformance pnpm --filter @getbourdon/conformance sync-fixtures`
|
|
39
|
+
3. Update `fixtures.pin.json` with the new `conformance_version` and the sha256 of the new
|
|
40
|
+
`fixtures/manifest.json`.
|
|
41
|
+
4. Run the workspace test suite; fix whatever the new contract flushes out **in the mirror packages**, never
|
|
42
|
+
by editing a fixture.
|
|
43
|
+
|
|
44
|
+
**Resolution order:** `BOURDON_CONFORMANCE_DIR`, else the vendored `fixtures/` snapshot, else the sibling
|
|
45
|
+
Python checkout `../bourdon/conformance`.
|
|
24
46
|
|
|
25
47
|
License: Apache-2.0 (the wire-contract surface is permissive so third parties can build conformant
|
|
26
48
|
implementations). The Bourdon engine is BUSL-1.1.
|
package/dist/index.cjs
CHANGED
|
@@ -23,9 +23,13 @@ __export(index_exports, {
|
|
|
23
23
|
assembleSecret: () => assembleSecret,
|
|
24
24
|
conformanceDir: () => conformanceDir,
|
|
25
25
|
loadManifest: () => loadManifest,
|
|
26
|
-
|
|
26
|
+
loadPin: () => loadPin,
|
|
27
|
+
loadRedactionBattery: () => loadRedactionBattery,
|
|
28
|
+
sha256File: () => sha256File,
|
|
29
|
+
verifyFixtureHashes: () => verifyFixtureHashes
|
|
27
30
|
});
|
|
28
31
|
module.exports = __toCommonJS(index_exports);
|
|
32
|
+
var import_node_crypto = require("crypto");
|
|
29
33
|
var import_node_fs = require("fs");
|
|
30
34
|
var import_node_path = require("path");
|
|
31
35
|
var import_node_url = require("url");
|
|
@@ -49,6 +53,27 @@ function loadJson(name) {
|
|
|
49
53
|
function loadManifest() {
|
|
50
54
|
return loadJson("manifest.json");
|
|
51
55
|
}
|
|
56
|
+
function loadPin() {
|
|
57
|
+
return JSON.parse(
|
|
58
|
+
(0, import_node_fs.readFileSync)((0, import_node_path.resolve)(moduleDir(), "..", "fixtures.pin.json"), "utf8")
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
function sha256File(path) {
|
|
62
|
+
return (0, import_node_crypto.createHash)("sha256").update((0, import_node_fs.readFileSync)(path)).digest("hex");
|
|
63
|
+
}
|
|
64
|
+
function verifyFixtureHashes(dir = conformanceDir()) {
|
|
65
|
+
const manifest = JSON.parse(
|
|
66
|
+
(0, import_node_fs.readFileSync)((0, import_node_path.resolve)(dir, "manifest.json"), "utf8")
|
|
67
|
+
);
|
|
68
|
+
const mismatches = [];
|
|
69
|
+
for (const fixture of manifest.fixtures) {
|
|
70
|
+
const actual = sha256File((0, import_node_path.resolve)(dir, fixture.path));
|
|
71
|
+
if (actual !== fixture.sha256) {
|
|
72
|
+
mismatches.push({ path: fixture.path, expected: fixture.sha256, actual });
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return mismatches;
|
|
76
|
+
}
|
|
52
77
|
function loadRedactionBattery() {
|
|
53
78
|
return loadJson("redaction_battery.json");
|
|
54
79
|
}
|
|
@@ -60,6 +85,9 @@ function assembleSecret(secret) {
|
|
|
60
85
|
assembleSecret,
|
|
61
86
|
conformanceDir,
|
|
62
87
|
loadManifest,
|
|
63
|
-
|
|
88
|
+
loadPin,
|
|
89
|
+
loadRedactionBattery,
|
|
90
|
+
sha256File,
|
|
91
|
+
verifyFixtureHashes
|
|
64
92
|
});
|
|
65
93
|
//# sourceMappingURL=index.cjs.map
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { existsSync, readFileSync } from \"node:fs\";\nimport { dirname, resolve } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\n/**\n * Typed loaders for the language-neutral parity fixtures produced by the Python\n * oracle (`~/repos/bourdon/tools/gen_conformance.py`). Python is the source of\n * truth; the @getbourdon/* TypeScript mirror asserts against these exact bytes.\n *\n * Resolution order:\n * 1. `BOURDON_CONFORMANCE_DIR` env var — the oracle checkout (parity tests +\n * oracle dev use this; highest priority so a build always asserts against\n * the live oracle).\n * 2. the fixtures BUNDLED in this package (`<pkg>/fixtures`, shipped in the\n * tarball) — what an installed `@getbourdon/conformance` consumer gets.\n * 3. the sibling Python checkout `../../bourdon/conformance` — dev fallback.\n *\n * The bundled copy is a vendored snapshot refreshed from the oracle by\n * `pnpm --filter @getbourdon/conformance sync-fixtures` (and in the release\n * workflow before publish), so the published package is self-contained.\n */\n\n// `import.meta.url` in ESM; esbuild empties it in the CJS bundle, where the\n// native `__dirname` global is the real directory — fall back to it.\ndeclare const __dirname: string | undefined;\nfunction moduleDir(): string {\n if (typeof import.meta !== \"undefined\" && import.meta.url) {\n return dirname(fileURLToPath(import.meta.url));\n }\n return typeof __dirname !== \"undefined\" ? __dirname : process.cwd();\n}\n\nexport interface RedactionSecretCase {\n /** Joined at load (`assembleSecret`) so no contiguous secret literal lands in git. */\n fragments: string[];\n expect_redacted: string;\n expect_contains_secret: boolean;\n}\n\nexport interface RedactionBenignCase {\n text: string;\n expect_redacted: string;\n expect_contains_secret: boolean;\n}\n\nexport interface RedactionBattery {\n redacted_sentinel: string;\n benign_limit: number;\n secrets: RedactionSecretCase[];\n benign: RedactionBenignCase[];\n}\n\nexport interface ConformanceFixtureMeta {\n path: string;\n sha256: string;\n producer: string;\n}\n\nexport interface ConformanceManifest {\n conformance_version: string;\n produced_against: { bourdon_version: string };\n fixtures: ConformanceFixtureMeta[];\n}\n\nexport function conformanceDir(): string {\n const override = process.env.BOURDON_CONFORMANCE_DIR;\n if (override) return override;\n // Bundled snapshot: <pkg>/fixtures, one level up from src/ or dist/.\n const bundled = resolve(moduleDir(), \"..\", \"fixtures\");\n if (existsSync(resolve(bundled, \"manifest.json\"))) return bundled;\n // Dev fallback: the sibling Python oracle checkout.\n return resolve(process.cwd(), \"..\", \"..\", \"bourdon\", \"conformance\");\n}\n\nfunction loadJson<T>(name: string): T {\n return JSON.parse(readFileSync(resolve(conformanceDir(), name), \"utf8\")) as T;\n}\n\nexport function loadManifest(): ConformanceManifest {\n return loadJson<ConformanceManifest>(\"manifest.json\");\n}\n\nexport function loadRedactionBattery(): RedactionBattery {\n return loadJson<RedactionBattery>(\"redaction_battery.json\");\n}\n\n/** Reconstruct a secret case's runtime string from its fragments. */\nexport function assembleSecret(secret: RedactionSecretCase): string {\n return secret.fragments.join(\"\");\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,qBAAyC;AACzC,uBAAiC;AACjC,sBAA8B;
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { createHash } from \"node:crypto\";\nimport { existsSync, readFileSync } from \"node:fs\";\nimport { dirname, resolve } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\n/**\n * Typed loaders for the language-neutral parity fixtures produced by the Python\n * oracle (`~/repos/bourdon/tools/gen_conformance.py`). Python is the source of\n * truth; the @getbourdon/* TypeScript mirror asserts against these exact bytes.\n *\n * Resolution order:\n * 1. `BOURDON_CONFORMANCE_DIR` env var — the oracle checkout (parity tests +\n * oracle dev use this; highest priority so a build always asserts against\n * the live oracle).\n * 2. the fixtures BUNDLED in this package (`<pkg>/fixtures`, shipped in the\n * tarball) — what an installed `@getbourdon/conformance` consumer gets.\n * 3. the sibling Python checkout `../../bourdon/conformance` — dev fallback.\n *\n * The bundled copy is a vendored snapshot refreshed from the oracle by\n * `pnpm --filter @getbourdon/conformance sync-fixtures` (and in the release\n * workflow before publish), so the published package is self-contained.\n */\n\n// `import.meta.url` in ESM; esbuild empties it in the CJS bundle, where the\n// native `__dirname` global is the real directory — fall back to it.\ndeclare const __dirname: string | undefined;\nfunction moduleDir(): string {\n if (typeof import.meta !== \"undefined\" && import.meta.url) {\n return dirname(fileURLToPath(import.meta.url));\n }\n return typeof __dirname !== \"undefined\" ? __dirname : process.cwd();\n}\n\nexport interface RedactionSecretCase {\n /** Joined at load (`assembleSecret`) so no contiguous secret literal lands in git. */\n fragments: string[];\n expect_redacted: string;\n expect_contains_secret: boolean;\n}\n\nexport interface RedactionBenignCase {\n text: string;\n expect_redacted: string;\n expect_contains_secret: boolean;\n}\n\nexport interface RedactionBattery {\n redacted_sentinel: string;\n benign_limit: number;\n secrets: RedactionSecretCase[];\n benign: RedactionBenignCase[];\n}\n\nexport interface ConformanceFixtureMeta {\n path: string;\n sha256: string;\n producer: string;\n}\n\nexport interface ConformanceManifest {\n conformance_version: string;\n produced_against: { bourdon_version: string };\n fixtures: ConformanceFixtureMeta[];\n}\n\nexport function conformanceDir(): string {\n const override = process.env.BOURDON_CONFORMANCE_DIR;\n if (override) return override;\n // Bundled snapshot: <pkg>/fixtures, one level up from src/ or dist/.\n const bundled = resolve(moduleDir(), \"..\", \"fixtures\");\n if (existsSync(resolve(bundled, \"manifest.json\"))) return bundled;\n // Dev fallback: the sibling Python oracle checkout.\n return resolve(process.cwd(), \"..\", \"..\", \"bourdon\", \"conformance\");\n}\n\nfunction loadJson<T>(name: string): T {\n return JSON.parse(readFileSync(resolve(conformanceDir(), name), \"utf8\")) as T;\n}\n\nexport function loadManifest(): ConformanceManifest {\n return loadJson<ConformanceManifest>(\"manifest.json\");\n}\n\nexport interface FixturePin {\n conformance_version: string;\n manifest_sha256: string;\n}\n\n/** The recorded fixture pin committed beside this package: which contract\n * version the vendored snapshot is, and the sha256 the manifest must hash to. */\nexport function loadPin(): FixturePin {\n return JSON.parse(\n readFileSync(resolve(moduleDir(), \"..\", \"fixtures.pin.json\"), \"utf8\"),\n ) as FixturePin;\n}\n\n/** sha256 hex of one file's raw bytes. */\nexport function sha256File(path: string): string {\n return createHash(\"sha256\").update(readFileSync(path)).digest(\"hex\");\n}\n\nexport interface FixtureMismatch {\n path: string;\n expected: string;\n actual: string;\n}\n\n/** Verify every fixture in `dir` against the sha256 its manifest stamps.\n * Returns the mismatches — an empty array is the only passing result. The\n * same routine backs the parity gate AND its mutation test, so the check\n * that guards releases is itself provably able to fail. */\nexport function verifyFixtureHashes(dir: string = conformanceDir()): FixtureMismatch[] {\n const manifest = JSON.parse(\n readFileSync(resolve(dir, \"manifest.json\"), \"utf8\"),\n ) as ConformanceManifest;\n const mismatches: FixtureMismatch[] = [];\n for (const fixture of manifest.fixtures) {\n const actual = sha256File(resolve(dir, fixture.path));\n if (actual !== fixture.sha256) {\n mismatches.push({ path: fixture.path, expected: fixture.sha256, actual });\n }\n }\n return mismatches;\n}\n\nexport function loadRedactionBattery(): RedactionBattery {\n return loadJson<RedactionBattery>(\"redaction_battery.json\");\n}\n\n/** Reconstruct a secret case's runtime string from its fragments. */\nexport function assembleSecret(secret: RedactionSecretCase): string {\n return secret.fragments.join(\"\");\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,yBAA2B;AAC3B,qBAAyC;AACzC,uBAAiC;AACjC,sBAA8B;AAH9B;AA0BA,SAAS,YAAoB;AAC3B,MAAI,OAAO,gBAAgB,eAAe,YAAY,KAAK;AACzD,eAAO,8BAAQ,+BAAc,YAAY,GAAG,CAAC;AAAA,EAC/C;AACA,SAAO,OAAO,cAAc,cAAc,YAAY,QAAQ,IAAI;AACpE;AAkCO,SAAS,iBAAyB;AACvC,QAAM,WAAW,QAAQ,IAAI;AAC7B,MAAI,SAAU,QAAO;AAErB,QAAM,cAAU,0BAAQ,UAAU,GAAG,MAAM,UAAU;AACrD,UAAI,+BAAW,0BAAQ,SAAS,eAAe,CAAC,EAAG,QAAO;AAE1D,aAAO,0BAAQ,QAAQ,IAAI,GAAG,MAAM,MAAM,WAAW,aAAa;AACpE;AAEA,SAAS,SAAY,MAAiB;AACpC,SAAO,KAAK,UAAM,iCAAa,0BAAQ,eAAe,GAAG,IAAI,GAAG,MAAM,CAAC;AACzE;AAEO,SAAS,eAAoC;AAClD,SAAO,SAA8B,eAAe;AACtD;AASO,SAAS,UAAsB;AACpC,SAAO,KAAK;AAAA,QACV,iCAAa,0BAAQ,UAAU,GAAG,MAAM,mBAAmB,GAAG,MAAM;AAAA,EACtE;AACF;AAGO,SAAS,WAAW,MAAsB;AAC/C,aAAO,+BAAW,QAAQ,EAAE,WAAO,6BAAa,IAAI,CAAC,EAAE,OAAO,KAAK;AACrE;AAYO,SAAS,oBAAoB,MAAc,eAAe,GAAsB;AACrF,QAAM,WAAW,KAAK;AAAA,QACpB,iCAAa,0BAAQ,KAAK,eAAe,GAAG,MAAM;AAAA,EACpD;AACA,QAAM,aAAgC,CAAC;AACvC,aAAW,WAAW,SAAS,UAAU;AACvC,UAAM,SAAS,eAAW,0BAAQ,KAAK,QAAQ,IAAI,CAAC;AACpD,QAAI,WAAW,QAAQ,QAAQ;AAC7B,iBAAW,KAAK,EAAE,MAAM,QAAQ,MAAM,UAAU,QAAQ,QAAQ,OAAO,CAAC;AAAA,IAC1E;AAAA,EACF;AACA,SAAO;AACT;AAEO,SAAS,uBAAyC;AACvD,SAAO,SAA2B,wBAAwB;AAC5D;AAGO,SAAS,eAAe,QAAqC;AAClE,SAAO,OAAO,UAAU,KAAK,EAAE;AACjC;","names":[]}
|
package/dist/index.d.cts
CHANGED
|
@@ -29,8 +29,27 @@ interface ConformanceManifest {
|
|
|
29
29
|
}
|
|
30
30
|
declare function conformanceDir(): string;
|
|
31
31
|
declare function loadManifest(): ConformanceManifest;
|
|
32
|
+
interface FixturePin {
|
|
33
|
+
conformance_version: string;
|
|
34
|
+
manifest_sha256: string;
|
|
35
|
+
}
|
|
36
|
+
/** The recorded fixture pin committed beside this package: which contract
|
|
37
|
+
* version the vendored snapshot is, and the sha256 the manifest must hash to. */
|
|
38
|
+
declare function loadPin(): FixturePin;
|
|
39
|
+
/** sha256 hex of one file's raw bytes. */
|
|
40
|
+
declare function sha256File(path: string): string;
|
|
41
|
+
interface FixtureMismatch {
|
|
42
|
+
path: string;
|
|
43
|
+
expected: string;
|
|
44
|
+
actual: string;
|
|
45
|
+
}
|
|
46
|
+
/** Verify every fixture in `dir` against the sha256 its manifest stamps.
|
|
47
|
+
* Returns the mismatches — an empty array is the only passing result. The
|
|
48
|
+
* same routine backs the parity gate AND its mutation test, so the check
|
|
49
|
+
* that guards releases is itself provably able to fail. */
|
|
50
|
+
declare function verifyFixtureHashes(dir?: string): FixtureMismatch[];
|
|
32
51
|
declare function loadRedactionBattery(): RedactionBattery;
|
|
33
52
|
/** Reconstruct a secret case's runtime string from its fragments. */
|
|
34
53
|
declare function assembleSecret(secret: RedactionSecretCase): string;
|
|
35
54
|
|
|
36
|
-
export { type ConformanceFixtureMeta, type ConformanceManifest, type RedactionBattery, type RedactionBenignCase, type RedactionSecretCase, assembleSecret, conformanceDir, loadManifest, loadRedactionBattery };
|
|
55
|
+
export { type ConformanceFixtureMeta, type ConformanceManifest, type FixtureMismatch, type FixturePin, type RedactionBattery, type RedactionBenignCase, type RedactionSecretCase, assembleSecret, conformanceDir, loadManifest, loadPin, loadRedactionBattery, sha256File, verifyFixtureHashes };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,36 +1,53 @@
|
|
|
1
|
-
interface RedactionSecretCase {
|
|
1
|
+
export interface RedactionSecretCase {
|
|
2
2
|
/** Joined at load (`assembleSecret`) so no contiguous secret literal lands in git. */
|
|
3
3
|
fragments: string[];
|
|
4
4
|
expect_redacted: string;
|
|
5
5
|
expect_contains_secret: boolean;
|
|
6
6
|
}
|
|
7
|
-
interface RedactionBenignCase {
|
|
7
|
+
export interface RedactionBenignCase {
|
|
8
8
|
text: string;
|
|
9
9
|
expect_redacted: string;
|
|
10
10
|
expect_contains_secret: boolean;
|
|
11
11
|
}
|
|
12
|
-
interface RedactionBattery {
|
|
12
|
+
export interface RedactionBattery {
|
|
13
13
|
redacted_sentinel: string;
|
|
14
14
|
benign_limit: number;
|
|
15
15
|
secrets: RedactionSecretCase[];
|
|
16
16
|
benign: RedactionBenignCase[];
|
|
17
17
|
}
|
|
18
|
-
interface ConformanceFixtureMeta {
|
|
18
|
+
export interface ConformanceFixtureMeta {
|
|
19
19
|
path: string;
|
|
20
20
|
sha256: string;
|
|
21
21
|
producer: string;
|
|
22
22
|
}
|
|
23
|
-
interface ConformanceManifest {
|
|
23
|
+
export interface ConformanceManifest {
|
|
24
24
|
conformance_version: string;
|
|
25
25
|
produced_against: {
|
|
26
26
|
bourdon_version: string;
|
|
27
27
|
};
|
|
28
28
|
fixtures: ConformanceFixtureMeta[];
|
|
29
29
|
}
|
|
30
|
-
declare function conformanceDir(): string;
|
|
31
|
-
declare function loadManifest(): ConformanceManifest;
|
|
32
|
-
|
|
30
|
+
export declare function conformanceDir(): string;
|
|
31
|
+
export declare function loadManifest(): ConformanceManifest;
|
|
32
|
+
export interface FixturePin {
|
|
33
|
+
conformance_version: string;
|
|
34
|
+
manifest_sha256: string;
|
|
35
|
+
}
|
|
36
|
+
/** The recorded fixture pin committed beside this package: which contract
|
|
37
|
+
* version the vendored snapshot is, and the sha256 the manifest must hash to. */
|
|
38
|
+
export declare function loadPin(): FixturePin;
|
|
39
|
+
/** sha256 hex of one file's raw bytes. */
|
|
40
|
+
export declare function sha256File(path: string): string;
|
|
41
|
+
export interface FixtureMismatch {
|
|
42
|
+
path: string;
|
|
43
|
+
expected: string;
|
|
44
|
+
actual: string;
|
|
45
|
+
}
|
|
46
|
+
/** Verify every fixture in `dir` against the sha256 its manifest stamps.
|
|
47
|
+
* Returns the mismatches — an empty array is the only passing result. The
|
|
48
|
+
* same routine backs the parity gate AND its mutation test, so the check
|
|
49
|
+
* that guards releases is itself provably able to fail. */
|
|
50
|
+
export declare function verifyFixtureHashes(dir?: string): FixtureMismatch[];
|
|
51
|
+
export declare function loadRedactionBattery(): RedactionBattery;
|
|
33
52
|
/** Reconstruct a secret case's runtime string from its fragments. */
|
|
34
|
-
declare function assembleSecret(secret: RedactionSecretCase): string;
|
|
35
|
-
|
|
36
|
-
export { type ConformanceFixtureMeta, type ConformanceManifest, type RedactionBattery, type RedactionBenignCase, type RedactionSecretCase, assembleSecret, conformanceDir, loadManifest, loadRedactionBattery };
|
|
53
|
+
export declare function assembleSecret(secret: RedactionSecretCase): string;
|
package/dist/index.js
CHANGED
|
@@ -1,36 +1,58 @@
|
|
|
1
|
-
|
|
2
|
-
import { existsSync, readFileSync } from "fs";
|
|
3
|
-
import { dirname, resolve } from "path";
|
|
4
|
-
import { fileURLToPath } from "url";
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
3
|
+
import { dirname, resolve } from "node:path";
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
5
5
|
function moduleDir() {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
}
|
|
11
|
-
function conformanceDir() {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
6
|
+
if (typeof import.meta !== "undefined" && import.meta.url) {
|
|
7
|
+
return dirname(fileURLToPath(import.meta.url));
|
|
8
|
+
}
|
|
9
|
+
return typeof __dirname !== "undefined" ? __dirname : process.cwd();
|
|
10
|
+
}
|
|
11
|
+
export function conformanceDir() {
|
|
12
|
+
const override = process.env.BOURDON_CONFORMANCE_DIR;
|
|
13
|
+
if (override)
|
|
14
|
+
return override;
|
|
15
|
+
// Bundled snapshot: <pkg>/fixtures, one level up from src/ or dist/.
|
|
16
|
+
const bundled = resolve(moduleDir(), "..", "fixtures");
|
|
17
|
+
if (existsSync(resolve(bundled, "manifest.json")))
|
|
18
|
+
return bundled;
|
|
19
|
+
// Dev fallback: the sibling Python oracle checkout.
|
|
20
|
+
return resolve(process.cwd(), "..", "..", "bourdon", "conformance");
|
|
17
21
|
}
|
|
18
22
|
function loadJson(name) {
|
|
19
|
-
|
|
23
|
+
return JSON.parse(readFileSync(resolve(conformanceDir(), name), "utf8"));
|
|
24
|
+
}
|
|
25
|
+
export function loadManifest() {
|
|
26
|
+
return loadJson("manifest.json");
|
|
27
|
+
}
|
|
28
|
+
/** The recorded fixture pin committed beside this package: which contract
|
|
29
|
+
* version the vendored snapshot is, and the sha256 the manifest must hash to. */
|
|
30
|
+
export function loadPin() {
|
|
31
|
+
return JSON.parse(readFileSync(resolve(moduleDir(), "..", "fixtures.pin.json"), "utf8"));
|
|
32
|
+
}
|
|
33
|
+
/** sha256 hex of one file's raw bytes. */
|
|
34
|
+
export function sha256File(path) {
|
|
35
|
+
return createHash("sha256").update(readFileSync(path)).digest("hex");
|
|
20
36
|
}
|
|
21
|
-
|
|
22
|
-
|
|
37
|
+
/** Verify every fixture in `dir` against the sha256 its manifest stamps.
|
|
38
|
+
* Returns the mismatches — an empty array is the only passing result. The
|
|
39
|
+
* same routine backs the parity gate AND its mutation test, so the check
|
|
40
|
+
* that guards releases is itself provably able to fail. */
|
|
41
|
+
export function verifyFixtureHashes(dir = conformanceDir()) {
|
|
42
|
+
const manifest = JSON.parse(readFileSync(resolve(dir, "manifest.json"), "utf8"));
|
|
43
|
+
const mismatches = [];
|
|
44
|
+
for (const fixture of manifest.fixtures) {
|
|
45
|
+
const actual = sha256File(resolve(dir, fixture.path));
|
|
46
|
+
if (actual !== fixture.sha256) {
|
|
47
|
+
mismatches.push({ path: fixture.path, expected: fixture.sha256, actual });
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
return mismatches;
|
|
23
51
|
}
|
|
24
|
-
function loadRedactionBattery() {
|
|
25
|
-
|
|
52
|
+
export function loadRedactionBattery() {
|
|
53
|
+
return loadJson("redaction_battery.json");
|
|
26
54
|
}
|
|
27
|
-
|
|
28
|
-
|
|
55
|
+
/** Reconstruct a secret case's runtime string from its fragments. */
|
|
56
|
+
export function assembleSecret(secret) {
|
|
57
|
+
return secret.fragments.join("");
|
|
29
58
|
}
|
|
30
|
-
export {
|
|
31
|
-
assembleSecret,
|
|
32
|
-
conformanceDir,
|
|
33
|
-
loadManifest,
|
|
34
|
-
loadRedactionBattery
|
|
35
|
-
};
|
|
36
|
-
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { existsSync, readFileSync } from \"node:fs\";\nimport { dirname, resolve } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\n/**\n * Typed loaders for the language-neutral parity fixtures produced by the Python\n * oracle (`~/repos/bourdon/tools/gen_conformance.py`). Python is the source of\n * truth; the @getbourdon/* TypeScript mirror asserts against these exact bytes.\n *\n * Resolution order:\n * 1. `BOURDON_CONFORMANCE_DIR` env var — the oracle checkout (parity tests +\n * oracle dev use this; highest priority so a build always asserts against\n * the live oracle).\n * 2. the fixtures BUNDLED in this package (`<pkg>/fixtures`, shipped in the\n * tarball) — what an installed `@getbourdon/conformance` consumer gets.\n * 3. the sibling Python checkout `../../bourdon/conformance` — dev fallback.\n *\n * The bundled copy is a vendored snapshot refreshed from the oracle by\n * `pnpm --filter @getbourdon/conformance sync-fixtures` (and in the release\n * workflow before publish), so the published package is self-contained.\n */\n\n// `import.meta.url` in ESM; esbuild empties it in the CJS bundle, where the\n// native `__dirname` global is the real directory — fall back to it.\ndeclare const __dirname: string | undefined;\nfunction moduleDir(): string {\n if (typeof import.meta !== \"undefined\" && import.meta.url) {\n return dirname(fileURLToPath(import.meta.url));\n }\n return typeof __dirname !== \"undefined\" ? __dirname : process.cwd();\n}\n\nexport interface RedactionSecretCase {\n /** Joined at load (`assembleSecret`) so no contiguous secret literal lands in git. */\n fragments: string[];\n expect_redacted: string;\n expect_contains_secret: boolean;\n}\n\nexport interface RedactionBenignCase {\n text: string;\n expect_redacted: string;\n expect_contains_secret: boolean;\n}\n\nexport interface RedactionBattery {\n redacted_sentinel: string;\n benign_limit: number;\n secrets: RedactionSecretCase[];\n benign: RedactionBenignCase[];\n}\n\nexport interface ConformanceFixtureMeta {\n path: string;\n sha256: string;\n producer: string;\n}\n\nexport interface ConformanceManifest {\n conformance_version: string;\n produced_against: { bourdon_version: string };\n fixtures: ConformanceFixtureMeta[];\n}\n\nexport function conformanceDir(): string {\n const override = process.env.BOURDON_CONFORMANCE_DIR;\n if (override) return override;\n // Bundled snapshot: <pkg>/fixtures, one level up from src/ or dist/.\n const bundled = resolve(moduleDir(), \"..\", \"fixtures\");\n if (existsSync(resolve(bundled, \"manifest.json\"))) return bundled;\n // Dev fallback: the sibling Python oracle checkout.\n return resolve(process.cwd(), \"..\", \"..\", \"bourdon\", \"conformance\");\n}\n\nfunction loadJson<T>(name: string): T {\n return JSON.parse(readFileSync(resolve(conformanceDir(), name), \"utf8\")) as T;\n}\n\nexport function loadManifest(): ConformanceManifest {\n return loadJson<ConformanceManifest>(\"manifest.json\");\n}\n\nexport function loadRedactionBattery(): RedactionBattery {\n return loadJson<RedactionBattery>(\"redaction_battery.json\");\n}\n\n/** Reconstruct a secret case's runtime string from its fragments. */\nexport function assembleSecret(secret: RedactionSecretCase): string {\n return secret.fragments.join(\"\");\n}\n"],"mappings":";AAAA,SAAS,YAAY,oBAAoB;AACzC,SAAS,SAAS,eAAe;AACjC,SAAS,qBAAqB;AAuB9B,SAAS,YAAoB;AAC3B,MAAI,OAAO,gBAAgB,eAAe,YAAY,KAAK;AACzD,WAAO,QAAQ,cAAc,YAAY,GAAG,CAAC;AAAA,EAC/C;AACA,SAAO,OAAO,cAAc,cAAc,YAAY,QAAQ,IAAI;AACpE;AAkCO,SAAS,iBAAyB;AACvC,QAAM,WAAW,QAAQ,IAAI;AAC7B,MAAI,SAAU,QAAO;AAErB,QAAM,UAAU,QAAQ,UAAU,GAAG,MAAM,UAAU;AACrD,MAAI,WAAW,QAAQ,SAAS,eAAe,CAAC,EAAG,QAAO;AAE1D,SAAO,QAAQ,QAAQ,IAAI,GAAG,MAAM,MAAM,WAAW,aAAa;AACpE;AAEA,SAAS,SAAY,MAAiB;AACpC,SAAO,KAAK,MAAM,aAAa,QAAQ,eAAe,GAAG,IAAI,GAAG,MAAM,CAAC;AACzE;AAEO,SAAS,eAAoC;AAClD,SAAO,SAA8B,eAAe;AACtD;AAEO,SAAS,uBAAyC;AACvD,SAAO,SAA2B,wBAAwB;AAC5D;AAGO,SAAS,eAAe,QAAqC;AAClE,SAAO,OAAO,UAAU,KAAK,EAAE;AACjC;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { createHash } from \"node:crypto\";\nimport { existsSync, readFileSync } from \"node:fs\";\nimport { dirname, resolve } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\n/**\n * Typed loaders for the language-neutral parity fixtures produced by the Python\n * oracle (`~/repos/bourdon/tools/gen_conformance.py`). Python is the source of\n * truth; the @getbourdon/* TypeScript mirror asserts against these exact bytes.\n *\n * Resolution order:\n * 1. `BOURDON_CONFORMANCE_DIR` env var — the oracle checkout (parity tests +\n * oracle dev use this; highest priority so a build always asserts against\n * the live oracle).\n * 2. the fixtures BUNDLED in this package (`<pkg>/fixtures`, shipped in the\n * tarball) — what an installed `@getbourdon/conformance` consumer gets.\n * 3. the sibling Python checkout `../../bourdon/conformance` — dev fallback.\n *\n * The bundled copy is a vendored snapshot refreshed from the oracle by\n * `pnpm --filter @getbourdon/conformance sync-fixtures` (and in the release\n * workflow before publish), so the published package is self-contained.\n */\n\n// `import.meta.url` in ESM; esbuild empties it in the CJS bundle, where the\n// native `__dirname` global is the real directory — fall back to it.\ndeclare const __dirname: string | undefined;\nfunction moduleDir(): string {\n if (typeof import.meta !== \"undefined\" && import.meta.url) {\n return dirname(fileURLToPath(import.meta.url));\n }\n return typeof __dirname !== \"undefined\" ? __dirname : process.cwd();\n}\n\nexport interface RedactionSecretCase {\n /** Joined at load (`assembleSecret`) so no contiguous secret literal lands in git. */\n fragments: string[];\n expect_redacted: string;\n expect_contains_secret: boolean;\n}\n\nexport interface RedactionBenignCase {\n text: string;\n expect_redacted: string;\n expect_contains_secret: boolean;\n}\n\nexport interface RedactionBattery {\n redacted_sentinel: string;\n benign_limit: number;\n secrets: RedactionSecretCase[];\n benign: RedactionBenignCase[];\n}\n\nexport interface ConformanceFixtureMeta {\n path: string;\n sha256: string;\n producer: string;\n}\n\nexport interface ConformanceManifest {\n conformance_version: string;\n produced_against: { bourdon_version: string };\n fixtures: ConformanceFixtureMeta[];\n}\n\nexport function conformanceDir(): string {\n const override = process.env.BOURDON_CONFORMANCE_DIR;\n if (override) return override;\n // Bundled snapshot: <pkg>/fixtures, one level up from src/ or dist/.\n const bundled = resolve(moduleDir(), \"..\", \"fixtures\");\n if (existsSync(resolve(bundled, \"manifest.json\"))) return bundled;\n // Dev fallback: the sibling Python oracle checkout.\n return resolve(process.cwd(), \"..\", \"..\", \"bourdon\", \"conformance\");\n}\n\nfunction loadJson<T>(name: string): T {\n return JSON.parse(readFileSync(resolve(conformanceDir(), name), \"utf8\")) as T;\n}\n\nexport function loadManifest(): ConformanceManifest {\n return loadJson<ConformanceManifest>(\"manifest.json\");\n}\n\nexport interface FixturePin {\n conformance_version: string;\n manifest_sha256: string;\n}\n\n/** The recorded fixture pin committed beside this package: which contract\n * version the vendored snapshot is, and the sha256 the manifest must hash to. */\nexport function loadPin(): FixturePin {\n return JSON.parse(\n readFileSync(resolve(moduleDir(), \"..\", \"fixtures.pin.json\"), \"utf8\"),\n ) as FixturePin;\n}\n\n/** sha256 hex of one file's raw bytes. */\nexport function sha256File(path: string): string {\n return createHash(\"sha256\").update(readFileSync(path)).digest(\"hex\");\n}\n\nexport interface FixtureMismatch {\n path: string;\n expected: string;\n actual: string;\n}\n\n/** Verify every fixture in `dir` against the sha256 its manifest stamps.\n * Returns the mismatches — an empty array is the only passing result. The\n * same routine backs the parity gate AND its mutation test, so the check\n * that guards releases is itself provably able to fail. */\nexport function verifyFixtureHashes(dir: string = conformanceDir()): FixtureMismatch[] {\n const manifest = JSON.parse(\n readFileSync(resolve(dir, \"manifest.json\"), \"utf8\"),\n ) as ConformanceManifest;\n const mismatches: FixtureMismatch[] = [];\n for (const fixture of manifest.fixtures) {\n const actual = sha256File(resolve(dir, fixture.path));\n if (actual !== fixture.sha256) {\n mismatches.push({ path: fixture.path, expected: fixture.sha256, actual });\n }\n }\n return mismatches;\n}\n\nexport function loadRedactionBattery(): RedactionBattery {\n return loadJson<RedactionBattery>(\"redaction_battery.json\");\n}\n\n/** Reconstruct a secret case's runtime string from its fragments. */\nexport function assembleSecret(secret: RedactionSecretCase): string {\n return secret.fragments.join(\"\");\n}\n"],"mappings":";AAAA,SAAS,kBAAkB;AAC3B,SAAS,YAAY,oBAAoB;AACzC,SAAS,SAAS,eAAe;AACjC,SAAS,qBAAqB;AAuB9B,SAAS,YAAoB;AAC3B,MAAI,OAAO,gBAAgB,eAAe,YAAY,KAAK;AACzD,WAAO,QAAQ,cAAc,YAAY,GAAG,CAAC;AAAA,EAC/C;AACA,SAAO,OAAO,cAAc,cAAc,YAAY,QAAQ,IAAI;AACpE;AAkCO,SAAS,iBAAyB;AACvC,QAAM,WAAW,QAAQ,IAAI;AAC7B,MAAI,SAAU,QAAO;AAErB,QAAM,UAAU,QAAQ,UAAU,GAAG,MAAM,UAAU;AACrD,MAAI,WAAW,QAAQ,SAAS,eAAe,CAAC,EAAG,QAAO;AAE1D,SAAO,QAAQ,QAAQ,IAAI,GAAG,MAAM,MAAM,WAAW,aAAa;AACpE;AAEA,SAAS,SAAY,MAAiB;AACpC,SAAO,KAAK,MAAM,aAAa,QAAQ,eAAe,GAAG,IAAI,GAAG,MAAM,CAAC;AACzE;AAEO,SAAS,eAAoC;AAClD,SAAO,SAA8B,eAAe;AACtD;AASO,SAAS,UAAsB;AACpC,SAAO,KAAK;AAAA,IACV,aAAa,QAAQ,UAAU,GAAG,MAAM,mBAAmB,GAAG,MAAM;AAAA,EACtE;AACF;AAGO,SAAS,WAAW,MAAsB;AAC/C,SAAO,WAAW,QAAQ,EAAE,OAAO,aAAa,IAAI,CAAC,EAAE,OAAO,KAAK;AACrE;AAYO,SAAS,oBAAoB,MAAc,eAAe,GAAsB;AACrF,QAAM,WAAW,KAAK;AAAA,IACpB,aAAa,QAAQ,KAAK,eAAe,GAAG,MAAM;AAAA,EACpD;AACA,QAAM,aAAgC,CAAC;AACvC,aAAW,WAAW,SAAS,UAAU;AACvC,UAAM,SAAS,WAAW,QAAQ,KAAK,QAAQ,IAAI,CAAC;AACpD,QAAI,WAAW,QAAQ,QAAQ;AAC7B,iBAAW,KAAK,EAAE,MAAM,QAAQ,MAAM,UAAU,QAAQ,QAAQ,OAAO,CAAC;AAAA,IAC1E;AAAA,EACF;AACA,SAAO;AACT;AAEO,SAAS,uBAAyC;AACvD,SAAO,SAA2B,wBAAwB;AAC5D;AAGO,SAAS,eAAe,QAAqC;AAClE,SAAO,OAAO,UAAU,KAAK,EAAE;AACjC;","names":[]}
|
package/fixtures/README.md
CHANGED
|
@@ -19,7 +19,7 @@ uncommitted diff (`git diff --exit-code -- conformance/`).
|
|
|
19
19
|
python tools/gen_conformance.py # rewrites conformance/ + manifest.json
|
|
20
20
|
```
|
|
21
21
|
|
|
22
|
-
After changing a pattern in `
|
|
22
|
+
After changing a pattern in `core.redaction` (or any oracle), regenerate, review the
|
|
23
23
|
diff, and bump `conformance_version` in `tools/gen_conformance.py` (patch = added cases,
|
|
24
24
|
minor = new family, major = a changed expected-output = a reviewed behavior change).
|
|
25
25
|
|
|
@@ -44,8 +44,16 @@ dict. `on_disk/` holds Python-written artifacts the TS side must parse identical
|
|
|
44
44
|
never a contiguous literal), and an append-only audit log produced by the real `record()` with frozen
|
|
45
45
|
timestamps. Both pytest (`tests/test_federation_conformance.py`) and the TS vitest suite assert these.
|
|
46
46
|
|
|
47
|
-
The `mcp_snapshots/` family pins the **JSON-in-TextContent wire contract** for
|
|
48
|
-
|
|
47
|
+
The `mcp_snapshots/` family pins the **JSON-in-TextContent wire contract** for **every**
|
|
48
|
+
tool `create_l6_server` registers (15 as of conformance 1.11.0) **plus** the three
|
|
49
|
+
`agent-library://` resource response contracts (`resource_agents`, `resource_agent_memory`,
|
|
50
|
+
`resource_entity` — snapshotted first, over the pure seed view). The generator refuses to
|
|
51
|
+
emit when a registered tool or resource lacks a snapshot case, so the surface stays
|
|
52
|
+
complete by construction. The three version-history tools (`list_memory_versions`,
|
|
53
|
+
`explain_memory_change`, `rollback_agent_memory`) are driven over a deterministic
|
|
54
|
+
version-history seed described in `mcp_snapshots/seed_library.json` (fixed prior-state
|
|
55
|
+
bytes + a fixed-ts provenance entry); `rollback_agent_memory` runs last because it
|
|
56
|
+
restores that seeded prior state. Each `*.res.json` is the live tool's payload (as `RemoteL6Client` recovers it:
|
|
49
57
|
`json.loads` of the single `TextContent.text` = `json.dumps(payload)`) run through one codified
|
|
50
58
|
NORMALIZER — sort object keys, round floats to 4dp, drop null/empty-list fields (to_dict
|
|
51
59
|
omission), freeze `last_updated`/`generated_at`/`generated_from`/`path`, drop latency fields,
|
|
@@ -70,6 +70,58 @@
|
|
|
70
70
|
"message": "'name' is a required property"
|
|
71
71
|
}
|
|
72
72
|
]
|
|
73
|
+
},
|
|
74
|
+
"session-impossible-calendar-date.json": {
|
|
75
|
+
"valid": false,
|
|
76
|
+
"expected": {
|
|
77
|
+
"keyword": "pattern",
|
|
78
|
+
"instancePath": "/recent_sessions/0/date"
|
|
79
|
+
},
|
|
80
|
+
"errors": [
|
|
81
|
+
{
|
|
82
|
+
"keyword": "anyOf",
|
|
83
|
+
"instancePath": "/recent_sessions/0/date",
|
|
84
|
+
"message": "'2026-99-99' is not valid under any of the given schemas"
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
"keyword": "pattern",
|
|
88
|
+
"instancePath": "/recent_sessions/0/date",
|
|
89
|
+
"message": "'2026-99-99' does not match '^(\\\\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\\\\d|3[01]))?$'"
|
|
90
|
+
}
|
|
91
|
+
]
|
|
92
|
+
},
|
|
93
|
+
"session-impossible-feb-30.json": {
|
|
94
|
+
"valid": false,
|
|
95
|
+
"expected": {
|
|
96
|
+
"keyword": "anyOf",
|
|
97
|
+
"instancePath": "/recent_sessions/0/date"
|
|
98
|
+
},
|
|
99
|
+
"errors": [
|
|
100
|
+
{
|
|
101
|
+
"keyword": "anyOf",
|
|
102
|
+
"instancePath": "/recent_sessions/0/date",
|
|
103
|
+
"message": "'2026-02-30' is not valid under any of the given schemas"
|
|
104
|
+
}
|
|
105
|
+
]
|
|
106
|
+
},
|
|
107
|
+
"entity-impossible-calendar-date.json": {
|
|
108
|
+
"valid": false,
|
|
109
|
+
"expected": {
|
|
110
|
+
"keyword": "format",
|
|
111
|
+
"instancePath": "/known_entities/0/valid_from"
|
|
112
|
+
},
|
|
113
|
+
"errors": [
|
|
114
|
+
{
|
|
115
|
+
"keyword": "format",
|
|
116
|
+
"instancePath": "/known_entities/0/valid_from",
|
|
117
|
+
"message": "'2026-13-05' is not a 'date'"
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
"keyword": "pattern",
|
|
121
|
+
"instancePath": "/known_entities/0/valid_from",
|
|
122
|
+
"message": "'2026-13-05' does not match '^\\\\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\\\\d|3[01])$'"
|
|
123
|
+
}
|
|
124
|
+
]
|
|
73
125
|
}
|
|
74
126
|
}
|
|
75
127
|
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"spec_version": "0.1",
|
|
3
|
+
"agent": {
|
|
4
|
+
"id": "alpha-agent",
|
|
5
|
+
"type": "note-capture"
|
|
6
|
+
},
|
|
7
|
+
"last_updated": "2026-06-29T12:00:00+00:00",
|
|
8
|
+
"recent_sessions": [
|
|
9
|
+
{
|
|
10
|
+
"date": "",
|
|
11
|
+
"key_actions": [
|
|
12
|
+
"undated native-store session"
|
|
13
|
+
]
|
|
14
|
+
}
|
|
15
|
+
]
|
|
16
|
+
}
|