assertledger 1.0.0 → 1.1.1
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/README.fr.md +3 -3
- package/README.md +3 -3
- package/SECURITY.md +11 -6
- package/conformance/schema-extensions.json +36 -0
- package/dist/build-info.d.ts +16 -0
- package/dist/build-info.d.ts.map +1 -0
- package/dist/build-info.js +18 -0
- package/dist/build-info.js.map +1 -0
- package/dist/build-info.json +7 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +117 -19
- package/dist/cli.js.map +1 -1
- package/dist/contracts/index.d.ts +943 -0
- package/dist/contracts/index.d.ts.map +1 -1
- package/dist/contracts/index.js +561 -21
- package/dist/contracts/index.js.map +1 -1
- package/dist/core/index.d.ts +10 -1
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +484 -8
- package/dist/core/index.js.map +1 -1
- package/dist/diagnostics.d.ts.map +1 -1
- package/dist/diagnostics.js +42 -2
- package/dist/diagnostics.js.map +1 -1
- package/dist/engine/adapters/node-test-runtime.d.ts +17 -0
- package/dist/engine/adapters/node-test-runtime.d.ts.map +1 -1
- package/dist/engine/adapters/node-test-runtime.js +45 -23
- package/dist/engine/adapters/node-test-runtime.js.map +1 -1
- package/dist/engine/container.d.ts +54 -0
- package/dist/engine/container.d.ts.map +1 -0
- package/dist/engine/container.js +464 -0
- package/dist/engine/container.js.map +1 -0
- package/dist/engine/git-regression.d.ts +12 -2
- package/dist/engine/git-regression.d.ts.map +1 -1
- package/dist/engine/git-regression.js +63 -16
- package/dist/engine/git-regression.js.map +1 -1
- package/dist/engine/index.d.ts +7 -1
- package/dist/engine/index.d.ts.map +1 -1
- package/dist/engine/index.js +300 -74
- package/dist/engine/index.js.map +1 -1
- package/dist/mcp/index.d.ts.map +1 -1
- package/dist/mcp/index.js +53 -1
- package/dist/mcp/index.js.map +1 -1
- package/dist/proof-planner/carry-over.d.ts +21 -0
- package/dist/proof-planner/carry-over.d.ts.map +1 -0
- package/dist/proof-planner/carry-over.js +212 -0
- package/dist/proof-planner/carry-over.js.map +1 -0
- package/dist/proof-planner/index.d.ts +11 -0
- package/dist/proof-planner/index.d.ts.map +1 -0
- package/dist/proof-planner/index.js +11 -0
- package/dist/proof-planner/index.js.map +1 -0
- package/dist/proof-planner/model.d.ts +272 -0
- package/dist/proof-planner/model.d.ts.map +1 -0
- package/dist/proof-planner/model.js +215 -0
- package/dist/proof-planner/model.js.map +1 -0
- package/dist/proof-planner/plan.d.ts +140 -0
- package/dist/proof-planner/plan.d.ts.map +1 -0
- package/dist/proof-planner/plan.js +1124 -0
- package/dist/proof-planner/plan.js.map +1 -0
- package/dist/proof-planner/policy.d.ts +100 -0
- package/dist/proof-planner/policy.d.ts.map +1 -0
- package/dist/proof-planner/policy.js +407 -0
- package/dist/proof-planner/policy.js.map +1 -0
- package/dist/proof-planner/render.d.ts +4 -0
- package/dist/proof-planner/render.d.ts.map +1 -0
- package/dist/proof-planner/render.js +73 -0
- package/dist/proof-planner/render.js.map +1 -0
- package/dist/sdk/index.d.ts +16 -6
- package/dist/sdk/index.d.ts.map +1 -1
- package/dist/sdk/index.js +63 -5
- package/dist/sdk/index.js.map +1 -1
- package/docs/agentic-test-profile.md +5 -0
- package/docs/architecture.md +15 -3
- package/docs/ci.md +7 -1
- package/docs/conformance-v1.md +11 -2
- package/docs/container-isolation.md +156 -0
- package/docs/evidence-export.md +146 -0
- package/docs/git-regression.md +7 -3
- package/docs/migration-timeout-discovery-inconclusive.md +126 -0
- package/docs/migration-verification-v2.md +55 -0
- package/docs/project-intent.md +3 -2
- package/docs/proof-model.md +28 -6
- package/docs/proof-planner.md +368 -0
- package/docs/reference.md +59 -12
- package/docs/roadmap.md +12 -4
- package/examples/agentic-profile/profile-manifest.mjs +5 -1
- package/examples/evidence-export/consumer.mjs +35 -0
- package/package.json +5 -5
- package/schemas/evidence-export-replay-result.v1.json +49 -0
- package/schemas/evidence-export-request.v1.json +681 -0
- package/schemas/evidence-export.v1.json +1479 -0
- package/schemas/evidence-manifest.v2.json +886 -0
- package/schemas/evidence-provider-manifest.v1.json +269 -0
- package/schemas/verification-request.v2.json +457 -0
package/dist/contracts/index.js
CHANGED
|
@@ -71,6 +71,31 @@ export const TrustedLocalIsolationSchema = z.strictObject({
|
|
|
71
71
|
acknowledgedUnsafeExecution: z.boolean(),
|
|
72
72
|
environmentAllowlist: z.array(EnvironmentVariableSchema).max(100),
|
|
73
73
|
});
|
|
74
|
+
export const VERIFICATION_SCHEMA_VERSION_V2 = "2.0.0";
|
|
75
|
+
// Only digest-pinned references are accepted; the leading alphanumeric also keeps a reference
|
|
76
|
+
// from being parsed as a container runtime option.
|
|
77
|
+
export const ContainerImageReferenceSchema = z
|
|
78
|
+
.string()
|
|
79
|
+
.max(512)
|
|
80
|
+
.regex(/^(?:[A-Za-z0-9][A-Za-z0-9.-]*(?::[0-9]{1,5})?\/)?[a-z0-9]+(?:(?:[._]|__|-+)[a-z0-9]+)*(?:\/[a-z0-9]+(?:(?:[._]|__|-+)[a-z0-9]+)*)*(?::[A-Za-z0-9_][A-Za-z0-9._-]{0,127})?@sha256:[a-f0-9]{64}$/);
|
|
81
|
+
const ContainerEnvironmentVariableSchema = z.strictObject({
|
|
82
|
+
name: EnvironmentVariableSchema,
|
|
83
|
+
value: z.string().max(4_096),
|
|
84
|
+
});
|
|
85
|
+
export const ContainerLimitsSchema = z.strictObject({
|
|
86
|
+
memoryBytes: z.int().min(67_108_864).max(68_719_476_736),
|
|
87
|
+
cpuMillicores: z.int().min(100).max(256_000),
|
|
88
|
+
pids: z.int().min(16).max(65_536),
|
|
89
|
+
temporaryDirectoryBytes: z.int().min(1_048_576).max(17_179_869_184),
|
|
90
|
+
});
|
|
91
|
+
// The host runtime command is operator configuration, never request data: a request cannot choose
|
|
92
|
+
// which host executable starts the container, and it cannot forward host environment values.
|
|
93
|
+
export const ContainerIsolationSchema = z.strictObject({
|
|
94
|
+
kind: z.literal("container"),
|
|
95
|
+
image: ContainerImageReferenceSchema,
|
|
96
|
+
environment: z.array(ContainerEnvironmentVariableSchema).max(100),
|
|
97
|
+
limits: ContainerLimitsSchema,
|
|
98
|
+
});
|
|
74
99
|
export const BudgetsSchema = z.strictObject({
|
|
75
100
|
maximumCandidates: z.int().min(1).max(1_000),
|
|
76
101
|
maximumWorlds: z.int().min(3).max(1_000),
|
|
@@ -110,6 +135,20 @@ export const VerificationRequestSchema = z
|
|
|
110
135
|
title: "TestForge verification request",
|
|
111
136
|
description: "A versioned campaign describing operator-owned worlds, candidate test overlays, budgets, and evidence policy.",
|
|
112
137
|
});
|
|
138
|
+
export const VerificationRequestV2Schema = z
|
|
139
|
+
.strictObject({
|
|
140
|
+
...VerificationRequestSchema.shape,
|
|
141
|
+
schemaVersion: z.literal(VERIFICATION_SCHEMA_VERSION_V2),
|
|
142
|
+
isolation: z.discriminatedUnion("kind", [
|
|
143
|
+
TrustedLocalIsolationSchema,
|
|
144
|
+
ContainerIsolationSchema,
|
|
145
|
+
]),
|
|
146
|
+
})
|
|
147
|
+
.meta({
|
|
148
|
+
id: "https://testforge.dev/schemas/verification-request.v2.json",
|
|
149
|
+
title: "AssertLedger verification request v2",
|
|
150
|
+
description: "A versioned campaign executed either in a digest-pinned container backend or in explicitly acknowledged unsandboxed trusted-local mode.",
|
|
151
|
+
});
|
|
113
152
|
export const RepositoryAnalysisSchema = z
|
|
114
153
|
.strictObject({
|
|
115
154
|
root: z.string().min(1),
|
|
@@ -388,6 +427,71 @@ export const EvidenceManifestSchema = z
|
|
|
388
427
|
title: "TestForge evidence manifest",
|
|
389
428
|
description: "The final auditable campaign artifact, including evidence, deterministic gates, decisions, and integrity digests.",
|
|
390
429
|
});
|
|
430
|
+
const ContainerExecutionControlsSchema = z.strictObject({
|
|
431
|
+
network: z.literal("none"),
|
|
432
|
+
rootFilesystem: z.literal("read-only"),
|
|
433
|
+
hostMounts: z.literal("none"),
|
|
434
|
+
workspace: z.literal("anonymous-volume"),
|
|
435
|
+
user: z.literal("65534:65534"),
|
|
436
|
+
capabilities: z.literal("none"),
|
|
437
|
+
noNewPrivileges: z.literal(true),
|
|
438
|
+
imagePull: z.literal("never"),
|
|
439
|
+
logDriver: z.literal("none"),
|
|
440
|
+
environment: z.array(ContainerEnvironmentVariableSchema).max(100),
|
|
441
|
+
limits: ContainerLimitsSchema,
|
|
442
|
+
});
|
|
443
|
+
const ExecutionBackendRecordSchema = z.discriminatedUnion("kind", [
|
|
444
|
+
z.strictObject({ kind: z.literal("trusted-local"), level: z.literal("UNSANDBOXED") }),
|
|
445
|
+
z.strictObject({
|
|
446
|
+
kind: z.literal("container"),
|
|
447
|
+
level: z.literal("CONTAINER"),
|
|
448
|
+
image: z.strictObject({
|
|
449
|
+
reference: ContainerImageReferenceSchema,
|
|
450
|
+
id: Sha256DigestSchema,
|
|
451
|
+
os: z.literal("linux"),
|
|
452
|
+
architecture: z.string().min(1).max(64),
|
|
453
|
+
}),
|
|
454
|
+
runtime: z.strictObject({
|
|
455
|
+
clientVersion: z.string().min(1).max(128),
|
|
456
|
+
serverVersion: z.string().min(1).max(128),
|
|
457
|
+
serverOs: z.literal("linux"),
|
|
458
|
+
serverArchitecture: z.string().min(1).max(64),
|
|
459
|
+
cgroupVersion: z.string().max(16),
|
|
460
|
+
securityOptions: z.array(z.string().min(1).max(512)).max(64),
|
|
461
|
+
}),
|
|
462
|
+
controls: ContainerExecutionControlsSchema,
|
|
463
|
+
}),
|
|
464
|
+
]);
|
|
465
|
+
const EvidenceContextV2Schema = z.strictObject({
|
|
466
|
+
...EvidenceContextSchema.shape,
|
|
467
|
+
execution: z.strictObject({
|
|
468
|
+
...EvidenceContextSchema.shape.execution.shape,
|
|
469
|
+
backend: ExecutionBackendRecordSchema,
|
|
470
|
+
}),
|
|
471
|
+
});
|
|
472
|
+
export const EvidenceManifestV2Schema = z
|
|
473
|
+
.strictObject({
|
|
474
|
+
...EvidenceManifestSchema.shape,
|
|
475
|
+
schemaVersion: z.literal(VERIFICATION_SCHEMA_VERSION_V2),
|
|
476
|
+
evidenceContext: EvidenceContextV2Schema,
|
|
477
|
+
isolation: z.discriminatedUnion("kind", [
|
|
478
|
+
z.strictObject({
|
|
479
|
+
kind: z.literal("trusted-local"),
|
|
480
|
+
level: z.literal("UNSANDBOXED"),
|
|
481
|
+
acknowledgedUnsafeExecution: z.literal(true),
|
|
482
|
+
}),
|
|
483
|
+
z.strictObject({
|
|
484
|
+
kind: z.literal("container"),
|
|
485
|
+
level: z.literal("CONTAINER"),
|
|
486
|
+
runtimeCommand: z.array(z.string().min(1).max(4_096)).min(1).max(16),
|
|
487
|
+
}),
|
|
488
|
+
]),
|
|
489
|
+
})
|
|
490
|
+
.meta({
|
|
491
|
+
id: "https://testforge.dev/schemas/evidence-manifest.v2.json",
|
|
492
|
+
title: "AssertLedger evidence manifest v2",
|
|
493
|
+
description: "The final auditable campaign artifact with a decision-bound record of the execution backend and its enforced controls.",
|
|
494
|
+
});
|
|
391
495
|
export const ReplayResultSchema = z
|
|
392
496
|
.strictObject({
|
|
393
497
|
valid: z.boolean(),
|
|
@@ -1304,6 +1408,297 @@ export const AgenticCorpusExperimentReplayResultSchema = z.strictObject({
|
|
|
1304
1408
|
observationSemanticsValid: z.boolean(),
|
|
1305
1409
|
resultSemanticsValid: z.boolean(),
|
|
1306
1410
|
});
|
|
1411
|
+
const GitObjectIdSchema = z.string().regex(/^(?:[a-f0-9]{40}|[a-f0-9]{64})$/);
|
|
1412
|
+
const EvidenceSourceRevisionSchema = z.discriminatedUnion("status", [
|
|
1413
|
+
z.strictObject({
|
|
1414
|
+
status: z.literal("RECORDED"),
|
|
1415
|
+
commit: GitObjectIdSchema,
|
|
1416
|
+
worktree: z.enum(["CLEAN", "DIRTY"]),
|
|
1417
|
+
}),
|
|
1418
|
+
z.strictObject({ status: z.literal("UNKNOWN") }),
|
|
1419
|
+
]);
|
|
1420
|
+
const EvidenceFormatSchema = z.strictObject({
|
|
1421
|
+
schemaId: z.string().min(1).max(512),
|
|
1422
|
+
schemaVersion: z.string().min(1).max(128),
|
|
1423
|
+
});
|
|
1424
|
+
export const EvidenceProviderManifestSchema = z
|
|
1425
|
+
.strictObject({
|
|
1426
|
+
schemaVersion: z.literal("1.0.0"),
|
|
1427
|
+
provider: z.strictObject({
|
|
1428
|
+
name: z.literal("assertledger"),
|
|
1429
|
+
version: z.string().min(1).max(128),
|
|
1430
|
+
sourceRevision: EvidenceSourceRevisionSchema,
|
|
1431
|
+
}),
|
|
1432
|
+
scope: z.string().min(1).max(2_048),
|
|
1433
|
+
formats: z.strictObject({
|
|
1434
|
+
accepts: z.array(EvidenceFormatSchema).max(100),
|
|
1435
|
+
emits: z.array(EvidenceFormatSchema).max(100),
|
|
1436
|
+
}),
|
|
1437
|
+
capabilities: z
|
|
1438
|
+
.array(z.strictObject({
|
|
1439
|
+
id: ReasonCodeSchema,
|
|
1440
|
+
status: z.enum(["SUPPORTED", "SUPPORTED_WHEN_RECORDED", "UNSUPPORTED"]),
|
|
1441
|
+
modality: z.enum(["TEST_OBSERVED", "RECORDED_METADATA", "NONE"]),
|
|
1442
|
+
description: z.string().min(1).max(2_048),
|
|
1443
|
+
}))
|
|
1444
|
+
.max(100),
|
|
1445
|
+
adapters: z
|
|
1446
|
+
.array(z.strictObject({
|
|
1447
|
+
kind: z.enum(["node-test", "testforge-command"]),
|
|
1448
|
+
profileId: z.string().min(1).max(128).nullable(),
|
|
1449
|
+
profileVersion: z.string().min(1).max(128).nullable(),
|
|
1450
|
+
official: z.boolean(),
|
|
1451
|
+
}))
|
|
1452
|
+
.max(100),
|
|
1453
|
+
cost: z.strictObject({
|
|
1454
|
+
unit: z.literal("PROCESS_EXECUTIONS"),
|
|
1455
|
+
estimate: z.string().min(1).max(512),
|
|
1456
|
+
assumptions: z.array(z.string().min(1).max(2_048)).max(100),
|
|
1457
|
+
}),
|
|
1458
|
+
limits: z.array(z.string().min(1).max(2_048)).max(100),
|
|
1459
|
+
manifestDigest: Sha256DigestSchema,
|
|
1460
|
+
})
|
|
1461
|
+
.meta({
|
|
1462
|
+
id: "https://testforge.dev/schemas/evidence-provider-manifest.v1.json",
|
|
1463
|
+
title: "AssertLedger evidence provider manifest",
|
|
1464
|
+
description: "Announced provider identity, capabilities, formats, cost model, and limits. An announced capability never proves that a control ran.",
|
|
1465
|
+
});
|
|
1466
|
+
const EvidenceConsumerRequestSchema = z.strictObject({
|
|
1467
|
+
reference: z.string().min(1).max(256).nullable(),
|
|
1468
|
+
profileId: z.string().min(1).max(256).nullable(),
|
|
1469
|
+
obligations: z
|
|
1470
|
+
.array(z.strictObject({ id: IdentifierSchema, control: ReasonCodeSchema }))
|
|
1471
|
+
.max(100),
|
|
1472
|
+
});
|
|
1473
|
+
export const EvidenceExportRequestSchema = z
|
|
1474
|
+
.strictObject({
|
|
1475
|
+
schemaVersion: z.literal("1.0.0"),
|
|
1476
|
+
manifest: EmbeddedEvidenceManifestSchema,
|
|
1477
|
+
consumerRequest: EvidenceConsumerRequestSchema.nullable(),
|
|
1478
|
+
})
|
|
1479
|
+
.meta({
|
|
1480
|
+
id: "https://testforge.dev/schemas/evidence-export-request.v1.json",
|
|
1481
|
+
title: "AssertLedger evidence export request",
|
|
1482
|
+
description: "A replay-valid evidence manifest and optional consumer references and requested controls.",
|
|
1483
|
+
});
|
|
1484
|
+
const EvidenceWorldKindSchema = z.enum(["REFERENCE", "TARGET", "NEUTRAL"]);
|
|
1485
|
+
export const EvidenceExportSchema = z
|
|
1486
|
+
.strictObject({
|
|
1487
|
+
schemaVersion: z.literal("1.0.0"),
|
|
1488
|
+
sourceManifest: EmbeddedEvidenceManifestSchema,
|
|
1489
|
+
sourceArtifactDigest: Sha256DigestSchema,
|
|
1490
|
+
consumerRequest: EvidenceConsumerRequestSchema.nullable(),
|
|
1491
|
+
result: z.strictObject({
|
|
1492
|
+
detection: z.enum(["OBSERVED", "NOT_OBSERVED", "NOT_ESTABLISHED"]),
|
|
1493
|
+
modality: z.enum(["TEST_OBSERVED", "NONE"]),
|
|
1494
|
+
reasonCode: z.enum([
|
|
1495
|
+
"REGRESSION_ASSERTION_OBSERVED",
|
|
1496
|
+
"TARGET_PASSED_WITHOUT_DETECTION",
|
|
1497
|
+
"ENGINE_ERROR",
|
|
1498
|
+
"CONTROL_EVIDENCE_INVALID",
|
|
1499
|
+
"CANDIDATE_EVIDENCE_INCONCLUSIVE",
|
|
1500
|
+
"CANDIDATE_EVIDENCE_INVALID",
|
|
1501
|
+
"TARGET_STRENGTH_INSUFFICIENT",
|
|
1502
|
+
"OPERATIONAL_OUTCOME_NOT_DETECTION",
|
|
1503
|
+
]),
|
|
1504
|
+
decision: z.strictObject({
|
|
1505
|
+
status: z.enum(["VERIFIED", "REJECTED", "INCONCLUSIVE", "ENGINE_ERROR"]),
|
|
1506
|
+
selectedCandidateIds: z.array(IdentifierSchema),
|
|
1507
|
+
reasonCodes: z.array(ReasonCodeSchema),
|
|
1508
|
+
}),
|
|
1509
|
+
candidates: z.array(z.strictObject({
|
|
1510
|
+
id: IdentifierSchema,
|
|
1511
|
+
digest: Sha256DigestSchema,
|
|
1512
|
+
status: z.enum(["ELIGIBLE", "UNSTABLE", "INCONCLUSIVE", "INVALID", "WEAK_ORACLE"]),
|
|
1513
|
+
selected: z.boolean(),
|
|
1514
|
+
reasonCodes: z.array(ReasonCodeSchema),
|
|
1515
|
+
worlds: z.array(z.strictObject({
|
|
1516
|
+
worldId: IdentifierSchema,
|
|
1517
|
+
kind: EvidenceWorldKindSchema,
|
|
1518
|
+
required: z.boolean(),
|
|
1519
|
+
weight: z.int().min(0).max(1_000_000),
|
|
1520
|
+
outcome: z.enum([
|
|
1521
|
+
"PASS",
|
|
1522
|
+
"ASSERTION_FAILURE",
|
|
1523
|
+
"COLLECTION_FAILURE",
|
|
1524
|
+
"COMPILE_FAILURE",
|
|
1525
|
+
"PROCESS_CRASH",
|
|
1526
|
+
"TIMEOUT",
|
|
1527
|
+
"INFRA_ERROR",
|
|
1528
|
+
"NO_TEST_DISCOVERED",
|
|
1529
|
+
"DIVERGENT",
|
|
1530
|
+
"MISSING",
|
|
1531
|
+
]),
|
|
1532
|
+
attempts: z.int().min(0),
|
|
1533
|
+
signal: z.enum(["RED", "GREEN", "NONE"]),
|
|
1534
|
+
detection: z.enum(["OBSERVED", "NOT_OBSERVED", "NOT_ESTABLISHED", "NOT_APPLICABLE"]),
|
|
1535
|
+
})),
|
|
1536
|
+
})),
|
|
1537
|
+
}),
|
|
1538
|
+
integrity: z.strictObject({
|
|
1539
|
+
sourceReplay: z.literal("VALID"),
|
|
1540
|
+
verifiedRails: z.tuple([
|
|
1541
|
+
z.literal("SCHEMA"),
|
|
1542
|
+
z.literal("DECISION_DIGEST"),
|
|
1543
|
+
z.literal("ARTIFACT_DIGEST"),
|
|
1544
|
+
z.literal("DECISION_SEMANTICS"),
|
|
1545
|
+
]),
|
|
1546
|
+
bindings: z.strictObject({
|
|
1547
|
+
artifactDigest: Sha256DigestSchema,
|
|
1548
|
+
decisionDigest: Sha256DigestSchema,
|
|
1549
|
+
repositoryDigest: z.union([Sha256DigestSchema, z.literal("invalid")]),
|
|
1550
|
+
policyDigest: Sha256DigestSchema,
|
|
1551
|
+
worldDigests: z.array(z.strictObject({ worldId: IdentifierSchema, digest: Sha256DigestSchema })),
|
|
1552
|
+
}),
|
|
1553
|
+
}),
|
|
1554
|
+
authenticity: z.strictObject({
|
|
1555
|
+
status: z.literal("UNAUTHENTICATED"),
|
|
1556
|
+
attestation: z.literal("NONE"),
|
|
1557
|
+
declaredProducer: z.strictObject({
|
|
1558
|
+
name: z.string().min(1).max(128),
|
|
1559
|
+
version: z.string().min(1).max(128),
|
|
1560
|
+
}),
|
|
1561
|
+
}),
|
|
1562
|
+
environment: z.strictObject({
|
|
1563
|
+
isolation: z.strictObject({
|
|
1564
|
+
kind: z.literal("trusted-local"),
|
|
1565
|
+
level: z.literal("UNSANDBOXED"),
|
|
1566
|
+
}),
|
|
1567
|
+
environmentAllowlist: z.array(z.string().min(1).max(128)).max(100),
|
|
1568
|
+
adapter: z.strictObject({
|
|
1569
|
+
kind: z.enum(["node-test", "testforge-command"]),
|
|
1570
|
+
name: z.string().min(1).max(128),
|
|
1571
|
+
version: z.string().min(1).max(128),
|
|
1572
|
+
framework: z.discriminatedUnion("status", [
|
|
1573
|
+
z.strictObject({
|
|
1574
|
+
status: z.literal("RECORDED"),
|
|
1575
|
+
profileId: z.string().min(1).max(128),
|
|
1576
|
+
profileVersion: z.string().min(1).max(128),
|
|
1577
|
+
official: z.boolean(),
|
|
1578
|
+
nodeVersion: z.string().min(1).max(128).nullable(),
|
|
1579
|
+
executableDigest: Sha256DigestSchema.nullable(),
|
|
1580
|
+
}),
|
|
1581
|
+
z.strictObject({ status: z.literal("UNKNOWN") }),
|
|
1582
|
+
]),
|
|
1583
|
+
}),
|
|
1584
|
+
}),
|
|
1585
|
+
confidence: z.strictObject({
|
|
1586
|
+
level: z.literal("REPLAY_CONSISTENT_UNAUTHENTICATED"),
|
|
1587
|
+
established: z.array(z.enum([
|
|
1588
|
+
"SOURCE_SCHEMA_VALID",
|
|
1589
|
+
"DECISION_DIGEST_RECOMPUTED",
|
|
1590
|
+
"ARTIFACT_DIGEST_RECOMPUTED",
|
|
1591
|
+
"DECISION_RECOMPUTED_FROM_RECORDED_OBSERVATIONS",
|
|
1592
|
+
])),
|
|
1593
|
+
notEstablished: z.array(z.enum([
|
|
1594
|
+
"PRODUCER_AUTHENTICITY",
|
|
1595
|
+
"OBSERVATION_TRUTHFULNESS",
|
|
1596
|
+
"EXECUTION_ISOLATION",
|
|
1597
|
+
"EXECUTION_FRESHNESS",
|
|
1598
|
+
"WORLD_SEMANTIC_RELEVANCE",
|
|
1599
|
+
])),
|
|
1600
|
+
}),
|
|
1601
|
+
scope: z.strictObject({
|
|
1602
|
+
requiredAttempts: z.int().min(1).max(1_000),
|
|
1603
|
+
candidates: z.int().min(0),
|
|
1604
|
+
observations: z.int().min(0),
|
|
1605
|
+
gitRevisions: z.enum(["RECORDED", "PARTIAL", "NOT_RECORDED"]),
|
|
1606
|
+
worlds: z.array(z.strictObject({
|
|
1607
|
+
id: IdentifierSchema,
|
|
1608
|
+
kind: EvidenceWorldKindSchema,
|
|
1609
|
+
required: z.boolean(),
|
|
1610
|
+
weight: z.int().min(0).max(1_000_000),
|
|
1611
|
+
digest: Sha256DigestSchema,
|
|
1612
|
+
declaredProvenance: z.string().min(1).max(1_024),
|
|
1613
|
+
git: z
|
|
1614
|
+
.strictObject({
|
|
1615
|
+
role: z.enum(["reference", "target", "neutral"]),
|
|
1616
|
+
commit: GitObjectIdSchema,
|
|
1617
|
+
tree: GitObjectIdSchema,
|
|
1618
|
+
objectFormat: z.enum(["sha1", "sha256"]),
|
|
1619
|
+
})
|
|
1620
|
+
.nullable(),
|
|
1621
|
+
})),
|
|
1622
|
+
}),
|
|
1623
|
+
controls: z.strictObject({
|
|
1624
|
+
executed: z.array(z.strictObject({
|
|
1625
|
+
control: z.enum([
|
|
1626
|
+
"CONTROL_WITHOUT_CANDIDATE",
|
|
1627
|
+
"REFERENCE_PASS",
|
|
1628
|
+
"REGRESSION_DETECTION",
|
|
1629
|
+
"NEUTRAL_PASS",
|
|
1630
|
+
"STABILITY_REPETITION",
|
|
1631
|
+
]),
|
|
1632
|
+
status: z.enum(["EXECUTED", "NOT_EXECUTED"]),
|
|
1633
|
+
observations: z.int().min(0),
|
|
1634
|
+
})),
|
|
1635
|
+
requested: z.union([
|
|
1636
|
+
z.strictObject({ status: z.literal("NOT_SUPPLIED") }),
|
|
1637
|
+
z.strictObject({
|
|
1638
|
+
status: z.enum(["NO_OBLIGATIONS", "COVERED", "PARTIAL", "NOT_COVERED"]),
|
|
1639
|
+
obligations: z.array(z.strictObject({
|
|
1640
|
+
id: IdentifierSchema,
|
|
1641
|
+
control: ReasonCodeSchema,
|
|
1642
|
+
coverage: z.enum(["EXECUTED", "NOT_EXECUTED", "UNSUPPORTED"]),
|
|
1643
|
+
})),
|
|
1644
|
+
}),
|
|
1645
|
+
]),
|
|
1646
|
+
omittedGates: z.array(z.strictObject({
|
|
1647
|
+
candidateId: IdentifierSchema,
|
|
1648
|
+
gate: GateResultSchema.shape.name,
|
|
1649
|
+
reasonCodes: z.array(ReasonCodeSchema),
|
|
1650
|
+
})),
|
|
1651
|
+
}),
|
|
1652
|
+
profile: z.union([
|
|
1653
|
+
z.strictObject({ status: z.literal("NOT_REQUESTED") }),
|
|
1654
|
+
z.strictObject({
|
|
1655
|
+
status: z.literal("UNKNOWN_PROFILE"),
|
|
1656
|
+
requestedProfileId: z.string().min(1).max(256),
|
|
1657
|
+
}),
|
|
1658
|
+
]),
|
|
1659
|
+
policy: z.strictObject({
|
|
1660
|
+
policyVersion: z.string().min(1).max(128),
|
|
1661
|
+
digest: Sha256DigestSchema,
|
|
1662
|
+
}),
|
|
1663
|
+
cost: z.strictObject({
|
|
1664
|
+
estimated: z.strictObject({
|
|
1665
|
+
unit: z.literal("PROCESS_EXECUTIONS"),
|
|
1666
|
+
value: z.int().min(0),
|
|
1667
|
+
basis: z.literal("RECORDED_CAMPAIGN_SHAPE"),
|
|
1668
|
+
assumptions: z.array(z.string().min(1).max(2_048)),
|
|
1669
|
+
}),
|
|
1670
|
+
observed: z.strictObject({
|
|
1671
|
+
unit: z.literal("PROCESS_EXECUTIONS"),
|
|
1672
|
+
executions: z.int().min(0),
|
|
1673
|
+
recordedWallTimeMs: z.number().finite().min(0).nullable(),
|
|
1674
|
+
wallTimeCoverage: z.enum(["COMPLETE", "PARTIAL", "NOT_RECORDED"]),
|
|
1675
|
+
}),
|
|
1676
|
+
execution: z.strictObject({
|
|
1677
|
+
freshness: z.literal("UNKNOWN"),
|
|
1678
|
+
cache: z.literal("NOT_RECORDED"),
|
|
1679
|
+
}),
|
|
1680
|
+
}),
|
|
1681
|
+
limitations: z.array(z.string().min(1).max(2_048)),
|
|
1682
|
+
exportDigest: Sha256DigestSchema,
|
|
1683
|
+
})
|
|
1684
|
+
.meta({
|
|
1685
|
+
id: "https://testforge.dev/schemas/evidence-export.v1.json",
|
|
1686
|
+
title: "AssertLedger evidence export",
|
|
1687
|
+
description: "A self-contained, replayable projection of replay-valid evidence that separates result, integrity, authenticity, environment, confidence, controls, and cost.",
|
|
1688
|
+
});
|
|
1689
|
+
export const EvidenceExportReplayResultSchema = z
|
|
1690
|
+
.strictObject({
|
|
1691
|
+
valid: z.boolean(),
|
|
1692
|
+
schemaValid: z.boolean(),
|
|
1693
|
+
sourceManifestValid: z.boolean(),
|
|
1694
|
+
exportDigestValid: z.boolean(),
|
|
1695
|
+
semanticsValid: z.boolean(),
|
|
1696
|
+
})
|
|
1697
|
+
.meta({
|
|
1698
|
+
id: "https://testforge.dev/schemas/evidence-export-replay-result.v1.json",
|
|
1699
|
+
title: "AssertLedger evidence export replay result",
|
|
1700
|
+
description: "Independent schema, source, digest, and semantic replay verdicts for an export.",
|
|
1701
|
+
});
|
|
1307
1702
|
export class ContractError extends Error {
|
|
1308
1703
|
code;
|
|
1309
1704
|
constructor(code, detail) {
|
|
@@ -1389,13 +1784,20 @@ function findReservedEnvironmentVariable(value) {
|
|
|
1389
1784
|
if (typeof value !== "object" || value === null || !("isolation" in value))
|
|
1390
1785
|
return undefined;
|
|
1391
1786
|
const isolation = value.isolation;
|
|
1392
|
-
if (typeof isolation !== "object" ||
|
|
1393
|
-
isolation === null ||
|
|
1394
|
-
!("environmentAllowlist" in isolation) ||
|
|
1395
|
-
!Array.isArray(isolation.environmentAllowlist)) {
|
|
1787
|
+
if (typeof isolation !== "object" || isolation === null)
|
|
1396
1788
|
return undefined;
|
|
1789
|
+
const names = [];
|
|
1790
|
+
if ("environmentAllowlist" in isolation && Array.isArray(isolation.environmentAllowlist)) {
|
|
1791
|
+
names.push(...isolation.environmentAllowlist);
|
|
1792
|
+
}
|
|
1793
|
+
if ("environment" in isolation && Array.isArray(isolation.environment)) {
|
|
1794
|
+
for (const variable of isolation.environment) {
|
|
1795
|
+
if (typeof variable === "object" && variable !== null && "name" in variable) {
|
|
1796
|
+
names.push(variable.name);
|
|
1797
|
+
}
|
|
1798
|
+
}
|
|
1397
1799
|
}
|
|
1398
|
-
return
|
|
1800
|
+
return names.find((variable) => {
|
|
1399
1801
|
if (typeof variable !== "string")
|
|
1400
1802
|
return false;
|
|
1401
1803
|
const normalized = variable.toUpperCase();
|
|
@@ -1411,6 +1813,55 @@ export function parseVerificationRequest(value) {
|
|
|
1411
1813
|
value.schemaVersion !== SCHEMA_VERSION) {
|
|
1412
1814
|
throw new ContractError("SCHEMA_VERSION_UNSUPPORTED");
|
|
1413
1815
|
}
|
|
1816
|
+
assertVerificationRequestPreconditions(value);
|
|
1817
|
+
const parsed = VerificationRequestSchema.safeParse(value);
|
|
1818
|
+
if (!parsed.success) {
|
|
1819
|
+
throw new ContractError("REQUEST_SCHEMA_INVALID", z.prettifyError(parsed.error));
|
|
1820
|
+
}
|
|
1821
|
+
const request = parsed.data;
|
|
1822
|
+
assertUniqueIdentifiers(request.worlds, "DUPLICATE_WORLD_ID");
|
|
1823
|
+
assertUniqueIdentifiers(request.candidates, "DUPLICATE_CANDIDATE_ID");
|
|
1824
|
+
assertWorldKinds(request);
|
|
1825
|
+
assertBudgets(request);
|
|
1826
|
+
return request;
|
|
1827
|
+
}
|
|
1828
|
+
/** Parses either the frozen v1 request or the v2 request that adds container isolation. */
|
|
1829
|
+
export function parseVersionedVerificationRequest(value) {
|
|
1830
|
+
if (typeof value === "object" &&
|
|
1831
|
+
value !== null &&
|
|
1832
|
+
"schemaVersion" in value &&
|
|
1833
|
+
value.schemaVersion === VERIFICATION_SCHEMA_VERSION_V2) {
|
|
1834
|
+
return parseVerificationRequestV2(value);
|
|
1835
|
+
}
|
|
1836
|
+
return parseVerificationRequest(value);
|
|
1837
|
+
}
|
|
1838
|
+
/** Parses only the v2 request, which adds container isolation to the frozen v1 request. */
|
|
1839
|
+
export function parseVerificationRequestV2(value) {
|
|
1840
|
+
if (typeof value !== "object" ||
|
|
1841
|
+
value === null ||
|
|
1842
|
+
!("schemaVersion" in value) ||
|
|
1843
|
+
value.schemaVersion !== VERIFICATION_SCHEMA_VERSION_V2) {
|
|
1844
|
+
throw new ContractError("SCHEMA_VERSION_UNSUPPORTED");
|
|
1845
|
+
}
|
|
1846
|
+
assertVerificationRequestPreconditions(value);
|
|
1847
|
+
const parsed = VerificationRequestV2Schema.safeParse(value);
|
|
1848
|
+
if (!parsed.success) {
|
|
1849
|
+
throw new ContractError("REQUEST_SCHEMA_INVALID", z.prettifyError(parsed.error));
|
|
1850
|
+
}
|
|
1851
|
+
const request = parsed.data;
|
|
1852
|
+
assertUniqueIdentifiers(request.worlds, "DUPLICATE_WORLD_ID");
|
|
1853
|
+
assertUniqueIdentifiers(request.candidates, "DUPLICATE_CANDIDATE_ID");
|
|
1854
|
+
assertWorldKinds(request);
|
|
1855
|
+
assertBudgets(request);
|
|
1856
|
+
if (request.isolation.kind === "container") {
|
|
1857
|
+
const names = request.isolation.environment.map((variable) => variable.name);
|
|
1858
|
+
if (new Set(names).size !== names.length) {
|
|
1859
|
+
throw new ContractError("DUPLICATE_CONTAINER_ENVIRONMENT_VARIABLE");
|
|
1860
|
+
}
|
|
1861
|
+
}
|
|
1862
|
+
return request;
|
|
1863
|
+
}
|
|
1864
|
+
function assertVerificationRequestPreconditions(value) {
|
|
1414
1865
|
const rawPolicy = "policy" in value ? value.policy : undefined;
|
|
1415
1866
|
if (typeof rawPolicy === "object" &&
|
|
1416
1867
|
rawPolicy !== null &&
|
|
@@ -1427,16 +1878,6 @@ export function parseVerificationRequest(value) {
|
|
|
1427
1878
|
if (reservedEnvironmentVariable !== undefined) {
|
|
1428
1879
|
throw new ContractError("RESERVED_ENVIRONMENT_VARIABLE", reservedEnvironmentVariable);
|
|
1429
1880
|
}
|
|
1430
|
-
const parsed = VerificationRequestSchema.safeParse(value);
|
|
1431
|
-
if (!parsed.success) {
|
|
1432
|
-
throw new ContractError("REQUEST_SCHEMA_INVALID", z.prettifyError(parsed.error));
|
|
1433
|
-
}
|
|
1434
|
-
const request = parsed.data;
|
|
1435
|
-
assertUniqueIdentifiers(request.worlds, "DUPLICATE_WORLD_ID");
|
|
1436
|
-
assertUniqueIdentifiers(request.candidates, "DUPLICATE_CANDIDATE_ID");
|
|
1437
|
-
assertWorldKinds(request);
|
|
1438
|
-
assertBudgets(request);
|
|
1439
|
-
return request;
|
|
1440
1881
|
}
|
|
1441
1882
|
export function parseRepositoryAnalysis(value) {
|
|
1442
1883
|
const parsed = RepositoryAnalysisSchema.safeParse(value);
|
|
@@ -1882,12 +2323,48 @@ export function parseEvidenceManifest(value) {
|
|
|
1882
2323
|
throw new ContractError("EVIDENCE_MANIFEST_INVALID", z.prettifyError(parsed.error));
|
|
1883
2324
|
}
|
|
1884
2325
|
const manifest = parsed.data;
|
|
2326
|
+
if (!manifestSummariesAreConsistent(manifest) || !manifestReferencesAreConsistent(manifest)) {
|
|
2327
|
+
throw new ContractError("EVIDENCE_MANIFEST_INCONSISTENT");
|
|
2328
|
+
}
|
|
2329
|
+
return manifest;
|
|
2330
|
+
}
|
|
2331
|
+
export function parseEvidenceManifestV2(value) {
|
|
2332
|
+
const parsed = EvidenceManifestV2Schema.safeParse(value);
|
|
2333
|
+
if (!parsed.success) {
|
|
2334
|
+
throw new ContractError("EVIDENCE_MANIFEST_INVALID", z.prettifyError(parsed.error));
|
|
2335
|
+
}
|
|
2336
|
+
const manifest = parsed.data;
|
|
2337
|
+
if (!manifestSummariesAreConsistent(manifest) ||
|
|
2338
|
+
!manifestReferencesAreConsistent(manifest) ||
|
|
2339
|
+
!executionBackendIsConsistent(manifest)) {
|
|
2340
|
+
throw new ContractError("EVIDENCE_MANIFEST_INCONSISTENT");
|
|
2341
|
+
}
|
|
2342
|
+
return manifest;
|
|
2343
|
+
}
|
|
2344
|
+
/** Parses either a frozen v1 manifest or a v2 manifest with an execution backend record. */
|
|
2345
|
+
export function parseVersionedEvidenceManifest(value) {
|
|
2346
|
+
return isJsonObject(value) && value.schemaVersion === VERIFICATION_SCHEMA_VERSION_V2
|
|
2347
|
+
? parseEvidenceManifestV2(value)
|
|
2348
|
+
: parseEvidenceManifest(value);
|
|
2349
|
+
}
|
|
2350
|
+
function executionBackendIsConsistent(manifest) {
|
|
2351
|
+
const execution = manifest.evidenceContext.execution;
|
|
2352
|
+
const backend = execution.backend;
|
|
2353
|
+
if (backend.kind !== manifest.isolation.kind || backend.level !== manifest.isolation.level) {
|
|
2354
|
+
return false;
|
|
2355
|
+
}
|
|
2356
|
+
if (backend.kind !== "container")
|
|
2357
|
+
return true;
|
|
2358
|
+
const names = backend.controls.environment.map((variable) => variable.name);
|
|
2359
|
+
return (new Set(names).size === names.length &&
|
|
2360
|
+
JSON.stringify([...names].sort()) === JSON.stringify(execution.environmentAllowlist));
|
|
2361
|
+
}
|
|
2362
|
+
function manifestReferencesAreConsistent(manifest) {
|
|
1885
2363
|
const worldIds = new Set(manifest.worlds.map((world) => world.id));
|
|
1886
2364
|
const candidateIds = new Set(manifest.candidates.map((candidate) => candidate.id));
|
|
1887
2365
|
const runIds = new Set(manifest.observations.map((observation) => observation.runId));
|
|
1888
2366
|
const contextWorldIds = new Set(manifest.evidenceContext.worlds.map((world) => world.id));
|
|
1889
|
-
const inconsistent =
|
|
1890
|
-
worldIds.size !== manifest.worlds.length ||
|
|
2367
|
+
const inconsistent = worldIds.size !== manifest.worlds.length ||
|
|
1891
2368
|
candidateIds.size !== manifest.candidates.length ||
|
|
1892
2369
|
runIds.size !== manifest.observations.length ||
|
|
1893
2370
|
contextWorldIds.size !== manifest.evidenceContext.worlds.length ||
|
|
@@ -1899,10 +2376,7 @@ export function parseEvidenceManifest(value) {
|
|
|
1899
2376
|
(observation.candidateId !== null && !candidateIds.has(observation.candidateId))) ||
|
|
1900
2377
|
manifest.candidates.some((candidate) => candidate.killedTargetIds.some((id) => !worldIds.has(id)) ||
|
|
1901
2378
|
candidate.gates.some((gate) => gate.evidenceRunIds.some((id) => !runIds.has(id))));
|
|
1902
|
-
|
|
1903
|
-
throw new ContractError("EVIDENCE_MANIFEST_INCONSISTENT");
|
|
1904
|
-
}
|
|
1905
|
-
return manifest;
|
|
2379
|
+
return !inconsistent;
|
|
1906
2380
|
}
|
|
1907
2381
|
export function parseReplayResult(value) {
|
|
1908
2382
|
const parsed = ReplayResultSchema.safeParse(value);
|
|
@@ -2453,6 +2927,54 @@ export function parseAgenticCorpusExperimentStructuredResult(value) {
|
|
|
2453
2927
|
}
|
|
2454
2928
|
return parsed.data;
|
|
2455
2929
|
}
|
|
2930
|
+
export function parseEvidenceProviderManifest(value) {
|
|
2931
|
+
const parsed = EvidenceProviderManifestSchema.safeParse(value);
|
|
2932
|
+
if (!parsed.success) {
|
|
2933
|
+
throw new ContractError("EVIDENCE_PROVIDER_MANIFEST_INVALID", z.prettifyError(parsed.error));
|
|
2934
|
+
}
|
|
2935
|
+
const capabilityIds = new Set(parsed.data.capabilities.map((capability) => capability.id));
|
|
2936
|
+
if (capabilityIds.size !== parsed.data.capabilities.length) {
|
|
2937
|
+
throw new ContractError("EVIDENCE_PROVIDER_MANIFEST_INCONSISTENT");
|
|
2938
|
+
}
|
|
2939
|
+
return parsed.data;
|
|
2940
|
+
}
|
|
2941
|
+
export function parseEvidenceExportRequest(value) {
|
|
2942
|
+
const parsed = EvidenceExportRequestSchema.safeParse(value);
|
|
2943
|
+
if (!parsed.success) {
|
|
2944
|
+
throw new ContractError("EVIDENCE_EXPORT_REQUEST_INVALID", z.prettifyError(parsed.error));
|
|
2945
|
+
}
|
|
2946
|
+
const request = parsed.data;
|
|
2947
|
+
parseEvidenceManifest(request.manifest);
|
|
2948
|
+
assertUniqueIdentifiers(request.consumerRequest?.obligations ?? [], "EVIDENCE_EXPORT_REQUEST_INVALID");
|
|
2949
|
+
return request;
|
|
2950
|
+
}
|
|
2951
|
+
export function parseEvidenceExport(value) {
|
|
2952
|
+
const parsed = EvidenceExportSchema.safeParse(value);
|
|
2953
|
+
if (!parsed.success) {
|
|
2954
|
+
throw new ContractError("EVIDENCE_EXPORT_INVALID", z.prettifyError(parsed.error));
|
|
2955
|
+
}
|
|
2956
|
+
const evidenceExport = parsed.data;
|
|
2957
|
+
parseEvidenceManifest(evidenceExport.sourceManifest);
|
|
2958
|
+
assertUniqueIdentifiers(evidenceExport.result.candidates, "EVIDENCE_EXPORT_INCONSISTENT");
|
|
2959
|
+
assertUniqueIdentifiers(evidenceExport.scope.worlds, "EVIDENCE_EXPORT_INCONSISTENT");
|
|
2960
|
+
assertUniqueIdentifiers(evidenceExport.consumerRequest?.obligations ?? [], "EVIDENCE_EXPORT_INCONSISTENT");
|
|
2961
|
+
return evidenceExport;
|
|
2962
|
+
}
|
|
2963
|
+
export function parseEvidenceExportReplayResult(value) {
|
|
2964
|
+
const parsed = EvidenceExportReplayResultSchema.safeParse(value);
|
|
2965
|
+
if (!parsed.success) {
|
|
2966
|
+
throw new ContractError("EVIDENCE_EXPORT_REPLAY_RESULT_INVALID", z.prettifyError(parsed.error));
|
|
2967
|
+
}
|
|
2968
|
+
const result = parsed.data;
|
|
2969
|
+
if (result.valid !==
|
|
2970
|
+
(result.schemaValid &&
|
|
2971
|
+
result.sourceManifestValid &&
|
|
2972
|
+
result.exportDigestValid &&
|
|
2973
|
+
result.semanticsValid)) {
|
|
2974
|
+
throw new ContractError("EVIDENCE_EXPORT_REPLAY_RESULT_INCONSISTENT");
|
|
2975
|
+
}
|
|
2976
|
+
return result;
|
|
2977
|
+
}
|
|
2456
2978
|
function jsonSchemaFor(schema, id) {
|
|
2457
2979
|
const generated = z.toJSONSchema(schema, {
|
|
2458
2980
|
target: "draft-2020-12",
|
|
@@ -2485,6 +3007,12 @@ export function repositoryInitResultJsonSchema() {
|
|
|
2485
3007
|
export function evidenceManifestJsonSchema() {
|
|
2486
3008
|
return jsonSchemaFor(EvidenceManifestSchema, "https://testforge.dev/schemas/evidence-manifest.v1.json");
|
|
2487
3009
|
}
|
|
3010
|
+
export function verificationRequestV2JsonSchema() {
|
|
3011
|
+
return jsonSchemaFor(VerificationRequestV2Schema, "https://testforge.dev/schemas/verification-request.v2.json");
|
|
3012
|
+
}
|
|
3013
|
+
export function evidenceManifestV2JsonSchema() {
|
|
3014
|
+
return jsonSchemaFor(EvidenceManifestV2Schema, "https://testforge.dev/schemas/evidence-manifest.v2.json");
|
|
3015
|
+
}
|
|
2488
3016
|
export function replayResultJsonSchema() {
|
|
2489
3017
|
return jsonSchemaFor(ReplayResultSchema, "https://testforge.dev/schemas/replay-result.v1.json");
|
|
2490
3018
|
}
|
|
@@ -2566,4 +3094,16 @@ export function agenticCorpusExperimentReplayRequestJsonSchema() {
|
|
|
2566
3094
|
export function agenticCorpusExperimentReplayResultJsonSchema() {
|
|
2567
3095
|
return jsonSchemaFor(AgenticCorpusExperimentReplayResultSchema, "https://testforge.dev/schemas/agentic-corpus-experiment-replay-result.v1.json");
|
|
2568
3096
|
}
|
|
3097
|
+
export function evidenceProviderManifestJsonSchema() {
|
|
3098
|
+
return jsonSchemaFor(EvidenceProviderManifestSchema, "https://testforge.dev/schemas/evidence-provider-manifest.v1.json");
|
|
3099
|
+
}
|
|
3100
|
+
export function evidenceExportRequestJsonSchema() {
|
|
3101
|
+
return jsonSchemaFor(EvidenceExportRequestSchema, "https://testforge.dev/schemas/evidence-export-request.v1.json");
|
|
3102
|
+
}
|
|
3103
|
+
export function evidenceExportJsonSchema() {
|
|
3104
|
+
return jsonSchemaFor(EvidenceExportSchema, "https://testforge.dev/schemas/evidence-export.v1.json");
|
|
3105
|
+
}
|
|
3106
|
+
export function evidenceExportReplayResultJsonSchema() {
|
|
3107
|
+
return jsonSchemaFor(EvidenceExportReplayResultSchema, "https://testforge.dev/schemas/evidence-export-replay-result.v1.json");
|
|
3108
|
+
}
|
|
2569
3109
|
//# sourceMappingURL=index.js.map
|