@nifrajs/testing 3.1.0 → 3.2.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/index.d.ts CHANGED
@@ -8,7 +8,10 @@
8
8
  * const { client, cookies } = testSession<typeof app>(app)
9
9
  */
10
10
  export { AdversarialContractError, type AdversarialContractOptions, type AdversarialContractReport, type AdversarialContractResult, assertAdversarialContract, type ContractCaseContext, type ContractCaseKind, type ContractCoverageGap, type ContractCoverageGapCode, type ContractReplay, type ContractRuntime, type ContractTarget, type ContractTestApp, type ContractWitness, runAdversarialContract, } from "./adversarial.js";
11
+ export { type CertifiableDeploymentAdapter, type CertifiableDescriptorAdapter, type CertifiableModelGateway, deploymentAdapterCertificationProfile, deploymentCertificationProfile, gatewayCertificationProfile, modelGatewayCertificationProfile, registryCertificationProfile, } from "./agent-certification.js";
12
+ export { type AgentEvalCase, type AgentEvalComponentEvidence, type AgentEvalCompositionOptions, type AgentEvalCompositionReport, AgentEvalRegressionError, type AgentEvalReport, type AgentEvalSuite, type AgentEvalSuiteSpec, type AgentFailureMatrixCase, AgentFailureMatrixError, type AgentFailureMatrixKind, type AgentFailureMatrixReport, assertAgentEval, assertAgentEvalBaseline, assertAgentFailureMatrix, type BaselineComparison, type BaselineOptions, type CaseComparison, type CaseResult, type ComparisonCode, compareAgentEvalBaseline, defineAgentEvalSuite, parseRubricVerdict, type RubricShape, type RubricSpec, type RubricVerdict, runAgentEvalComposition, runAgentFailureMatrix, type ScoreTolerance, } from "./agent-eval.js";
11
13
  export { AdapterCertificationError, type AdapterCertificationProfile, type AdapterCertificationReport, assertAdapterCertification, type CertifiableCacheEntry, type CertifiableCacheStore, type CertifiableDomainEvent, type CertifiableEventDeliveryAdapter, type CertifiableEventRecord, type CertifiableJobStore, type CertifiableRuntimeAdapter, type CertifiableRuntimeServer, type CertifiableStorageAdapter, type CertificationCapabilityEvidence, type CertificationCheck, type CertificationCheckEvidence, cacheStoreCertificationProfile, certifyAdapter, defineCertificationProfile, eventDeliveryCertificationProfile, jobStoreCertificationProfile, runtimeAdapterCertificationProfile, storageAdapterCertificationProfile, verifyAdapterCertification, } from "./certification.js";
14
+ export { type ContractLabHandler, type ContractLabRuntimeAdapter, type ContractLabServer, type ContractLabWitness, contractLabWitnesses, createReferenceContractLabHandler, runContractLab, runContractLabOverHttp, runContractLabThroughAdapter, } from "./contract-lab.js";
12
15
  export { type CookieJar, cookieJar } from "./cookies.js";
13
16
  export { createFailureLab, type FailureDirective, type FailureEvidence, FailureInjectedError, type FailureKind, type FailureLab, type FailureLabOptions, type FailureReplay, type FailureScenario, type FailureScenarioReport, runFailureScenario, } from "./failure-lab.js";
