agentfootprint 9.61.1 → 9.63.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/dist/core/agent/evidence/gate.js +13 -0
- package/dist/core/agent/evidence/gate.js.map +1 -1
- package/dist/core/agent/repeatedCall.js +70 -11
- package/dist/core/agent/repeatedCall.js.map +1 -1
- package/dist/core/agent/stages/callLLM.js +47 -0
- package/dist/core/agent/stages/callLLM.js.map +1 -1
- package/dist/core/agent/stages/toolCalls.js +27 -1
- package/dist/core/agent/stages/toolCalls.js.map +1 -1
- package/dist/core/slots/buildToolsSlot.js +22 -3
- package/dist/core/slots/buildToolsSlot.js.map +1 -1
- package/dist/core/tools.js +1 -0
- package/dist/core/tools.js.map +1 -1
- package/dist/esm/core/agent/evidence/gate.d.ts +13 -0
- package/dist/esm/core/agent/evidence/gate.js +13 -0
- package/dist/esm/core/agent/evidence/gate.js.map +1 -1
- package/dist/esm/core/agent/repeatedCall.d.ts +45 -2
- package/dist/esm/core/agent/repeatedCall.js +70 -11
- package/dist/esm/core/agent/repeatedCall.js.map +1 -1
- package/dist/esm/core/agent/stages/callLLM.d.ts +7 -1
- package/dist/esm/core/agent/stages/callLLM.js +47 -0
- package/dist/esm/core/agent/stages/callLLM.js.map +1 -1
- package/dist/esm/core/agent/stages/toolCalls.js +27 -1
- package/dist/esm/core/agent/stages/toolCalls.js.map +1 -1
- package/dist/esm/core/slots/buildToolsSlot.js +22 -3
- package/dist/esm/core/slots/buildToolsSlot.js.map +1 -1
- package/dist/esm/core/tools.d.ts +53 -0
- package/dist/esm/core/tools.js +1 -0
- package/dist/esm/core/tools.js.map +1 -1
- package/dist/esm/events/payloads.d.ts +14 -0
- package/dist/esm/integrity/disposition/lifecycle.d.ts +13 -2
- package/dist/esm/integrity/disposition/lifecycle.js +77 -12
- package/dist/esm/integrity/disposition/lifecycle.js.map +1 -1
- package/dist/esm/integrity/unsupported-argument/check.d.ts +95 -0
- package/dist/esm/integrity/unsupported-argument/check.js +190 -0
- package/dist/esm/integrity/unsupported-argument/check.js.map +1 -0
- package/dist/esm/lib/trace-toolpack/traceToolpack.js +7 -5
- package/dist/esm/lib/trace-toolpack/traceToolpack.js.map +1 -1
- package/dist/esm/recorders/observability/commentary/commentaryTemplates.js +15 -1
- package/dist/esm/recorders/observability/commentary/commentaryTemplates.js.map +1 -1
- package/dist/integrity/disposition/lifecycle.js +79 -14
- package/dist/integrity/disposition/lifecycle.js.map +1 -1
- package/dist/integrity/unsupported-argument/check.js +195 -0
- package/dist/integrity/unsupported-argument/check.js.map +1 -0
- package/dist/lib/trace-toolpack/traceToolpack.js +7 -5
- package/dist/lib/trace-toolpack/traceToolpack.js.map +1 -1
- package/dist/recorders/observability/commentary/commentaryTemplates.js +15 -1
- package/dist/recorders/observability/commentary/commentaryTemplates.js.map +1 -1
- package/dist/types/core/agent/evidence/gate.d.ts +13 -0
- package/dist/types/core/agent/evidence/gate.d.ts.map +1 -1
- package/dist/types/core/agent/repeatedCall.d.ts +45 -2
- package/dist/types/core/agent/repeatedCall.d.ts.map +1 -1
- package/dist/types/core/agent/stages/callLLM.d.ts +7 -1
- package/dist/types/core/agent/stages/callLLM.d.ts.map +1 -1
- package/dist/types/core/agent/stages/toolCalls.d.ts.map +1 -1
- package/dist/types/core/slots/buildToolsSlot.d.ts.map +1 -1
- package/dist/types/core/tools.d.ts +53 -0
- package/dist/types/core/tools.d.ts.map +1 -1
- package/dist/types/events/payloads.d.ts +14 -0
- package/dist/types/events/payloads.d.ts.map +1 -1
- package/dist/types/integrity/disposition/lifecycle.d.ts +13 -2
- package/dist/types/integrity/disposition/lifecycle.d.ts.map +1 -1
- package/dist/types/integrity/unsupported-argument/check.d.ts +96 -0
- package/dist/types/integrity/unsupported-argument/check.d.ts.map +1 -0
- package/dist/types/lib/trace-toolpack/traceToolpack.d.ts.map +1 -1
- package/dist/types/recorders/observability/commentary/commentaryTemplates.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tools.js","sourceRoot":"","sources":["../../../src/core/tools.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAKxC,OAAO,EAAE,eAAe,EAAkB,MAAM,uBAAuB,CAAC;AAGxE,OAAO,EAAE,cAAc,EAAwB,MAAM,2BAA2B,CAAC;AACjF,OAAO,EAAE,kBAAkB,EAAqB,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"tools.js","sourceRoot":"","sources":["../../../src/core/tools.ts"],"names":[],"mappings":"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"}
|
|
@@ -1368,6 +1368,20 @@ export interface ToolRepeatedCallPayload {
|
|
|
1368
1368
|
readonly argsFingerprint: string;
|
|
1369
1369
|
/** Digest of the result — never the result. */
|
|
1370
1370
|
readonly resultFingerprint: string;
|
|
1371
|
+
/**
|
|
1372
|
+
* Which fingerprint decided the match, when it was not the usual pair
|
|
1373
|
+
* (9.62.0). `'arguments'` means this landing matched on the tool's
|
|
1374
|
+
* arguments ALONE — the tool declared `repeatedWhen: 'arguments'`
|
|
1375
|
+
* (`core/tools.ts`), so `resultFingerprint` above is still a true digest
|
|
1376
|
+
* of what came back but played no part in deciding this was a repeat.
|
|
1377
|
+
*
|
|
1378
|
+
* Additive and default-omitted: every event this library emitted before
|
|
1379
|
+
* 9.62.0, and every event for a tool that has not opted in, carries no
|
|
1380
|
+
* `mode` key at all — not `mode: undefined` written out, the key simply
|
|
1381
|
+
* absent — so an existing payload-key-set assertion anywhere does not see
|
|
1382
|
+
* a new field appear under it.
|
|
1383
|
+
*/
|
|
1384
|
+
readonly mode?: 'arguments';
|
|
1371
1385
|
}
|
|
1372
1386
|
/**
|
|
1373
1387
|
* A tool looked and found nothing, and said so with `absent(…)`.
|
|
@@ -8,8 +8,11 @@
|
|
|
8
8
|
* Role: a check is registered exactly when its preconditions exist on
|
|
9
9
|
* THIS agent (wire: always — every run calls the model;
|
|
10
10
|
* compose-invariant: a mount kernel is configured; dangling: at
|
|
11
|
-
* least one tool declared `argumentsFrom
|
|
12
|
-
*
|
|
11
|
+
* least one tool declared `argumentsFrom`, which arms BOTH the
|
|
12
|
+
* compose-seam dangling-reference check and the choice-seam
|
|
13
|
+
* unsupported-argument check off the same declaration).
|
|
14
|
+
* Registration is what makes silence auditable — an unregistered
|
|
15
|
+
* check is honest
|
|
13
16
|
* absence, a registered one that never notes is the wiring rot
|
|
14
17
|
* `assertAlive` exists to name.
|
|
15
18
|
*
|
|
@@ -26,6 +29,14 @@ export type IntegrityPosture = 'observe' | 'dev';
|
|
|
26
29
|
export interface IntegrityChecksPresent {
|
|
27
30
|
readonly wire: boolean;
|
|
28
31
|
readonly composeInvariant: boolean;
|
|
32
|
+
/**
|
|
33
|
+
* At least one tool declared `Tool.argumentsFrom`. ONE FLAG, TWO CHECKS
|
|
34
|
+
* (9.63.0): the same declaration arms `dangling-reference` at the compose
|
|
35
|
+
* seam and `unsupported-argument` at the choice seam — one asks whether the
|
|
36
|
+
* ground is still in reach while the tool is offered, the other whether the
|
|
37
|
+
* value the model chose came from that ground when it was called. They are
|
|
38
|
+
* not separated here because nothing can arm one without arming the other.
|
|
39
|
+
*/
|
|
29
40
|
readonly dangling: boolean;
|
|
30
41
|
/** A `.claims()` contract is declared (9.61.0). */
|
|
31
42
|
readonly claim?: boolean;
|
|
@@ -8,8 +8,11 @@
|
|
|
8
8
|
* Role: a check is registered exactly when its preconditions exist on
|
|
9
9
|
* THIS agent (wire: always — every run calls the model;
|
|
10
10
|
* compose-invariant: a mount kernel is configured; dangling: at
|
|
11
|
-
* least one tool declared `argumentsFrom
|
|
12
|
-
*
|
|
11
|
+
* least one tool declared `argumentsFrom`, which arms BOTH the
|
|
12
|
+
* compose-seam dangling-reference check and the choice-seam
|
|
13
|
+
* unsupported-argument check off the same declaration).
|
|
14
|
+
* Registration is what makes silence auditable — an unregistered
|
|
15
|
+
* check is honest
|
|
13
16
|
* absence, a registered one that never notes is the wiring rot
|
|
14
17
|
* `assertAlive` exists to name.
|
|
15
18
|
*
|
|
@@ -24,6 +27,7 @@ import { dispositionLedger } from './ledger.js';
|
|
|
24
27
|
import { invariantViolationsOf } from '../invariant-violation/check.js';
|
|
25
28
|
import { wireViolationsOf } from '../invariant-violation/wire.js';
|
|
26
29
|
import { danglingReferencesOf } from '../dangling-reference/check.js';
|
|
30
|
+
import { unsupportedArgumentsOf } from '../unsupported-argument/check.js';
|
|
27
31
|
import { unsupportedClaimsOf } from '../unsupported-claim/check.js';
|
|
28
32
|
/**
|
|
29
33
|
* Start one run's ledger: register the present checks and, in dev posture,
|
|
@@ -33,35 +37,96 @@ export function beginIntegrityRun(present, posture) {
|
|
|
33
37
|
const ledger = dispositionLedger();
|
|
34
38
|
if (present.wire)
|
|
35
39
|
ledger.register('invariant-violation', 'wire');
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
40
|
+
// An UNARMED check is a row, not a silence.
|
|
41
|
+
//
|
|
42
|
+
// Every optional check is registered whether or not this run armed it, and
|
|
43
|
+
// one the app never opted into is noted `not-applicable` immediately —
|
|
44
|
+
// which is the literal truth: the check looked for its subject (a maps
|
|
45
|
+
// plan, a tool declaring `argumentsFrom`, a claims contract) and this run
|
|
46
|
+
// has none. Before this, an unarmed check filed NO row at all, and the
|
|
47
|
+
// always-on `wire` row sat there green beside it; read casually — which is
|
|
48
|
+
// exactly how the library's own reference agent got read for weeks — a run
|
|
49
|
+
// that checked nothing was indistinguishable from a run where everything
|
|
50
|
+
// passed.
|
|
51
|
+
//
|
|
52
|
+
// Per check, deliberately, rather than one all-or-nothing block for the
|
|
53
|
+
// case where the app armed none of them. The common shape in the field is
|
|
54
|
+
// PARTIAL: a consumer declares `argumentsFrom`, arms the two checks that
|
|
55
|
+
// field carries, and never learns that the rest never ran. An
|
|
56
|
+
// all-or-nothing block goes quiet
|
|
57
|
+
// the moment one check is armed, which is precisely when the remaining
|
|
58
|
+
// blind spots start to matter.
|
|
59
|
+
//
|
|
60
|
+
// This reuses the ledger's existing vocabulary rather than adding a flag or
|
|
61
|
+
// a second channel, so the rows travel through `report()`, the
|
|
62
|
+
// `agentfootprint.integrity.disposition` event and `find_context_errors`'s
|
|
63
|
+
// partial-coverage headline with no change at any consumer. And
|
|
64
|
+
// `notApplicable` counts as touched in `assertAlive`'s theorem, so an
|
|
65
|
+
// unarmed check can never itself trip `CheckerDeadError`: not opting in is
|
|
66
|
+
// not wiring rot, and the two must stay tellable apart.
|
|
67
|
+
const armed = (kind, seam, isArmed) => {
|
|
68
|
+
ledger.register(kind, seam);
|
|
69
|
+
if (!isArmed)
|
|
70
|
+
ledger.note(kind, seam, 'not-applicable');
|
|
71
|
+
};
|
|
72
|
+
armed('invariant-violation', 'compose', present.composeInvariant === true);
|
|
73
|
+
armed('dangling-reference', 'compose', present.dangling === true);
|
|
74
|
+
armed('unsupported-argument', 'choice', present.dangling === true);
|
|
75
|
+
armed('unsupported-claim', 'claim', present.claim === true);
|
|
42
76
|
if (posture !== 'dev')
|
|
43
77
|
return ledger;
|
|
44
|
-
// The canaries — one known-bad fixture per
|
|
78
|
+
// The canaries — one known-bad fixture per REGISTERED check, through the
|
|
45
79
|
// REAL pure function. Epoch -1 marks them as no run iteration's business.
|
|
80
|
+
//
|
|
81
|
+
// Registered, note, and no longer only armed. The four optional checks now
|
|
82
|
+
// file a row whether or not this run had a subject for them, and a
|
|
83
|
+
// `not-applicable` row with no canary beside it is the exact ambiguity this
|
|
84
|
+
// whole change set exists to remove: a checker that has ROTTED and a checker
|
|
85
|
+
// that simply had nothing to look at produce an identical row. The canary is
|
|
86
|
+
// the only thing that tells them apart, and it costs a pure function call on
|
|
87
|
+
// a fixture.
|
|
88
|
+
//
|
|
89
|
+
// The alternative — canary only what the app armed — reads reasonable and is
|
|
90
|
+
// wrong for the same reason a green report from a check that never ran is
|
|
91
|
+
// decoration: the moment somebody DOES arm `.claims()`, they inherit whatever
|
|
92
|
+
// state that checker rotted into while nobody was looking, and nothing in the
|
|
93
|
+
// record will say how long it had been dead. Dev posture is a library-health
|
|
94
|
+
// instrument, so it proves the machinery, not this run's subset of it.
|
|
46
95
|
if (present.wire) {
|
|
47
96
|
ledger.noteSynthetic('invariant-violation', 'wire', 'minted');
|
|
48
97
|
const caught = wireViolationsOf({ names: ['canary_tool'], provenance: 'canary: composed frame' }, { names: ['canary_tool', 'canary_ghost'], provenance: 'canary: wire' }, -1);
|
|
49
98
|
if (caught.length > 0)
|
|
50
99
|
ledger.noteSynthetic('invariant-violation', 'wire', 'caught');
|
|
51
100
|
}
|
|
52
|
-
|
|
101
|
+
{
|
|
53
102
|
ledger.noteSynthetic('invariant-violation', 'compose', 'minted');
|
|
54
103
|
const caught = invariantViolationsOf({ mapId: 'canary-map', standing: 'parked', iteration: -1, ownedToolNames: ['canary_tool'] }, { names: ['canary_tool'], provenance: 'canary: serving' });
|
|
55
104
|
if (caught.length > 0)
|
|
56
105
|
ledger.noteSynthetic('invariant-violation', 'compose', 'caught');
|
|
57
106
|
}
|
|
58
|
-
|
|
107
|
+
{
|
|
59
108
|
ledger.noteSynthetic('dangling-reference', 'compose', 'minted');
|
|
60
109
|
const caught = danglingReferencesOf([{ name: 'canary_tool', argumentsFrom: ['canary_ground'] }], new Set(['canary_ground']), new Set(), -1);
|
|
61
110
|
if (caught.length > 0)
|
|
62
111
|
ledger.noteSynthetic('dangling-reference', 'compose', 'caught');
|
|
63
112
|
}
|
|
64
|
-
|
|
113
|
+
{
|
|
114
|
+
// The choice-seam canary: an ARMED call carrying a value the corpus does
|
|
115
|
+
// not contain. The fixture's corpus deliberately says nothing that could
|
|
116
|
+
// match, so a check that still finds nothing is a check that cannot fire.
|
|
117
|
+
ledger.noteSynthetic('unsupported-argument', 'choice', 'minted');
|
|
118
|
+
const caught = unsupportedArgumentsOf([
|
|
119
|
+
{
|
|
120
|
+
toolName: 'canary_tool',
|
|
121
|
+
toolCallId: 'canary',
|
|
122
|
+
args: { id: 'canary-fabricated-id' },
|
|
123
|
+
argumentsFrom: ['canary_ground'],
|
|
124
|
+
},
|
|
125
|
+
], { grounded: ['canary: this frame served no identifiers'], assistant: [] }, -1);
|
|
126
|
+
if (caught.length > 0)
|
|
127
|
+
ledger.noteSynthetic('unsupported-argument', 'choice', 'caught');
|
|
128
|
+
}
|
|
129
|
+
{
|
|
65
130
|
ledger.noteSynthetic('unsupported-claim', 'claim', 'minted');
|
|
66
131
|
const caught = unsupportedClaimsOf([{ answerField: 'canary', entity: 'canary-entity', field: 'canary-field' }], [
|
|
67
132
|
{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lifecycle.js","sourceRoot":"","sources":["../../../../src/integrity/disposition/lifecycle.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"lifecycle.js","sourceRoot":"","sources":["../../../../src/integrity/disposition/lifecycle.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* unsupported-argument — the model ACTED on a value nothing served, at the
|
|
3
|
+
* CHOICE seam.
|
|
4
|
+
*
|
|
5
|
+
* Pattern: pure function over (the calls, the frame they were chosen from);
|
|
6
|
+
* the domain check.
|
|
7
|
+
* Role: the decidable fragment of "did the model bind this reference to
|
|
8
|
+
* something the run actually served?". The measured failure: on the
|
|
9
|
+
* second turn of a triage conversation the window had dropped the
|
|
10
|
+
* user message carrying the true entity id and kept the assistant's
|
|
11
|
+
* own rendered answer. Asked for the status of "that machine", the
|
|
12
|
+
* model resolved the reference out of its OWN prior prose, took a
|
|
13
|
+
* truncated job-name fragment for a machine name, called the lookup
|
|
14
|
+
* tool with it, got an honest "nothing found", and told the person
|
|
15
|
+
* their protected machine had no backup record. Every shipped rail
|
|
16
|
+
* passed honestly — the coverage envelope, the absence envelope and
|
|
17
|
+
* the evidence gate all held, because every value in the answer
|
|
18
|
+
* really WAS grounded. The defect was the REFERENT, bound wrong at
|
|
19
|
+
* the argument, and the argument was the one seam with no check.
|
|
20
|
+
*
|
|
21
|
+
* DECLARED, NEVER INFERRED — the `argumentsFrom` precedent, second use. A
|
|
22
|
+
* tool is this check's subject only because its author said its arguments
|
|
23
|
+
* come from another tool's results; a tool that declares nothing is never
|
|
24
|
+
* examined, which is the whole zero-delta story. One declaration now arms two
|
|
25
|
+
* seams: `dangling-reference` asks whether the ground is still in reach when
|
|
26
|
+
* the tool is OFFERED, this asks whether the value the model chose came from
|
|
27
|
+
* that ground when the tool is CALLED.
|
|
28
|
+
*
|
|
29
|
+
* ASSISTANT TEXT IS NOT GROUND, and that is the entire idea. The system
|
|
30
|
+
* prompt, the user's messages and every tool result are things the RUN put in
|
|
31
|
+
* front of the model. Its own earlier turns are things it wrote. A value whose
|
|
32
|
+
* only source is the model's own rendered prose has been re-derived from a
|
|
33
|
+
* rendering rather than read from evidence, and re-deriving is exactly how a
|
|
34
|
+
* truncated job name becomes a machine name.
|
|
35
|
+
*
|
|
36
|
+
* THE FENCES, stated because they are the check's honesty:
|
|
37
|
+
* - NON-STRINGS ARE NEVER CHECKED. Numbers, booleans and null are not
|
|
38
|
+
* identifier-shaped, and substring-grounding them would accuse every
|
|
39
|
+
* literal the model legitimately computed.
|
|
40
|
+
* - VALUES UNDER FOUR CHARACTERS ARE NEVER CHECKED. Below that, substring
|
|
41
|
+
* matching is noise in both directions — 'up' and 'a1' land inside
|
|
42
|
+
* unrelated words in any corpus.
|
|
43
|
+
* - SERVED ANYWHERE PASSES, case-insensitively. The value need only appear
|
|
44
|
+
* inside SOME served string; see the README's stated leniency.
|
|
45
|
+
* - DECLARED VOCABULARY PASSES. A value the tool's own `inputSchema` lists in
|
|
46
|
+
* an `enum` was served BY THE SCHEMA — the model read it off the tool
|
|
47
|
+
* definition, not out of its own prose.
|
|
48
|
+
* Two states remain, and they file DIFFERENT messages because they call for
|
|
49
|
+
* different fixes: grounded only in the model's own prose (re-fetch the real
|
|
50
|
+
* ground), and grounded nowhere in the window at all (nothing served it).
|
|
51
|
+
*
|
|
52
|
+
* Detection only. Nothing here blocks, rewrites or delays a call.
|
|
53
|
+
*/
|
|
54
|
+
import type { ContextError } from '../finding/types.js';
|
|
55
|
+
/** One tool call the model chose to make, with the arming that makes it checkable. */
|
|
56
|
+
export interface ArgumentChoice {
|
|
57
|
+
readonly toolName: string;
|
|
58
|
+
/** The provider's id for this call — what the witness points a reader at. */
|
|
59
|
+
readonly toolCallId: string;
|
|
60
|
+
readonly args: Readonly<Record<string, unknown>>;
|
|
61
|
+
/** `Tool.argumentsFrom` — the tools whose results were meant to ground these arguments. */
|
|
62
|
+
readonly argumentsFrom: readonly string[];
|
|
63
|
+
/**
|
|
64
|
+
* Values the tool's own `inputSchema` declares in an `enum`. Best-effort and
|
|
65
|
+
* FLAT (see {@link declaredEnumValuesOf}): a value declared for one field
|
|
66
|
+
* excuses that value at any field of the same tool. Deliberately lenient on
|
|
67
|
+
* an accusation boundary.
|
|
68
|
+
*/
|
|
69
|
+
readonly declaredEnums?: ReadonlySet<string>;
|
|
70
|
+
}
|
|
71
|
+
/** The frame the model chose from, split by whether it can GROUND anything. */
|
|
72
|
+
export interface ChoiceCorpus {
|
|
73
|
+
/** System prompt, user messages, tool results — everything the RUN served. */
|
|
74
|
+
readonly grounded: readonly string[];
|
|
75
|
+
/** The model's own earlier turns. Never ground: this is what the defect is made of. */
|
|
76
|
+
readonly assistant: readonly string[];
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Best-effort: every string an `enum` array declares anywhere in a tool's
|
|
80
|
+
* `inputSchema`. Flat by design — a per-path map would be more precise, and on
|
|
81
|
+
* an accusation boundary the lenient direction is the safe one. An absent or
|
|
82
|
+
* non-object schema yields an empty set, which simply means no enum fence.
|
|
83
|
+
*/
|
|
84
|
+
export declare function declaredEnumValuesOf(schema: unknown): ReadonlySet<string>;
|
|
85
|
+
/**
|
|
86
|
+
* Check every armed call's identifier-like string arguments against the frame
|
|
87
|
+
* the model chose from.
|
|
88
|
+
*
|
|
89
|
+
* @param calls the ARMED tool calls of one response — a caller filters by
|
|
90
|
+
* `argumentsFrom` before calling; nothing here re-decides who is a subject.
|
|
91
|
+
* @param corpus the exact request this response was assembled from, split into
|
|
92
|
+
* what the run served and what the model itself wrote.
|
|
93
|
+
* @param epoch the run iteration, stamped on every witness.
|
|
94
|
+
*/
|
|
95
|
+
export declare function unsupportedArgumentsOf(calls: readonly ArgumentChoice[], corpus: ChoiceCorpus, epoch: number): readonly ContextError[];
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* unsupported-argument — the model ACTED on a value nothing served, at the
|
|
3
|
+
* CHOICE seam.
|
|
4
|
+
*
|
|
5
|
+
* Pattern: pure function over (the calls, the frame they were chosen from);
|
|
6
|
+
* the domain check.
|
|
7
|
+
* Role: the decidable fragment of "did the model bind this reference to
|
|
8
|
+
* something the run actually served?". The measured failure: on the
|
|
9
|
+
* second turn of a triage conversation the window had dropped the
|
|
10
|
+
* user message carrying the true entity id and kept the assistant's
|
|
11
|
+
* own rendered answer. Asked for the status of "that machine", the
|
|
12
|
+
* model resolved the reference out of its OWN prior prose, took a
|
|
13
|
+
* truncated job-name fragment for a machine name, called the lookup
|
|
14
|
+
* tool with it, got an honest "nothing found", and told the person
|
|
15
|
+
* their protected machine had no backup record. Every shipped rail
|
|
16
|
+
* passed honestly — the coverage envelope, the absence envelope and
|
|
17
|
+
* the evidence gate all held, because every value in the answer
|
|
18
|
+
* really WAS grounded. The defect was the REFERENT, bound wrong at
|
|
19
|
+
* the argument, and the argument was the one seam with no check.
|
|
20
|
+
*
|
|
21
|
+
* DECLARED, NEVER INFERRED — the `argumentsFrom` precedent, second use. A
|
|
22
|
+
* tool is this check's subject only because its author said its arguments
|
|
23
|
+
* come from another tool's results; a tool that declares nothing is never
|
|
24
|
+
* examined, which is the whole zero-delta story. One declaration now arms two
|
|
25
|
+
* seams: `dangling-reference` asks whether the ground is still in reach when
|
|
26
|
+
* the tool is OFFERED, this asks whether the value the model chose came from
|
|
27
|
+
* that ground when the tool is CALLED.
|
|
28
|
+
*
|
|
29
|
+
* ASSISTANT TEXT IS NOT GROUND, and that is the entire idea. The system
|
|
30
|
+
* prompt, the user's messages and every tool result are things the RUN put in
|
|
31
|
+
* front of the model. Its own earlier turns are things it wrote. A value whose
|
|
32
|
+
* only source is the model's own rendered prose has been re-derived from a
|
|
33
|
+
* rendering rather than read from evidence, and re-deriving is exactly how a
|
|
34
|
+
* truncated job name becomes a machine name.
|
|
35
|
+
*
|
|
36
|
+
* THE FENCES, stated because they are the check's honesty:
|
|
37
|
+
* - NON-STRINGS ARE NEVER CHECKED. Numbers, booleans and null are not
|
|
38
|
+
* identifier-shaped, and substring-grounding them would accuse every
|
|
39
|
+
* literal the model legitimately computed.
|
|
40
|
+
* - VALUES UNDER FOUR CHARACTERS ARE NEVER CHECKED. Below that, substring
|
|
41
|
+
* matching is noise in both directions — 'up' and 'a1' land inside
|
|
42
|
+
* unrelated words in any corpus.
|
|
43
|
+
* - SERVED ANYWHERE PASSES, case-insensitively. The value need only appear
|
|
44
|
+
* inside SOME served string; see the README's stated leniency.
|
|
45
|
+
* - DECLARED VOCABULARY PASSES. A value the tool's own `inputSchema` lists in
|
|
46
|
+
* an `enum` was served BY THE SCHEMA — the model read it off the tool
|
|
47
|
+
* definition, not out of its own prose.
|
|
48
|
+
* Two states remain, and they file DIFFERENT messages because they call for
|
|
49
|
+
* different fixes: grounded only in the model's own prose (re-fetch the real
|
|
50
|
+
* ground), and grounded nowhere in the window at all (nothing served it).
|
|
51
|
+
*
|
|
52
|
+
* Detection only. Nothing here blocks, rewrites or delays a call.
|
|
53
|
+
*/
|
|
54
|
+
/** Below this, substring matching says nothing. */
|
|
55
|
+
const MIN_CHECKED_LENGTH = 4;
|
|
56
|
+
/** Longest a single value is quoted at inside a message. */
|
|
57
|
+
const MAX_QUOTED_CHARS = 80;
|
|
58
|
+
/** Deepest a schema is walked for `enum` declarations. */
|
|
59
|
+
const MAX_SCHEMA_DEPTH = 8;
|
|
60
|
+
function clip(value) {
|
|
61
|
+
return value.length <= MAX_QUOTED_CHARS ? value : `${value.slice(0, MAX_QUOTED_CHARS - 1)}…`;
|
|
62
|
+
}
|
|
63
|
+
/** Every string leaf of an arguments object, with its dot-path. */
|
|
64
|
+
function* stringLeaves(node, path) {
|
|
65
|
+
if (typeof node === 'string') {
|
|
66
|
+
yield { path, value: node };
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
if (Array.isArray(node)) {
|
|
70
|
+
for (let i = 0; i < node.length; i++) {
|
|
71
|
+
yield* stringLeaves(node[i], path === '' ? String(i) : `${path}.${String(i)}`);
|
|
72
|
+
}
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
if (node !== null && typeof node === 'object') {
|
|
76
|
+
for (const [key, value] of Object.entries(node)) {
|
|
77
|
+
yield* stringLeaves(value, path === '' ? key : `${path}.${key}`);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Best-effort: every string an `enum` array declares anywhere in a tool's
|
|
83
|
+
* `inputSchema`. Flat by design — a per-path map would be more precise, and on
|
|
84
|
+
* an accusation boundary the lenient direction is the safe one. An absent or
|
|
85
|
+
* non-object schema yields an empty set, which simply means no enum fence.
|
|
86
|
+
*/
|
|
87
|
+
export function declaredEnumValuesOf(schema) {
|
|
88
|
+
const values = new Set();
|
|
89
|
+
const walk = (node, depth) => {
|
|
90
|
+
if (depth > MAX_SCHEMA_DEPTH || node === null || typeof node !== 'object')
|
|
91
|
+
return;
|
|
92
|
+
if (Array.isArray(node)) {
|
|
93
|
+
for (const item of node)
|
|
94
|
+
walk(item, depth + 1);
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
const obj = node;
|
|
98
|
+
if (Array.isArray(obj.enum)) {
|
|
99
|
+
for (const declared of obj.enum)
|
|
100
|
+
if (typeof declared === 'string')
|
|
101
|
+
values.add(declared);
|
|
102
|
+
}
|
|
103
|
+
for (const value of Object.values(obj))
|
|
104
|
+
walk(value, depth + 1);
|
|
105
|
+
};
|
|
106
|
+
walk(schema, 0);
|
|
107
|
+
return values;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Check every armed call's identifier-like string arguments against the frame
|
|
111
|
+
* the model chose from.
|
|
112
|
+
*
|
|
113
|
+
* @param calls the ARMED tool calls of one response — a caller filters by
|
|
114
|
+
* `argumentsFrom` before calling; nothing here re-decides who is a subject.
|
|
115
|
+
* @param corpus the exact request this response was assembled from, split into
|
|
116
|
+
* what the run served and what the model itself wrote.
|
|
117
|
+
* @param epoch the run iteration, stamped on every witness.
|
|
118
|
+
*/
|
|
119
|
+
export function unsupportedArgumentsOf(calls, corpus, epoch) {
|
|
120
|
+
const findings = [];
|
|
121
|
+
if (calls.length === 0)
|
|
122
|
+
return findings;
|
|
123
|
+
const served = corpus.grounded.map((text) => text.toLowerCase());
|
|
124
|
+
const written = corpus.assistant.map((text) => text.toLowerCase());
|
|
125
|
+
const frame = `frame this call was assembled from: ${String(served.length)} served string(s) ` +
|
|
126
|
+
`(system prompt, user messages, tool results) and ${String(written.length)} assistant turn(s)`;
|
|
127
|
+
for (const call of calls) {
|
|
128
|
+
const subject = { kind: 'tool', id: call.toolName };
|
|
129
|
+
const declared = new Set([...(call.declaredEnums ?? [])].map((v) => v.toLowerCase()));
|
|
130
|
+
const grounds = call.argumentsFrom.join(' or ');
|
|
131
|
+
const refetch = grounds.length > 0
|
|
132
|
+
? `call ${grounds} again and use a value it returns`
|
|
133
|
+
: 're-read the value from the tool that serves it';
|
|
134
|
+
for (const leaf of stringLeaves(call.args, '')) {
|
|
135
|
+
const value = leaf.value.trim();
|
|
136
|
+
if (value.length < MIN_CHECKED_LENGTH)
|
|
137
|
+
continue;
|
|
138
|
+
const needle = value.toLowerCase();
|
|
139
|
+
if (declared.has(needle))
|
|
140
|
+
continue;
|
|
141
|
+
if (served.some((text) => text.includes(needle)))
|
|
142
|
+
continue;
|
|
143
|
+
const selfReferenced = written.some((text) => text.includes(needle));
|
|
144
|
+
const witnesses = [
|
|
145
|
+
{
|
|
146
|
+
subject,
|
|
147
|
+
predicate: leaf.path,
|
|
148
|
+
value: leaf.value,
|
|
149
|
+
epoch,
|
|
150
|
+
stratum: 'asserted',
|
|
151
|
+
provenance: `tool call ${call.toolCallId}: argument '${leaf.path}' as the model chose it`,
|
|
152
|
+
},
|
|
153
|
+
{
|
|
154
|
+
subject,
|
|
155
|
+
predicate: leaf.path,
|
|
156
|
+
value: selfReferenced
|
|
157
|
+
? 'served by nothing — present only in the model’s own earlier answer'
|
|
158
|
+
: 'served by nothing in the window the model saw',
|
|
159
|
+
epoch,
|
|
160
|
+
stratum: 'asserted',
|
|
161
|
+
provenance: frame,
|
|
162
|
+
},
|
|
163
|
+
];
|
|
164
|
+
findings.push({
|
|
165
|
+
kind: 'unsupported-argument',
|
|
166
|
+
seam: 'choice',
|
|
167
|
+
subjects: [subject],
|
|
168
|
+
// The dot-path IS the discriminator: two arguments of one call are two
|
|
169
|
+
// defects, and without it the second collapses into the first (the
|
|
170
|
+
// `unsupported-claim` per-field lesson, same substrate rule).
|
|
171
|
+
predicate: leaf.path,
|
|
172
|
+
witnesses,
|
|
173
|
+
epoch,
|
|
174
|
+
message: selfReferenced
|
|
175
|
+
? `'${call.toolName}' was called with ${leaf.path} = "${clip(value)}", and the only ` +
|
|
176
|
+
`place that value appears in the frame the model chose from is the model’s own ` +
|
|
177
|
+
`earlier answer. Rendered text is not evidence — a value re-read out of prose can ` +
|
|
178
|
+
`be a fragment of something else entirely. To ground it, ${refetch}. Nothing here ` +
|
|
179
|
+
`blocked the call.`
|
|
180
|
+
: `'${call.toolName}' was called with ${leaf.path} = "${clip(value)}", and that value ` +
|
|
181
|
+
`appears nowhere in the frame the model chose from — not in the instructions, not ` +
|
|
182
|
+
`in any message from the user, not in any tool result. Nothing served it, so ` +
|
|
183
|
+
`nothing in this run can say what it refers to. To ground it, ${refetch}. Nothing ` +
|
|
184
|
+
`here blocked the call.`,
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
return findings;
|
|
189
|
+
}
|
|
190
|
+
//# sourceMappingURL=check.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"check.js","sourceRoot":"","sources":["../../../../src/integrity/unsupported-argument/check.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoDG;AA8BH,mDAAmD;AACnD,MAAM,kBAAkB,GAAG,CAAC,CAAC;AAE7B,4DAA4D;AAC5D,MAAM,gBAAgB,GAAG,EAAE,CAAC;AAE5B,0DAA0D;AAC1D,MAAM,gBAAgB,GAAG,CAAC,CAAC;AAE3B,SAAS,IAAI,CAAC,KAAa;IACzB,OAAO,KAAK,CAAC,MAAM,IAAI,gBAAgB,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,gBAAgB,GAAG,CAAC,CAAC,GAAG,CAAC;AAC/F,CAAC;AAED,mEAAmE;AACnE,QAAQ,CAAC,CAAC,YAAY,CAAC,IAAa,EAAE,IAAY;IAChD,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC7B,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;QAC5B,OAAO;IACT,CAAC;IACD,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;QACxB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACrC,KAAK,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,IAAI,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QACjF,CAAC;QACD,OAAO;IACT,CAAC;IACD,IAAI,IAAI,KAAK,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC9C,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAA+B,CAAC,EAAE,CAAC;YAC3E,KAAK,CAAC,CAAC,YAAY,CAAC,KAAK,EAAE,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,IAAI,GAAG,EAAE,CAAC,CAAC;QACnE,CAAC;IACH,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,oBAAoB,CAAC,MAAe;IAClD,MAAM,MAAM,GAAG,IAAI,GAAG,EAAU,CAAC;IACjC,MAAM,IAAI,GAAG,CAAC,IAAa,EAAE,KAAa,EAAQ,EAAE;QAClD,IAAI,KAAK,GAAG,gBAAgB,IAAI,IAAI,KAAK,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ;YAAE,OAAO;QAClF,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;YACxB,KAAK,MAAM,IAAI,IAAI,IAAI;gBAAE,IAAI,CAAC,IAAI,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC;YAC/C,OAAO;QACT,CAAC;QACD,MAAM,GAAG,GAAG,IAA+B,CAAC;QAC5C,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YAC5B,KAAK,MAAM,QAAQ,IAAI,GAAG,CAAC,IAAI;gBAAE,IAAI,OAAO,QAAQ,KAAK,QAAQ;oBAAE,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAC1F,CAAC;QACD,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC;YAAE,IAAI,CAAC,KAAK,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC;IACjE,CAAC,CAAC;IACF,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IAChB,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,sBAAsB,CACpC,KAAgC,EAChC,MAAoB,EACpB,KAAa;IAEb,MAAM,QAAQ,GAAmB,EAAE,CAAC;IACpC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,QAAQ,CAAC;IACxC,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;IACjE,MAAM,OAAO,GAAG,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;IACnE,MAAM,KAAK,GACT,uCAAuC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,oBAAoB;QAChF,oDAAoD,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,oBAAoB,CAAC;IAEjG,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,OAAO,GAAe,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAC;QAChE,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,aAAa,IAAI,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;QACtF,MAAM,OAAO,GAAG,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAChD,MAAM,OAAO,GACX,OAAO,CAAC,MAAM,GAAG,CAAC;YAChB,CAAC,CAAC,QAAQ,OAAO,mCAAmC;YACpD,CAAC,CAAC,gDAAgD,CAAC;QAEvD,KAAK,MAAM,IAAI,IAAI,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC,EAAE,CAAC;YAC/C,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;YAChC,IAAI,KAAK,CAAC,MAAM,GAAG,kBAAkB;gBAAE,SAAS;YAChD,MAAM,MAAM,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC;YACnC,IAAI,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC;gBAAE,SAAS;YACnC,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;gBAAE,SAAS;YAC3D,MAAM,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;YAErE,MAAM,SAAS,GAAgB;gBAC7B;oBACE,OAAO;oBACP,SAAS,EAAE,IAAI,CAAC,IAAI;oBACpB,KAAK,EAAE,IAAI,CAAC,KAAK;oBACjB,KAAK;oBACL,OAAO,EAAE,UAAU;oBACnB,UAAU,EAAE,aAAa,IAAI,CAAC,UAAU,eAAe,IAAI,CAAC,IAAI,yBAAyB;iBAC1F;gBACD;oBACE,OAAO;oBACP,SAAS,EAAE,IAAI,CAAC,IAAI;oBACpB,KAAK,EAAE,cAAc;wBACnB,CAAC,CAAC,oEAAoE;wBACtE,CAAC,CAAC,+CAA+C;oBACnD,KAAK;oBACL,OAAO,EAAE,UAAU;oBACnB,UAAU,EAAE,KAAK;iBAClB;aACF,CAAC;YAEF,QAAQ,CAAC,IAAI,CAAC;gBACZ,IAAI,EAAE,sBAAsB;gBAC5B,IAAI,EAAE,QAAQ;gBACd,QAAQ,EAAE,CAAC,OAAO,CAAC;gBACnB,uEAAuE;gBACvE,mEAAmE;gBACnE,8DAA8D;gBAC9D,SAAS,EAAE,IAAI,CAAC,IAAI;gBACpB,SAAS;gBACT,KAAK;gBACL,OAAO,EAAE,cAAc;oBACrB,CAAC,CAAC,IAAI,IAAI,CAAC,QAAQ,qBAAqB,IAAI,CAAC,IAAI,OAAO,IAAI,CAAC,KAAK,CAAC,kBAAkB;wBACnF,gFAAgF;wBAChF,mFAAmF;wBACnF,2DAA2D,OAAO,iBAAiB;wBACnF,mBAAmB;oBACrB,CAAC,CAAC,IAAI,IAAI,CAAC,QAAQ,qBAAqB,IAAI,CAAC,IAAI,OAAO,IAAI,CAAC,KAAK,CAAC,oBAAoB;wBACrF,mFAAmF;wBACnF,8EAA8E;wBAC9E,gEAAgE,OAAO,YAAY;wBACnF,wBAAwB;aAC7B,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC"}
|
|
@@ -452,7 +452,7 @@ function buildRunOverview(artifacts, index) {
|
|
|
452
452
|
* compile HERE, rather than becoming a value the tool's enum silently
|
|
453
453
|
* rejects at run time.
|
|
454
454
|
* - the honesty gate. `ContextErrorKind` names five defect classes;
|
|
455
|
-
* `src/integrity/` ships
|
|
455
|
+
* `src/integrity/` ships four checks. Offering the fifth in the
|
|
456
456
|
* schema enum invites a query whose only possible answer is a negative
|
|
457
457
|
* verdict about a class nothing in the library could have filed — the
|
|
458
458
|
* tool telling a model "no duplicate-execution errors" when nothing on
|
|
@@ -462,7 +462,7 @@ function buildRunOverview(artifacts, index) {
|
|
|
462
462
|
*/
|
|
463
463
|
const CONTEXT_ERROR_KIND_CHECKS = {
|
|
464
464
|
'invariant-violation': 'src/integrity/invariant-violation (write + wire)',
|
|
465
|
-
'unsupported-argument':
|
|
465
|
+
'unsupported-argument': 'src/integrity/unsupported-argument (choice)',
|
|
466
466
|
'dangling-reference': 'src/integrity/dangling-reference (compose)',
|
|
467
467
|
'duplicate-execution': false,
|
|
468
468
|
'unsupported-claim': 'src/integrity/unsupported-claim (claim)',
|
|
@@ -754,12 +754,14 @@ function buildFindContextErrors(artifacts, index, reader, opts) {
|
|
|
754
754
|
name: 'find_context_errors',
|
|
755
755
|
description: 'What did this run CONTRADICT ITSELF about? Lists the Context Integrity findings the ' +
|
|
756
756
|
'library already caught — an invariant violated, an offered action whose inputs left ' +
|
|
757
|
-
'scope, a claim the record does not support — each with the
|
|
757
|
+
'scope, an argument nothing served, a claim the record does not support — each with the ' +
|
|
758
|
+
'step it was filed at and the ' +
|
|
758
759
|
'exact drill that opens the state behind it. Call it EARLY when an answer looks wrong: a ' +
|
|
759
760
|
'contradiction the library already caught beats re-deriving one. Reads only; nothing is ' +
|
|
760
761
|
're-checked or re-judged. When no finding evidence was captured it says so plainly rather ' +
|
|
761
|
-
`than reporting a clean run. The finding type also names ${UNFILABLE_CONTEXT_ERROR_KINDS.map((kind) => `'${kind}'`).join(' and ')}, and no check in this build files them — this tool cannot report on ` +
|
|
762
|
-
'
|
|
762
|
+
`than reporting a clean run. The finding type also names ${UNFILABLE_CONTEXT_ERROR_KINDS.map((kind) => `'${kind}'`).join(' and ')}, and no check in this build files ${UNFILABLE_CONTEXT_ERROR_KINDS.length === 1 ? 'it' : 'them'} — this tool cannot report on ` +
|
|
763
|
+
`that class${UNFILABLE_CONTEXT_ERROR_KINDS.length === 1 ? '' : 'es'} at all, so its ` +
|
|
764
|
+
'silence about it is not evidence. ' +
|
|
763
765
|
`Bounded by limit (default ${FINDINGS_DEFAULT}, hard cap ${TOOLPACK_HARD_CAPS.contextErrorsMax}).`,
|
|
764
766
|
inputSchema: {
|
|
765
767
|
type: 'object',
|