agentfootprint 9.94.2 → 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.
Files changed (114) hide show
  1. package/CHANGELOG.md +75 -0
  2. package/CLAUDE.md +2 -0
  3. package/dist/answer-validation/evidence.js +121 -0
  4. package/dist/answer-validation/evidence.js.map +1 -0
  5. package/dist/answer-validation/index.js +10 -0
  6. package/dist/answer-validation/index.js.map +1 -0
  7. package/dist/answer-validation/types.js +24 -0
  8. package/dist/answer-validation/types.js.map +1 -0
  9. package/dist/answer-validation/validate.js +326 -0
  10. package/dist/answer-validation/validate.js.map +1 -0
  11. package/dist/cache/CacheGateDecider.js +7 -1
  12. package/dist/cache/CacheGateDecider.js.map +1 -1
  13. package/dist/core/Agent.js +56 -2
  14. package/dist/core/Agent.js.map +1 -1
  15. package/dist/core/agent/AgentBuilder.js +27 -1
  16. package/dist/core/agent/AgentBuilder.js.map +1 -1
  17. package/dist/core/agent/buildAgentChart.js +17 -2
  18. package/dist/core/agent/buildAgentChart.js.map +1 -1
  19. package/dist/core/agent/buildDynamicAgentChart.js +15 -2
  20. package/dist/core/agent/buildDynamicAgentChart.js.map +1 -1
  21. package/dist/core/agent/outputEnforcement.js.map +1 -1
  22. package/dist/core/agent/stages/answerValidation.js +57 -0
  23. package/dist/core/agent/stages/answerValidation.js.map +1 -0
  24. package/dist/core/agent/stages/breakFinal.js +11 -1
  25. package/dist/core/agent/stages/breakFinal.js.map +1 -1
  26. package/dist/core/agent/stages/callLLM.js +7 -5
  27. package/dist/core/agent/stages/callLLM.js.map +1 -1
  28. package/dist/core/agent/stages/prepareFinal.js +35 -2
  29. package/dist/core/agent/stages/prepareFinal.js.map +1 -1
  30. package/dist/core/agent/stages/route.js +9 -5
  31. package/dist/core/agent/stages/route.js.map +1 -1
  32. package/dist/core/agent/stages/toolCalls.js +7 -1
  33. package/dist/core/agent/stages/toolCalls.js.map +1 -1
  34. package/dist/esm/answer-validation/evidence.d.ts +12 -0
  35. package/dist/esm/answer-validation/evidence.js +117 -0
  36. package/dist/esm/answer-validation/evidence.js.map +1 -0
  37. package/dist/esm/answer-validation/index.d.ts +3 -0
  38. package/dist/esm/answer-validation/index.js +4 -0
  39. package/dist/esm/answer-validation/index.js.map +1 -0
  40. package/dist/esm/answer-validation/types.d.ts +94 -0
  41. package/dist/esm/answer-validation/types.js +20 -0
  42. package/dist/esm/answer-validation/types.js.map +1 -0
  43. package/dist/esm/answer-validation/validate.d.ts +15 -0
  44. package/dist/esm/answer-validation/validate.js +321 -0
  45. package/dist/esm/answer-validation/validate.js.map +1 -0
  46. package/dist/esm/cache/CacheGateDecider.js +7 -1
  47. package/dist/esm/cache/CacheGateDecider.js.map +1 -1
  48. package/dist/esm/core/Agent.d.ts +6 -1
  49. package/dist/esm/core/Agent.js +56 -2
  50. package/dist/esm/core/Agent.js.map +1 -1
  51. package/dist/esm/core/agent/AgentBuilder.d.ts +11 -0
  52. package/dist/esm/core/agent/AgentBuilder.js +27 -1
  53. package/dist/esm/core/agent/AgentBuilder.js.map +1 -1
  54. package/dist/esm/core/agent/buildAgentChart.d.ts +2 -0
  55. package/dist/esm/core/agent/buildAgentChart.js +19 -4
  56. package/dist/esm/core/agent/buildAgentChart.js.map +1 -1
  57. package/dist/esm/core/agent/buildDynamicAgentChart.js +17 -4
  58. package/dist/esm/core/agent/buildDynamicAgentChart.js.map +1 -1
  59. package/dist/esm/core/agent/outputEnforcement.d.ts +2 -0
  60. package/dist/esm/core/agent/outputEnforcement.js.map +1 -1
  61. package/dist/esm/core/agent/stages/answerValidation.d.ts +10 -0
  62. package/dist/esm/core/agent/stages/answerValidation.js +53 -0
  63. package/dist/esm/core/agent/stages/answerValidation.js.map +1 -0
  64. package/dist/esm/core/agent/stages/breakFinal.d.ts +6 -0
  65. package/dist/esm/core/agent/stages/breakFinal.js +9 -0
  66. package/dist/esm/core/agent/stages/breakFinal.js.map +1 -1
  67. package/dist/esm/core/agent/stages/callLLM.d.ts +2 -0
  68. package/dist/esm/core/agent/stages/callLLM.js +7 -5
  69. package/dist/esm/core/agent/stages/callLLM.js.map +1 -1
  70. package/dist/esm/core/agent/stages/prepareFinal.d.ts +7 -0
  71. package/dist/esm/core/agent/stages/prepareFinal.js +33 -1
  72. package/dist/esm/core/agent/stages/prepareFinal.js.map +1 -1
  73. package/dist/esm/core/agent/stages/route.js +9 -5
  74. package/dist/esm/core/agent/stages/route.js.map +1 -1
  75. package/dist/esm/core/agent/stages/toolCalls.js +7 -1
  76. package/dist/esm/core/agent/stages/toolCalls.js.map +1 -1
  77. package/dist/esm/core/agent/types.d.ts +6 -0
  78. package/dist/esm/index.d.ts +1 -0
  79. package/dist/esm/index.js +2 -0
  80. package/dist/esm/index.js.map +1 -1
  81. package/dist/index.js +4 -1
  82. package/dist/index.js.map +1 -1
  83. package/dist/types/answer-validation/evidence.d.ts +13 -0
  84. package/dist/types/answer-validation/evidence.d.ts.map +1 -0
  85. package/dist/types/answer-validation/index.d.ts +4 -0
  86. package/dist/types/answer-validation/index.d.ts.map +1 -0
  87. package/dist/types/answer-validation/types.d.ts +95 -0
  88. package/dist/types/answer-validation/types.d.ts.map +1 -0
  89. package/dist/types/answer-validation/validate.d.ts +16 -0
  90. package/dist/types/answer-validation/validate.d.ts.map +1 -0
  91. package/dist/types/cache/CacheGateDecider.d.ts.map +1 -1
  92. package/dist/types/core/Agent.d.ts +6 -1
  93. package/dist/types/core/Agent.d.ts.map +1 -1
  94. package/dist/types/core/agent/AgentBuilder.d.ts +11 -0
  95. package/dist/types/core/agent/AgentBuilder.d.ts.map +1 -1
  96. package/dist/types/core/agent/buildAgentChart.d.ts +2 -0
  97. package/dist/types/core/agent/buildAgentChart.d.ts.map +1 -1
  98. package/dist/types/core/agent/buildDynamicAgentChart.d.ts.map +1 -1
  99. package/dist/types/core/agent/outputEnforcement.d.ts +2 -0
  100. package/dist/types/core/agent/outputEnforcement.d.ts.map +1 -1
  101. package/dist/types/core/agent/stages/answerValidation.d.ts +11 -0
  102. package/dist/types/core/agent/stages/answerValidation.d.ts.map +1 -0
  103. package/dist/types/core/agent/stages/breakFinal.d.ts +6 -0
  104. package/dist/types/core/agent/stages/breakFinal.d.ts.map +1 -1
  105. package/dist/types/core/agent/stages/callLLM.d.ts +2 -0
  106. package/dist/types/core/agent/stages/callLLM.d.ts.map +1 -1
  107. package/dist/types/core/agent/stages/prepareFinal.d.ts +7 -0
  108. package/dist/types/core/agent/stages/prepareFinal.d.ts.map +1 -1
  109. package/dist/types/core/agent/stages/toolCalls.d.ts.map +1 -1
  110. package/dist/types/core/agent/types.d.ts +6 -0
  111. package/dist/types/core/agent/types.d.ts.map +1 -1
  112. package/dist/types/index.d.ts +1 -0
  113. package/dist/types/index.d.ts.map +1 -1
  114. package/package.json +2 -2