14
17
  export { defineFaultProfile, type FaultProfile, type FaultProfileFault, type FaultProfileFaultKind, type FaultProfileReport, type FaultProfileScenario, type FaultProfileScenarioReport, type RunFaultProfileOptions, referenceFaultProfile, runFaultProfile, } from "./fault-profile.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EACL,wBAAwB,EACxB,KAAK,0BAA0B,EAC/B,KAAK,yBAAyB,EAC9B,KAAK,yBAAyB,EAC9B,yBAAyB,EACzB,KAAK,mBAAmB,EACxB,KAAK,gBAAgB,EACrB,KAAK,mBAAmB,EACxB,KAAK,uBAAuB,EAC5B,KAAK,cAAc,EACnB,KAAK,eAAe,EACpB,KAAK,cAAc,EACnB,KAAK,eAAe,EACpB,KAAK,eAAe,EACpB,sBAAsB,GACvB,MAAM,kBAAkB,CAAA;AACzB,OAAO,EACL,yBAAyB,EACzB,KAAK,2BAA2B,EAChC,KAAK,0BAA0B,EAC/B,0BAA0B,EAC1B,KAAK,qBAAqB,EAC1B,KAAK,qBAAqB,EAC1B,KAAK,sBAAsB,EAC3B,KAAK,+BAA+B,EACpC,KAAK,sBAAsB,EAC3B,KAAK,mBAAmB,EACxB,KAAK,yBAAyB,EAC9B,KAAK,wBAAwB,EAC7B,KAAK,yBAAyB,EAC9B,KAAK,+BAA+B,EACpC,KAAK,kBAAkB,EACvB,KAAK,0BAA0B,EAC/B,8BAA8B,EAC9B,cAAc,EACd,0BAA0B,EAC1B,iCAAiC,EACjC,4BAA4B,EAC5B,kCAAkC,EAClC,kCAAkC,EAClC,0BAA0B,GAC3B,MAAM,oBAAoB,CAAA;AAC3B,OAAO,EAAE,KAAK,SAAS,EAAE,SAAS,EAAE,MAAM,cAAc,CAAA;AACxD,OAAO,EACL,gBAAgB,EAChB,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACpB,oBAAoB,EACpB,KAAK,WAAW,EAChB,KAAK,UAAU,EACf,KAAK,iBAAiB,EACtB,KAAK,aAAa,EAClB,KAAK,eAAe,EACpB,KAAK,qBAAqB,EAC1B,kBAAkB,GACnB,MAAM,kBAAkB,CAAA;AACzB,OAAO,EACL,kBAAkB,EAClB,KAAK,YAAY,EACjB,KAAK,iBAAiB,EACtB,KAAK,qBAAqB,EAC1B,KAAK,kBAAkB,EACvB,KAAK,oBAAoB,EACzB,KAAK,0BAA0B,EAC/B,KAAK,sBAAsB,EAC3B,qBAAqB,EACrB,eAAe,GAChB,MAAM,oBAAoB,CAAA;AAC3B,OAAO,EACL,KAAK,YAAY,EACjB,KAAK,qBAAqB,EAC1B,KAAK,gBAAgB,EACrB,gBAAgB,GACjB,MAAM,kBAAkB,CAAA;AACzB,OAAO,EACL,qBAAqB,EACrB,KAAK,eAAe,EACpB,KAAK,oBAAoB,EACzB,KAAK,sBAAsB,EAC3B,eAAe,EACf,KAAK,6BAA6B,EAClC,sBAAsB,EACtB,KAAK,eAAe,EACpB,mBAAmB,EACnB,KAAK,oBAAoB,EACzB,KAAK,qBAAqB,EAC1B,iBAAiB,EACjB,cAAc,EACd,OAAO,GACR,MAAM,eAAe,CAAA;AACtB,OAAO,EAAE,KAAK,OAAO,EAAE,KAAK,WAAW,EAAE,KAAK,kBAAkB,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AACnG,OAAO,EACL,eAAe,EACf,oBAAoB,EACpB,cAAc,EACd,eAAe,GAChB,MAAM,oBAAoB,CAAA;AAC3B,OAAO,EACL,0BAA0B,EAC1B,KAAK,iCAAiC,EACtC,yBAAyB,EACzB,0BAA0B,EAC1B,KAAK,uBAAuB,EAC5B,gBAAgB,EAChB,gBAAgB,EAChB,aAAa,EACb,KAAK,qBAAqB,EAC1B,KAAK,0BAA0B,EAC/B,KAAK,yBAAyB,EAC9B,KAAK,sBAAsB,EAC3B,KAAK,aAAa,EAClB,KAAK,oBAAoB,EACzB,sBAAsB,GACvB,MAAM,iBAAiB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -8,7 +8,10 @@
8
8
  * const { client, cookies } = testSession<typeof app>(app)
9
9
  */
10
10
  export { AdversarialContractError, assertAdversarialContract, runAdversarialContract, } from "./adversarial.js";
