proof-harness 0.1.0-next.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/COMPATIBILITY.md +26 -0
- package/LICENSE +201 -0
- package/PROOF_SDK_CONTRACT.md +1255 -0
- package/README.md +60 -0
- package/cli/config.mjs +116 -0
- package/cli/engines/generate_proof_action_registry.mjs +271 -0
- package/cli/engines/parse_proof_schema.mjs +457 -0
- package/cli/engines/proof_coverage.mjs +871 -0
- package/cli/engines/proof_drift.mjs +980 -0
- package/cli/engines/proof_module_check.mjs +498 -0
- package/cli/engines/proof_mutation_check.mjs +1084 -0
- package/cli/engines/proof_mutation_inventory.mjs +508 -0
- package/cli/engines/proof_source_mutation.mjs +35 -0
- package/cli/engines/proof_verify.mjs +620 -0
- package/cli/engines/scan_module_meta.mjs +352 -0
- package/cli/engines/scan_proof_capabilities.mjs +359 -0
- package/cli/proof-harness.mjs +107 -0
- package/dist/action-types-C3OmHRyH.d.ts +26 -0
- package/dist/fixture-B-dmnG5G.d.ts +105 -0
- package/dist/mission-types-Dr5rBHYO.d.ts +299 -0
- package/dist/node.d.ts +79 -0
- package/dist/node.js +553 -0
- package/dist/node.js.map +1 -0
- package/dist/playwright.d.ts +433 -0
- package/dist/playwright.js +1824 -0
- package/dist/playwright.js.map +1 -0
- package/dist/portable-vocabulary.d.ts +86 -0
- package/dist/portable-vocabulary.js +43 -0
- package/dist/portable-vocabulary.js.map +1 -0
- package/dist/server.d.ts +55 -0
- package/dist/server.js +376 -0
- package/dist/server.js.map +1 -0
- package/dist/shared.d.ts +169 -0
- package/dist/shared.js +121 -0
- package/dist/shared.js.map +1 -0
- package/dist/trace-types-DkIzq-l9.d.ts +333 -0
- package/package.json +109 -0
- package/proof-consumer-fixtures/README.md +60 -0
- package/proof-consumer-fixtures/aggregates/M-CONFORMANCE-FAIL.json +112 -0
- package/proof-consumer-fixtures/aggregates/M-CONFORMANCE-PASS.json +101 -0
- package/proof-consumer-fixtures/baseline/failing/widgets-tenant-isolation.json +46 -0
- package/proof-consumer-fixtures/baseline/passing/widgets-tenant-isolation.json +45 -0
- package/proof-consumer-fixtures/corpus.json +102 -0
- package/proof-consumer-fixtures/duplicates/first/widgets-tenant-isolation.json +12 -0
- package/proof-consumer-fixtures/duplicates/second/widgets-tenant-isolation.json +12 -0
- package/proof-consumer-fixtures/inputs/capabilities.json +4 -0
- package/proof-consumer-fixtures/inputs/mission.json +20 -0
- package/proof-consumer-fixtures/inputs/schema.json +4 -0
- package/proof-consumer-fixtures/malformed/invalid-trace.json.invalid +4 -0
- package/proof-consumer-fixtures/malformed/wrong-manifest-version.json +11 -0
- package/proof-consumer-fixtures/malformed/wrong-trace-shape.json +8 -0
- package/proof-consumer-fixtures/mutations/MUT-WIDGETS-LEAK/mutation.json +17 -0
- package/proof-consumer-fixtures/mutations/MUT-WIDGETS-LEAK/widgets-tenant-isolation.json +50 -0
package/package.json
ADDED
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "proof-harness",
|
|
3
|
+
"version": "0.1.0-next.1",
|
|
4
|
+
"description": "Verification and conformance helpers for proof traces, missions, fixtures, and Playwright probes.",
|
|
5
|
+
"license": "Apache-2.0",
|
|
6
|
+
"author": {
|
|
7
|
+
"name": "The Nexus Collective GmbH",
|
|
8
|
+
"url": "https://nexuscollective.io"
|
|
9
|
+
},
|
|
10
|
+
"repository": {
|
|
11
|
+
"type": "git",
|
|
12
|
+
"url": "git+https://github.com/TiKa-Nexus/proof-harness.git"
|
|
13
|
+
},
|
|
14
|
+
"homepage": "https://github.com/TiKa-Nexus/proof-harness#readme",
|
|
15
|
+
"bugs": {
|
|
16
|
+
"url": "https://github.com/TiKa-Nexus/proof-harness/issues"
|
|
17
|
+
},
|
|
18
|
+
"type": "module",
|
|
19
|
+
"files": [
|
|
20
|
+
"dist",
|
|
21
|
+
"cli",
|
|
22
|
+
"README.md",
|
|
23
|
+
"COMPATIBILITY.md",
|
|
24
|
+
"PROOF_SDK_CONTRACT.md",
|
|
25
|
+
"proof-consumer-fixtures"
|
|
26
|
+
],
|
|
27
|
+
"bin": {
|
|
28
|
+
"proof-harness": "./cli/proof-harness.mjs"
|
|
29
|
+
},
|
|
30
|
+
"sideEffects": false,
|
|
31
|
+
"exports": {
|
|
32
|
+
"./shared": {
|
|
33
|
+
"types": "./dist/shared.d.ts",
|
|
34
|
+
"import": "./dist/shared.js",
|
|
35
|
+
"default": "./dist/shared.js"
|
|
36
|
+
},
|
|
37
|
+
"./node": {
|
|
38
|
+
"types": "./dist/node.d.ts",
|
|
39
|
+
"import": "./dist/node.js",
|
|
40
|
+
"default": "./dist/node.js"
|
|
41
|
+
},
|
|
42
|
+
"./playwright": {
|
|
43
|
+
"types": "./dist/playwright.d.ts",
|
|
44
|
+
"import": "./dist/playwright.js",
|
|
45
|
+
"default": "./dist/playwright.js"
|
|
46
|
+
},
|
|
47
|
+
"./server": {
|
|
48
|
+
"types": "./dist/server.d.ts",
|
|
49
|
+
"import": "./dist/server.js",
|
|
50
|
+
"default": "./dist/server.js"
|
|
51
|
+
},
|
|
52
|
+
"./portable-vocabulary": {
|
|
53
|
+
"types": "./dist/portable-vocabulary.d.ts",
|
|
54
|
+
"import": "./dist/portable-vocabulary.js",
|
|
55
|
+
"default": "./dist/portable-vocabulary.js"
|
|
56
|
+
},
|
|
57
|
+
"./package.json": "./package.json"
|
|
58
|
+
},
|
|
59
|
+
"scripts": {
|
|
60
|
+
"build": "tsup",
|
|
61
|
+
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
62
|
+
"lint": "eslint .",
|
|
63
|
+
"test": "vitest run src/__tests",
|
|
64
|
+
"conformance": "vitest run conformance",
|
|
65
|
+
"pack:check": "vitest run tests/package-content.test.ts",
|
|
66
|
+
"check": "pnpm build && pnpm typecheck && pnpm lint && pnpm test && pnpm conformance && pnpm pack:check",
|
|
67
|
+
"prepack": "pnpm build"
|
|
68
|
+
},
|
|
69
|
+
"engines": {
|
|
70
|
+
"node": ">=24 <25"
|
|
71
|
+
},
|
|
72
|
+
"peerDependencies": {
|
|
73
|
+
"@playwright/test": "^1.49.1",
|
|
74
|
+
"@supabase/supabase-js": "^2.108.2",
|
|
75
|
+
"next": "^16.3.0"
|
|
76
|
+
},
|
|
77
|
+
"peerDependenciesMeta": {
|
|
78
|
+
"@playwright/test": {
|
|
79
|
+
"optional": true
|
|
80
|
+
},
|
|
81
|
+
"@supabase/supabase-js": {
|
|
82
|
+
"optional": true
|
|
83
|
+
},
|
|
84
|
+
"next": {
|
|
85
|
+
"optional": true
|
|
86
|
+
}
|
|
87
|
+
},
|
|
88
|
+
"publishConfig": {
|
|
89
|
+
"access": "public",
|
|
90
|
+
"provenance": true
|
|
91
|
+
},
|
|
92
|
+
"dependencies": {
|
|
93
|
+
"@next/env": "16.3.0"
|
|
94
|
+
},
|
|
95
|
+
"devDependencies": {
|
|
96
|
+
"@eslint/js": "9.39.1",
|
|
97
|
+
"@playwright/test": "^1.57.0",
|
|
98
|
+
"@supabase/supabase-js": "^2.108.2",
|
|
99
|
+
"@types/node": "^24.13.3",
|
|
100
|
+
"eslint": "9.39.1",
|
|
101
|
+
"globals": "^15.15.0",
|
|
102
|
+
"next": "^16.3.0",
|
|
103
|
+
"tsup": "^8.5.1",
|
|
104
|
+
"typescript": "5.9.3",
|
|
105
|
+
"typescript-eslint": "8.49.0",
|
|
106
|
+
"vitest": "3.0.5"
|
|
107
|
+
},
|
|
108
|
+
"packageManager": "pnpm@11.9.0+sha512.bd682d5d03fe525ef7c9fd6780c6884d1e756ac4c9c9fe00c538782824310dcf90e3ddc4f53835f06dfaebd5085e41855e0bcbb3b60de2ac5bbab89e5036f03b"
|
|
109
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# Proof consumer conformance fixtures
|
|
2
|
+
|
|
3
|
+
This directory is the executable ingestion contract for systems that download
|
|
4
|
+
`proof-traces` and `proof-traces-mutated`. The prose contract remains
|
|
5
|
+
[`PROOF_SDK_CONTRACT.md`](../PROOF_SDK_CONTRACT.md); `corpus.json` names each
|
|
6
|
+
case and its expected classification or rejection.
|
|
7
|
+
|
|
8
|
+
## What the corpus covers
|
|
9
|
+
|
|
10
|
+
- a passing and a failing per-spec `TraceArtifact`
|
|
11
|
+
- passing and failing mission aggregates containing those traces
|
|
12
|
+
- a mutation directory whose trace deliberately reuses the baseline filename
|
|
13
|
+
- two valid traces with the same `proofId`
|
|
14
|
+
- invalid JSON, a wrong trace shape, and an unsupported manifest version
|
|
15
|
+
|
|
16
|
+
The small `inputs/` artifacts let the passing and failing traces run through the
|
|
17
|
+
same `validateMission` implementation used by `pnpm proof:verify`.
|
|
18
|
+
|
|
19
|
+
## Required ingestion behavior
|
|
20
|
+
|
|
21
|
+
1. Parse JSON without repairing or defaulting malformed input.
|
|
22
|
+
2. Classify before accumulating. A per-spec trace has `schemaVersion: 2` and a
|
|
23
|
+
`steps` array; a mission aggregate has `schemaVersion: 1` plus `proofs` and
|
|
24
|
+
`traces` arrays. Never count the aggregate itself as another trace.
|
|
25
|
+
3. Keep normal and mutation artifacts in separate namespaces. The mutation
|
|
26
|
+
trace intentionally has the same filename and `proofId` as the passing
|
|
27
|
+
baseline trace.
|
|
28
|
+
4. Preserve and cross-check mutation identity. The directory name,
|
|
29
|
+
`mutation.json.id`, and every trace's `mutation.id` must agree, and
|
|
30
|
+
`mutation.planted` must be `true`.
|
|
31
|
+
5. Reject duplicate `proofId` values in one baseline bundle before writing to a
|
|
32
|
+
map or database. Last-write-wins loses evidence and provenance.
|
|
33
|
+
6. Read a mission verdict from the aggregate's top-level `passed` boolean, not
|
|
34
|
+
file presence or the HTTP/check status alone. Keep `issues` on failure.
|
|
35
|
+
7. Retain `requirementEvidence`. Every satisfied entry must resolve to the named
|
|
36
|
+
`proofId`/`specFile` and to a passing assertion with the same
|
|
37
|
+
`kind`/`target`/`role` inside `traces`.
|
|
38
|
+
8. Treat mutation traces as detection evidence, never as mission evidence. A
|
|
39
|
+
red mutation trace is expected when `mutation.json.detected` is `true`.
|
|
40
|
+
|
|
41
|
+
`corpus.json` uses stable expected error labels (`invalid_json`,
|
|
42
|
+
`trace_shape`, and `duplicate_proof_id`) for conformance assertions. Consumers
|
|
43
|
+
may expose different public error names, but must reject the same inputs for the
|
|
44
|
+
same reasons.
|
|
45
|
+
|
|
46
|
+
## Running the reference checks
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
pnpm conformance
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
External orchestrators should run this same directory through their production
|
|
53
|
+
ingestion path and assert the outcomes in `corpus.json`. The package conformance
|
|
54
|
+
tests prove that the fixtures agree with the canonical mission validator; they
|
|
55
|
+
cannot prove that another system preserves the same classifications after
|
|
56
|
+
download, extraction, storage, or deduplication.
|
|
57
|
+
|
|
58
|
+
GitHub token permissions, check-run classification, and repository-readiness
|
|
59
|
+
polling are intentionally outside this corpus because they are integration
|
|
60
|
+
policy rather than evidence format behavior.
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": 1,
|
|
3
|
+
"missionId": "M-CONFORMANCE",
|
|
4
|
+
"provenance": {
|
|
5
|
+
"commit": "2222222222222222222222222222222222222222",
|
|
6
|
+
"branch": "feature/proof-consumer",
|
|
7
|
+
"dirty": false,
|
|
8
|
+
"repository": "example/proof-consumer",
|
|
9
|
+
"ci": true,
|
|
10
|
+
"runId": "1002",
|
|
11
|
+
"command": "node scripts/proof_verify.mjs",
|
|
12
|
+
"nodeVersion": "v24.6.0",
|
|
13
|
+
"platform": "linux-x64"
|
|
14
|
+
},
|
|
15
|
+
"passed": false,
|
|
16
|
+
"aggregatedAt": "2026-08-24T12:02:30.000Z",
|
|
17
|
+
"manifestSummary": {
|
|
18
|
+
"missionTitle": "Consumer conformance fixture",
|
|
19
|
+
"capabilities_must_exist": 0,
|
|
20
|
+
"schema_must_contain": 0,
|
|
21
|
+
"trace_must_prove": 1
|
|
22
|
+
},
|
|
23
|
+
"issues": [
|
|
24
|
+
{
|
|
25
|
+
"category": "trace_missing",
|
|
26
|
+
"message": "no passing role=\"primary\" assertion found with kind=\"tenant_isolation\" and target=\"widgets\"; found 1 matching assertion(s) but they FAILED: [widgets-tenant-isolation] outsider saw 1 of 1 widget rows; description: \"A member cannot read another workspace's widgets\"",
|
|
27
|
+
"context": {
|
|
28
|
+
"requirement": {
|
|
29
|
+
"kind": "tenant_isolation",
|
|
30
|
+
"target": "widgets",
|
|
31
|
+
"proofId": "widgets-tenant-isolation",
|
|
32
|
+
"description": "A member cannot read another workspace's widgets"
|
|
33
|
+
},
|
|
34
|
+
"candidateCount": 1
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
],
|
|
38
|
+
"requirementEvidence": [
|
|
39
|
+
{
|
|
40
|
+
"kind": "tenant_isolation",
|
|
41
|
+
"target": "widgets",
|
|
42
|
+
"role": "primary",
|
|
43
|
+
"satisfied": false
|
|
44
|
+
}
|
|
45
|
+
],
|
|
46
|
+
"proofs": [
|
|
47
|
+
{
|
|
48
|
+
"proofId": "widgets-tenant-isolation",
|
|
49
|
+
"missionId": "M-CONFORMANCE",
|
|
50
|
+
"specFile": "e2e/proofs/widgets-tenant-isolation.proof.ts",
|
|
51
|
+
"specHash": "0123456789ab",
|
|
52
|
+
"passed": false,
|
|
53
|
+
"durationMs": 25,
|
|
54
|
+
"stepCount": 1,
|
|
55
|
+
"assertionCount": 2,
|
|
56
|
+
"assertionStatus": {
|
|
57
|
+
"passed": 1,
|
|
58
|
+
"failed": 1,
|
|
59
|
+
"incomplete": 0,
|
|
60
|
+
"skipped": 0
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
],
|
|
64
|
+
"traces": [
|
|
65
|
+
{
|
|
66
|
+
"schemaVersion": 2,
|
|
67
|
+
"proofId": "widgets-tenant-isolation",
|
|
68
|
+
"missionId": "M-CONFORMANCE",
|
|
69
|
+
"specFile": "e2e/proofs/widgets-tenant-isolation.proof.ts",
|
|
70
|
+
"specHash": "0123456789ab",
|
|
71
|
+
"commit": "2222222222222222222222222222222222222222",
|
|
72
|
+
"dirty": false,
|
|
73
|
+
"timestamp": "2026-08-24T12:02:00.000Z",
|
|
74
|
+
"durationMs": 25,
|
|
75
|
+
"passed": false,
|
|
76
|
+
"steps": [
|
|
77
|
+
{
|
|
78
|
+
"intent": "Prove workspace B cannot select workspace A's widgets",
|
|
79
|
+
"kind": "tenant_isolation",
|
|
80
|
+
"target": "widgets",
|
|
81
|
+
"observation": "The outsider unexpectedly saw the fixture row.",
|
|
82
|
+
"passed": false,
|
|
83
|
+
"actor": "member",
|
|
84
|
+
"workspaceId": "00000000-0000-0000-0000-000000000001",
|
|
85
|
+
"durationMs": 25,
|
|
86
|
+
"error": "[PROOF_FAIL] tenant_isolation: expected 0 rows; found 1; check widgets SELECT policy",
|
|
87
|
+
"assertions": [
|
|
88
|
+
{
|
|
89
|
+
"kind": "tenant_isolation",
|
|
90
|
+
"target": "widgets",
|
|
91
|
+
"operation": "select",
|
|
92
|
+
"passed": false,
|
|
93
|
+
"status": "failed",
|
|
94
|
+
"role": "primary",
|
|
95
|
+
"detail": "outsider saw 1 of 1 widget rows",
|
|
96
|
+
"emittedBy": "assert.tenantIsolation"
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
"kind": "happy_path",
|
|
100
|
+
"target": "widgets",
|
|
101
|
+
"operation": "select",
|
|
102
|
+
"passed": true,
|
|
103
|
+
"status": "passed",
|
|
104
|
+
"role": "control",
|
|
105
|
+
"detail": "owner saw the fixture widget row"
|
|
106
|
+
}
|
|
107
|
+
]
|
|
108
|
+
}
|
|
109
|
+
]
|
|
110
|
+
}
|
|
111
|
+
]
|
|
112
|
+
}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": 1,
|
|
3
|
+
"missionId": "M-CONFORMANCE",
|
|
4
|
+
"provenance": {
|
|
5
|
+
"commit": "1111111111111111111111111111111111111111",
|
|
6
|
+
"branch": "feature/proof-consumer",
|
|
7
|
+
"dirty": false,
|
|
8
|
+
"repository": "example/proof-consumer",
|
|
9
|
+
"ci": true,
|
|
10
|
+
"runId": "1001",
|
|
11
|
+
"command": "node scripts/proof_verify.mjs",
|
|
12
|
+
"nodeVersion": "v24.6.0",
|
|
13
|
+
"platform": "linux-x64"
|
|
14
|
+
},
|
|
15
|
+
"passed": true,
|
|
16
|
+
"aggregatedAt": "2026-08-24T12:01:30.000Z",
|
|
17
|
+
"manifestSummary": {
|
|
18
|
+
"missionTitle": "Consumer conformance fixture",
|
|
19
|
+
"capabilities_must_exist": 0,
|
|
20
|
+
"schema_must_contain": 0,
|
|
21
|
+
"trace_must_prove": 1
|
|
22
|
+
},
|
|
23
|
+
"issues": [],
|
|
24
|
+
"requirementEvidence": [
|
|
25
|
+
{
|
|
26
|
+
"kind": "tenant_isolation",
|
|
27
|
+
"target": "widgets",
|
|
28
|
+
"role": "primary",
|
|
29
|
+
"satisfied": true,
|
|
30
|
+
"proofId": "widgets-tenant-isolation",
|
|
31
|
+
"specFile": "e2e/proofs/widgets-tenant-isolation.proof.ts",
|
|
32
|
+
"detail": "outsider saw 0 of 1 widget rows",
|
|
33
|
+
"emittedBy": "assert.tenantIsolation"
|
|
34
|
+
}
|
|
35
|
+
],
|
|
36
|
+
"proofs": [
|
|
37
|
+
{
|
|
38
|
+
"proofId": "widgets-tenant-isolation",
|
|
39
|
+
"missionId": "M-CONFORMANCE",
|
|
40
|
+
"specFile": "e2e/proofs/widgets-tenant-isolation.proof.ts",
|
|
41
|
+
"specHash": "0123456789ab",
|
|
42
|
+
"passed": true,
|
|
43
|
+
"durationMs": 24,
|
|
44
|
+
"stepCount": 1,
|
|
45
|
+
"assertionCount": 2,
|
|
46
|
+
"assertionStatus": {
|
|
47
|
+
"passed": 2,
|
|
48
|
+
"failed": 0,
|
|
49
|
+
"incomplete": 0,
|
|
50
|
+
"skipped": 0
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
],
|
|
54
|
+
"traces": [
|
|
55
|
+
{
|
|
56
|
+
"schemaVersion": 2,
|
|
57
|
+
"proofId": "widgets-tenant-isolation",
|
|
58
|
+
"missionId": "M-CONFORMANCE",
|
|
59
|
+
"specFile": "e2e/proofs/widgets-tenant-isolation.proof.ts",
|
|
60
|
+
"specHash": "0123456789ab",
|
|
61
|
+
"commit": "1111111111111111111111111111111111111111",
|
|
62
|
+
"dirty": false,
|
|
63
|
+
"timestamp": "2026-08-24T12:01:00.000Z",
|
|
64
|
+
"durationMs": 24,
|
|
65
|
+
"passed": true,
|
|
66
|
+
"steps": [
|
|
67
|
+
{
|
|
68
|
+
"intent": "Prove workspace B cannot select workspace A's widgets",
|
|
69
|
+
"kind": "tenant_isolation",
|
|
70
|
+
"target": "widgets",
|
|
71
|
+
"observation": "The outsider saw 0 of 1 rows and the owner saw the fixture row.",
|
|
72
|
+
"passed": true,
|
|
73
|
+
"actor": "member",
|
|
74
|
+
"workspaceId": "00000000-0000-0000-0000-000000000001",
|
|
75
|
+
"durationMs": 24,
|
|
76
|
+
"assertions": [
|
|
77
|
+
{
|
|
78
|
+
"kind": "tenant_isolation",
|
|
79
|
+
"target": "widgets",
|
|
80
|
+
"operation": "select",
|
|
81
|
+
"passed": true,
|
|
82
|
+
"status": "passed",
|
|
83
|
+
"role": "primary",
|
|
84
|
+
"detail": "outsider saw 0 of 1 widget rows",
|
|
85
|
+
"emittedBy": "assert.tenantIsolation"
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
"kind": "happy_path",
|
|
89
|
+
"target": "widgets",
|
|
90
|
+
"operation": "select",
|
|
91
|
+
"passed": true,
|
|
92
|
+
"status": "passed",
|
|
93
|
+
"role": "control",
|
|
94
|
+
"detail": "owner saw the fixture widget row"
|
|
95
|
+
}
|
|
96
|
+
]
|
|
97
|
+
}
|
|
98
|
+
]
|
|
99
|
+
}
|
|
100
|
+
]
|
|
101
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": 2,
|
|
3
|
+
"proofId": "widgets-tenant-isolation",
|
|
4
|
+
"missionId": "M-CONFORMANCE",
|
|
5
|
+
"specFile": "e2e/proofs/widgets-tenant-isolation.proof.ts",
|
|
6
|
+
"specHash": "0123456789ab",
|
|
7
|
+
"commit": "2222222222222222222222222222222222222222",
|
|
8
|
+
"dirty": false,
|
|
9
|
+
"timestamp": "2026-08-24T12:02:00.000Z",
|
|
10
|
+
"durationMs": 25,
|
|
11
|
+
"passed": false,
|
|
12
|
+
"steps": [
|
|
13
|
+
{
|
|
14
|
+
"intent": "Prove workspace B cannot select workspace A's widgets",
|
|
15
|
+
"kind": "tenant_isolation",
|
|
16
|
+
"target": "widgets",
|
|
17
|
+
"observation": "The outsider unexpectedly saw the fixture row.",
|
|
18
|
+
"passed": false,
|
|
19
|
+
"actor": "member",
|
|
20
|
+
"workspaceId": "00000000-0000-0000-0000-000000000001",
|
|
21
|
+
"durationMs": 25,
|
|
22
|
+
"error": "[PROOF_FAIL] tenant_isolation: expected 0 rows; found 1; check widgets SELECT policy",
|
|
23
|
+
"assertions": [
|
|
24
|
+
{
|
|
25
|
+
"kind": "tenant_isolation",
|
|
26
|
+
"target": "widgets",
|
|
27
|
+
"operation": "select",
|
|
28
|
+
"passed": false,
|
|
29
|
+
"status": "failed",
|
|
30
|
+
"role": "primary",
|
|
31
|
+
"detail": "outsider saw 1 of 1 widget rows",
|
|
32
|
+
"emittedBy": "assert.tenantIsolation"
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
"kind": "happy_path",
|
|
36
|
+
"target": "widgets",
|
|
37
|
+
"operation": "select",
|
|
38
|
+
"passed": true,
|
|
39
|
+
"status": "passed",
|
|
40
|
+
"role": "control",
|
|
41
|
+
"detail": "owner saw the fixture widget row"
|
|
42
|
+
}
|
|
43
|
+
]
|
|
44
|
+
}
|
|
45
|
+
]
|
|
46
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": 2,
|
|
3
|
+
"proofId": "widgets-tenant-isolation",
|
|
4
|
+
"missionId": "M-CONFORMANCE",
|
|
5
|
+
"specFile": "e2e/proofs/widgets-tenant-isolation.proof.ts",
|
|
6
|
+
"specHash": "0123456789ab",
|
|
7
|
+
"commit": "1111111111111111111111111111111111111111",
|
|
8
|
+
"dirty": false,
|
|
9
|
+
"timestamp": "2026-08-24T12:01:00.000Z",
|
|
10
|
+
"durationMs": 24,
|
|
11
|
+
"passed": true,
|
|
12
|
+
"steps": [
|
|
13
|
+
{
|
|
14
|
+
"intent": "Prove workspace B cannot select workspace A's widgets",
|
|
15
|
+
"kind": "tenant_isolation",
|
|
16
|
+
"target": "widgets",
|
|
17
|
+
"observation": "The outsider saw 0 of 1 rows and the owner saw the fixture row.",
|
|
18
|
+
"passed": true,
|
|
19
|
+
"actor": "member",
|
|
20
|
+
"workspaceId": "00000000-0000-0000-0000-000000000001",
|
|
21
|
+
"durationMs": 24,
|
|
22
|
+
"assertions": [
|
|
23
|
+
{
|
|
24
|
+
"kind": "tenant_isolation",
|
|
25
|
+
"target": "widgets",
|
|
26
|
+
"operation": "select",
|
|
27
|
+
"passed": true,
|
|
28
|
+
"status": "passed",
|
|
29
|
+
"role": "primary",
|
|
30
|
+
"detail": "outsider saw 0 of 1 widget rows",
|
|
31
|
+
"emittedBy": "assert.tenantIsolation"
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
"kind": "happy_path",
|
|
35
|
+
"target": "widgets",
|
|
36
|
+
"operation": "select",
|
|
37
|
+
"passed": true,
|
|
38
|
+
"status": "passed",
|
|
39
|
+
"role": "control",
|
|
40
|
+
"detail": "owner saw the fixture widget row"
|
|
41
|
+
}
|
|
42
|
+
]
|
|
43
|
+
}
|
|
44
|
+
]
|
|
45
|
+
}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": 1,
|
|
3
|
+
"description": "Canonical conformance corpus for consumers of Proof evidence artifacts.",
|
|
4
|
+
"sharedInputs": {
|
|
5
|
+
"manifest": "inputs/mission.json",
|
|
6
|
+
"capabilities": "inputs/capabilities.json",
|
|
7
|
+
"schema": "inputs/schema.json"
|
|
8
|
+
},
|
|
9
|
+
"cases": [
|
|
10
|
+
{
|
|
11
|
+
"id": "baseline-passing",
|
|
12
|
+
"kind": "baseline_trace",
|
|
13
|
+
"path": "baseline/passing/widgets-tenant-isolation.json",
|
|
14
|
+
"expected": {
|
|
15
|
+
"classification": "trace",
|
|
16
|
+
"missionValidation": "pass"
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
"id": "baseline-failing",
|
|
21
|
+
"kind": "baseline_trace",
|
|
22
|
+
"path": "baseline/failing/widgets-tenant-isolation.json",
|
|
23
|
+
"expected": {
|
|
24
|
+
"classification": "trace",
|
|
25
|
+
"missionValidation": "fail",
|
|
26
|
+
"issueCategories": ["trace_missing"]
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
"id": "mission-aggregate-passing",
|
|
31
|
+
"kind": "mission_aggregate",
|
|
32
|
+
"path": "aggregates/M-CONFORMANCE-PASS.json",
|
|
33
|
+
"expected": {
|
|
34
|
+
"classification": "mission_aggregate",
|
|
35
|
+
"passed": true,
|
|
36
|
+
"mustNotBeIngestedAsTrace": true
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
"id": "mission-aggregate-failing",
|
|
41
|
+
"kind": "mission_aggregate",
|
|
42
|
+
"path": "aggregates/M-CONFORMANCE-FAIL.json",
|
|
43
|
+
"expected": {
|
|
44
|
+
"classification": "mission_aggregate",
|
|
45
|
+
"passed": false,
|
|
46
|
+
"issueCategories": ["trace_missing"],
|
|
47
|
+
"mustNotBeIngestedAsTrace": true
|
|
48
|
+
}
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
"id": "mutation-directory",
|
|
52
|
+
"kind": "mutation_directory",
|
|
53
|
+
"path": "mutations/MUT-WIDGETS-LEAK",
|
|
54
|
+
"expected": {
|
|
55
|
+
"classification": "mutation_directory",
|
|
56
|
+
"mutationId": "MUT-WIDGETS-LEAK",
|
|
57
|
+
"detected": true,
|
|
58
|
+
"mustRemainSeparateFromBaseline": true
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
"id": "duplicate-proof-id",
|
|
63
|
+
"kind": "duplicate_set",
|
|
64
|
+
"paths": [
|
|
65
|
+
"duplicates/first/widgets-tenant-isolation.json",
|
|
66
|
+
"duplicates/second/widgets-tenant-isolation.json"
|
|
67
|
+
],
|
|
68
|
+
"expected": {
|
|
69
|
+
"classification": "reject",
|
|
70
|
+
"error": "duplicate_proof_id"
|
|
71
|
+
}
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
"id": "malformed-json",
|
|
75
|
+
"kind": "malformed",
|
|
76
|
+
"path": "malformed/invalid-trace.json.invalid",
|
|
77
|
+
"expected": {
|
|
78
|
+
"classification": "reject",
|
|
79
|
+
"error": "invalid_json"
|
|
80
|
+
}
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
"id": "malformed-trace-shape",
|
|
84
|
+
"kind": "malformed",
|
|
85
|
+
"path": "malformed/wrong-trace-shape.json",
|
|
86
|
+
"expected": {
|
|
87
|
+
"classification": "reject",
|
|
88
|
+
"error": "trace_shape"
|
|
89
|
+
}
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
"id": "malformed-manifest",
|
|
93
|
+
"kind": "malformed_manifest",
|
|
94
|
+
"path": "malformed/wrong-manifest-version.json",
|
|
95
|
+
"expected": {
|
|
96
|
+
"classification": "manifest",
|
|
97
|
+
"missionValidation": "fail",
|
|
98
|
+
"issueCategories": ["manifest_shape"]
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
]
|
|
102
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": 2,
|
|
3
|
+
"proofId": "widgets-tenant-isolation",
|
|
4
|
+
"specFile": "e2e/proofs/widgets-tenant-isolation.proof.ts",
|
|
5
|
+
"specHash": "0123456789ab",
|
|
6
|
+
"commit": "3333333333333333333333333333333333333333",
|
|
7
|
+
"dirty": false,
|
|
8
|
+
"timestamp": "2026-08-24T12:04:00.000Z",
|
|
9
|
+
"durationMs": 10,
|
|
10
|
+
"passed": true,
|
|
11
|
+
"steps": []
|
|
12
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": 2,
|
|
3
|
+
"proofId": "widgets-tenant-isolation",
|
|
4
|
+
"specFile": "e2e/proofs/widgets-tenant-isolation.proof.ts",
|
|
5
|
+
"specHash": "fedcba987654",
|
|
6
|
+
"commit": "4444444444444444444444444444444444444444",
|
|
7
|
+
"dirty": false,
|
|
8
|
+
"timestamp": "2026-08-24T12:05:00.000Z",
|
|
9
|
+
"durationMs": 11,
|
|
10
|
+
"passed": true,
|
|
11
|
+
"steps": []
|
|
12
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": 1,
|
|
3
|
+
"missionId": "M-CONFORMANCE",
|
|
4
|
+
"missionTitle": "Consumer conformance fixture",
|
|
5
|
+
"productRepo": "example/proof-consumer",
|
|
6
|
+
"prBranch": "feature/proof-consumer",
|
|
7
|
+
"createdAt": "2026-08-24T12:00:00.000Z",
|
|
8
|
+
"requirements": {
|
|
9
|
+
"capabilities_must_exist": [],
|
|
10
|
+
"schema_must_contain": [],
|
|
11
|
+
"trace_must_prove": [
|
|
12
|
+
{
|
|
13
|
+
"kind": "tenant_isolation",
|
|
14
|
+
"target": "widgets",
|
|
15
|
+
"proofId": "widgets-tenant-isolation",
|
|
16
|
+
"description": "A member cannot read another workspace's widgets"
|
|
17
|
+
}
|
|
18
|
+
]
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": 99,
|
|
3
|
+
"missionId": "M-CONFORMANCE-MALFORMED",
|
|
4
|
+
"missionTitle": "Unsupported manifest version",
|
|
5
|
+
"createdAt": "2026-08-24T12:06:00.000Z",
|
|
6
|
+
"requirements": {
|
|
7
|
+
"capabilities_must_exist": [],
|
|
8
|
+
"schema_must_contain": [],
|
|
9
|
+
"trace_must_prove": []
|
|
10
|
+
}
|
|
11
|
+
}
|