@sourcey/catalog-verifier 1.1.12 → 1.1.14
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/SOURCEY-CLOSURE.json +53 -53
- package/dist/contracts/agent-readiness/src/binding.d.ts +22 -0
- package/dist/contracts/agent-readiness/src/binding.d.ts.map +1 -1
- package/dist/contracts/agent-readiness/src/binding.js +52 -4
- package/dist/contracts/agent-readiness/src/binding.js.map +1 -1
- package/dist/contracts/agent-readiness/src/declaration-acquisition.d.ts +1 -0
- package/dist/contracts/agent-readiness/src/declaration-acquisition.d.ts.map +1 -1
- package/dist/contracts/agent-readiness/src/declaration.d.ts +4 -0
- package/dist/contracts/agent-readiness/src/declaration.d.ts.map +1 -1
- package/dist/contracts/agent-readiness/src/jobs.d.ts +3 -0
- package/dist/contracts/agent-readiness/src/jobs.d.ts.map +1 -1
- package/dist/contracts/agent-readiness/src/jobs.js +1 -0
- package/dist/contracts/agent-readiness/src/jobs.js.map +1 -1
- package/dist/contracts/agent-readiness/src/offer-relations.d.ts +1 -0
- package/dist/contracts/agent-readiness/src/offer-relations.d.ts.map +1 -1
- package/dist/contracts/agent-readiness/src/operate-policy.d.ts +2 -0
- package/dist/contracts/agent-readiness/src/operate-policy.d.ts.map +1 -1
- package/dist/contracts/agent-readiness/src/release-index.d.ts +9 -0
- package/dist/contracts/agent-readiness/src/release-index.d.ts.map +1 -1
- package/dist/contracts/agent-readiness/src/revision.d.ts +17 -0
- package/dist/contracts/agent-readiness/src/revision.d.ts.map +1 -1
- package/dist/contracts/agent-readiness/src/run.d.ts +8 -0
- package/dist/contracts/agent-readiness/src/run.d.ts.map +1 -1
- package/dist/contracts/agent-readiness/src/run.js +8 -2
- package/dist/contracts/agent-readiness/src/run.js.map +1 -1
- package/dist/contracts/api/src/endpoints.d.ts +26 -0
- package/dist/contracts/api/src/endpoints.d.ts.map +1 -1
- package/dist/contracts/api/src/read.d.ts +13 -1
- package/dist/contracts/api/src/read.d.ts.map +1 -1
- package/dist/contracts/api/src/read.js +1 -1
- package/dist/contracts/api/src/submissions.d.ts +1 -0
- package/dist/contracts/api/src/submissions.d.ts.map +1 -1
- package/dist/modules/agent-readiness-engine/src/assertions.d.ts +23 -2
- package/dist/modules/agent-readiness-engine/src/assertions.d.ts.map +1 -1
- package/dist/modules/agent-readiness-engine/src/assertions.js +90 -8
- package/dist/modules/agent-readiness-engine/src/assertions.js.map +1 -1
- package/dist/modules/agent-readiness-engine/src/binding.d.ts +3 -2
- package/dist/modules/agent-readiness-engine/src/binding.d.ts.map +1 -1
- package/dist/modules/agent-readiness-engine/src/binding.js +34 -22
- package/dist/modules/agent-readiness-engine/src/binding.js.map +1 -1
- package/dist/modules/agent-readiness-engine/src/checks.d.ts +46 -7
- package/dist/modules/agent-readiness-engine/src/checks.d.ts.map +1 -1
- package/dist/modules/agent-readiness-engine/src/checks.js +146 -11
- package/dist/modules/agent-readiness-engine/src/checks.js.map +1 -1
- package/dist/modules/agent-readiness-jobs/src/index.d.ts +464 -7
- package/dist/modules/agent-readiness-jobs/src/index.d.ts.map +1 -1
- package/dist/modules/agent-readiness-jobs/src/index.js +397 -7
- package/dist/modules/agent-readiness-jobs/src/index.js.map +1 -1
- package/dist/modules/agent-readiness-policy/src/current-policy.d.ts +1 -1
- package/dist/modules/agent-readiness-repository/src/change.d.ts.map +1 -1
- package/dist/modules/agent-readiness-repository/src/change.js +19 -3
- package/dist/modules/agent-readiness-repository/src/change.js.map +1 -1
- package/dist/modules/release/src/verification-policies.d.ts +1 -1
- package/package.json +1 -1
|
@@ -1,4 +1,14 @@
|
|
|
1
1
|
import { ipAddressVersion } from "provenry/primitives";
|
|
2
|
+
/** The HTTP methods an observed call may use; a query may send its terms in a body. */
|
|
3
|
+
export const OBSERVED_CALL_METHODS = {
|
|
4
|
+
read: ["GET", "HEAD"],
|
|
5
|
+
write: ["POST", "PUT", "PATCH", "DELETE"],
|
|
6
|
+
query: ["GET", "POST"],
|
|
7
|
+
};
|
|
8
|
+
/** Whether an observation may locate the operand from this source. */
|
|
9
|
+
export function operandReads(operand, source) {
|
|
10
|
+
return source === operand.source || (operand.callerNamed === true && source === "request");
|
|
11
|
+
}
|
|
2
12
|
const pass = () => ({ holds: true, reason: "The canonical assertion holds." });
|
|
3
13
|
const fail = (reason) => ({ holds: false, reason });
|
|
4
14
|
const identifier = (value) => typeof value === "string" && value.trim().length > 0 && value.length <= 512;
|
|
@@ -6,11 +16,43 @@ const resourceIdentifier = (value) => identifier(value) || (typeof value === "nu
|
|
|
6
16
|
const object = (value) => value !== null && typeof value === "object" && !Array.isArray(value)
|
|
7
17
|
? value
|
|
8
18
|
: null;
|
|
19
|
+
/**
|
|
20
|
+
* Whether a sent value carries an identifier: it occurs there, and not as part
|
|
21
|
+
* of a longer run of letters and digits, so `id:rec-1` carries `rec-1` and
|
|
22
|
+
* `rec-10` does not.
|
|
23
|
+
*/
|
|
24
|
+
function carries(text, id) {
|
|
25
|
+
const word = /^[A-Za-z0-9]$/u;
|
|
26
|
+
for (let at = text.indexOf(id); at >= 0; at = text.indexOf(id, at + 1)) {
|
|
27
|
+
const joinsBefore = word.test(id[0]) && word.test(text[at - 1] ?? "");
|
|
28
|
+
const joinsAfter = word.test(id.at(-1)) && word.test(text[at + id.length] ?? "");
|
|
29
|
+
if (!joinsBefore && !joinsAfter)
|
|
30
|
+
return true;
|
|
31
|
+
}
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* The identifier a creation established: one its response returned, or one the caller named
|
|
36
|
+
* in what it sent, which must then carry the run's nonce so it is this run's.
|
|
37
|
+
*/
|
|
38
|
+
function createdIdentifier(input, name) {
|
|
39
|
+
const id = input.values.get(name);
|
|
40
|
+
if (!resourceIdentifier(id))
|
|
41
|
+
return undefined;
|
|
42
|
+
return input.requests.has(name) && !carries(String(id), input.context.nonce) ? undefined : id;
|
|
43
|
+
}
|
|
9
44
|
const created = {
|
|
45
|
+
observations: [{ name: "id", source: "json", method: "write", callerNamed: true }],
|
|
46
|
+
evaluate: (input) => createdIdentifier(input, "id") !== undefined
|
|
47
|
+
? pass()
|
|
48
|
+
: fail("The creation established no resource identifier of this run's."),
|
|
49
|
+
};
|
|
50
|
+
/** A message's identifier is the service's: a caller never names it. */
|
|
51
|
+
const accepted = {
|
|
10
52
|
observations: [{ name: "id", source: "json", method: "write" }],
|
|
11
53
|
evaluate: ({ values }) => resourceIdentifier(values.get("id"))
|
|
12
54
|
? pass()
|
|
13
|
-
: fail("The
|
|
55
|
+
: fail("The service did not return the message's identifier."),
|
|
14
56
|
};
|
|
15
57
|
/**
|
|
16
58
|
* Portable Sourcey job semantics. A binding supplies locations only: never a
|
|
@@ -115,19 +157,59 @@ const proofs = {
|
|
|
115
157
|
resource_created: created,
|
|
116
158
|
resource_read_back: {
|
|
117
159
|
observations: [
|
|
118
|
-
{ name: "created_id", source: "json", method: "write" },
|
|
160
|
+
{ name: "created_id", source: "json", method: "write", callerNamed: true },
|
|
119
161
|
{ name: "read_id", source: "json", method: "read" },
|
|
120
162
|
{ name: "content", source: "json", method: "read" },
|
|
121
163
|
],
|
|
122
164
|
sameCall: [["read_id", "content"]],
|
|
123
165
|
differentCall: [["created_id", "read_id"]],
|
|
124
|
-
evaluate: (
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
166
|
+
evaluate: (input) => {
|
|
167
|
+
const id = createdIdentifier(input, "created_id");
|
|
168
|
+
return id !== undefined &&
|
|
169
|
+
id === input.values.get("read_id") &&
|
|
170
|
+
input.values.get("content") === input.context.nonce
|
|
171
|
+
? pass()
|
|
172
|
+
: fail("The readback does not establish the created resource with this run's nonce.");
|
|
173
|
+
},
|
|
174
|
+
},
|
|
175
|
+
/**
|
|
176
|
+
* Found by what was asked, not by the key: the query the call sent is the
|
|
177
|
+
* run's nonce, and nothing it sent carries the created identifier, which the
|
|
178
|
+
* request's templates alone cannot rule out (a literal or another response
|
|
179
|
+
* can still hold it). A name the caller gave carries the nonce, so it must
|
|
180
|
+
* add to it: the bare nonce would be the query itself.
|
|
181
|
+
*/
|
|
182
|
+
resource_found_by_query: {
|
|
183
|
+
observations: [
|
|
184
|
+
{ name: "created_id", source: "json", method: "write", callerNamed: true },
|
|
185
|
+
{ name: "query", source: "request", method: "query" },
|
|
186
|
+
{ name: "found_id", source: "json", method: "query" },
|
|
187
|
+
{ name: "content", source: "json", method: "query" },
|
|
188
|
+
],
|
|
189
|
+
sameCall: [
|
|
190
|
+
["query", "found_id"],
|
|
191
|
+
["found_id", "content"],
|
|
192
|
+
],
|
|
193
|
+
differentCall: [["created_id", "found_id"]],
|
|
194
|
+
independentCall: [["query", "created_id"]],
|
|
195
|
+
evaluate(input) {
|
|
196
|
+
const { values, requests, context } = input;
|
|
197
|
+
const id = createdIdentifier(input, "created_id");
|
|
198
|
+
const sent = requests.get("query");
|
|
199
|
+
if (id === undefined)
|
|
200
|
+
return fail("The creation established no resource identifier of this run's.");
|
|
201
|
+
if (values.get("query") !== context.nonce || sent === undefined) {
|
|
202
|
+
return fail("The query did not send this run's nonce.");
|
|
203
|
+
}
|
|
204
|
+
if (sent.some((text) => carries(text, String(id)))) {
|
|
205
|
+
return fail("The query sent the created identifier, so it did not find the resource.");
|
|
206
|
+
}
|
|
207
|
+
return values.get("found_id") === id && values.get("content") === context.nonce
|
|
208
|
+
? pass()
|
|
209
|
+
: fail("The query did not return the created resource with this run's nonce.");
|
|
210
|
+
},
|
|
129
211
|
},
|
|
130
|
-
message_accepted:
|
|
212
|
+
message_accepted: accepted,
|
|
131
213
|
sink_received: {
|
|
132
214
|
observations: [],
|
|
133
215
|
async evaluate({ context, sink }) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"assertions.js","sourceRoot":"","sources":["../../../../modules/agent-readiness-engine/src/assertions.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"assertions.js","sourceRoot":"","sources":["../../../../modules/agent-readiness-engine/src/assertions.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,8 +2,9 @@ import { type AgentReadinessJob, type AgentReadinessJobBinding } from "../../../
|
|
|
2
2
|
/**
|
|
3
3
|
* Why a binding cannot perform its library job, or nothing. A binding maps
|
|
4
4
|
* every library observation exactly once, reads only the job's inputs and sinks,
|
|
5
|
-
*
|
|
6
|
-
*
|
|
5
|
+
* places the run's nonce wherever it locates a request observation, and cleans
|
|
6
|
+
* up when the job is consequential. Whether its calls stay on its declared
|
|
7
|
+
* surface is the declaration's own rule, checked where it is parsed.
|
|
7
8
|
*/
|
|
8
9
|
export declare function agentReadinessBindingIssues(input: {
|
|
9
10
|
readonly job: AgentReadinessJob;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"binding.d.ts","sourceRoot":"","sources":["../../../../modules/agent-readiness-engine/src/binding.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,iBAAiB,EACtB,KAAK,wBAAwB,
|
|
1
|
+
{"version":3,"file":"binding.d.ts","sourceRoot":"","sources":["../../../../modules/agent-readiness-engine/src/binding.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,iBAAiB,EACtB,KAAK,wBAAwB,EAK9B,MAAM,iDAAiD,CAAC;AAIzD;;;;;;GAMG;AACH,wBAAgB,2BAA2B,CAAC,KAAK,EAAE;IACjD,QAAQ,CAAC,GAAG,EAAE,iBAAiB,CAAC;IAChC,QAAQ,CAAC,OAAO,EAAE,wBAAwB,CAAC;CAC5C,GAAG,SAAS,MAAM,EAAE,CAuHpB"}
|
|
@@ -1,10 +1,12 @@
|
|
|
1
|
-
import { agentReadinessBindingCalls,
|
|
2
|
-
import { agentReadinessAssertionProof } from "./assertions.js";
|
|
1
|
+
import { agentReadinessBindingCalls, agentReadinessCallTemplates, agentReadinessRequestTemplate, agentReadinessTemplateReferences, } from "../../../contracts/agent-readiness/src/index.js";
|
|
2
|
+
import { agentReadinessAssertionProof, OBSERVED_CALL_METHODS, operandReads } from "./assertions.js";
|
|
3
|
+
import { valueAtPointer } from "./templates.js";
|
|
3
4
|
/**
|
|
4
5
|
* Why a binding cannot perform its library job, or nothing. A binding maps
|
|
5
6
|
* every library observation exactly once, reads only the job's inputs and sinks,
|
|
6
|
-
*
|
|
7
|
-
*
|
|
7
|
+
* places the run's nonce wherever it locates a request observation, and cleans
|
|
8
|
+
* up when the job is consequential. Whether its calls stay on its declared
|
|
9
|
+
* surface is the declaration's own rule, checked where it is parsed.
|
|
8
10
|
*/
|
|
9
11
|
export function agentReadinessBindingIssues(input) {
|
|
10
12
|
const { job, binding } = input;
|
|
@@ -20,6 +22,10 @@ export function agentReadinessBindingIssues(input) {
|
|
|
20
22
|
issues.push(`Assertion ${name} is not one of ${job.job_id}'s.`);
|
|
21
23
|
}
|
|
22
24
|
const calls = new Map(binding.calls.map((call) => [call.call_id, call]));
|
|
25
|
+
const nonces = new Set([
|
|
26
|
+
"{{run.nonce}}",
|
|
27
|
+
...job.inputs.flatMap(({ kind, name }) => (kind === "nonce" ? [`{{input.${name}}}`] : [])),
|
|
28
|
+
]);
|
|
23
29
|
for (const assertion of job.assertions) {
|
|
24
30
|
const located = binding.assertions.find(({ assertion: name }) => name === assertion.name);
|
|
25
31
|
if (!located)
|
|
@@ -32,14 +38,24 @@ export function agentReadinessBindingIssues(input) {
|
|
|
32
38
|
issues.push(`Assertion ${assertion.name} does not locate ${required.name}.`);
|
|
33
39
|
continue;
|
|
34
40
|
}
|
|
35
|
-
if (observed.source
|
|
41
|
+
if (!operandReads(required, observed.source)) {
|
|
36
42
|
issues.push(`Assertion ${assertion.name}'s ${required.name} must read ${required.source}.`);
|
|
37
43
|
}
|
|
38
44
|
const call = calls.get(observed.call);
|
|
39
|
-
if (call?.kind === "http" &&
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
45
|
+
if (call?.kind === "http" &&
|
|
46
|
+
required.method &&
|
|
47
|
+
!OBSERVED_CALL_METHODS[required.method].includes(call.method)) {
|
|
48
|
+
issues.push(`Assertion ${assertion.name}'s ${required.name} needs a ${required.method} call.`);
|
|
49
|
+
}
|
|
50
|
+
if (call && observed.source === "request" && operandReads(required, "request")) {
|
|
51
|
+
// A query is the nonce itself; a name the caller gives carries it.
|
|
52
|
+
const template = valueAtPointer(agentReadinessRequestTemplate(call), observed.pointer);
|
|
53
|
+
const placed = typeof template === "string" &&
|
|
54
|
+
(required.source === "request"
|
|
55
|
+
? nonces.has(template)
|
|
56
|
+
: [...nonces].some((nonce) => template.includes(nonce)));
|
|
57
|
+
if (!placed) {
|
|
58
|
+
issues.push(`Assertion ${assertion.name}'s ${required.name} must locate the run's nonce in the request.`);
|
|
43
59
|
}
|
|
44
60
|
}
|
|
45
61
|
}
|
|
@@ -60,6 +76,14 @@ export function agentReadinessBindingIssues(input) {
|
|
|
60
76
|
if (a && b && a.call === b.call)
|
|
61
77
|
issues.push(`Assertion ${assertion.name}'s ${left} and ${right} must read different calls.`);
|
|
62
78
|
}
|
|
79
|
+
for (const [left, right] of proof.independentCall ?? []) {
|
|
80
|
+
const a = observations.get(left);
|
|
81
|
+
const b = observations.get(right);
|
|
82
|
+
const sent = a && calls.get(a.call);
|
|
83
|
+
const reads = (template) => agentReadinessTemplateReferences(template)?.some((reference) => reference.kind === "call" && reference.callId === b?.call);
|
|
84
|
+
if (b && sent && agentReadinessCallTemplates(sent).some(reads))
|
|
85
|
+
issues.push(`Assertion ${assertion.name}'s ${left} must not read ${right}'s call.`);
|
|
86
|
+
}
|
|
63
87
|
}
|
|
64
88
|
for (const { from, to } of job.observation_links) {
|
|
65
89
|
const locate = (reference) => binding.assertions
|
|
@@ -73,19 +97,7 @@ export function agentReadinessBindingIssues(input) {
|
|
|
73
97
|
}
|
|
74
98
|
const values = new Set(job.inputs.filter(({ kind }) => kind !== "sink").map(({ name }) => name));
|
|
75
99
|
const sinks = new Set(job.inputs.filter(({ kind }) => kind === "sink").map(({ name }) => name));
|
|
76
|
-
const templates =
|
|
77
|
-
for (const { call } of agentReadinessBindingCalls(binding)) {
|
|
78
|
-
if (call.kind === "http") {
|
|
79
|
-
templates.push(call.url, ...call.headers.map(({ value }) => value), ...(call.body === null
|
|
80
|
-
? []
|
|
81
|
-
: call.body.media_type === "application/json"
|
|
82
|
-
? agentReadinessJsonTemplates(call.body.json)
|
|
83
|
-
: call.body.form.map(({ value }) => value)));
|
|
84
|
-
}
|
|
85
|
-
else {
|
|
86
|
-
templates.push(...agentReadinessJsonTemplates(call.arguments));
|
|
87
|
-
}
|
|
88
|
-
}
|
|
100
|
+
const templates = agentReadinessBindingCalls(binding).flatMap(({ call }) => agentReadinessCallTemplates(call));
|
|
89
101
|
for (const template of templates) {
|
|
90
102
|
for (const reference of agentReadinessTemplateReferences(template) ?? []) {
|
|
91
103
|
if (reference.kind === "input" && !values.has(reference.name)) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"binding.js","sourceRoot":"","sources":["../../../../modules/agent-readiness-engine/src/binding.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,0BAA0B,EAC1B,2BAA2B,EAC3B,gCAAgC,GACjC,MAAM,iDAAiD,CAAC;AACzD,OAAO,EAAE,4BAA4B,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"binding.js","sourceRoot":"","sources":["../../../../modules/agent-readiness-engine/src/binding.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,9 +1,13 @@
|
|
|
1
|
-
import type
|
|
2
|
-
import type
|
|
1
|
+
import { type ExchangeMethod, type ExchangeRecord } from "provenry/exchange/records";
|
|
2
|
+
import { type AgentReadinessJob, type AgentReadinessJobBinding } from "../../../contracts/agent-readiness/src/index.js";
|
|
3
3
|
import { type TemplateContext } from "./templates.js";
|
|
4
|
-
/** What one call returned, in the terms checks read. */
|
|
4
|
+
/** What one call sent and returned, in the terms checks read. */
|
|
5
5
|
export interface CallResult {
|
|
6
6
|
readonly kind: "http" | "mcp";
|
|
7
|
+
/** The method its record says was sent; null when no exchange of the call was recorded. */
|
|
8
|
+
readonly method: ExchangeMethod | null;
|
|
9
|
+
/** What the call sent; null unless the body handed with it is the one its record seals. */
|
|
10
|
+
readonly request: SentRequest | null;
|
|
7
11
|
/** The HTTP status of a call that got a response. */
|
|
8
12
|
readonly status: number | null;
|
|
9
13
|
/** The JSON document returned: an HTTP body read as JSON by content, or an MCP tool result. */
|
|
@@ -13,6 +17,35 @@ export interface CallResult {
|
|
|
13
17
|
/** For an MCP call: true when the tool answered without error. */
|
|
14
18
|
readonly mcpOk: boolean | null;
|
|
15
19
|
}
|
|
20
|
+
/**
|
|
21
|
+
* What a call handed to its exchange beyond what its record keeps: the body,
|
|
22
|
+
* which the record seals only by digest, and header values, which it never
|
|
23
|
+
* records. Method, URL and media type are read from the record itself.
|
|
24
|
+
*/
|
|
25
|
+
export interface HandedRequest {
|
|
26
|
+
readonly body: Uint8Array | null;
|
|
27
|
+
readonly headers: Readonly<Record<string, string>>;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* A request as it was sent, in the terms checks read. Exchange custody adds to
|
|
31
|
+
* what a call hands it only the body's content type, its own transport headers
|
|
32
|
+
* (`accept-encoding` and its user agent) and the credentials the call names;
|
|
33
|
+
* every header name it adds is recorded, but a credential's value never
|
|
34
|
+
* reaches Sourcey.
|
|
35
|
+
*/
|
|
36
|
+
export interface SentRequest {
|
|
37
|
+
/** What request observations read: see `agentReadinessRequestDocument`. */
|
|
38
|
+
readonly document: unknown;
|
|
39
|
+
/**
|
|
40
|
+
* Every value it sent that Sourcey can read, as text: each header name its
|
|
41
|
+
* record keeps, custody's included, the header values handed with it and its
|
|
42
|
+
* content type; then an HTTP call's path segments, query parameters and body
|
|
43
|
+
* fields, or an MCP call's tool name and arguments, names and keys included.
|
|
44
|
+
*/
|
|
45
|
+
readonly inputs: readonly string[];
|
|
46
|
+
/** The credentials custody attached, by the handle digests its record names. */
|
|
47
|
+
readonly credentials: readonly string[];
|
|
48
|
+
}
|
|
16
49
|
/** Observes Sourcey's sinks; a run without one cannot hold a sink assertion. */
|
|
17
50
|
export interface SinkPort {
|
|
18
51
|
received(input: {
|
|
@@ -24,10 +57,10 @@ export interface CheckOutcome {
|
|
|
24
57
|
readonly holds: boolean;
|
|
25
58
|
readonly reason: string;
|
|
26
59
|
}
|
|
27
|
-
/** An HTTP
|
|
28
|
-
export declare function httpCallResult(record: ExchangeRecord, body: Uint8Array | null): CallResult;
|
|
29
|
-
/** An MCP tool call's answer as a call result. */
|
|
30
|
-
export declare function mcpCallResult(answer: {
|
|
60
|
+
/** An HTTP exchange as a call result: its response as JSON by content, or the events of a stream. */
|
|
61
|
+
export declare function httpCallResult(handed: HandedRequest, record: ExchangeRecord, body: Uint8Array | null): CallResult;
|
|
62
|
+
/** An MCP tool call's exchange and answer as a call result. */
|
|
63
|
+
export declare function mcpCallResult(handed: HandedRequest, record: ExchangeRecord, answer: {
|
|
31
64
|
readonly outcome: "result" | "error" | "unanswered";
|
|
32
65
|
readonly result?: unknown;
|
|
33
66
|
}): CallResult;
|
|
@@ -36,6 +69,12 @@ export declare function evaluateAssertions(input: {
|
|
|
36
69
|
readonly job: AgentReadinessJob;
|
|
37
70
|
readonly binding: AgentReadinessJobBinding;
|
|
38
71
|
readonly calls: ReadonlyMap<string, CallResult>;
|
|
72
|
+
/**
|
|
73
|
+
* The credentials the run held before its first job call, by handle digest:
|
|
74
|
+
* entered, or issued by its delegation. A job call keeps no credential, so
|
|
75
|
+
* none of these derives from any job call's response.
|
|
76
|
+
*/
|
|
77
|
+
readonly credentialsBeforeJob: ReadonlySet<string>;
|
|
39
78
|
readonly context: TemplateContext;
|
|
40
79
|
readonly sink?: SinkPort;
|
|
41
80
|
}): Promise<readonly {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"checks.d.ts","sourceRoot":"","sources":["../../../../modules/agent-readiness-engine/src/checks.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"checks.d.ts","sourceRoot":"","sources":["../../../../modules/agent-readiness-engine/src/checks.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,32 +1,133 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { FORM_MEDIA_TYPE, } from "provenry/exchange/records";
|
|
2
|
+
import { sha256Bytes } from "provenry/primitives";
|
|
3
|
+
import { agentReadinessRequestDocument, } from "../../../contracts/agent-readiness/src/index.js";
|
|
4
|
+
import { agentReadinessAssertionProof, operandReads } from "./assertions.js";
|
|
2
5
|
import { valueAtPointer } from "./templates.js";
|
|
3
|
-
/** An HTTP
|
|
4
|
-
export function httpCallResult(record, body) {
|
|
6
|
+
/** An HTTP exchange as a call result: its response as JSON by content, or the events of a stream. */
|
|
7
|
+
export function httpCallResult(handed, record, body) {
|
|
8
|
+
const sent = sentHttpRequest(handed, record);
|
|
9
|
+
const { method } = record.request;
|
|
5
10
|
if (record.outcome !== "responded" || body === null) {
|
|
6
|
-
return {
|
|
11
|
+
return {
|
|
12
|
+
kind: "http",
|
|
13
|
+
method,
|
|
14
|
+
request: sent,
|
|
15
|
+
status: null,
|
|
16
|
+
document: undefined,
|
|
17
|
+
events: null,
|
|
18
|
+
mcpOk: null,
|
|
19
|
+
};
|
|
7
20
|
}
|
|
8
21
|
const text = utf8(body);
|
|
9
22
|
const streamed = record.response.body.media_type === "text/event-stream";
|
|
10
23
|
return {
|
|
11
24
|
kind: "http",
|
|
25
|
+
method,
|
|
26
|
+
request: sent,
|
|
12
27
|
status: record.response.status,
|
|
13
28
|
document: streamed || text === null ? undefined : json(text),
|
|
14
29
|
events: streamed && text !== null ? streamEvents(text) : null,
|
|
15
30
|
mcpOk: null,
|
|
16
31
|
};
|
|
17
32
|
}
|
|
18
|
-
/** An MCP tool call's answer as a call result. */
|
|
19
|
-
export function mcpCallResult(answer) {
|
|
33
|
+
/** An MCP tool call's exchange and answer as a call result. */
|
|
34
|
+
export function mcpCallResult(handed, record, answer) {
|
|
20
35
|
const isError = answer.outcome === "result" &&
|
|
21
36
|
answer.result?.isError === true;
|
|
22
37
|
return {
|
|
23
38
|
kind: "mcp",
|
|
24
|
-
|
|
39
|
+
method: record.request.method,
|
|
40
|
+
request: sentMcpRequest(handed, record),
|
|
41
|
+
status: record.outcome === "responded" ? record.response.status : null,
|
|
25
42
|
document: answer.outcome === "result" ? answer.result : undefined,
|
|
26
43
|
events: null,
|
|
27
44
|
mcpOk: answer.outcome === "result" ? !isError : answer.outcome === "error" ? false : null,
|
|
28
45
|
};
|
|
29
46
|
}
|
|
47
|
+
/** What an HTTP call sent: its URL query and body, and every input with its path and headers. */
|
|
48
|
+
function sentHttpRequest(handed, record) {
|
|
49
|
+
const text = sealedBody(handed, record);
|
|
50
|
+
if (text === undefined)
|
|
51
|
+
return null;
|
|
52
|
+
const mediaType = record.request.body?.media_type;
|
|
53
|
+
const parsed = text !== null && mediaType === "application/json" ? json(text) : undefined;
|
|
54
|
+
const body = text === null
|
|
55
|
+
? null
|
|
56
|
+
: mediaType === FORM_MEDIA_TYPE
|
|
57
|
+
? { form: [...new URLSearchParams(text)] }
|
|
58
|
+
: parsed === undefined
|
|
59
|
+
? undefined
|
|
60
|
+
: { json: parsed };
|
|
61
|
+
// A body that is neither JSON nor a form is not one a binding sends.
|
|
62
|
+
if (body === undefined)
|
|
63
|
+
return null;
|
|
64
|
+
const url = new URL(record.request.url);
|
|
65
|
+
const document = agentReadinessRequestDocument({ query: [...url.searchParams], body });
|
|
66
|
+
return sentRequest(handed, record, document, [
|
|
67
|
+
...url.pathname
|
|
68
|
+
.split("/")
|
|
69
|
+
.filter((segment) => segment !== "")
|
|
70
|
+
.map(decodedSegment),
|
|
71
|
+
...Object.values(document).flatMap(texts),
|
|
72
|
+
]);
|
|
73
|
+
}
|
|
74
|
+
/** What an MCP call sent: the tool name and arguments of its JSON-RPC request. */
|
|
75
|
+
function sentMcpRequest(handed, record) {
|
|
76
|
+
const text = sealedBody(handed, record);
|
|
77
|
+
const message = text ? json(text) : undefined;
|
|
78
|
+
if (message === undefined)
|
|
79
|
+
return null;
|
|
80
|
+
const params = message?.params;
|
|
81
|
+
return sentRequest(handed, record, agentReadinessRequestDocument({ arguments: params?.arguments }), [...texts(params?.name), ...texts(params?.arguments)]);
|
|
82
|
+
}
|
|
83
|
+
/** A sealed request with its headers and credentials, as its record and the handed values show them. */
|
|
84
|
+
function sentRequest(handed, record, document, inputs) {
|
|
85
|
+
const { body, credentials, header_names } = record.request;
|
|
86
|
+
return {
|
|
87
|
+
document,
|
|
88
|
+
inputs: [
|
|
89
|
+
...header_names,
|
|
90
|
+
...Object.values(handed.headers),
|
|
91
|
+
...(body ? [body.media_type] : []),
|
|
92
|
+
...inputs,
|
|
93
|
+
],
|
|
94
|
+
credentials: credentials.map(({ handle_digest }) => handle_digest),
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* The body text handed with a request, only when its record seals those exact
|
|
99
|
+
* bytes: null when neither has a body; undefined when the bytes are not the
|
|
100
|
+
* record's or are not text.
|
|
101
|
+
*/
|
|
102
|
+
function sealedBody(handed, record) {
|
|
103
|
+
const sealed = record.request.body;
|
|
104
|
+
if (handed.body === null)
|
|
105
|
+
return sealed === null ? null : undefined;
|
|
106
|
+
return sealed?.content_digest === sha256Bytes(handed.body)
|
|
107
|
+
? (utf8(handed.body) ?? undefined)
|
|
108
|
+
: undefined;
|
|
109
|
+
}
|
|
110
|
+
/** A JSON value's keys and scalars, as text. */
|
|
111
|
+
function texts(value) {
|
|
112
|
+
if (typeof value === "string")
|
|
113
|
+
return [value];
|
|
114
|
+
if (typeof value === "number" || typeof value === "boolean")
|
|
115
|
+
return [String(value)];
|
|
116
|
+
if (Array.isArray(value))
|
|
117
|
+
return value.flatMap(texts);
|
|
118
|
+
if (value !== null && typeof value === "object") {
|
|
119
|
+
return Object.entries(value).flatMap(([key, item]) => [key, ...texts(item)]);
|
|
120
|
+
}
|
|
121
|
+
return [];
|
|
122
|
+
}
|
|
123
|
+
function decodedSegment(segment) {
|
|
124
|
+
try {
|
|
125
|
+
return decodeURIComponent(segment);
|
|
126
|
+
}
|
|
127
|
+
catch {
|
|
128
|
+
return segment;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
30
131
|
/** Each library assertion, under Sourcey's semantics over the located observations. */
|
|
31
132
|
export async function evaluateAssertions(input) {
|
|
32
133
|
const results = [];
|
|
@@ -36,6 +137,7 @@ export async function evaluateAssertions(input) {
|
|
|
36
137
|
throw new Error(`The binding does not map assertion ${assertion.name}.`);
|
|
37
138
|
const proof = agentReadinessAssertionProof(assertion.proof);
|
|
38
139
|
const values = new Map();
|
|
140
|
+
const requests = new Map();
|
|
39
141
|
let failure = null;
|
|
40
142
|
for (const [index, required] of proof.observations.entries()) {
|
|
41
143
|
const observation = mapped.observations.find(({ name }) => name === required.name);
|
|
@@ -43,20 +145,37 @@ export async function evaluateAssertions(input) {
|
|
|
43
145
|
const ok = call?.kind === "http"
|
|
44
146
|
? call.status !== null && call.status >= 200 && call.status <= 299
|
|
45
147
|
: call?.mcpOk === true;
|
|
46
|
-
|
|
148
|
+
const sent = observation?.source === "request" ? call?.request : undefined;
|
|
149
|
+
if (!observation ||
|
|
150
|
+
!operandReads(required, observation.source) ||
|
|
151
|
+
!call ||
|
|
152
|
+
!ok ||
|
|
153
|
+
sent === null) {
|
|
47
154
|
failure = {
|
|
48
155
|
check: index,
|
|
49
156
|
reason: `No successful ${required.source} observation establishes ${required.name}.`,
|
|
50
157
|
};
|
|
51
158
|
break;
|
|
52
159
|
}
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
160
|
+
const declared = input.binding.calls.find(({ call_id }) => call_id === observation.call);
|
|
161
|
+
const unrecorded = recordIssue(declared, call, sent, input.credentialsBeforeJob);
|
|
162
|
+
if (unrecorded !== null) {
|
|
163
|
+
failure = { check: index, reason: unrecorded };
|
|
164
|
+
break;
|
|
165
|
+
}
|
|
166
|
+
const { pointer } = observation;
|
|
167
|
+
if (sent)
|
|
168
|
+
requests.set(required.name, sent.inputs);
|
|
169
|
+
values.set(required.name, sent
|
|
170
|
+
? valueAtPointer(sent.document, pointer)
|
|
171
|
+
: observation.source === "json"
|
|
172
|
+
? valueAtPointer(call.document, pointer)
|
|
173
|
+
: call.events?.map((event) => valueAtPointer(event, pointer)));
|
|
56
174
|
}
|
|
57
175
|
if (failure === null) {
|
|
58
176
|
const outcome = await proof.evaluate({
|
|
59
177
|
values,
|
|
178
|
+
requests,
|
|
60
179
|
context: input.context,
|
|
61
180
|
...(input.sink ? { sink: input.sink } : {}),
|
|
62
181
|
});
|
|
@@ -67,6 +186,22 @@ export async function evaluateAssertions(input) {
|
|
|
67
186
|
}
|
|
68
187
|
return results;
|
|
69
188
|
}
|
|
189
|
+
/**
|
|
190
|
+
* Why an observed call's record cannot stand for it, or nothing. The record
|
|
191
|
+
* must show the method the binding declared. A request observation also reads
|
|
192
|
+
* only a request whose every credential the run held before the job: custody's
|
|
193
|
+
* one addition Sourcey cannot read is a credential's value, and only then can
|
|
194
|
+
* no value it added derive from a job call's response.
|
|
195
|
+
*/
|
|
196
|
+
function recordIssue(declared, call, sent, credentialsBeforeJob) {
|
|
197
|
+
if (declared?.kind === "http" && call.method !== declared.method) {
|
|
198
|
+
return `Call ${declared.call_id} was sent as ${call.method}, not its declared ${declared.method}.`;
|
|
199
|
+
}
|
|
200
|
+
if (sent?.credentials.some((handle) => !credentialsBeforeJob.has(handle))) {
|
|
201
|
+
return "The request carried a credential the run did not hold before the job.";
|
|
202
|
+
}
|
|
203
|
+
return null;
|
|
204
|
+
}
|
|
70
205
|
/**
|
|
71
206
|
* Whether the safe invalid request failed typed: true or false is a fact about
|
|
72
207
|
* the service; null (a transport failure, a 5xx, an unanswered call) is residue.
|