11
+ export { deploymentAdapterCertificationProfile, deploymentCertificationProfile, gatewayCertificationProfile, modelGatewayCertificationProfile, registryCertificationProfile, } from "./agent-certification.js";
12
+ export { AgentEvalRegressionError, AgentFailureMatrixError, assertAgentEval, assertAgentEvalBaseline, assertAgentFailureMatrix, compareAgentEvalBaseline, defineAgentEvalSuite, parseRubricVerdict, runAgentEvalComposition, runAgentFailureMatrix, } from "./agent-eval.js";
11
13
  export { AdapterCertificationError, assertAdapterCertification, cacheStoreCertificationProfile, certifyAdapter, defineCertificationProfile, eventDeliveryCertificationProfile, jobStoreCertificationProfile, runtimeAdapterCertificationProfile, storageAdapterCertificationProfile, verifyAdapterCertification, } from "./certification.js";
14
+ export { contractLabWitnesses, createReferenceContractLabHandler, runContractLab, runContractLabOverHttp, runContractLabThroughAdapter, } from "./contract-lab.js";
12
15
  export { cookieJar } from "./cookies.js";
13
16
  export { createFailureLab, FailureInjectedError, runFailureScenario, } from "./failure-lab.js";
14
17
  export { defineFaultProfile, referenceFaultProfile, runFaultProfile, } from "./fault-profile.js";
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EACL,wBAAwB,EAIxB,yBAAyB,EAUzB,sBAAsB,GACvB,MAAM,kBAAkB,CAAA;AACzB,OAAO,EACL,yBAAyB,EAGzB,0BAA0B,EAa1B,8BAA8B,EAC9B,cAAc,EACd,0BAA0B,EAC1B,iCAAiC,EACjC,4BAA4B,EAC5B,kCAAkC,EAClC,kCAAkC,EAClC,0BAA0B,GAC3B,MAAM,oBAAoB,CAAA;AAC3B,OAAO,EAAkB,SAAS,EAAE,MAAM,cAAc,CAAA;AACxD,OAAO,EACL,gBAAgB,EAGhB,oBAAoB,EAOpB,kBAAkB,GACnB,MAAM,kBAAkB,CAAA;AACzB,OAAO,EACL,kBAAkB,EAQlB,qBAAqB,EACrB,eAAe,GAChB,MAAM,oBAAoB,CAAA;AAC3B,OAAO,EAIL,gBAAgB,GACjB,MAAM,kBAAkB,CAAA;AACzB,OAAO,EACL,qBAAqB,EAIrB,eAAe,EAEf,sBAAsB,EAEtB,mBAAmB,EAGnB,iBAAiB,EACjB,cAAc,EACd,OAAO,GACR,MAAM,eAAe,CAAA;AACtB,OAAO,EAA2D,WAAW,EAAE,MAAM,cAAc,CAAA;AACnG,OAAO,EACL,eAAe,EACf,oBAAoB,EACpB,cAAc,EACd,eAAe,GAChB,MAAM,oBAAoB,CAAA;AAC3B,OAAO,EACL,0BAA0B,EAE1B,yBAAyB,EACzB,0BAA0B,EAE1B,gBAAgB,EAChB,gBAAgB,EAChB,aAAa,EAOb,sBAAsB,GACvB,MAAM,iBAAiB,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EACL,wBAAwB,EAIxB,yBAAyB,EAUzB,sBAAsB,GACvB,MAAM,kBAAkB,CAAA;AACzB,OAAO,EAIL,qCAAqC,EACrC,8BAA8B,EAC9B,2BAA2B,EAC3B,gCAAgC,EAChC,4BAA4B,GAC7B,MAAM,0BAA0B,CAAA;AACjC,OAAO,EAKL,wBAAwB,EAKxB,uBAAuB,EAGvB,eAAe,EACf,uBAAuB,EACvB,wBAAwB,EAMxB,wBAAwB,EACxB,oBAAoB,EACpB,kBAAkB,EAIlB,uBAAuB,EACvB,qBAAqB,GAEtB,MAAM,iBAAiB,CAAA;AACxB,OAAO,EACL,yBAAyB,EAGzB,0BAA0B,EAa1B,8BAA8B,EAC9B,cAAc,EACd,0BAA0B,EAC1B,iCAAiC,EACjC,4BAA4B,EAC5B,kCAAkC,EAClC,kCAAkC,EAClC,0BAA0B,GAC3B,MAAM,oBAAoB,CAAA;AAC3B,OAAO,EAKL,oBAAoB,EACpB,iCAAiC,EACjC,cAAc,EACd,sBAAsB,EACtB,4BAA4B,GAC7B,MAAM,mBAAmB,CAAA;AAC1B,OAAO,EAAkB,SAAS,EAAE,MAAM,cAAc,CAAA;AACxD,OAAO,EACL,gBAAgB,EAGhB,oBAAoB,EAOpB,kBAAkB,GACnB,MAAM,kBAAkB,CAAA;AACzB,OAAO,EACL,kBAAkB,EAQlB,qBAAqB,EACrB,eAAe,GAChB,MAAM,oBAAoB,CAAA;AAC3B,OAAO,EAIL,gBAAgB,GACjB,MAAM,kBAAkB,CAAA;AACzB,OAAO,EACL,qBAAqB,EAIrB,eAAe,EAEf,sBAAsB,EAEtB,mBAAmB,EAGnB,iBAAiB,EACjB,cAAc,EACd,OAAO,GACR,MAAM,eAAe,CAAA;AACtB,OAAO,EAA2D,WAAW,EAAE,MAAM,cAAc,CAAA;AACnG,OAAO,EACL,eAAe,EACf,oBAAoB,EACpB,cAAc,EACd,eAAe,GAChB,MAAM,oBAAoB,CAAA;AAC3B,OAAO,EACL,0BAA0B,EAE1B,yBAAyB,EACzB,0BAA0B,EAE1B,gBAAgB,EAChB,gBAAgB,EAChB,aAAa,EAOb,sBAAsB,GACvB,MAAM,iBAAiB,CAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nifrajs/testing",
3
- "version": "3.1.0",
3
+ "version": "3.2.0",
4
4
  "description": "Contract-derived adversarial tests, runtime-matrix response conformance, and cookie-aware in-process sessions for Nifra apps.",
