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
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
import { h as ProofKind, d as AssertionRole, k as ProofVerb, l as RlsClassification, y as PolicyCommand } from './trace-types-DkIzq-l9.js';
|
|
2
|
+
import { ACTION_CHANGE_KINDS, TABLE_CHANGE_KINDS } from './portable-vocabulary.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Manifest schema version. Deliberately still 1 after the July 2026 validator
|
|
6
|
+
* work: `trace_must_prove[].role` and `.proofId` are OPTIONAL additions, so
|
|
7
|
+
* every v1 manifest is still shape-valid and consumers need not regenerate
|
|
8
|
+
* anything. Note that validation did get stricter — a `control` assertion can
|
|
9
|
+
* no longer satisfy a requirement — so a manifest that passed on a vacuous
|
|
10
|
+
* probe before may now (correctly) fail. That is a behaviour tightening, not a
|
|
11
|
+
* shape change, and bumping the version would have forced a rewrite of every
|
|
12
|
+
* existing manifest for no benefit.
|
|
13
|
+
*/
|
|
14
|
+
declare const MISSION_MANIFEST_SCHEMA_VERSION = 1;
|
|
15
|
+
interface CapabilityRequirement {
|
|
16
|
+
/** Matches `createAction({ functionName: <name> })` exactly. */
|
|
17
|
+
name: string;
|
|
18
|
+
/** Module folder name (e.g. `"issues"`, not `"__business-logic/issues"`). */
|
|
19
|
+
module: string;
|
|
20
|
+
/** One of PROOF_VERBS. */
|
|
21
|
+
verb: ProofVerb;
|
|
22
|
+
/** Free-form noun, lowercased by convention (e.g. `"issue"`, `"workspace"`). */
|
|
23
|
+
object: string;
|
|
24
|
+
/** Optional: invariants that the action's `withProof({ invariants })` must advertise. */
|
|
25
|
+
invariants?: readonly string[];
|
|
26
|
+
}
|
|
27
|
+
interface SchemaRequirement {
|
|
28
|
+
/** Unqualified public-schema table name. */
|
|
29
|
+
table: string;
|
|
30
|
+
/** Columns that must exist on the table. Order-insensitive. */
|
|
31
|
+
required_columns: readonly string[];
|
|
32
|
+
/** One of RLS_CLASSIFICATIONS. */
|
|
33
|
+
rls_classification: RlsClassification;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* "No policy on this table targets this role for these commands."
|
|
37
|
+
*
|
|
38
|
+
* Exists because `rls_classification` is one label per table and Postgres RLS is
|
|
39
|
+
* per-command: `audit_logs` being "admin readable, service writable" cannot be
|
|
40
|
+
* said with a single label, and the label a manifest picks would have to be a
|
|
41
|
+
* lie in one direction or the other.
|
|
42
|
+
*
|
|
43
|
+
* Checks reachability, not the predicate — `USING` and `WITH CHECK` are not read.
|
|
44
|
+
* A policy `TO authenticated USING (is_super_admin())` counts as targeting
|
|
45
|
+
* `authenticated`, so "this role may act only under condition X" is not
|
|
46
|
+
* expressible here and belongs in `trace_must_prove`, where something exercises
|
|
47
|
+
* it. Write prohibitions ("members never INSERT into the audit log") are the
|
|
48
|
+
* natural fit.
|
|
49
|
+
*
|
|
50
|
+
* Deliberately only the prohibition, never "a policy must exist". A policy's
|
|
51
|
+
* existence is weak evidence — it says a rule was written, not that it works —
|
|
52
|
+
* and the thing that makes a permission real is a passing proof, which belongs in
|
|
53
|
+
* `trace_must_prove`. A prohibition is different: it is a claim that can fail
|
|
54
|
+
* dangerously and silently, and it is checkable from the migrations alone.
|
|
55
|
+
*/
|
|
56
|
+
interface PolicyProhibition {
|
|
57
|
+
/** Unqualified public-schema table name. */
|
|
58
|
+
table: string;
|
|
59
|
+
/**
|
|
60
|
+
* Database role that must not be granted access, e.g. `"authenticated"` or
|
|
61
|
+
* `"anon"`. A policy with no `TO` clause defaults to `PUBLIC` in Postgres and
|
|
62
|
+
* therefore counts as granting every role.
|
|
63
|
+
*/
|
|
64
|
+
role: string;
|
|
65
|
+
/**
|
|
66
|
+
* Commands the prohibition covers. Omit to mean "any command". A policy
|
|
67
|
+
* declared `FOR ALL` matches whatever is listed here, because that is what it
|
|
68
|
+
* does in the database.
|
|
69
|
+
*/
|
|
70
|
+
commands?: readonly PolicyCommand[];
|
|
71
|
+
/** Human-readable statement of the rule, echoed in the failure message. */
|
|
72
|
+
description: string;
|
|
73
|
+
}
|
|
74
|
+
interface TraceRequirement {
|
|
75
|
+
/** One of PROOF_KINDS. */
|
|
76
|
+
kind: ProofKind;
|
|
77
|
+
/**
|
|
78
|
+
* Free-form identifier the assertion emits. Must match an assertion's
|
|
79
|
+
* `target` exactly (e.g. table name for `tenant_isolation`, capability
|
|
80
|
+
* name for `authorization`).
|
|
81
|
+
*/
|
|
82
|
+
target: string;
|
|
83
|
+
/** Human-readable statement of what should be proved. */
|
|
84
|
+
description: string;
|
|
85
|
+
/**
|
|
86
|
+
* Which evidential role must satisfy this requirement. Defaults to
|
|
87
|
+
* `"primary"`, which is almost always what you want: a `"control"`
|
|
88
|
+
* assertion passes by design and proves only that the probe was capable of
|
|
89
|
+
* failing, so it must never stand in for the claim itself.
|
|
90
|
+
*
|
|
91
|
+
* Accepts the deprecated spellings `"negative"` / `"positive_control"`.
|
|
92
|
+
*/
|
|
93
|
+
role?: AssertionRole;
|
|
94
|
+
/**
|
|
95
|
+
* Optional: restrict matching to assertions emitted by this proof.
|
|
96
|
+
*
|
|
97
|
+
* By default a requirement may be satisfied by a matching assertion from
|
|
98
|
+
* ANY proof in the run. That is convenient but means an unrelated spec can
|
|
99
|
+
* unknowingly satisfy a mission's requirement. Set this when the mission
|
|
100
|
+
* cares that a SPECIFIC proof made the claim. Either way, the aggregated
|
|
101
|
+
* trace records which proof actually supplied the evidence.
|
|
102
|
+
*/
|
|
103
|
+
proofId?: string;
|
|
104
|
+
/**
|
|
105
|
+
* What origin of assertion may satisfy this requirement.
|
|
106
|
+
*
|
|
107
|
+
* - `"helper"` — only assertions stamped `emittedBy` by an SDK `assert.*`
|
|
108
|
+
* helper count. Helper assertions went through the SDK's vacuity
|
|
109
|
+
* controls and ground-truth re-reads; a spec-recorded assertion asserts
|
|
110
|
+
* whatever the spec wrote into it.
|
|
111
|
+
* - `"any"` — spec-recorded assertions (raw `recordAssertion`) count too.
|
|
112
|
+
* Those claims remain backstopped by the mutation inventory, which is
|
|
113
|
+
* why bespoke probes (RPC grants, column guards) stay expressible.
|
|
114
|
+
*
|
|
115
|
+
* `tenant_isolation` is always `"helper"`, and the stamp is additionally
|
|
116
|
+
* identity-checked (see TENANT_ISOLATION_TABLE_HELPERS in trace-types):
|
|
117
|
+
* declaring `evidence: "any"` for it is a `manifest_shape` error, so the
|
|
118
|
+
* mission gate and strict coverage can never disagree about whether a raw
|
|
119
|
+
* isolation assertion is admissible. Every other kind defaults to `"any"`.
|
|
120
|
+
*/
|
|
121
|
+
evidence?: EvidenceOrigin;
|
|
122
|
+
}
|
|
123
|
+
/** Origin of assertion allowed to satisfy a `trace_must_prove` entry. */
|
|
124
|
+
type EvidenceOrigin = "helper" | "any";
|
|
125
|
+
interface MissionRequirements {
|
|
126
|
+
capabilities_must_exist: readonly CapabilityRequirement[];
|
|
127
|
+
schema_must_contain: readonly SchemaRequirement[];
|
|
128
|
+
trace_must_prove: readonly TraceRequirement[];
|
|
129
|
+
/**
|
|
130
|
+
* Optional, so every existing v1 manifest stays shape-valid. Omitting it means
|
|
131
|
+
* "no policy-level claims", not "policies are fine".
|
|
132
|
+
*/
|
|
133
|
+
policies_must_not_allow?: readonly PolicyProhibition[];
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Change kinds an action declaration may allow. Like tables, a modified
|
|
137
|
+
* action is decomposed into facets and EVERY facet must be covered — a
|
|
138
|
+
* mission expecting an invariant declaration to change does not thereby
|
|
139
|
+
* authorize an RBAC/auth middleware change on the same action.
|
|
140
|
+
*
|
|
141
|
+
* Derived from the single runtime source in
|
|
142
|
+
* [`portable-vocabulary.mjs`](./portable-vocabulary.mjs), which the
|
|
143
|
+
* dependency-free Node scripts import directly; see there for the per-facet
|
|
144
|
+
* meanings.
|
|
145
|
+
*/
|
|
146
|
+
type ActionChangeKind = (typeof ACTION_CHANGE_KINDS)[number];
|
|
147
|
+
/**
|
|
148
|
+
* Change kinds a table declaration may allow. A "modified" table entry is
|
|
149
|
+
* decomposed into facets, and EVERY facet must be covered by the declaration —
|
|
150
|
+
* declaring `columns_added` on a table does not authorize a policy change on
|
|
151
|
+
* the same table. Derived from `portable-vocabulary.mjs`.
|
|
152
|
+
*/
|
|
153
|
+
type TableChangeKind = (typeof TABLE_CHANGE_KINDS)[number];
|
|
154
|
+
|
|
155
|
+
/** Exact-ref action declaration. A bare string ref means "any change". */
|
|
156
|
+
interface ExpectedActionChange {
|
|
157
|
+
/** `<module>:<name>`, the same ref capabilities.json uses. */
|
|
158
|
+
ref: string;
|
|
159
|
+
/** Omit for "any change to this action". */
|
|
160
|
+
changes?: readonly ActionChangeKind[];
|
|
161
|
+
}
|
|
162
|
+
/** Table declaration. A bare string name means "any tracked change". */
|
|
163
|
+
interface ExpectedTableChange {
|
|
164
|
+
name: string;
|
|
165
|
+
/** Omit for "any tracked change to this table". */
|
|
166
|
+
changes?: readonly TableChangeKind[];
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* The proof-surface change budget a mission grants its PR.
|
|
170
|
+
*
|
|
171
|
+
* Everything else in the manifest states what MUST exist; this block bounds
|
|
172
|
+
* what else MAY change on the surfaces drift tracks. Read by
|
|
173
|
+
* the package drift engine, which diffs the regenerated
|
|
174
|
+
* `capabilities.json` / `schema.json` / `package.json` / lockfile against the
|
|
175
|
+
* PR's base and fails (`drift_undeclared`) on a high-severity delta outside
|
|
176
|
+
* the declared budget.
|
|
177
|
+
*
|
|
178
|
+
* Scope is deliberately narrow-by-default:
|
|
179
|
+
*
|
|
180
|
+
* - `modules` covers only ADDED actions in the named module (the
|
|
181
|
+
* new-module convenience). Modifying or removing an existing action is
|
|
182
|
+
* never authorized by a module declaration — a mission that expects a
|
|
183
|
+
* guard or signature change on an existing action must name the exact
|
|
184
|
+
* ref in `actions`, so "add a small feature" can never quietly license
|
|
185
|
+
* weakening an unrelated action in the same module.
|
|
186
|
+
* - String shorthands ("issues" in `tables`, "issues:createIssue" in
|
|
187
|
+
* `actions`) mean "any change" and are the coarse form; the object forms
|
|
188
|
+
* narrow to specific change kinds.
|
|
189
|
+
*
|
|
190
|
+
* Omitting the block keeps drift report-only, so every existing v1 manifest
|
|
191
|
+
* behaves exactly as before.
|
|
192
|
+
*/
|
|
193
|
+
interface ExpectedChanges {
|
|
194
|
+
/**
|
|
195
|
+
* Module leaf names (e.g. `"issues"`) in which NEW actions may appear.
|
|
196
|
+
* Does not authorize modification or removal of existing actions.
|
|
197
|
+
*/
|
|
198
|
+
modules?: readonly string[];
|
|
199
|
+
/** Exact action refs that may change; see {@link ExpectedActionChange}. */
|
|
200
|
+
actions?: readonly (string | ExpectedActionChange)[];
|
|
201
|
+
/** Tables that may change; see {@link ExpectedTableChange}. */
|
|
202
|
+
tables?: readonly (string | ExpectedTableChange)[];
|
|
203
|
+
/**
|
|
204
|
+
* Runtime dependencies (`package.json` `dependencies`) that may be added,
|
|
205
|
+
* removed, or version-changed. Every runtime dependency delta is
|
|
206
|
+
* high-severity — a swap or downgrade changes shipped behavior as surely as
|
|
207
|
+
* an addition.
|
|
208
|
+
*/
|
|
209
|
+
dependencies?: readonly string[];
|
|
210
|
+
/**
|
|
211
|
+
* Expect a lockfile-only resolution change (pnpm-lock.yaml differs while
|
|
212
|
+
* the package.json dependency surface does not). Rare and suspicious by
|
|
213
|
+
* default, hence explicitly declared rather than inferred.
|
|
214
|
+
*/
|
|
215
|
+
lockfile?: boolean;
|
|
216
|
+
}
|
|
217
|
+
interface MissionManifest {
|
|
218
|
+
/** Pinned to MISSION_MANIFEST_SCHEMA_VERSION. */
|
|
219
|
+
schemaVersion: number;
|
|
220
|
+
/** Ticket id from the consumer's kanban (e.g. `"M-042"`). */
|
|
221
|
+
missionId: string;
|
|
222
|
+
/** Short human-readable title. */
|
|
223
|
+
missionTitle: string;
|
|
224
|
+
/** Product repo slug (informational). */
|
|
225
|
+
productRepo?: string;
|
|
226
|
+
/** PR branch name (informational). */
|
|
227
|
+
prBranch?: string;
|
|
228
|
+
/** ISO-8601 timestamp the manifest was generated. */
|
|
229
|
+
createdAt: string;
|
|
230
|
+
requirements: MissionRequirements;
|
|
231
|
+
/**
|
|
232
|
+
* Optional drift bound; see {@link ExpectedChanges}. Absent means the drift
|
|
233
|
+
* report is informational only.
|
|
234
|
+
*/
|
|
235
|
+
expectedChanges?: ExpectedChanges;
|
|
236
|
+
/** Free-form notes for reviewers / the coding agent. */
|
|
237
|
+
acceptanceNotes?: string;
|
|
238
|
+
}
|
|
239
|
+
type ValidationCategory = "capability_missing" | "capability_mismatch" | "schema_missing" | "schema_column_missing" | "schema_rls_mismatch"
|
|
240
|
+
/** A policy grants access the manifest declared must not exist. */
|
|
241
|
+
| "schema_policy_permits" | "trace_missing"
|
|
242
|
+
/**
|
|
243
|
+
* A passing assertion matched the requirement but was recorded directly by
|
|
244
|
+
* spec code (`recordAssertion`) where the requirement demands an SDK-helper
|
|
245
|
+
* origin (`evidence: "helper"`, the default for `tenant_isolation`).
|
|
246
|
+
*/
|
|
247
|
+
| "trace_unverified" | "manifest_shape"
|
|
248
|
+
/** The Playwright run itself exited non-zero. Reported by the CLI, not the validator. */
|
|
249
|
+
| "proof_run"
|
|
250
|
+
/** The run produced no trace artifacts at all, so there is nothing to validate. */
|
|
251
|
+
| "no_traces"
|
|
252
|
+
/**
|
|
253
|
+
* A trace in the directory was recorded against a different commit than the
|
|
254
|
+
* current run — leftover evidence that cannot speak for the code under review.
|
|
255
|
+
* Reported by the CLI, which knows the run's commit; the validator sees only
|
|
256
|
+
* the bundle it is handed.
|
|
257
|
+
*/
|
|
258
|
+
| "stale_trace";
|
|
259
|
+
/**
|
|
260
|
+
* Which proof supplied the evidence for a satisfied `trace_must_prove` entry.
|
|
261
|
+
*
|
|
262
|
+
* Recorded for every requirement — satisfied or not — so a reviewer can audit
|
|
263
|
+
* the mapping instead of trusting that "0 issues" meant the right proof made
|
|
264
|
+
* the claim. Requirements are matched against all assertions in the run, so
|
|
265
|
+
* without this the attribution would be invisible.
|
|
266
|
+
*/
|
|
267
|
+
interface RequirementEvidence {
|
|
268
|
+
kind: ProofKind;
|
|
269
|
+
target: string;
|
|
270
|
+
role: AssertionRole;
|
|
271
|
+
satisfied: boolean;
|
|
272
|
+
/** proofId of the trace whose assertion satisfied it, when satisfied. */
|
|
273
|
+
proofId?: string;
|
|
274
|
+
/** Spec file that produced that trace, when known. */
|
|
275
|
+
specFile?: string;
|
|
276
|
+
/** The satisfying assertion's `detail`, verbatim. */
|
|
277
|
+
detail?: string;
|
|
278
|
+
/**
|
|
279
|
+
* The satisfying assertion's helper provenance, when it has one. Absent
|
|
280
|
+
* means the evidence was recorded directly by spec code.
|
|
281
|
+
*/
|
|
282
|
+
emittedBy?: string;
|
|
283
|
+
}
|
|
284
|
+
interface ValidationIssue {
|
|
285
|
+
category: ValidationCategory;
|
|
286
|
+
/** Human-readable summary including expected vs found. */
|
|
287
|
+
message: string;
|
|
288
|
+
/** Structured context for machine consumers (optional). */
|
|
289
|
+
context?: Record<string, unknown>;
|
|
290
|
+
}
|
|
291
|
+
interface ValidationResult {
|
|
292
|
+
missionId: string;
|
|
293
|
+
ok: boolean;
|
|
294
|
+
issues: ValidationIssue[];
|
|
295
|
+
/** Attribution for every `trace_must_prove` entry, in manifest order. */
|
|
296
|
+
evidence?: RequirementEvidence[];
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
export { type CapabilityRequirement as C, MISSION_MANIFEST_SCHEMA_VERSION as M, type SchemaRequirement as S, type TraceRequirement as T, type ValidationResult as V, type MissionManifest as a, type MissionRequirements as b, type ValidationCategory as c, type ValidationIssue as d };
|
package/dist/node.d.ts
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { V as ValidationResult } from './mission-types-Dr5rBHYO.js';
|
|
2
|
+
import { T as TraceArtifact, a as TraceAssertion } from './trace-types-DkIzq-l9.js';
|
|
3
|
+
import './portable-vocabulary.js';
|
|
4
|
+
|
|
5
|
+
interface CapabilitiesArtifact {
|
|
6
|
+
schemaVersion: number;
|
|
7
|
+
capabilities: Array<{
|
|
8
|
+
name: string;
|
|
9
|
+
module: string;
|
|
10
|
+
/** Literal exported wrapper function used by the generated invoke registry. */
|
|
11
|
+
exportName?: string | null;
|
|
12
|
+
verb: string | null;
|
|
13
|
+
object: string | null;
|
|
14
|
+
invariants: readonly string[];
|
|
15
|
+
/** Derived scanner signal; absent on older additive v1 artifacts. */
|
|
16
|
+
acceptsWorkspaceId?: boolean;
|
|
17
|
+
/** Internal BOT/server-only plumbing is not a user-invoked boundary. */
|
|
18
|
+
internalOnly?: boolean;
|
|
19
|
+
/** Direct next/cache updateTag is not safe through the proof route. */
|
|
20
|
+
usesDirectUpdateTag?: boolean;
|
|
21
|
+
/** Concrete writes issued through createSupabaseServiceClient(). */
|
|
22
|
+
serviceRoleMutations?: ReadonlyArray<{
|
|
23
|
+
table: string;
|
|
24
|
+
operation: "insert" | "upsert" | "update" | "delete";
|
|
25
|
+
}>;
|
|
26
|
+
/** Relevant guards observed in the action pipeline. */
|
|
27
|
+
middleware?: {
|
|
28
|
+
auth: boolean;
|
|
29
|
+
tenantIsolation: boolean;
|
|
30
|
+
rbac: boolean;
|
|
31
|
+
};
|
|
32
|
+
file: string;
|
|
33
|
+
}>;
|
|
34
|
+
unclassified?: readonly unknown[];
|
|
35
|
+
}
|
|
36
|
+
interface SchemaPolicy {
|
|
37
|
+
name: string;
|
|
38
|
+
/** One of POLICY_COMMANDS as the parser reports it. */
|
|
39
|
+
command: string;
|
|
40
|
+
/** Roles from the policy's `TO` clause. Empty means no clause, i.e. PUBLIC. */
|
|
41
|
+
roles: readonly string[];
|
|
42
|
+
}
|
|
43
|
+
interface SchemaArtifact {
|
|
44
|
+
schemaVersion: number;
|
|
45
|
+
tables: Array<{
|
|
46
|
+
name: string;
|
|
47
|
+
columns: readonly string[];
|
|
48
|
+
rls_classification: string;
|
|
49
|
+
policies: readonly SchemaPolicy[];
|
|
50
|
+
sourceFiles: readonly string[];
|
|
51
|
+
}>;
|
|
52
|
+
unclassified?: readonly unknown[];
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* A trace bundle for validation is the aggregated list of every trace the
|
|
56
|
+
* proof run emitted. Kept as `TraceArtifact[]` so v0.6's per-proof JSON
|
|
57
|
+
* files can be concatenated without transformation.
|
|
58
|
+
*/
|
|
59
|
+
type TraceBundle = readonly TraceArtifact[];
|
|
60
|
+
/**
|
|
61
|
+
* An assertion plus the proof it came from. Attribution has to survive the
|
|
62
|
+
* flattening, otherwise a satisfied requirement can't be traced back to the
|
|
63
|
+
* spec that satisfied it.
|
|
64
|
+
*/
|
|
65
|
+
interface AttributedAssertion extends TraceAssertion {
|
|
66
|
+
proofId: string;
|
|
67
|
+
specFile?: string;
|
|
68
|
+
}
|
|
69
|
+
/** Flatten every assertion across every trace / step, keeping attribution. */
|
|
70
|
+
declare function collectAssertions(bundle: TraceBundle): AttributedAssertion[];
|
|
71
|
+
interface ValidateMissionInput {
|
|
72
|
+
manifest: unknown;
|
|
73
|
+
capabilities: CapabilitiesArtifact;
|
|
74
|
+
schema: SchemaArtifact;
|
|
75
|
+
traces: TraceBundle;
|
|
76
|
+
}
|
|
77
|
+
declare function validateMission(input: ValidateMissionInput): ValidationResult;
|
|
78
|
+
|
|
79
|
+
export { type CapabilitiesArtifact, type SchemaArtifact, type TraceBundle, type ValidateMissionInput, collectAssertions, validateMission };
|