agentfootprint 9.94.3 → 9.95.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/CHANGELOG.md +23 -0
- package/CLAUDE.md +2 -0
- package/dist/answer-validation/evidence.js +121 -0
- package/dist/answer-validation/evidence.js.map +1 -0
- package/dist/answer-validation/index.js +10 -0
- package/dist/answer-validation/index.js.map +1 -0
- package/dist/answer-validation/types.js +24 -0
- package/dist/answer-validation/types.js.map +1 -0
- package/dist/answer-validation/validate.js +326 -0
- package/dist/answer-validation/validate.js.map +1 -0
- package/dist/core/Agent.js +56 -2
- package/dist/core/Agent.js.map +1 -1
- package/dist/core/agent/AgentBuilder.js +27 -1
- package/dist/core/agent/AgentBuilder.js.map +1 -1
- package/dist/core/agent/buildAgentChart.js +17 -2
- package/dist/core/agent/buildAgentChart.js.map +1 -1
- package/dist/core/agent/buildDynamicAgentChart.js +15 -2
- package/dist/core/agent/buildDynamicAgentChart.js.map +1 -1
- package/dist/core/agent/outputEnforcement.js.map +1 -1
- package/dist/core/agent/stages/answerValidation.js +57 -0
- package/dist/core/agent/stages/answerValidation.js.map +1 -0
- package/dist/core/agent/stages/breakFinal.js +11 -1
- package/dist/core/agent/stages/breakFinal.js.map +1 -1
- package/dist/core/agent/stages/callLLM.js +7 -5
- package/dist/core/agent/stages/callLLM.js.map +1 -1
- package/dist/core/agent/stages/prepareFinal.js +35 -2
- package/dist/core/agent/stages/prepareFinal.js.map +1 -1
- package/dist/core/agent/stages/route.js +9 -5
- package/dist/core/agent/stages/route.js.map +1 -1
- package/dist/esm/answer-validation/evidence.d.ts +12 -0
- package/dist/esm/answer-validation/evidence.js +117 -0
- package/dist/esm/answer-validation/evidence.js.map +1 -0
- package/dist/esm/answer-validation/index.d.ts +3 -0
- package/dist/esm/answer-validation/index.js +4 -0
- package/dist/esm/answer-validation/index.js.map +1 -0
- package/dist/esm/answer-validation/types.d.ts +94 -0
- package/dist/esm/answer-validation/types.js +20 -0
- package/dist/esm/answer-validation/types.js.map +1 -0
- package/dist/esm/answer-validation/validate.d.ts +15 -0
- package/dist/esm/answer-validation/validate.js +321 -0
- package/dist/esm/answer-validation/validate.js.map +1 -0
- package/dist/esm/core/Agent.d.ts +6 -1
- package/dist/esm/core/Agent.js +56 -2
- package/dist/esm/core/Agent.js.map +1 -1
- package/dist/esm/core/agent/AgentBuilder.d.ts +11 -0
- package/dist/esm/core/agent/AgentBuilder.js +27 -1
- package/dist/esm/core/agent/AgentBuilder.js.map +1 -1
- package/dist/esm/core/agent/buildAgentChart.d.ts +2 -0
- package/dist/esm/core/agent/buildAgentChart.js +19 -4
- package/dist/esm/core/agent/buildAgentChart.js.map +1 -1
- package/dist/esm/core/agent/buildDynamicAgentChart.js +17 -4
- package/dist/esm/core/agent/buildDynamicAgentChart.js.map +1 -1
- package/dist/esm/core/agent/outputEnforcement.d.ts +2 -0
- package/dist/esm/core/agent/outputEnforcement.js.map +1 -1
- package/dist/esm/core/agent/stages/answerValidation.d.ts +10 -0
- package/dist/esm/core/agent/stages/answerValidation.js +53 -0
- package/dist/esm/core/agent/stages/answerValidation.js.map +1 -0
- package/dist/esm/core/agent/stages/breakFinal.d.ts +6 -0
- package/dist/esm/core/agent/stages/breakFinal.js +9 -0
- package/dist/esm/core/agent/stages/breakFinal.js.map +1 -1
- package/dist/esm/core/agent/stages/callLLM.d.ts +2 -0
- package/dist/esm/core/agent/stages/callLLM.js +7 -5
- package/dist/esm/core/agent/stages/callLLM.js.map +1 -1
- package/dist/esm/core/agent/stages/prepareFinal.d.ts +7 -0
- package/dist/esm/core/agent/stages/prepareFinal.js +33 -1
- package/dist/esm/core/agent/stages/prepareFinal.js.map +1 -1
- package/dist/esm/core/agent/stages/route.js +9 -5
- package/dist/esm/core/agent/stages/route.js.map +1 -1
- package/dist/esm/core/agent/types.d.ts +6 -0
- package/dist/esm/index.d.ts +1 -0
- package/dist/esm/index.js +2 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/index.js +4 -1
- package/dist/index.js.map +1 -1
- package/dist/types/answer-validation/evidence.d.ts +13 -0
- package/dist/types/answer-validation/evidence.d.ts.map +1 -0
- package/dist/types/answer-validation/index.d.ts +4 -0
- package/dist/types/answer-validation/index.d.ts.map +1 -0
- package/dist/types/answer-validation/types.d.ts +95 -0
- package/dist/types/answer-validation/types.d.ts.map +1 -0
- package/dist/types/answer-validation/validate.d.ts +16 -0
- package/dist/types/answer-validation/validate.d.ts.map +1 -0
- package/dist/types/core/Agent.d.ts +6 -1
- package/dist/types/core/Agent.d.ts.map +1 -1
- package/dist/types/core/agent/AgentBuilder.d.ts +11 -0
- package/dist/types/core/agent/AgentBuilder.d.ts.map +1 -1
- package/dist/types/core/agent/buildAgentChart.d.ts +2 -0
- package/dist/types/core/agent/buildAgentChart.d.ts.map +1 -1
- package/dist/types/core/agent/buildDynamicAgentChart.d.ts.map +1 -1
- package/dist/types/core/agent/outputEnforcement.d.ts +2 -0
- package/dist/types/core/agent/outputEnforcement.d.ts.map +1 -1
- package/dist/types/core/agent/stages/answerValidation.d.ts +11 -0
- package/dist/types/core/agent/stages/answerValidation.d.ts.map +1 -0
- package/dist/types/core/agent/stages/breakFinal.d.ts +6 -0
- package/dist/types/core/agent/stages/breakFinal.d.ts.map +1 -1
- package/dist/types/core/agent/stages/callLLM.d.ts +2 -0
- package/dist/types/core/agent/stages/callLLM.d.ts.map +1 -1
- package/dist/types/core/agent/stages/prepareFinal.d.ts +7 -0
- package/dist/types/core/agent/stages/prepareFinal.d.ts.map +1 -1
- package/dist/types/core/agent/types.d.ts +6 -0
- package/dist/types/core/agent/types.d.ts.map +1 -1
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.d.ts.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,29 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [9.95.0] - 2026-09-12
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- Opt-in `.answerValidation()` checks schema-parsed JSON against host-owned
|
|
13
|
+
evidence before final answer delivery. Enforce mode refuses failed or
|
|
14
|
+
unverified checks; observe mode records them without refusing. Scoped,
|
|
15
|
+
read-only artifact resolution has per-validation read, byte and time limits.
|
|
16
|
+
Reports separate actual checks from unavailable evidence and artifact reads.
|
|
17
|
+
- Configured agents withhold draft tokens and deliver the checked canonical
|
|
18
|
+
value consistently through `run`, `runTyped`, final events and memory.
|
|
19
|
+
Output fallback and coverage suffix combinations are explicitly refused in
|
|
20
|
+
this version; automatic repair and free-text entailment are outside scope.
|
|
21
|
+
|
|
22
|
+
## [9.94.4] - 2026-09-12
|
|
23
|
+
|
|
24
|
+
### Documentation
|
|
25
|
+
|
|
26
|
+
- Propose optional answer validation against referenced evidence in
|
|
27
|
+
[proposal 013](docs/proposals/013-answer-validation.md), with executable tests
|
|
28
|
+
of current claim-checking and output-enforcement boundaries. This is a
|
|
29
|
+
feature request; it introduces no runtime API or validation guarantee.
|
|
30
|
+
|
|
8
31
|
## [9.94.3] - 2026-09-12
|
|
9
32
|
|
|
10
33
|
### Fixed — two behaviours that moved with footprintjs 9.22.0+ and 9.24.0, found by running the suite on them
|
package/CLAUDE.md
CHANGED
|
@@ -17,6 +17,7 @@ not in this table, search `src/index.ts` for the nearest noun before writing cod
|
|
|
17
17
|
|
|
18
18
|
| If you are about to build… | It is | Where | Since |
|
|
19
19
|
|---|---|---|---|
|
|
20
|
+
| checking a typed final answer against scoped evidence before streaming or memory delivery — optional host-authored checks with enforce/observe modes, canonical JSON and bounded read-only artifacts | `answerValidation` + `AnswerValidationError` | `src/answer-validation/` | 9.95.0 |
|
|
20
21
|
| turning a written operational procedure (a runbook, a triage playbook) into ONE agent tool whose every answer is EVIDENCE — coverage folded up from the inner tools it calls, rule name+version, verdict rows with GENERATED meanings, and the recorded walk as an artifact ticket, never bytes | `runbookAsTool` — dials: `procedure` (factory, invoked per call with `ctx.tools`) + `resultKind` (`'verdict/*'` arms the rowset projection; anything else ships spine + the chart's `report`) + `rules {name, version}` (default absent ⇒ `rule_version: 'undeclared'`) + `verdicts {decider, maxRows}` (default 50; `verdict_meanings` = statically declared branches + this run's rule labels + the DEFAULT branch's label, which reaches evidence only when the chart calls `decide(s, rules, {branch, label})` — fp ≥9.16.1, the default is chosen by NO rule so nothing else can name it, and inside a generated fan-out branch the static walk is blind too; an undeclared or blank label stays ABSENT from the map, never invented from a branch id, and there is deliberately NO caller-supplied meanings map) + `presentation` (`'prose'` default = ship `table` + `VERDICT_RENDER_NOTE` "output it VERBATIM"; `'panel'` = the HOST renders the rowset, so NO `table` key at all + `PANEL_RENDER_NOTE` "the rows are already on the reader's screen — do not reproduce them"; the rowset half is byte-identical across modes, `table` stays RESERVED in both, an unknown value THROWS at definition) + `walk {cap, recording}` (cap default 500; over-cap ⇒ control-flow projection, declared · `recording: true` or `{label, maxBytes}`, default OFF — ALSO files the inner chart's own `{snapshot, events, structure}` under `recording/run` and puts its ref on the spine as `walk.recording_ref`, because the ROW projection cannot be drawn; snapshot read from the REDACTED mirror so one `redact` means the same for both; over `maxBytes` (`DEFAULT_RECORDING_MAX_BYTES` = 5,000,000) it is REFUSED not truncated; every absence — no store / over size / unserializable / store threw — is STATED in `walk.recording_note`, and the four `recording_*` fields are absent entirely when the dial is off) + `composedOf` (drift-checked at agent BUILD) + kept `recorders`/`keepRecord`/`keepRecordLimit`/`redact`; reserved state keys `verdicts`/`coverage`/`report` (the `report` bag lands BESIDE the spine, never over it — a report field spelling `af_coverage`/`af_provenance`/`rule_version`/`walk`/`report_note` or a live projection key is discarded and NAMED in `result.report_note`; precedence is explicit in `report.ts`, never spread order); inner `absent()` passes through VERBATIM unless the call said `allowAbsent`; walk kind `recording/chart-walk` + `walk_segment` discriminant | `src/core/runbook/` | 9.76.0, recording 9.79.0 |
|
|
21
22
|
| speaking MCP from a BROWSER — the SDK is browser-clean (its client + streamableHttp bundle at `platform:'browser'` with zero `node:` edges and never pull in `client/stdio.js`); the one barrier was that `lazyRequire` gets CALLED there, so the fix is to let the caller supply what the loader would have found | `mcpClient({ sdk })` (`McpSdk` = the two SDK modules you imported statically; the library STILL builds the transport, so headers/fetch/gateway vending/`retryOnThrottle`/`_meta` all keep working) · `mcpClient({ connection })` (`McpConnection` = listTools/callTool/close, deliberately NO `connect` — you already did; the only arm that reaches the SDK's `jsonSchemaValidator`, i.e. CSP) + `McpConnectionOptions`; `refuseConflictingOptions` REFUSES at construction every option a transport would have consumed, naming where it moved (a knob naming a behaviour that no longer happens is the defect class); `transportUrl` resolves a relative `url` against `globalThis.location.href` (absolute takes the identical branch, Node refuses by name); `sdkLoadFailure` classifies the seven load sites so a browser is never told to install a package it has (resolution failure ⇒ byte-identical historical message); `retryingFetch` + `ThrottleFetch` promoted out of `@internal` so the connection arm keeps its 429 handling. stdio keeps `lazyRequire` FOREVER — it spawns a subprocess. ZERO packaging change: no subpath, no `browser` condition (TypeScript is blind to it), peer stays optional (no literal dynamic `import()`). Fenced by `test/lib/mcp/browserGraph.test.ts` | `src/lib/mcp/` | 9.81.0 |
|
|
22
23
|
| calling ANOTHER registered tool from inside a tool's `execute` — composition over the agent's own dispatch map instead of importing the module and building a second query stack | `agentToolDispatch` + `ctx.tools` (ToolDispatch has/call) — sees static and skill-carried tools, NEVER ToolProvider-delivered ones (no build-time list, the 9.72.0 caveat); inner calls get the outer facts with hasArtifacts false and a derived toolCallId, `needs` resolved fail-closed non-interactively, `checkIn` and `wants` tools refused by name, no nested dispatch; declare ingredients via `composedOf` (and `gates` for a pausing procedure) — both travel MCP `_meta` | `src/core/agent/toolDispatch.ts` | 9.76.0 |
|
|
@@ -85,6 +86,7 @@ Entry points — FIFTEEN doors, and `package.json` `exports` is exhaustive, so a
|
|
|
85
86
|
|
|
86
87
|
| src/ | one job |
|
|
87
88
|
|---|---|
|
|
89
|
+
| answer-validation/ | optional final-answer contract, scoped bounded artifact reads, canonical JSON and explicit check dispositions; the Agent route owns invocation and final capture owns delivery |
|
|
88
90
|
| core/ | primitives: Agent.ts (ReAct runner), LLMCall.ts, RunnerBase.ts (dispatcher + attach + enable.*), tools.ts (defineTool), pause.ts, runCheckpoint.ts |
|
|
89
91
|
| core/agent/evidence/ | (9.35.0) the evidence gate — `.namesAndNumbersFromEvidence()`. Pure + deterministic BY LAW (no model, no embedding: a guard that needed a bigger model to police a smaller one inverts the library's thesis). normalize (one spelling per value, both sides) → extract (which tokens are DATA — conservative, justified clause by clause) → evidenceIndex (STRUCTURAL walk of `role:'tool'` results; the exempt corpus is user message + user/system turns + `systemPromptInjections`, MINUS the library's own frames — see frames.ts, the laundering bug) → gate (resolve/judge/sentences) → errors (`UnsupportedValuesError`). Fabrication detector, NOT a correctness judge: a false claim built from real values passes |
|
|
90
92
|
| core/agent/coverage/ | the two FIELD-INVENTED result primitives. `absent()` = an absence that names its own coverage (checked / not checked / cannot cover) and says a retry returns the same; `coverage(result, …)` = the ledger of what a clean verdict does NOT rule out. Both RECOGNIZED (reserved `af_absent`/`af_coverage` keys, the effects-envelope strictness law), not conventions. Pure; the moving parts are `declareCoverage` in stages/toolCalls.ts, the whitelist in evidence/evidenceIndex.ts, and `prepareFinalWithLimitsStage` |
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createAnswerEvidenceResolver = void 0;
|
|
4
|
+
/** Bounded reads over the existing store. No new store, scope, or ref grammar. */
|
|
5
|
+
const naming_js_1 = require("../artifacts/naming.js");
|
|
6
|
+
const payload_js_1 = require("../artifacts/payload.js");
|
|
7
|
+
const types_js_1 = require("../artifacts/types.js");
|
|
8
|
+
/** @internal Run-local read session. Closing invalidates even retained readers. */
|
|
9
|
+
function createAnswerEvidenceResolver(store, scope, limits, signal) {
|
|
10
|
+
const boundScope = Object.freeze({ ...scope });
|
|
11
|
+
const cache = new Map();
|
|
12
|
+
const resolved = new Set();
|
|
13
|
+
let reads = 0;
|
|
14
|
+
let pendingReads = 0;
|
|
15
|
+
let reservedBytes = 0;
|
|
16
|
+
let closed = false;
|
|
17
|
+
let failure;
|
|
18
|
+
const unavailable = (reason) => {
|
|
19
|
+
failure ??= reason;
|
|
20
|
+
return { ok: false, reason };
|
|
21
|
+
};
|
|
22
|
+
const isClosed = () => closed || signal.aborted;
|
|
23
|
+
const load = async (ref, kind) => {
|
|
24
|
+
if (!store)
|
|
25
|
+
return unavailable('no-store');
|
|
26
|
+
try {
|
|
27
|
+
const described = await store.head(boundScope, ref);
|
|
28
|
+
if (isClosed())
|
|
29
|
+
return unavailable('closed');
|
|
30
|
+
if (described === null)
|
|
31
|
+
return unavailable('missing-or-expired');
|
|
32
|
+
// Memory stores may return their own metadata object: snapshot before the
|
|
33
|
+
// next await, and never hand that live value to an author callback.
|
|
34
|
+
const head = structuredClone(described);
|
|
35
|
+
if (head.ref !== ref || !Number.isSafeInteger(head.bytes) || head.bytes < 0)
|
|
36
|
+
return unavailable('invalid-record');
|
|
37
|
+
if (head.kind !== kind)
|
|
38
|
+
return unavailable('kind-mismatch');
|
|
39
|
+
if (head.bytes > limits.maxBytes - reservedBytes)
|
|
40
|
+
return unavailable('max-bytes');
|
|
41
|
+
reservedBytes += head.bytes; // Reserve before await: parallel reads share this budget.
|
|
42
|
+
const record = await store.get(boundScope, ref);
|
|
43
|
+
if (isClosed())
|
|
44
|
+
return unavailable('closed');
|
|
45
|
+
if (record === null)
|
|
46
|
+
return unavailable('missing-or-expired');
|
|
47
|
+
const meta = structuredClone(record.meta);
|
|
48
|
+
if (meta.ref !== ref ||
|
|
49
|
+
meta.kind !== kind ||
|
|
50
|
+
meta.bytes !== head.bytes ||
|
|
51
|
+
meta.digest !== head.digest ||
|
|
52
|
+
meta.createdAt !== head.createdAt ||
|
|
53
|
+
meta.expiresAt !== head.expiresAt ||
|
|
54
|
+
meta.mediaType !== head.mediaType)
|
|
55
|
+
return unavailable('invalid-record');
|
|
56
|
+
// get is the store's verifying read, including its own expiry clock.
|
|
57
|
+
// A nonconforming adapter may allocate too much inside get; the port has
|
|
58
|
+
// no bounded-read verb. Never deliver an understated parcel as accepted.
|
|
59
|
+
const bytes = (0, payload_js_1.canonicalPayloadBytes)(record.data);
|
|
60
|
+
if (bytes.byteLength !== meta.bytes)
|
|
61
|
+
return unavailable('invalid-record');
|
|
62
|
+
if (bytes.byteLength > limits.maxBytes)
|
|
63
|
+
return unavailable('max-bytes');
|
|
64
|
+
const data = (0, payload_js_1.decodeCanonicalPayload)((0, payload_js_1.payloadShapeOf)(record.data), bytes.slice());
|
|
65
|
+
if (isClosed())
|
|
66
|
+
return unavailable('closed');
|
|
67
|
+
resolved.add(ref);
|
|
68
|
+
return { ok: true, record: { meta, data } };
|
|
69
|
+
}
|
|
70
|
+
catch (error) {
|
|
71
|
+
if (isClosed())
|
|
72
|
+
return unavailable('closed');
|
|
73
|
+
return unavailable(error instanceof types_js_1.ArtifactIntegrityError ? 'digest-mismatch' : 'store-error');
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
const resolver = Object.freeze({
|
|
77
|
+
async resolve(ref, options) {
|
|
78
|
+
if (isClosed())
|
|
79
|
+
return unavailable('closed');
|
|
80
|
+
if (!(0, naming_js_1.isArtifactRef)(ref) || options === null || typeof options !== 'object')
|
|
81
|
+
return unavailable('invalid-input');
|
|
82
|
+
const descriptor = Object.getOwnPropertyDescriptor(options, 'kind');
|
|
83
|
+
if (!descriptor ||
|
|
84
|
+
!('value' in descriptor) ||
|
|
85
|
+
typeof descriptor.value !== 'string' ||
|
|
86
|
+
descriptor.value.trim() === '' ||
|
|
87
|
+
descriptor.value.length > 256)
|
|
88
|
+
return unavailable('invalid-input');
|
|
89
|
+
const kind = descriptor.value;
|
|
90
|
+
const key = JSON.stringify([ref, kind]);
|
|
91
|
+
let pending = cache.get(key);
|
|
92
|
+
if (!pending) {
|
|
93
|
+
if (reads >= limits.maxReads)
|
|
94
|
+
return unavailable('max-reads');
|
|
95
|
+
reads++;
|
|
96
|
+
pendingReads++;
|
|
97
|
+
pending = load(ref, kind).finally(() => {
|
|
98
|
+
pendingReads--;
|
|
99
|
+
});
|
|
100
|
+
cache.set(key, pending);
|
|
101
|
+
}
|
|
102
|
+
const result = await pending;
|
|
103
|
+
if (isClosed())
|
|
104
|
+
return unavailable('closed');
|
|
105
|
+
// One callback cannot mutate a cached parcel subsequently used by another
|
|
106
|
+
// check. Metadata and data are detached on every successful delivery.
|
|
107
|
+
return result.ok ? { ok: true, record: structuredClone(result.record) } : { ...result };
|
|
108
|
+
},
|
|
109
|
+
});
|
|
110
|
+
return {
|
|
111
|
+
resolver,
|
|
112
|
+
resolvedRefs: () => [...resolved],
|
|
113
|
+
failureReason: () => failure ?? (pendingReads > 0 ? 'closed' : undefined),
|
|
114
|
+
close() {
|
|
115
|
+
closed = true;
|
|
116
|
+
cache.clear();
|
|
117
|
+
},
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
exports.createAnswerEvidenceResolver = createAnswerEvidenceResolver;
|
|
121
|
+
//# sourceMappingURL=evidence.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"evidence.js","sourceRoot":"","sources":["../../src/answer-validation/evidence.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.executeAnswerValidation = exports.resolveAnswerValidation = exports.AnswerValidationError = void 0;
|
|
4
|
+
/** Explicit, bounded validation of schema-accepted JSON answers. */
|
|
5
|
+
var types_js_1 = require("./types.js");
|
|
6
|
+
Object.defineProperty(exports, "AnswerValidationError", { enumerable: true, get: function () { return types_js_1.AnswerValidationError; } });
|
|
7
|
+
var validate_js_1 = require("./validate.js");
|
|
8
|
+
Object.defineProperty(exports, "resolveAnswerValidation", { enumerable: true, get: function () { return validate_js_1.resolveAnswerValidation; } });
|
|
9
|
+
Object.defineProperty(exports, "executeAnswerValidation", { enumerable: true, get: function () { return validate_js_1.executeAnswerValidation; } });
|
|
10
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/answer-validation/index.ts"],"names":[],"mappings":";;;AAAA,oEAAoE;AACpE,uCAYoB;AAXlB,iHAAA,qBAAqB,OAAA;AAYvB,6CAAiF;AAAxE,sHAAA,uBAAuB,OAAA;AAAE,sHAAA,uBAAuB,OAAA"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AnswerValidationError = void 0;
|
|
4
|
+
/** An enforcing host refused delivery; diagnostic metadata only, never content. */
|
|
5
|
+
class AnswerValidationError extends Error {
|
|
6
|
+
code = 'ERR_ANSWER_VALIDATION';
|
|
7
|
+
report;
|
|
8
|
+
constructor(report) {
|
|
9
|
+
super(`Answer validation '${report.validatorId}' did not pass (${report.status}).`);
|
|
10
|
+
this.name = 'AnswerValidationError';
|
|
11
|
+
this.report = Object.freeze({
|
|
12
|
+
...report,
|
|
13
|
+
checks: Object.freeze(report.checks.map((check) => Object.freeze({
|
|
14
|
+
...check,
|
|
15
|
+
...(check.evidenceRefs !== undefined && {
|
|
16
|
+
evidenceRefs: Object.freeze([...check.evidenceRefs]),
|
|
17
|
+
}),
|
|
18
|
+
}))),
|
|
19
|
+
resolvedRefs: Object.freeze([...report.resolvedRefs]),
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
exports.AnswerValidationError = AnswerValidationError;
|
|
24
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/answer-validation/types.ts"],"names":[],"mappings":";;;AA6GA,mFAAmF;AACnF,MAAa,qBAAsB,SAAQ,KAAK;IACrC,IAAI,GAAG,uBAAgC,CAAC;IACxC,MAAM,CAAyB;IAExC,YAAY,MAA8B;QACxC,KAAK,CAAC,sBAAsB,MAAM,CAAC,WAAW,mBAAmB,MAAM,CAAC,MAAM,IAAI,CAAC,CAAC;QACpF,IAAI,CAAC,IAAI,GAAG,uBAAuB,CAAC;QACpC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;YAC1B,GAAG,MAAM;YACT,MAAM,EAAE,MAAM,CAAC,MAAM,CACnB,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAC1B,MAAM,CAAC,MAAM,CAAC;gBACZ,GAAG,KAAK;gBACR,GAAG,CAAC,KAAK,CAAC,YAAY,KAAK,SAAS,IAAI;oBACtC,YAAY,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,KAAK,CAAC,YAAY,CAAC,CAAC;iBACrD,CAAC;aACH,CAAC,CACH,CACF;YACD,YAAY,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,MAAM,CAAC,YAAY,CAAC,CAAC;SACtD,CAAC,CAAC;IACL,CAAC;CACF;AAtBD,sDAsBC"}
|
|
@@ -0,0 +1,326 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.executeAnswerValidation = exports.resolveAnswerValidation = void 0;
|
|
4
|
+
/** One explicit JSON-answer validation; the runner owns when to invoke it. */
|
|
5
|
+
const outputSchema_js_1 = require("../core/outputSchema.js");
|
|
6
|
+
const payload_js_1 = require("../artifacts/payload.js");
|
|
7
|
+
const evidence_js_1 = require("./evidence.js");
|
|
8
|
+
const DEFAULT_LIMITS = Object.freeze({
|
|
9
|
+
maxReads: 16,
|
|
10
|
+
maxBytes: 4 * 1024 * 1024,
|
|
11
|
+
maxChecks: 100,
|
|
12
|
+
maxCandidateBytes: 1024 * 1024,
|
|
13
|
+
timeoutMs: 5000,
|
|
14
|
+
});
|
|
15
|
+
const encoder = new TextEncoder();
|
|
16
|
+
const dispositions = new Set(['checked-pass', 'checked-fail', 'not-applicable', 'unreachable']);
|
|
17
|
+
function ownData(value, allowed) {
|
|
18
|
+
if (value === null ||
|
|
19
|
+
typeof value !== 'object' ||
|
|
20
|
+
Array.isArray(value) ||
|
|
21
|
+
![Object.prototype, null].includes(Object.getPrototypeOf(value)))
|
|
22
|
+
throw new Error('Expected a plain data object.');
|
|
23
|
+
const result = Object.create(null);
|
|
24
|
+
for (const key of Reflect.ownKeys(value)) {
|
|
25
|
+
if (typeof key !== 'string' || (allowed && !allowed.includes(key)))
|
|
26
|
+
throw new Error('Unknown property.');
|
|
27
|
+
const descriptor = Object.getOwnPropertyDescriptor(value, key);
|
|
28
|
+
if (!descriptor?.enumerable || !('value' in descriptor))
|
|
29
|
+
throw new Error('Expected an enumerable data property.');
|
|
30
|
+
Object.defineProperty(result, key, { value: descriptor.value, enumerable: true });
|
|
31
|
+
}
|
|
32
|
+
return result;
|
|
33
|
+
}
|
|
34
|
+
function text(value, max) {
|
|
35
|
+
if (typeof value !== 'string' || value.trim() === '' || value.length > max)
|
|
36
|
+
throw new Error('Expected bounded non-empty text.');
|
|
37
|
+
return value;
|
|
38
|
+
}
|
|
39
|
+
/** Validate and snapshot an authored contract once, before running an agent. */
|
|
40
|
+
function resolveAnswerValidation(options) {
|
|
41
|
+
const source = ownData(options, ['id', 'version', 'mode', 'limits', 'validate']);
|
|
42
|
+
const id = text(source.id, 128);
|
|
43
|
+
const version = text(source.version, 128);
|
|
44
|
+
const mode = source.mode === undefined ? 'enforce' : source.mode;
|
|
45
|
+
if (mode !== 'enforce' && mode !== 'observe')
|
|
46
|
+
throw new Error('answerValidation.mode must be enforce or observe.');
|
|
47
|
+
if (typeof source.validate !== 'function')
|
|
48
|
+
throw new Error('answerValidation.validate must be a function.');
|
|
49
|
+
const validate = source.validate;
|
|
50
|
+
const supplied = source.limits === undefined ? {} : ownData(source.limits, Object.keys(DEFAULT_LIMITS));
|
|
51
|
+
const limits = { ...DEFAULT_LIMITS };
|
|
52
|
+
for (const key of Object.keys(DEFAULT_LIMITS)) {
|
|
53
|
+
if (Object.hasOwn(supplied, key)) {
|
|
54
|
+
const value = supplied[key];
|
|
55
|
+
if (typeof value !== 'number' ||
|
|
56
|
+
!Number.isSafeInteger(value) ||
|
|
57
|
+
value <= 0 ||
|
|
58
|
+
(key === 'timeoutMs' && value > 2147483647))
|
|
59
|
+
throw new Error(`answerValidation.limits.${key} must be a positive bounded integer.`);
|
|
60
|
+
limits[key] = value;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return Object.freeze({
|
|
64
|
+
id,
|
|
65
|
+
version,
|
|
66
|
+
mode,
|
|
67
|
+
limits: Object.freeze(limits),
|
|
68
|
+
validate: (candidate, context) => validate(candidate, context),
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
exports.resolveAnswerValidation = resolveAnswerValidation;
|
|
72
|
+
/** JSON copy without invoking toJSON/getters or silently dropping data. */
|
|
73
|
+
function jsonCopy(value, maxBytes, freeze) {
|
|
74
|
+
let budget = maxBytes;
|
|
75
|
+
const ancestors = new Set();
|
|
76
|
+
const spend = (bytes) => {
|
|
77
|
+
budget -= bytes;
|
|
78
|
+
if (budget < 0)
|
|
79
|
+
throw new Error('JSON byte limit.');
|
|
80
|
+
};
|
|
81
|
+
const string = (item) => {
|
|
82
|
+
if (item.length > budget)
|
|
83
|
+
throw new Error('JSON byte limit.');
|
|
84
|
+
spend(encoder.encode(JSON.stringify(item)).byteLength);
|
|
85
|
+
};
|
|
86
|
+
const copy = (item, depth) => {
|
|
87
|
+
if (depth > 100)
|
|
88
|
+
throw new Error('JSON nesting limit.');
|
|
89
|
+
if (item === null) {
|
|
90
|
+
spend(4);
|
|
91
|
+
return null;
|
|
92
|
+
}
|
|
93
|
+
if (typeof item === 'string') {
|
|
94
|
+
string(item);
|
|
95
|
+
return item;
|
|
96
|
+
}
|
|
97
|
+
if (typeof item === 'boolean') {
|
|
98
|
+
spend(item ? 4 : 5);
|
|
99
|
+
return item;
|
|
100
|
+
}
|
|
101
|
+
if (typeof item === 'number') {
|
|
102
|
+
if (!Number.isFinite(item) || Object.is(item, -0))
|
|
103
|
+
throw new Error('Non-lossless JSON number.');
|
|
104
|
+
spend(JSON.stringify(item).length);
|
|
105
|
+
return item;
|
|
106
|
+
}
|
|
107
|
+
if (typeof item !== 'object')
|
|
108
|
+
throw new Error('Non-JSON value.');
|
|
109
|
+
if (ancestors.has(item))
|
|
110
|
+
throw new Error('Cyclic JSON value.');
|
|
111
|
+
ancestors.add(item);
|
|
112
|
+
spend(2);
|
|
113
|
+
let output;
|
|
114
|
+
if (Array.isArray(item)) {
|
|
115
|
+
if (Object.getPrototypeOf(item) !== Array.prototype)
|
|
116
|
+
throw new Error('Non-JSON array prototype.');
|
|
117
|
+
if (item.length > budget + 1)
|
|
118
|
+
throw new Error('JSON byte limit.');
|
|
119
|
+
const keys = Reflect.ownKeys(item);
|
|
120
|
+
if (keys.length !== item.length + 1)
|
|
121
|
+
throw new Error('Sparse or decorated array.');
|
|
122
|
+
const result = [];
|
|
123
|
+
for (let index = 0; index < item.length; index++) {
|
|
124
|
+
const descriptor = Object.getOwnPropertyDescriptor(item, String(index));
|
|
125
|
+
if (!descriptor?.enumerable || !('value' in descriptor))
|
|
126
|
+
throw new Error('Sparse or accessor array.');
|
|
127
|
+
if (index)
|
|
128
|
+
spend(1);
|
|
129
|
+
result.push(copy(descriptor.value, depth + 1));
|
|
130
|
+
}
|
|
131
|
+
output = result;
|
|
132
|
+
}
|
|
133
|
+
else {
|
|
134
|
+
const fields = ownData(item);
|
|
135
|
+
const result = {};
|
|
136
|
+
let index = 0;
|
|
137
|
+
for (const key of Object.keys(fields)) {
|
|
138
|
+
if (index++)
|
|
139
|
+
spend(1);
|
|
140
|
+
string(key);
|
|
141
|
+
spend(1);
|
|
142
|
+
Object.defineProperty(result, key, {
|
|
143
|
+
value: copy(fields[key], depth + 1),
|
|
144
|
+
enumerable: true,
|
|
145
|
+
writable: true,
|
|
146
|
+
configurable: true,
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
output = result;
|
|
150
|
+
}
|
|
151
|
+
ancestors.delete(item);
|
|
152
|
+
return freeze ? Object.freeze(output) : output;
|
|
153
|
+
};
|
|
154
|
+
return copy(value, 0);
|
|
155
|
+
}
|
|
156
|
+
function readChecks(value, config, resolved) {
|
|
157
|
+
// Bound before copying. The copy rejects getters, class instances, cycles,
|
|
158
|
+
// decorated arrays and values JSON would otherwise silently discard.
|
|
159
|
+
const source = ownData(value, ['checks']);
|
|
160
|
+
if (!Array.isArray(source.checks) || source.checks.length > config.limits.maxChecks)
|
|
161
|
+
throw new Error('Invalid checks.');
|
|
162
|
+
const detached = jsonCopy(source.checks, config.limits.maxChecks * 4096, false);
|
|
163
|
+
const ids = new Set();
|
|
164
|
+
const refs = new Set(resolved);
|
|
165
|
+
return detached.map((raw) => {
|
|
166
|
+
const check = ownData(raw, ['id', 'disposition', 'reason', 'path', 'evidenceRefs']);
|
|
167
|
+
const id = text(check.id, 128);
|
|
168
|
+
if (ids.has(id) ||
|
|
169
|
+
typeof check.disposition !== 'string' ||
|
|
170
|
+
!dispositions.has(check.disposition))
|
|
171
|
+
throw new Error('Invalid check identity or disposition.');
|
|
172
|
+
ids.add(id);
|
|
173
|
+
const reason = check.reason === undefined ? undefined : text(check.reason, 1024);
|
|
174
|
+
const path = check.path;
|
|
175
|
+
if (path !== undefined && (typeof path !== 'string' || path.length > 256))
|
|
176
|
+
throw new Error('Invalid check path.');
|
|
177
|
+
let evidenceRefs;
|
|
178
|
+
if (check.evidenceRefs !== undefined) {
|
|
179
|
+
if (!Array.isArray(check.evidenceRefs) || check.evidenceRefs.length > config.limits.maxReads)
|
|
180
|
+
throw new Error('Invalid evidence references.');
|
|
181
|
+
evidenceRefs = check.evidenceRefs.map((ref) => {
|
|
182
|
+
if (typeof ref !== 'string' || !refs.has(ref))
|
|
183
|
+
throw new Error('Unresolved evidence reference.');
|
|
184
|
+
return ref;
|
|
185
|
+
});
|
|
186
|
+
if (new Set(evidenceRefs).size !== evidenceRefs.length)
|
|
187
|
+
throw new Error('Duplicate evidence reference.');
|
|
188
|
+
}
|
|
189
|
+
return Object.freeze({
|
|
190
|
+
id,
|
|
191
|
+
disposition: check.disposition,
|
|
192
|
+
...(reason !== undefined && { reason }),
|
|
193
|
+
...(path !== undefined && { path }),
|
|
194
|
+
...(evidenceRefs !== undefined && { evidenceRefs: Object.freeze(evidenceRefs) }),
|
|
195
|
+
});
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Validate once. Content is present only when delivery is permitted by this
|
|
200
|
+
* contract. It is the exact JSON string whose detached value was checked;
|
|
201
|
+
* callers must not reparse through a transforming schema or rewrite afterward.
|
|
202
|
+
*/
|
|
203
|
+
async function executeAnswerValidation(raw, parser, config, store, scope, signal) {
|
|
204
|
+
const controller = new AbortController();
|
|
205
|
+
const evidence = (0, evidence_js_1.createAnswerEvidenceResolver)(store, scope, config.limits, controller.signal);
|
|
206
|
+
let reason;
|
|
207
|
+
let schemaAccepted = false;
|
|
208
|
+
let canonical;
|
|
209
|
+
let candidateDigest;
|
|
210
|
+
let checks = [];
|
|
211
|
+
let active = true;
|
|
212
|
+
let stop;
|
|
213
|
+
const abort = () => {
|
|
214
|
+
reason = 'aborted';
|
|
215
|
+
controller.abort();
|
|
216
|
+
stop?.();
|
|
217
|
+
};
|
|
218
|
+
const timedOut = () => {
|
|
219
|
+
reason = 'timeout';
|
|
220
|
+
controller.abort();
|
|
221
|
+
stop?.();
|
|
222
|
+
};
|
|
223
|
+
const deadline = Date.now() + config.limits.timeoutMs;
|
|
224
|
+
const timer = setTimeout(timedOut, config.limits.timeoutMs);
|
|
225
|
+
signal?.addEventListener('abort', abort, { once: true });
|
|
226
|
+
if (signal?.aborted)
|
|
227
|
+
abort();
|
|
228
|
+
try {
|
|
229
|
+
const interrupted = new Promise((resolve) => {
|
|
230
|
+
stop = resolve;
|
|
231
|
+
if (controller.signal.aborted)
|
|
232
|
+
resolve();
|
|
233
|
+
});
|
|
234
|
+
const work = async () => {
|
|
235
|
+
if (controller.signal.aborted)
|
|
236
|
+
return;
|
|
237
|
+
let candidate;
|
|
238
|
+
try {
|
|
239
|
+
if (raw.length > config.limits.maxCandidateBytes ||
|
|
240
|
+
encoder.encode(raw).byteLength > config.limits.maxCandidateBytes) {
|
|
241
|
+
reason = 'candidate-limit';
|
|
242
|
+
return;
|
|
243
|
+
}
|
|
244
|
+
candidate = (0, outputSchema_js_1.applyOutputSchema)(raw, parser);
|
|
245
|
+
}
|
|
246
|
+
catch {
|
|
247
|
+
reason = 'schema-rejected';
|
|
248
|
+
return;
|
|
249
|
+
}
|
|
250
|
+
try {
|
|
251
|
+
candidate = jsonCopy(candidate, config.limits.maxCandidateBytes, true);
|
|
252
|
+
canonical = JSON.stringify(candidate);
|
|
253
|
+
schemaAccepted = true;
|
|
254
|
+
}
|
|
255
|
+
catch {
|
|
256
|
+
reason = 'non-json-candidate';
|
|
257
|
+
return;
|
|
258
|
+
}
|
|
259
|
+
if (Date.now() >= deadline) {
|
|
260
|
+
timedOut();
|
|
261
|
+
return;
|
|
262
|
+
}
|
|
263
|
+
try {
|
|
264
|
+
const digest = await (0, payload_js_1.computeArtifactDigest)(canonical);
|
|
265
|
+
if (!active || controller.signal.aborted)
|
|
266
|
+
return;
|
|
267
|
+
candidateDigest = digest;
|
|
268
|
+
const returned = await config.validate(candidate, Object.freeze({ signal: controller.signal, artifacts: evidence.resolver }));
|
|
269
|
+
if (!active || controller.signal.aborted)
|
|
270
|
+
return;
|
|
271
|
+
if (Date.now() >= deadline) {
|
|
272
|
+
timedOut();
|
|
273
|
+
return;
|
|
274
|
+
}
|
|
275
|
+
try {
|
|
276
|
+
checks = readChecks(returned, config, evidence.resolvedRefs());
|
|
277
|
+
}
|
|
278
|
+
catch {
|
|
279
|
+
reason = 'invalid-validator-result';
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
catch {
|
|
283
|
+
if (active && !controller.signal.aborted)
|
|
284
|
+
reason = 'validator-error';
|
|
285
|
+
}
|
|
286
|
+
};
|
|
287
|
+
await Promise.race([work(), interrupted]);
|
|
288
|
+
}
|
|
289
|
+
finally {
|
|
290
|
+
active = false;
|
|
291
|
+
clearTimeout(timer);
|
|
292
|
+
signal?.removeEventListener('abort', abort);
|
|
293
|
+
evidence.close();
|
|
294
|
+
controller.abort();
|
|
295
|
+
}
|
|
296
|
+
const failed = checks.filter((check) => check.disposition === 'checked-fail').length;
|
|
297
|
+
const checked = failed + checks.filter((check) => check.disposition === 'checked-pass').length;
|
|
298
|
+
const unreachable = checks.filter((check) => check.disposition === 'unreachable').length;
|
|
299
|
+
const notApplicable = checks.filter((check) => check.disposition === 'not-applicable').length;
|
|
300
|
+
if (!reason && evidence.failureReason())
|
|
301
|
+
reason = `evidence-${evidence.failureReason()}`;
|
|
302
|
+
if (!reason && checked === 0)
|
|
303
|
+
reason = 'no-comparable-checks';
|
|
304
|
+
if (!reason && unreachable > 0)
|
|
305
|
+
reason = 'unreachable-checks';
|
|
306
|
+
const status = reason ? 'unverified' : failed > 0 ? 'failed' : 'passed';
|
|
307
|
+
const report = Object.freeze({
|
|
308
|
+
validatorId: config.id,
|
|
309
|
+
validatorVersion: config.version,
|
|
310
|
+
mode: config.mode,
|
|
311
|
+
status,
|
|
312
|
+
checked,
|
|
313
|
+
failed,
|
|
314
|
+
unreachable,
|
|
315
|
+
notApplicable,
|
|
316
|
+
checks: Object.freeze(checks),
|
|
317
|
+
schemaAccepted,
|
|
318
|
+
...(reason !== undefined && { reason }),
|
|
319
|
+
...(candidateDigest !== undefined && { candidateDigest }),
|
|
320
|
+
resolvedRefs: Object.freeze(evidence.resolvedRefs()),
|
|
321
|
+
});
|
|
322
|
+
const content = status === 'passed' || config.mode === 'observe' ? canonical ?? raw : undefined;
|
|
323
|
+
return { report, ...(content !== undefined && { content }) };
|
|
324
|
+
}
|
|
325
|
+
exports.executeAnswerValidation = executeAnswerValidation;
|
|
326
|
+
//# sourceMappingURL=validate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate.js","sourceRoot":"","sources":["../../src/answer-validation/validate.ts"],"names":[],"mappings":"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"}
|