5
5
  "keywords": [
6
6
  "bun",
@@ -28,6 +28,11 @@
28
28
  "types": "./dist/certification.d.ts",
29
29
  "default": "./dist/certification.js"
30
30
  },
31
+ "./contract-lab": {
32
+ "bun": "./src/contract-lab.ts",
33
+ "types": "./dist/contract-lab.d.ts",
34
+ "default": "./dist/contract-lab.js"
35
+ },
31
36
  "./zod": {
32
37
  "bun": "./src/zod.ts",
33
38
  "types": "./dist/zod.d.ts",
@@ -44,11 +49,11 @@
44
49
  },
45
50
  "license": "MIT",
46
51
  "dependencies": {
47
- "@nifrajs/client": "3.1.0",
48
- "@nifrajs/agent": "3.1.0",
49
- "@nifrajs/core": "3.1.0",
50
- "@nifrajs/mcp": "3.1.0",
51
- "@nifrajs/mock": "3.1.0"
52
+ "@nifrajs/client": "3.2.0",
53
+ "@nifrajs/agent": "3.2.0",
54
+ "@nifrajs/core": "3.2.0",
55
+ "@nifrajs/mcp": "3.2.0",
56
+ "@nifrajs/mock": "3.2.0"
52
57
  },
53
58
  "peerDependencies": {
54
59
  "zod": ">=4.0.0"
@@ -0,0 +1,296 @@
1
+ /**
2
+ * Certification profile for capability-descriptor adapters.
3
+ *
4
+ * An adapter that projects a tool, MCP tool, extension, model, or deployment target into a
5
+ * {@link CapabilityDescriptor} is certified structurally: its output must parse cleanly, carry a real
6
+ * schema digest, be free of any content-bearing field, compose into a deterministic snapshot, and
7
+ * surface a schema change on a stable identity as drift rather than a silent overwrite. The profile
8
+ * is dependency-free test evidence - an adapter package uses it only in CI, and the resulting matrix
9
+ * is portable JSON that names capabilities, never payloads.
10
+ */
11
+
12
+ import {
13
+ AgentDeployment,
14
+ type AgentDeploymentAdapter,
15
+ createDeploymentAuthority,
16
+ type ModelGateway,
17
+ parseDeploymentCapabilityReport,
18
+ parseModelGatewayError,
19
+ parseModelGatewayResult,
20
+ runModelGateway,
21
+ structuredOutputParser,
22
+ } from "@nifrajs/agent"
23
+ import {
24
+ type CapabilityDescriptor,
25
+ composeRegistrySnapshot,
26
+ parseCapabilityDescriptor,
27
+ RegistryError,
28
+ } from "@nifrajs/agent/registry"
29
+ import { type AdapterCertificationProfile, defineCertificationProfile } from "./certification.ts"
30
+
31
+ /**
32
+ * The test-only surface a descriptor adapter exposes for certification. `describe` yields the
33
+ * adapter's representative descriptor; `describeDrift` yields a descriptor with the SAME identity
34
+ * (kind and name) but a DIFFERENT schema digest, so the drift check can prove the adapter's identity
35
+ * is stable across a schema change instead of colliding into it.
36
+ */
37
+ export interface CertifiableDescriptorAdapter {
38
+ describe(): CapabilityDescriptor | Promise<CapabilityDescriptor>
39
+ describeDrift(): CapabilityDescriptor | Promise<CapabilityDescriptor>
40
+ }
41
+
42
+ const ALLOWED_KEYS: ReadonlySet<string> = new Set([
43
+ "descriptorVersion",
44
+ "kind",
45
+ "name",
46
+ "version",
47
+ "schemaDigest",
48
+ "requiredCapabilities",
49
+ "approval",
50
+ "retry",
51
+ "idempotency",
52
+ "isolation",
53
+ ])
54
+
55
+ const SCHEMA_DIGEST = /^[0-9a-f]{64}$/
56
+
57
+ /**
58
+ * Build the descriptor-adapter certification profile. Every check runs against a fresh adapter, so a
59
+ * failure never leaks into the next capability's evidence.
60
+ */
61
+ export function registryCertificationProfile(): AdapterCertificationProfile<CertifiableDescriptorAdapter> {
62
+ return defineCertificationProfile<CertifiableDescriptorAdapter>({
63
+ id: "capability-descriptor",
64
+ version: 1,
65
+ capabilities: ["content-free", "schema-digest", "snapshot-determinism", "drift-detection"],
66
+ checks: [
67
+ {
68
+ id: "content-free",
69
+ capability: "content-free",
70
+ async run(adapter) {
71
+ const descriptor = await adapter.describe()
72
+ const parsed = parseCapabilityDescriptor(descriptor)
73
+ for (const key of Object.keys(parsed)) {
74
+ if (!ALLOWED_KEYS.has(key)) throw new Error("DescriptorExtraField")
75
+ }
76
+ if (parsed.descriptorVersion !== 1) throw new Error("DescriptorVersion")
77
+ },
78
+ },
79
+ {
80
+ id: "schema-digest",
81
+ capability: "schema-digest",
82
+ async run(adapter) {
83
+ const descriptor = await adapter.describe()
84
+ if (!SCHEMA_DIGEST.test(descriptor.schemaDigest))
85
+ throw new Error("DescriptorSchemaDigest")
86
+ if (descriptor.version.length === 0) throw new Error("DescriptorVersionMissing")
87
+ },
88
+ },
89
+ {
90
+ id: "snapshot-determinism",
91
+ capability: "snapshot-determinism",
92
+ async run(adapter) {
93
+ const descriptor = await adapter.describe()
94
+ const first = await composeRegistrySnapshot([descriptor])
95
+ const second = await composeRegistrySnapshot([descriptor])
96
+ if (first.digest !== second.digest) throw new Error("SnapshotNonDeterministic")
97
+ if (first.descriptors.length !== 1) throw new Error("SnapshotDescriptorCount")
98
+ },
99
+ },
100
+ {
101
+ id: "identity-drift",
102
+ capability: "drift-detection",
103
+ async run(adapter) {
104
+ const descriptor = await adapter.describe()
105
+ const drift = await adapter.describeDrift()
106
+ if (descriptor.kind !== drift.kind || descriptor.name !== drift.name)
107
+ throw new Error("DriftIdentityMismatch")
108
+ if (descriptor.schemaDigest === drift.schemaDigest)
109
+ throw new Error("DriftDigestUnchanged")
110
+ let code: string | undefined
111
+ try {
112
+ await composeRegistrySnapshot([descriptor, drift])
113
+ } catch (error) {
114
+ if (error instanceof RegistryError) code = error.code
115
+ }
116
+ if (code !== "schema_drift") throw new Error("DriftNotDetected")
117
+ },
118
+ },
119
+ ],
120
+ })
121
+ }
122
+
123
+ class NamedCertificationFailure extends Error {
124
+ constructor(name: string) {
125
+ super(name)
126
+ this.name = name
127
+ }
128
+ }
129
+
130
+ export interface CertifiableModelGateway extends ModelGateway {}
131
+
132
+ /** Certification for provider-neutral gateways. It never emits request or response content. */
133
+ export function gatewayCertificationProfile(): AdapterCertificationProfile<CertifiableModelGateway> {
134
+ return defineCertificationProfile<CertifiableModelGateway>({
135
+ id: "model-gateway",
136
+ version: 1,
137
+ capabilities: ["parse-boundary", "error-taxonomy", "fallback-policy", "evidence-firewall"],
138
+ checks: [
139
+ {
140
+ id: "parse-boundary",
141
+ capability: "parse-boundary",
142
+ async run(adapter) {
143
+ const result = await runModelGateway(
144
+ adapter,
145
+ { input: { probe: true }, parser: structuredOutputParser((value) => value) },
146
+ { routes: ["cert-route"], retryableCodes: [], budget: { maxAttempts: 1 } },
147
+ )
148
+ if (!result.ok || result.evidence.some((item) => Object.hasOwn(item, "input")))
149
+ throw new NamedCertificationFailure("GatewayParseBoundary")
150
+ },
151
+ },
152
+ {
153
+ id: "error-taxonomy",
154
+ capability: "error-taxonomy",
155
+ run() {
156
+ for (const code of [
157
+ "malformed_output",
158
+ "refusal",
159
+ "timeout",
160
+ "rate_limit",
161
+ "unavailable",
162
+ "policy_denied",
163
+ "cancelled",
164
+ "internal",
165
+ ] as const) {
166
+ if (parseModelGatewayError({ code }).code !== code)
167
+ throw new NamedCertificationFailure("GatewayErrorTaxonomy")
168
+ }
169
+ },
170
+ },
171
+ {
172
+ id: "fallback-policy",
173
+ capability: "fallback-policy",
174
+ async run(adapter) {
175
+ const result = await runModelGateway(
176
+ adapter,
177
+ { input: { probe: true } },
178
+ {
179
+ routes: ["cert-route", "cert-fallback"],
180
+ retryableCodes: ["rate_limit", "unavailable"],
181
+ allowFallback: true,
182
+ budget: { maxAttempts: 2 },
183
+ },
184
+ )
185
+ if (result.evidence.some((item) => item.kind === "fallback")) return
186
+ if (!result.ok) throw new NamedCertificationFailure("GatewayFallback")
187
+ },
188
+ },
189
+ {
190
+ id: "evidence-firewall",
191
+ capability: "evidence-firewall",
192
+ async run(adapter) {
193
+ const raw = await adapter.complete({
194
+ routeId: "cert-route",
195
+ input: { probe: true },
196
+ signal: new AbortController().signal,
197
+ envelope: { attempt: 1, attemptsRemaining: 0 },
198
+ })
199
+ if (parseModelGatewayResult(raw).ok === false && isRecordWithKey(raw, "evidence"))
200
+ throw new NamedCertificationFailure("GatewayEvidenceFirewall")
201
+ const result = await runModelGateway(
202
+ adapter,
203
+ { input: { prompt: "transient" } },
204
+ { routes: ["cert-route"], retryableCodes: [], budget: { maxAttempts: 1 } },
205
+ )
206
+ const evidence = JSON.stringify(result.evidence).toLowerCase()
207
+ if (/prompt|message|response|credential|secret|diagnostic|stack|content/.test(evidence))
208
+ throw new NamedCertificationFailure("GatewayEvidenceFirewall")
209
+ },
210
+ },
211
+ ],
212
+ })
213
+ }
214
+
215
+ function isRecordWithKey(value: unknown, key: string): boolean {
216
+ return (
217
+ typeof value === "object" &&
218
+ value !== null &&
219
+ !Array.isArray(value) &&
220
+ Object.hasOwn(value, key)
221
+ )
222
+ }
223
+
224
+ export const modelGatewayCertificationProfile = gatewayCertificationProfile
225
+
226
+ export interface CertifiableDeploymentAdapter extends AgentDeploymentAdapter {
227
+ /** Required only when the adapter claims real OS hostile-code isolation. */
228
+ readonly verifyHostileCodeIsolation?: () => boolean | PromiseLike<boolean>
229
+ }
230
+
231
+ /** Certification for lifecycle cleanup, capability truthfulness, authority, and isolation claims. */
232
+ export function deploymentCertificationProfile(): AdapterCertificationProfile<CertifiableDeploymentAdapter> {
233
+ return defineCertificationProfile<CertifiableDeploymentAdapter>({
234
+ id: "deployment-adapter",
235
+ version: 1,
236
+ capabilities: ["capability-truthfulness", "lifecycle", "cleanup", "isolation-claims"],
237
+ checks: [
238
+ {
239
+ id: "capability-truthfulness",
240
+ capability: "capability-truthfulness",
241
+ async run(adapter) {
242
+ const report = parseDeploymentCapabilityReport(await adapter.capabilityReport())
243
+ if (report.adapterId !== adapter.id)
244
+ throw new NamedCertificationFailure("DeploymentCapability")
245
+ },
246
+ },
247
+ {
248
+ id: "lifecycle",
249
+ capability: "lifecycle",
250
+ async run(adapter) {
251
+ const deployment = new AgentDeployment(
252
+ adapter,
253
+ createDeploymentAuthority({ workspaceMaxBytes: 1024 * 1024 }),
254
+ )
255
+ await deployment.prepare({ deploymentId: "cert-deployment" })
256
+ await deployment.start()
257
+ const inspection = await deployment.inspect()
258
+ if (inspection.state !== "running")
259
+ throw new NamedCertificationFailure("DeploymentLifecycle")
260
+ await deployment.cancel()
261
+ await deployment.dispose()
262
+ },
263
+ },
264
+ {
265
+ id: "cleanup",
266
+ capability: "cleanup",
267
+ async run(adapter) {
268
+ const deployment = new AgentDeployment(
269
+ adapter,
270
+ createDeploymentAuthority({ workspaceMaxBytes: 1024 * 1024 }),
271
+ )
272
+ await deployment.prepare({ deploymentId: "cert-cleanup" })
273
+ await deployment.dispose()
274
+ if (deployment.lifecycleState !== "disposed")
275
+ throw new NamedCertificationFailure("DeploymentCleanup")
276
+ },
277
+ },
278
+ {
279
+ id: "isolation-claims",
280
+ capability: "isolation-claims",
281
+ async run(adapter) {
282
+ const report = parseDeploymentCapabilityReport(await adapter.capabilityReport())
283
+ if (report.capabilities.hostileCodeIsolation === "os") {
284
+ if (
285
+ adapter.verifyHostileCodeIsolation === undefined ||
286
+ !(await adapter.verifyHostileCodeIsolation())
287
+ )
288
+ throw new NamedCertificationFailure("DeploymentIsolationClaim")
289
+ }
290
+ },
291
+ },
292
+ ],
293
+ })
294
+ }
295
+
296
+ export const deploymentAdapterCertificationProfile = deploymentCertificationProfile