@@ -0,0 +1,117 @@
1
+ /** Bounded reads over the existing store. No new store, scope, or ref grammar. */
2
+ import { isArtifactRef } from '../artifacts/naming.js';
3
+ import { canonicalPayloadBytes, decodeCanonicalPayload, payloadShapeOf, } from '../artifacts/payload.js';
4
+ import { ArtifactIntegrityError, } from '../artifacts/types.js';
5
+ /** @internal Run-local read session. Closing invalidates even retained readers. */
6
+ export function createAnswerEvidenceResolver(store, scope, limits, signal) {
7
+ const boundScope = Object.freeze({ ...scope });
8
+ const cache = new Map();
9
+ const resolved = new Set();
10
+ let reads = 0;
11
+ let pendingReads = 0;
12
+ let reservedBytes = 0;
13
+ let closed = false;
14
+ let failure;
15
+ const unavailable = (reason) => {
16
+ failure ??= reason;
17
+ return { ok: false, reason };
18
+ };
19
+ const isClosed = () => closed || signal.aborted;
20
+ const load = async (ref, kind) => {
21
+ if (!store)
22
+ return unavailable('no-store');
23
+ try {
24
+ const described = await store.head(boundScope, ref);
25
+ if (isClosed())
26
+ return unavailable('closed');
27
+ if (described === null)
28
+ return unavailable('missing-or-expired');
29
+ // Memory stores may return their own metadata object: snapshot before the
30
+ // next await, and never hand that live value to an author callback.
31
+ const head = structuredClone(described);
32
+ if (head.ref !== ref || !Number.isSafeInteger(head.bytes) || head.bytes < 0)
33
+ return unavailable('invalid-record');
34
+ if (head.kind !== kind)
35
+ return unavailable('kind-mismatch');
36
+ if (head.bytes > limits.maxBytes - reservedBytes)
37
+ return unavailable('max-bytes');
38
+ reservedBytes += head.bytes; // Reserve before await: parallel reads share this budget.
39
+ const record = await store.get(boundScope, ref);
40
+ if (isClosed())
41
+ return unavailable('closed');
42
+ if (record === null)
43
+ return unavailable('missing-or-expired');
44
+ const meta = structuredClone(record.meta);
45
+ if (meta.ref !== ref ||
46
+ meta.kind !== kind ||
47
+ meta.bytes !== head.bytes ||
48
+ meta.digest !== head.digest ||
49
+ meta.createdAt !== head.createdAt ||
50
+ meta.expiresAt !== head.expiresAt ||
51
+ meta.mediaType !== head.mediaType)
52
+ return unavailable('invalid-record');
53
+ // get is the store's verifying read, including its own expiry clock.
54
+ // A nonconforming adapter may allocate too much inside get; the port has
55
+ // no bounded-read verb. Never deliver an understated parcel as accepted.
56
+ const bytes = canonicalPayloadBytes(record.data);
57
+ if (bytes.byteLength !== meta.bytes)
58
+ return unavailable('invalid-record');
59
+ if (bytes.byteLength > limits.maxBytes)
60
+ return unavailable('max-bytes');
61
+ const data = decodeCanonicalPayload(payloadShapeOf(record.data), bytes.slice());
62
+ if (isClosed())
63
+ return unavailable('closed');
64
+ resolved.add(ref);
65
+ return { ok: true, record: { meta, data } };
66
+ }
67
+ catch (error) {
68
+ if (isClosed())
69
+ return unavailable('closed');
70
+ return unavailable(error instanceof ArtifactIntegrityError ? 'digest-mismatch' : 'store-error');
71
+ }
72
+ };
73
+ const resolver = Object.freeze({
74
+ async resolve(ref, options) {
75
+ if (isClosed())
76
+ return unavailable('closed');
77
+ if (!isArtifactRef(ref) || options === null || typeof options !== 'object')
78
+ return unavailable('invalid-input');
79
+ const descriptor = Object.getOwnPropertyDescriptor(options, 'kind');
80
+ if (!descriptor ||
81
+ !('value' in descriptor) ||
82
+ typeof descriptor.value !== 'string' ||
83
+ descriptor.value.trim() === '' ||
84
+ descriptor.value.length > 256)
85
+ return unavailable('invalid-input');
86
+ const kind = descriptor.value;
87
+ const key = JSON.stringify([ref, kind]);
88
+ let pending = cache.get(key);
89
+ if (!pending) {
90
+ if (reads >= limits.maxReads)
91
+ return unavailable('max-reads');
92
+ reads++;
93
+ pendingReads++;
94
+ pending = load(ref, kind).finally(() => {
95
+ pendingReads--;
96
+ });
97
+ cache.set(key, pending);
98
+ }
99
+ const result = await pending;
100
+ if (isClosed())
101
+ return unavailable('closed');
102
+ // One callback cannot mutate a cached parcel subsequently used by another
103
+ // check. Metadata and data are detached on every successful delivery.
104
+ return result.ok ? { ok: true, record: structuredClone(result.record) } : { ...result };
105
+ },
106
+ });
107
+ return {
108
+ resolver,
109
+ resolvedRefs: () => [...resolved],
110
+ failureReason: () => failure ?? (pendingReads > 0 ? 'closed' : undefined),
111
+ close() {
112
+ closed = true;
113
+ cache.clear();
114
+ },
115
+ };
116
+ }
117
+ //# 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,3 @@
1
+ /** Explicit, bounded validation of schema-accepted JSON answers. */
2
+ export { AnswerValidationError, type AnswerCheck, type AnswerEvidenceRefusal, type AnswerEvidenceResolution, type AnswerEvidenceResolver, type AnswerValidationContext, type AnswerValidationLimits, type AnswerValidationOptions, type AnswerValidationReport, type AnswerValidationResult, type ResolvedAnswerValidation, } from './types.js';
3
+ export { resolveAnswerValidation, executeAnswerValidation } from './validate.js';
@@ -0,0 +1,4 @@
1
+ /** Explicit, bounded validation of schema-accepted JSON answers. */
2
+ export { AnswerValidationError, } from './types.js';
3
+ export { resolveAnswerValidation, executeAnswerValidation } from './validate.js';
4
+ //# 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,OAAO,EACL,qBAAqB,GAWtB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,uBAAuB,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAC"}
@@ -0,0 +1,94 @@
1
+ /** Explicit, author-supplied validation of a schema-accepted JSON answer. */
2
+ import type { ArtifactRecord, ArtifactRef } from '../artifacts/types.js';
3
+ import type { Disposition } from '../integrity/disposition/types.js';
4
+ /** One named obligation. Only checked-pass/checked-fail count as checks run. */
5
+ export interface AnswerCheck {
6
+ readonly id: string;
7
+ readonly disposition: Disposition;
8
+ /** Short diagnostic data, never interpreted as an instruction. */
9
+ readonly reason?: string;
10
+ readonly path?: string;
11
+ /** Must have resolved through this validation's artifact capability. */
12
+ readonly evidenceRefs?: readonly ArtifactRef[];
13
+ }
14
+ /** Why a requested artifact could not be delivered to the validator. */
15
+ export type AnswerEvidenceRefusal = 'closed' | 'invalid-input' | 'no-store' | 'missing-or-expired' | 'kind-mismatch' | 'digest-mismatch' | 'max-reads' | 'max-bytes' | 'invalid-record' | 'store-error';
16
+ /** A resolved parcel, or an explicit absence; absence never carries payloads. */
17
+ export type AnswerEvidenceResolution = {
18
+ readonly ok: true;
19
+ readonly record: ArtifactRecord;
20
+ } | {
21
+ readonly ok: false;
22
+ readonly reason: AnswerEvidenceRefusal;
23
+ };
24
+ /** Read-only, bounded, and pre-bound to the run's artifact scope. */
25
+ export interface AnswerEvidenceResolver {
26
+ /** Exact kind match, as with tool wants. No listing or automatic parent walk. */
27
+ resolve(ref: ArtifactRef, options: {
28
+ readonly kind: string;
29
+ }): Promise<AnswerEvidenceResolution>;
30
+ }
31
+ /** Capabilities for this invocation only; retained readers close on completion. */
32
+ export interface AnswerValidationContext {
33
+ readonly signal: AbortSignal;
34
+ readonly artifacts: AnswerEvidenceResolver;
35
+ }
36
+ /** Bounds are per validation, positive safe integers, with no unbounded mode. */
37
+ export interface AnswerValidationLimits {
38
+ /** Distinct ref+kind lookup attempts; duplicates share a cached read. Default 16. */
39
+ readonly maxReads?: number;
40
+ /** Total accepted/reserved artifact payload bytes. Default 4 MiB. */
41
+ readonly maxBytes?: number;
42
+ /** Maximum returned checks. Default 100. */
43
+ readonly maxChecks?: number;
44
+ /** UTF-8 bytes of input and canonical candidate, each bounded. Default 1 MiB. */
45
+ readonly maxCandidateBytes?: number;
46
+ /** Async deadline; cannot preempt synchronous author code. Default 5000 ms. */
47
+ readonly timeoutMs?: number;
48
+ }
49
+ /** The validator reports comparisons; the framework derives their outcome. */
50
+ export interface AnswerValidationResult {
51
+ readonly checks: readonly AnswerCheck[];
52
+ }
53
+ /** Opt-in contract. The callback cannot replace the accepted answer. */
54
+ export interface AnswerValidationOptions<T = unknown> {
55
+ readonly id: string;
56
+ readonly version: string;
57
+ /** Enforce withholds non-passing results; observe records them. Default enforce. */
58
+ readonly mode?: 'enforce' | 'observe';
59
+ readonly limits?: AnswerValidationLimits;
60
+ validate(candidate: Readonly<T>, context: AnswerValidationContext): AnswerValidationResult | Promise<AnswerValidationResult>;
61
+ }
62
+ /** Validated, detached configuration used by the runner. */
63
+ export interface ResolvedAnswerValidation {
64
+ readonly id: string;
65
+ readonly version: string;
66
+ readonly mode: 'enforce' | 'observe';
67
+ readonly limits: Required<AnswerValidationLimits>;
68
+ validate(candidate: unknown, context: AnswerValidationContext): AnswerValidationResult | Promise<AnswerValidationResult>;
69
+ }
70
+ /** Cloneable decision record. It contains no candidate or artifact payload. */
71
+ export interface AnswerValidationReport {
72
+ readonly validatorId: string;
73
+ readonly validatorVersion: string;
74
+ readonly mode: 'enforce' | 'observe';
75
+ readonly status: 'passed' | 'failed' | 'unverified';
76
+ readonly checked: number;
77
+ readonly failed: number;
78
+ readonly unreachable: number;
79
+ readonly notApplicable: number;
80
+ readonly checks: readonly AnswerCheck[];
81
+ readonly reason?: string;
82
+ /** SHA-256 of the exact canonical JSON content considered for delivery. */
83
+ readonly candidateDigest?: string;
84
+ /** Successfully resolved refs, distinct, not a count of semantic comparisons. */
85
+ readonly resolvedRefs: readonly ArtifactRef[];
86
+ /** The schema parser accepted and its output is a lossless canonical JSON value. */
87
+ readonly schemaAccepted: boolean;
88
+ }
89
+ /** An enforcing host refused delivery; diagnostic metadata only, never content. */
90
+ export declare class AnswerValidationError extends Error {
91
+ readonly code: "ERR_ANSWER_VALIDATION";
92
+ readonly report: AnswerValidationReport;
93
+ constructor(report: AnswerValidationReport);
94
+ }
@@ -0,0 +1,20 @@
1
+ /** An enforcing host refused delivery; diagnostic metadata only, never content. */
2
+ export class AnswerValidationError extends Error {
3
+ code = 'ERR_ANSWER_VALIDATION';
4
+ report;
5
+ constructor(report) {
6
+ super(`Answer validation '${report.validatorId}' did not pass (${report.status}).`);
7
+ this.name = 'AnswerValidationError';
8
+ this.report = Object.freeze({
9
+ ...report,
10
+ checks: Object.freeze(report.checks.map((check) => Object.freeze({
11
+ ...check,
12
+ ...(check.evidenceRefs !== undefined && {
13
+ evidenceRefs: Object.freeze([...check.evidenceRefs]),
14
+ }),
15
+ }))),
16
+ resolvedRefs: Object.freeze([...report.resolvedRefs]),
17
+ });
18
+ }
19
+ }
20
+ //# 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,MAAM,OAAO,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"}
@@ -0,0 +1,15 @@
1
+ /** One explicit JSON-answer validation; the runner owns when to invoke it. */
2
+ import { type OutputSchemaParser } from '../core/outputSchema.js';
3
+ import type { ArtifactScope, ArtifactStore } from '../artifacts/types.js';
4
+ import type { AnswerValidationOptions, AnswerValidationReport, ResolvedAnswerValidation } from './types.js';
5
+ /** Validate and snapshot an authored contract once, before running an agent. */
6
+ export declare function resolveAnswerValidation<T = unknown>(options: AnswerValidationOptions<T>): ResolvedAnswerValidation;
7
+ /**
8
+ * Validate once. Content is present only when delivery is permitted by this
9
+ * contract. It is the exact JSON string whose detached value was checked;
10
+ * callers must not reparse through a transforming schema or rewrite afterward.
11
+ */
12
+ export declare function executeAnswerValidation(raw: string, parser: OutputSchemaParser<unknown>, config: ResolvedAnswerValidation, store: ArtifactStore | undefined, scope: ArtifactScope, signal?: AbortSignal): Promise<{
13
+ report: AnswerValidationReport;
14
+ content?: string;
15
+ }>;
@@ -0,0 +1,321 @@
1
+ /** One explicit JSON-answer validation; the runner owns when to invoke it. */
2
+ import { applyOutputSchema } from '../core/outputSchema.js';
3
+ import { computeArtifactDigest } from '../artifacts/payload.js';
4
+ import { createAnswerEvidenceResolver } from './evidence.js';
5
+ const DEFAULT_LIMITS = Object.freeze({
6
+ maxReads: 16,
7
+ maxBytes: 4 * 1024 * 1024,
8
+ maxChecks: 100,
9
+ maxCandidateBytes: 1024 * 1024,
10
+ timeoutMs: 5000,
11
+ });
12
+ const encoder = new TextEncoder();
13
+ const dispositions = new Set(['checked-pass', 'checked-fail', 'not-applicable', 'unreachable']);
14
+ function ownData(value, allowed) {
15
+ if (value === null ||
16
+ typeof value !== 'object' ||
17
+ Array.isArray(value) ||
18
+ ![Object.prototype, null].includes(Object.getPrototypeOf(value)))
19
+ throw new Error('Expected a plain data object.');
20
+ const result = Object.create(null);
21
+ for (const key of Reflect.ownKeys(value)) {
22
+ if (typeof key !== 'string' || (allowed && !allowed.includes(key)))
23
+ throw new Error('Unknown property.');
24
+ const descriptor = Object.getOwnPropertyDescriptor(value, key);
25
+ if (!descriptor?.enumerable || !('value' in descriptor))
26
+ throw new Error('Expected an enumerable data property.');
27
+ Object.defineProperty(result, key, { value: descriptor.value, enumerable: true });
28
+ }
29
+ return result;
30
+ }
31
+ function text(value, max) {
32
+ if (typeof value !== 'string' || value.trim() === '' || value.length > max)
33
+ throw new Error('Expected bounded non-empty text.');
34
+ return value;
35
+ }
36
+ /** Validate and snapshot an authored contract once, before running an agent. */
37
+ export function resolveAnswerValidation(options) {
38
+ const source = ownData(options, ['id', 'version', 'mode', 'limits', 'validate']);
39
+ const id = text(source.id, 128);
40
+ const version = text(source.version, 128);
41
+ const mode = source.mode === undefined ? 'enforce' : source.mode;
42
+ if (mode !== 'enforce' && mode !== 'observe')
43
+ throw new Error('answerValidation.mode must be enforce or observe.');
44
+ if (typeof source.validate !== 'function')
45
+ throw new Error('answerValidation.validate must be a function.');
46
+ const validate = source.validate;
47
+ const supplied = source.limits === undefined ? {} : ownData(source.limits, Object.keys(DEFAULT_LIMITS));
48
+ const limits = { ...DEFAULT_LIMITS };
49
+ for (const key of Object.keys(DEFAULT_LIMITS)) {
50
+ if (Object.hasOwn(supplied, key)) {
51
+ const value = supplied[key];
52
+ if (typeof value !== 'number' ||
53
+ !Number.isSafeInteger(value) ||
54
+ value <= 0 ||
55
+ (key === 'timeoutMs' && value > 2147483647))
56
+ throw new Error(`answerValidation.limits.${key} must be a positive bounded integer.`);
57
+ limits[key] = value;
58
+ }
59
+ }
60
+ return Object.freeze({
61
+ id,
62
+ version,
63
+ mode,
64
+ limits: Object.freeze(limits),
65
+ validate: (candidate, context) => validate(candidate, context),
66
+ });
67
+ }
68
+ /** JSON copy without invoking toJSON/getters or silently dropping data. */
69
+ function jsonCopy(value, maxBytes, freeze) {
70
+ let budget = maxBytes;
71
+ const ancestors = new Set();
72
+ const spend = (bytes) => {
73
+ budget -= bytes;
74
+ if (budget < 0)
75
+ throw new Error('JSON byte limit.');
76
+ };
77
+ const string = (item) => {
78
+ if (item.length > budget)
79
+ throw new Error('JSON byte limit.');
80
+ spend(encoder.encode(JSON.stringify(item)).byteLength);
81
+ };
82
+ const copy = (item, depth) => {
83
+ if (depth > 100)
84
+ throw new Error('JSON nesting limit.');
85
+ if (item === null) {
86
+ spend(4);
87
+ return null;
88
+ }
89
+ if (typeof item === 'string') {
90
+ string(item);
91
+ return item;
92
+ }
93
+ if (typeof item === 'boolean') {
94
+ spend(item ? 4 : 5);
95
+ return item;
96
+ }
97
+ if (typeof item === 'number') {
98
+ if (!Number.isFinite(item) || Object.is(item, -0))
99
+ throw new Error('Non-lossless JSON number.');
100
+ spend(JSON.stringify(item).length);
101
+ return item;
102
+ }
103
+ if (typeof item !== 'object')
104
+ throw new Error('Non-JSON value.');
105
+ if (ancestors.has(item))
106
+ throw new Error('Cyclic JSON value.');
107
+ ancestors.add(item);
108
+ spend(2);
109
+ let output;
110
+ if (Array.isArray(item)) {
111
+ if (Object.getPrototypeOf(item) !== Array.prototype)
112
+ throw new Error('Non-JSON array prototype.');
113
+ if (item.length > budget + 1)
114
+ throw new Error('JSON byte limit.');
115
+ const keys = Reflect.ownKeys(item);
116
+ if (keys.length !== item.length + 1)
117
+ throw new Error('Sparse or decorated array.');
118
+ const result = [];
119
+ for (let index = 0; index < item.length; index++) {
120
+ const descriptor = Object.getOwnPropertyDescriptor(item, String(index));
121
+ if (!descriptor?.enumerable || !('value' in descriptor))
122
+ throw new Error('Sparse or accessor array.');
123
+ if (index)
124
+ spend(1);
125
+ result.push(copy(descriptor.value, depth + 1));
126
+ }
127
+ output = result;
128
+ }
129
+ else {
130
+ const fields = ownData(item);
131
+ const result = {};
132
+ let index = 0;
133
+ for (const key of Object.keys(fields)) {
134
+ if (index++)
135
+ spend(1);
136
+ string(key);
137
+ spend(1);
138
+ Object.defineProperty(result, key, {
139
+ value: copy(fields[key], depth + 1),
140
+ enumerable: true,
141
+ writable: true,
142
+ configurable: true,
143
+ });
144
+ }
145
+ output = result;
146
+ }
147
+ ancestors.delete(item);
148
+ return freeze ? Object.freeze(output) : output;
149
+ };
150
+ return copy(value, 0);
151
+ }
152
+ function readChecks(value, config, resolved) {
153
+ // Bound before copying. The copy rejects getters, class instances, cycles,
154
+ // decorated arrays and values JSON would otherwise silently discard.
155
+ const source = ownData(value, ['checks']);
156
+ if (!Array.isArray(source.checks) || source.checks.length > config.limits.maxChecks)
157
+ throw new Error('Invalid checks.');
158
+ const detached = jsonCopy(source.checks, config.limits.maxChecks * 4096, false);
159
+ const ids = new Set();
160
+ const refs = new Set(resolved);
161
+ return detached.map((raw) => {
162
+ const check = ownData(raw, ['id', 'disposition', 'reason', 'path', 'evidenceRefs']);
163
+ const id = text(check.id, 128);
164
+ if (ids.has(id) ||
165
+ typeof check.disposition !== 'string' ||
166
+ !dispositions.has(check.disposition))
167
+ throw new Error('Invalid check identity or disposition.');
168
+ ids.add(id);
169
+ const reason = check.reason === undefined ? undefined : text(check.reason, 1024);
170
+ const path = check.path;
171
+ if (path !== undefined && (typeof path !== 'string' || path.length > 256))
172
+ throw new Error('Invalid check path.');
173
+ let evidenceRefs;
174
+ if (check.evidenceRefs !== undefined) {
175
+ if (!Array.isArray(check.evidenceRefs) || check.evidenceRefs.length > config.limits.maxReads)
176
+ throw new Error('Invalid evidence references.');
177
+ evidenceRefs = check.evidenceRefs.map((ref) => {
178
+ if (typeof ref !== 'string' || !refs.has(ref))
179
+ throw new Error('Unresolved evidence reference.');
180
+ return ref;
181
+ });
182
+ if (new Set(evidenceRefs).size !== evidenceRefs.length)
183
+ throw new Error('Duplicate evidence reference.');
184
+ }
185
+ return Object.freeze({
186
+ id,
187
+ disposition: check.disposition,
188
+ ...(reason !== undefined && { reason }),
189
+ ...(path !== undefined && { path }),
190
+ ...(evidenceRefs !== undefined && { evidenceRefs: Object.freeze(evidenceRefs) }),
191
+ });
192
+ });
193
+ }
194
+ /**
195
+ * Validate once. Content is present only when delivery is permitted by this
196
+ * contract. It is the exact JSON string whose detached value was checked;
197
+ * callers must not reparse through a transforming schema or rewrite afterward.
198
+ */
199
+ export async function executeAnswerValidation(raw, parser, config, store, scope, signal) {
200
+ const controller = new AbortController();
201
+ const evidence = createAnswerEvidenceResolver(store, scope, config.limits, controller.signal);
202
+ let reason;
203
+ let schemaAccepted = false;
204
+ let canonical;
205
+ let candidateDigest;
206
+ let checks = [];
207
+ let active = true;
208
+ let stop;
209
+ const abort = () => {
210
+ reason = 'aborted';
211
+ controller.abort();
212
+ stop?.();
213
+ };
214
+ const timedOut = () => {
215
+ reason = 'timeout';
216
+ controller.abort();
217
+ stop?.();
218
+ };
219
+ const deadline = Date.now() + config.limits.timeoutMs;
220
+ const timer = setTimeout(timedOut, config.limits.timeoutMs);
221
+ signal?.addEventListener('abort', abort, { once: true });
222
+ if (signal?.aborted)
223
+ abort();
224
+ try {
225
+ const interrupted = new Promise((resolve) => {
226
+ stop = resolve;
227
+ if (controller.signal.aborted)
228
+ resolve();
229
+ });
230
+ const work = async () => {
231
+ if (controller.signal.aborted)
232
+ return;
233
+ let candidate;
234
+ try {
235
+ if (raw.length > config.limits.maxCandidateBytes ||
236
+ encoder.encode(raw).byteLength > config.limits.maxCandidateBytes) {
237
+ reason = 'candidate-limit';
238
+ return;
239
+ }
240
+ candidate = applyOutputSchema(raw, parser);
241
+ }
242
+ catch {
243
+ reason = 'schema-rejected';
244
+ return;
245
+ }
246
+ try {
247
+ candidate = jsonCopy(candidate, config.limits.maxCandidateBytes, true);
248
+ canonical = JSON.stringify(candidate);
249
+ schemaAccepted = true;
250
+ }
251
+ catch {
252
+ reason = 'non-json-candidate';
253
+ return;
254
+ }
255
+ if (Date.now() >= deadline) {
256
+ timedOut();
257
+ return;
258
+ }
259
+ try {
260
+ const digest = await computeArtifactDigest(canonical);
261
+ if (!active || controller.signal.aborted)
262
+ return;
263
+ candidateDigest = digest;
264
+ const returned = await config.validate(candidate, Object.freeze({ signal: controller.signal, artifacts: evidence.resolver }));
265
+ if (!active || controller.signal.aborted)
266
+ return;
267
+ if (Date.now() >= deadline) {
268
+ timedOut();
269
+ return;
270
+ }
271
+ try {
272
+ checks = readChecks(returned, config, evidence.resolvedRefs());
273
+ }
274
+ catch {
275
+ reason = 'invalid-validator-result';
276
+ }
277
+ }
278
+ catch {
279
+ if (active && !controller.signal.aborted)
280
+ reason = 'validator-error';
281
+ }
282
+ };
283
+ await Promise.race([work(), interrupted]);
284
+ }
285
+ finally {
286
+ active = false;
287
+ clearTimeout(timer);
288
+ signal?.removeEventListener('abort', abort);
289
+ evidence.close();
290
+ controller.abort();
291
+ }
292
+ const failed = checks.filter((check) => check.disposition === 'checked-fail').length;
293
+ const checked = failed + checks.filter((check) => check.disposition === 'checked-pass').length;
294
+ const unreachable = checks.filter((check) => check.disposition === 'unreachable').length;
295
+ const notApplicable = checks.filter((check) => check.disposition === 'not-applicable').length;
296
+ if (!reason && evidence.failureReason())
297
+ reason = `evidence-${evidence.failureReason()}`;
298
+ if (!reason && checked === 0)
299
+ reason = 'no-comparable-checks';
300
+ if (!reason && unreachable > 0)
301
+ reason = 'unreachable-checks';
302
+ const status = reason ? 'unverified' : failed > 0 ? 'failed' : 'passed';
303
+ const report = Object.freeze({
304
+ validatorId: config.id,
305
+ validatorVersion: config.version,
306
+ mode: config.mode,
307
+ status,
308
+ checked,
309
+ failed,
310
+ unreachable,
311
+ notApplicable,
312
+ checks: Object.freeze(checks),
313
+ schemaAccepted,
314
+ ...(reason !== undefined && { reason }),
315
+ ...(candidateDigest !== undefined && { candidateDigest }),
316
+ resolvedRefs: Object.freeze(evidence.resolvedRefs()),
317
+ });
318
+ const content = status === 'passed' || config.mode === 'observe' ? canonical ?? raw : undefined;
319
+ return { report, ...(content !== undefined && { content }) };
320
+ }
321
+ //# 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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"}
@@ -58,7 +58,13 @@ export function detectSkillChurn(history, windowSize = SKILL_CHURN_WINDOW, thres
58
58
  const recent = history.slice(-windowSize);
59
59
  const uniqueSkills = new Set();
60
60
  for (const s of recent) {
61
- if (s !== undefined)
61
+ // A skill id is a string; anything else is "no skill on this turn". The
62
+ // slot is `undefined` when the run had no skill yet — and it was `null`
63
+ // in every record written before footprintjs 9.24.0, whose scope
64
+ // round-tripped the array through JSON. That `null` counted here as a
65
+ // skill and turned caching OFF on the first turn after two real skills
66
+ // (a phantom churn; found by the 9.24.0 byte-identity run).
67
+ if (typeof s === 'string')
62
68
  uniqueSkills.add(s);
63
69
  }
64
70
  return uniqueSkills.size >= threshold;
@@ -1 +1 @@
1
- {"version":3,"file":"CacheGateDecider.js","sourceRoot":"","sources":["../../../src/cache/CacheGateDecider.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,EAAE,MAAM,EAAwC,MAAM,aAAa,CAAC;AA6B3E;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,GAAG,CAAC;AAElC;;;GAGG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAC;AAEpC;;;;GAIG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,CAAC;AAEvC;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAC9B,OAAwC,EACxC,aAAqB,kBAAkB,EACvC,YAAoB,qBAAqB;IAEzC,IAAI,OAAO,CAAC,MAAM,GAAG,SAAS;QAAE,OAAO,KAAK,CAAC,CAAC,yBAAyB;IACvE,MAAM,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,UAAU,CAAC,CAAC;IAC1C,MAAM,YAAY,GAAG,IAAI,GAAG,EAAU,CAAC;IACvC,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;QACvB,IAAI,CAAC,KAAK,SAAS;YAAE,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IAC3C,CAAC;IACD,OAAO,YAAY,CAAC,IAAI,IAAI,SAAS,CAAC;AACxC,CAAC;AAQD;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,eAAe,CAAC,KAAiC;IAC/D,OAAO,MAAM,CACX,KAAK,EACL;QACE;YACE,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,eAAe,KAAK,IAAI;YACvC,IAAI,EAAE,YAAY;YAClB,KAAK,EAAE,uDAAuD;SAC/D;QACD;YACE,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,aAAa,KAAK,SAAS,IAAI,CAAC,CAAC,aAAa,GAAG,cAAc;YAC9E,IAAI,EAAE,YAAY;YAClB,KAAK,EAAE,cAAc,cAAc,GAAG,GAAG,kBAAkB;SAC5D;QACD;YACE,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,gBAAgB,CAAC,CAAC,CAAC,YAAY,CAAC;YAC7C,IAAI,EAAE,YAAY;YAClB,KAAK,EAAE,iBAAiB,qBAAqB,0BAA0B,kBAAkB,SAAS;SACnG;KACF,EACD,eAAe,CAChB,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,UAAU,kBAAkB,CAChC,KAGE;IAEF,MAAM,GAAG,GAAG,KAAK,CAAC,qBAAqB,IAAI,EAAE,CAAC;IAC9C,MAAM,OAAO,GAAG,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IACjE,MAAM,KAAK,GAAG,KAAK,CAAC,YAAY,IAAI,EAAE,CAAC;IACvC,MAAM,IAAI,GAAG,CAAC,GAAG,KAAK,EAAE,OAAO,CAAC,CAAC;IACjC,+DAA+D;IAC/D,mDAAmD;IACnD,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,GAAG,kBAAkB,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,kBAAkB,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAClG,KAAK,CAAC,YAAY,GAAG,OAAO,CAAC;AAC/B,CAAC"}
1
+ {"version":3,"file":"CacheGateDecider.js","sourceRoot":"","sources":["../../../src/cache/CacheGateDecider.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,EAAE,MAAM,EAAwC,MAAM,aAAa,CAAC;AA6B3E;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,GAAG,CAAC;AAElC;;;GAGG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAC;AAEpC;;;;GAIG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,CAAC;AAEvC;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAC9B,OAAwC,EACxC,aAAqB,kBAAkB,EACvC,YAAoB,qBAAqB;IAEzC,IAAI,OAAO,CAAC,MAAM,GAAG,SAAS;QAAE,OAAO,KAAK,CAAC,CAAC,yBAAyB;IACvE,MAAM,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,UAAU,CAAC,CAAC;IAC1C,MAAM,YAAY,GAAG,IAAI,GAAG,EAAU,CAAC;IACvC,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;QACvB,wEAAwE;QACxE,wEAAwE;QACxE,iEAAiE;QACjE,sEAAsE;QACtE,uEAAuE;QACvE,4DAA4D;QAC5D,IAAI,OAAO,CAAC,KAAK,QAAQ;YAAE,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IACjD,CAAC;IACD,OAAO,YAAY,CAAC,IAAI,IAAI,SAAS,CAAC;AACxC,CAAC;AAQD;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,eAAe,CAAC,KAAiC;IAC/D,OAAO,MAAM,CACX,KAAK,EACL;QACE;YACE,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,eAAe,KAAK,IAAI;YACvC,IAAI,EAAE,YAAY;YAClB,KAAK,EAAE,uDAAuD;SAC/D;QACD;YACE,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,aAAa,KAAK,SAAS,IAAI,CAAC,CAAC,aAAa,GAAG,cAAc;YAC9E,IAAI,EAAE,YAAY;YAClB,KAAK,EAAE,cAAc,cAAc,GAAG,GAAG,kBAAkB;SAC5D;QACD;YACE,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,gBAAgB,CAAC,CAAC,CAAC,YAAY,CAAC;YAC7C,IAAI,EAAE,YAAY;YAClB,KAAK,EAAE,iBAAiB,qBAAqB,0BAA0B,kBAAkB,SAAS;SACnG;KACF,EACD,eAAe,CAChB,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,UAAU,kBAAkB,CAChC,KAGE;IAEF,MAAM,GAAG,GAAG,KAAK,CAAC,qBAAqB,IAAI,EAAE,CAAC;IAC9C,MAAM,OAAO,GAAG,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IACjE,MAAM,KAAK,GAAG,KAAK,CAAC,YAAY,IAAI,EAAE,CAAC;IACvC,MAAM,IAAI,GAAG,CAAC,GAAG,KAAK,EAAE,OAAO,CAAC,CAAC;IACjC,+DAA+D;IAC/D,mDAAmD;IACnD,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,GAAG,kBAAkB,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,kBAAkB,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAClG,KAAK,CAAC,YAAY,GAAG,OAAO,CAAC;AAC/B,CAAC"}