@voltro/plan 0.82.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/CHANGELOG.md +16790 -0
- package/LICENSE +61 -0
- package/README.md +26 -0
- package/SECURITY.md +56 -0
- package/THIRD-PARTY-NOTICES.md +11 -0
- package/dist/index.d.ts +596 -0
- package/dist/index.js +952 -0
- package/package.json +42 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,596 @@
|
|
|
1
|
+
import { Schema } from 'effect';
|
|
2
|
+
|
|
3
|
+
/** Whether any diagnostic blocks (security or error; warnings too when strict). */
|
|
4
|
+
export declare const blocks: (ds: ReadonlyArray<Diagnostic>, strict?: boolean) => boolean;
|
|
5
|
+
|
|
6
|
+
/** JSON with object keys sorted at every level; arrays keep their order. */
|
|
7
|
+
export declare const canonicalJson: (value: unknown) => string;
|
|
8
|
+
|
|
9
|
+
export declare type Certificate = ClosureFile['certificates'][number];
|
|
10
|
+
|
|
11
|
+
/** Reads the clock once per run, so a whole run sees one "now". */
|
|
12
|
+
export declare interface Clock {
|
|
13
|
+
readonly now: () => Date;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export declare const CLOSURE_SCHEMA_VERSION = "voltro-plan-closure/v1";
|
|
17
|
+
|
|
18
|
+
export declare type ClosureDecision = {
|
|
19
|
+
readonly outcome: 'recorded';
|
|
20
|
+
readonly file: ClosureFile;
|
|
21
|
+
readonly run: ClosureRun;
|
|
22
|
+
readonly certificate: Certificate | null;
|
|
23
|
+
} | {
|
|
24
|
+
readonly outcome: 'refused';
|
|
25
|
+
readonly diagnostic: Diagnostic;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
export declare type ClosureFile = Schema.Schema.Type<ReturnType<typeof closureFileSchema>>;
|
|
29
|
+
|
|
30
|
+
/** One plan's closure record: its passes and certificates, oldest first. */
|
|
31
|
+
export declare const closureFileSchema: (shape: ProgramShape) => Schema.Struct<{
|
|
32
|
+
schemaVersion: Schema.Literal<["voltro-plan-closure/v1"]>;
|
|
33
|
+
plan: Schema.filter<typeof Schema.String>;
|
|
34
|
+
runs: Schema.Array$<Schema.Struct<{
|
|
35
|
+
id: Schema.filter<typeof Schema.String>;
|
|
36
|
+
pass: Schema.Literal<["contract", "adversarial"]>;
|
|
37
|
+
reviewer: Schema.filter<typeof Schema.String>;
|
|
38
|
+
reviewContext: Schema.filter<typeof Schema.String>;
|
|
39
|
+
planRevision: Schema.filter<typeof Schema.String>;
|
|
40
|
+
completedAt: Schema.filter<typeof Schema.String>;
|
|
41
|
+
findingRefs: Schema.Array$<Schema.filter<typeof Schema.String>>;
|
|
42
|
+
result: Schema.Literal<["passed", "findings"]>;
|
|
43
|
+
/** The `voltro plan` version that ran the pass. */
|
|
44
|
+
toolVersion: Schema.filter<typeof Schema.String>;
|
|
45
|
+
}>>;
|
|
46
|
+
certificates: Schema.Array$<Schema.Struct<{
|
|
47
|
+
id: Schema.filter<typeof Schema.String>;
|
|
48
|
+
plan: Schema.filter<typeof Schema.String>;
|
|
49
|
+
planRevision: Schema.filter<typeof Schema.String>;
|
|
50
|
+
workItems: Schema.Array$<Schema.filter<typeof Schema.String>>;
|
|
51
|
+
evidenceRefs: Schema.Array$<Schema.filter<typeof Schema.String>>;
|
|
52
|
+
closureRuns: Schema.filter<Schema.Array$<Schema.filter<typeof Schema.String>>>;
|
|
53
|
+
confirmedBy: Schema.filter<typeof Schema.String>;
|
|
54
|
+
issuedAt: Schema.filter<typeof Schema.String>;
|
|
55
|
+
toolVersion: Schema.filter<typeof Schema.String>;
|
|
56
|
+
}>>;
|
|
57
|
+
}>;
|
|
58
|
+
|
|
59
|
+
export declare interface ClosureRequest {
|
|
60
|
+
readonly pass: 'contract' | 'adversarial';
|
|
61
|
+
readonly reviewer: string;
|
|
62
|
+
readonly reviewContext: string;
|
|
63
|
+
readonly findings: ReadonlyArray<string>;
|
|
64
|
+
readonly at: string;
|
|
65
|
+
readonly toolVersion: string;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export declare type ClosureRun = ClosureFile['runs'][number];
|
|
69
|
+
|
|
70
|
+
export declare type ClosureState = {
|
|
71
|
+
readonly state: 'open';
|
|
72
|
+
}
|
|
73
|
+
/** The contract pass is done on this revision; the adversarial audit is owed. */
|
|
74
|
+
| {
|
|
75
|
+
readonly state: 'closure-1';
|
|
76
|
+
readonly run: ClosureRun;
|
|
77
|
+
} | {
|
|
78
|
+
readonly state: 'certified';
|
|
79
|
+
readonly certificate: Certificate;
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
/** Where a plan stands in closure, on its current revision. */
|
|
83
|
+
export declare const closureState: (file: ClosureFile | undefined, revision: string) => ClosureState;
|
|
84
|
+
|
|
85
|
+
export declare const COMMAND_SCHEMA_VERSION = "voltro-plan-command/v1";
|
|
86
|
+
|
|
87
|
+
export declare interface CommandEnvelope<R> {
|
|
88
|
+
readonly schemaVersion: typeof COMMAND_SCHEMA_VERSION;
|
|
89
|
+
readonly command: 'lint' | 'status' | 'next' | 'evidence add' | 'close' | 'impact';
|
|
90
|
+
readonly ok: boolean;
|
|
91
|
+
/** The project root, relative, with `/`. */
|
|
92
|
+
readonly root: string;
|
|
93
|
+
readonly inputsFingerprint: string;
|
|
94
|
+
readonly toolVersion: string;
|
|
95
|
+
readonly result: R;
|
|
96
|
+
readonly diagnostics: ReadonlyArray<Diagnostic>;
|
|
97
|
+
readonly observedAt: string;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Record one closure pass for a plan. Refused unless every mandatory item is
|
|
102
|
+
* verified and no finding against the plan is open; the adversarial pass also
|
|
103
|
+
* needs a passed contract pass on the same revision, by another reviewer in
|
|
104
|
+
* another context. A pass that names findings reopens the plan instead. After
|
|
105
|
+
* the adversarial pass passes, the certificate is issued.
|
|
106
|
+
*/
|
|
107
|
+
export declare const decideClosure: (grammar: IdGrammar, instance: PlanInstance, file: ClosureFile | undefined, revision: string, statusOf: (id: string) => string | undefined, evidence: ReadonlyArray<Evidence>, findings: ReadonlyArray<Finding>, request: ClosureRequest) => ClosureDecision;
|
|
108
|
+
|
|
109
|
+
/** Decide one `evidence add` against the program and the evidence already there. */
|
|
110
|
+
export declare const decideEvidence: (program: Program, grammar: IdGrammar, request: EvidenceRequest) => EvidenceDecision;
|
|
111
|
+
|
|
112
|
+
/** The hard dependency cycles, each once, starting at its smallest id; deterministic. */
|
|
113
|
+
export declare const dependencyCycles: (edges: ReadonlyMap<string, ReadonlyArray<string>>) => ReadonlyArray<ReadonlyArray<string>>;
|
|
114
|
+
|
|
115
|
+
export declare const DERIVED: ReadonlySet<WorkItemStatus>;
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* The state an item is in: its recorded working state (proposed, ready, active,
|
|
119
|
+
* blocked), or `verified` when the evidence says so. A recorded `verified` or
|
|
120
|
+
* `closed` the evidence does not carry falls back to `active`.
|
|
121
|
+
*/
|
|
122
|
+
export declare const derivedStatus: (item: WorkItem, gaps: ReadonlyArray<string>) => WorkItemStatus;
|
|
123
|
+
|
|
124
|
+
export declare interface Diagnostic {
|
|
125
|
+
/** `<class>/<rule>`, e.g. `graph/missing-dependency`. */
|
|
126
|
+
readonly ruleId: string;
|
|
127
|
+
readonly severity: Severity;
|
|
128
|
+
readonly message: string;
|
|
129
|
+
readonly locator: Locator;
|
|
130
|
+
readonly related: ReadonlyArray<string>;
|
|
131
|
+
readonly nextAction: string;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
export declare const envelope: <R>(fields: Omit<CommandEnvelope<R>, "schemaVersion">) => CommandEnvelope<R>;
|
|
135
|
+
|
|
136
|
+
export declare type Evidence = Schema.Schema.Type<ReturnType<typeof evidenceSchema>>;
|
|
137
|
+
|
|
138
|
+
export declare const EVIDENCE_KINDS: readonly ["commit", "typecheck", "unit-test", "integration-test", "e2e", "browser", "schema", "migration", "roundtrip", "documentation", "agent-guide", "template", "security", "privacy", "accessibility", "rights", "operations", "performance", "research", "review", "artifact"];
|
|
139
|
+
|
|
140
|
+
export declare type EvidenceDecision = {
|
|
141
|
+
readonly outcome: 'add';
|
|
142
|
+
readonly evidence: Evidence;
|
|
143
|
+
} | {
|
|
144
|
+
readonly outcome: 'same';
|
|
145
|
+
readonly evidence: Evidence;
|
|
146
|
+
} | {
|
|
147
|
+
readonly outcome: 'refused';
|
|
148
|
+
readonly diagnostic: Diagnostic;
|
|
149
|
+
readonly exit: number;
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
export declare interface EvidenceIndex {
|
|
153
|
+
readonly evidence: ReadonlyMap<string, Evidence>;
|
|
154
|
+
/** The evidence naming each work item among its subjects. */
|
|
155
|
+
readonly bySubject: ReadonlyMap<string, ReadonlyArray<Evidence>>;
|
|
156
|
+
/** Open findings per work item. */
|
|
157
|
+
readonly openFindings: ReadonlyMap<string, ReadonlyArray<Finding>>;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
export declare interface EvidenceRequest {
|
|
161
|
+
readonly workItem: string;
|
|
162
|
+
/** The checks and requirements it proves: `A01`, `E01`, or their full ids. */
|
|
163
|
+
readonly proves: ReadonlyArray<string>;
|
|
164
|
+
readonly kind: string;
|
|
165
|
+
readonly title: string;
|
|
166
|
+
readonly uri: string;
|
|
167
|
+
readonly result: 'passed' | 'failed' | 'informational';
|
|
168
|
+
readonly producedBy: string;
|
|
169
|
+
readonly command?: string;
|
|
170
|
+
readonly environment?: string;
|
|
171
|
+
readonly fingerprint?: string;
|
|
172
|
+
readonly idempotencyKey?: string;
|
|
173
|
+
readonly observedAt: string;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/** One piece of evidence: what was observed, by whom, about which subjects. */
|
|
177
|
+
export declare const evidenceSchema: (shape: ProgramShape) => Schema.Struct<{
|
|
178
|
+
id: Schema.filter<typeof Schema.String>;
|
|
179
|
+
kind: Schema.Literal<["commit", "typecheck", "unit-test", "integration-test", "e2e", "browser", "schema", "migration", "roundtrip", "documentation", "agent-guide", "template", "security", "privacy", "accessibility", "rights", "operations", "performance", "research", "review", "artifact"]>;
|
|
180
|
+
title: Schema.filter<typeof Schema.String>;
|
|
181
|
+
uri: Schema.filter<typeof Schema.String>;
|
|
182
|
+
fingerprint: Schema.optional<Schema.filter<typeof Schema.String>>;
|
|
183
|
+
result: Schema.Literal<["passed", "failed", "informational"]>;
|
|
184
|
+
subjectRefs: Schema.Array$<Schema.filter<typeof Schema.String>>;
|
|
185
|
+
command: Schema.optional<Schema.filter<typeof Schema.String>>;
|
|
186
|
+
environment: Schema.optional<Schema.filter<typeof Schema.String>>;
|
|
187
|
+
producedBy: Schema.filter<typeof Schema.String>;
|
|
188
|
+
reviewedBy: Schema.optional<Schema.filter<typeof Schema.String>>;
|
|
189
|
+
observedAt: Schema.filter<typeof Schema.String>;
|
|
190
|
+
/** Set by `voltro plan evidence add`: the same key with the same payload is the same evidence. */
|
|
191
|
+
idempotencyKey: Schema.optional<Schema.filter<typeof Schema.String>>;
|
|
192
|
+
}>;
|
|
193
|
+
|
|
194
|
+
/** The process exit code of a command (0 ok, 1 gate failed, 2 usage, 3 unreadable input, 6 security). */
|
|
195
|
+
export declare const EXIT: {
|
|
196
|
+
readonly ok: 0;
|
|
197
|
+
readonly failed: 1;
|
|
198
|
+
readonly usage: 2;
|
|
199
|
+
readonly input: 3;
|
|
200
|
+
readonly conflict: 4;
|
|
201
|
+
readonly provider: 5;
|
|
202
|
+
readonly security: 6;
|
|
203
|
+
readonly internal: 70;
|
|
204
|
+
};
|
|
205
|
+
|
|
206
|
+
export declare type Finding = Schema.Schema.Type<ReturnType<typeof findingSchema>>;
|
|
207
|
+
|
|
208
|
+
/** A finding against work items: open until resolved or accepted as a risk. */
|
|
209
|
+
export declare const findingSchema: (shape: ProgramShape) => Schema.Struct<{
|
|
210
|
+
id: Schema.filter<typeof Schema.String>;
|
|
211
|
+
title: Schema.filter<typeof Schema.String>;
|
|
212
|
+
severity: Schema.Literal<["critical", "high", "medium", "low"]>;
|
|
213
|
+
status: Schema.Literal<["open", "resolved", "accepted-risk"]>;
|
|
214
|
+
source: Schema.Literal<["contract-reconciliation", "adversarial-audit", "test", "incident", "research", "review", "production"]>;
|
|
215
|
+
targetWorkItems: Schema.filter<Schema.Array$<Schema.Schema<string, string, never>>>;
|
|
216
|
+
impactTags: Schema.Array$<Schema.filter<typeof Schema.String>>;
|
|
217
|
+
evidenceRefs: Schema.optional<Schema.filter<Schema.Array$<Schema.Schema<string, string, never>>>>;
|
|
218
|
+
openedAt: Schema.filter<typeof Schema.String>;
|
|
219
|
+
resolvedAt: Schema.optional<Schema.filter<typeof Schema.String>>;
|
|
220
|
+
}>;
|
|
221
|
+
|
|
222
|
+
/** The `sha256:` fingerprint of a value's canonical JSON. */
|
|
223
|
+
export declare const fingerprint: (value: unknown) => string;
|
|
224
|
+
|
|
225
|
+
export declare interface IdGrammar {
|
|
226
|
+
readonly prefix: string;
|
|
227
|
+
readonly plan: RegExp;
|
|
228
|
+
readonly workItem: RegExp;
|
|
229
|
+
readonly acceptance: RegExp;
|
|
230
|
+
readonly requirement: RegExp;
|
|
231
|
+
readonly source: RegExp;
|
|
232
|
+
readonly evidence: RegExp;
|
|
233
|
+
readonly finding: RegExp;
|
|
234
|
+
readonly adr: RegExp;
|
|
235
|
+
readonly closureRun: RegExp;
|
|
236
|
+
readonly certificate: RegExp;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
/** The id shapes of a program with `prefix`; throws for a prefix that is not 2–10 capitals/digits. */
|
|
240
|
+
export declare const idGrammar: (prefix: string) => IdGrammar;
|
|
241
|
+
|
|
242
|
+
export declare interface ImpactInput {
|
|
243
|
+
readonly tags: ReadonlyArray<string>;
|
|
244
|
+
/** Project-relative, with `/`. */
|
|
245
|
+
readonly files: ReadonlyArray<string>;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
export declare const impactOf: (program: Program, input: ImpactInput) => ImpactResult;
|
|
249
|
+
|
|
250
|
+
export declare interface ImpactResult {
|
|
251
|
+
readonly direct: ReadonlyArray<{
|
|
252
|
+
readonly workItem: string;
|
|
253
|
+
readonly because: ReadonlyArray<string>;
|
|
254
|
+
}>;
|
|
255
|
+
/** Items affected through a dependency: the path from a direct item. */
|
|
256
|
+
readonly transitive: ReadonlyArray<{
|
|
257
|
+
readonly workItem: string;
|
|
258
|
+
readonly path: ReadonlyArray<string>;
|
|
259
|
+
}>;
|
|
260
|
+
readonly plans: ReadonlyArray<string>;
|
|
261
|
+
/** Certificates on current revisions that the change puts in question: their plans must close again. */
|
|
262
|
+
readonly certificates: ReadonlyArray<{
|
|
263
|
+
readonly plan: string;
|
|
264
|
+
readonly certificate: string;
|
|
265
|
+
}>;
|
|
266
|
+
/** Changed files no work item names. */
|
|
267
|
+
readonly unknown: ReadonlyArray<string>;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
export declare const indexEvidence: (evidence: ReadonlyArray<Evidence>, findings: ReadonlyArray<Finding>) => EvidenceIndex;
|
|
271
|
+
|
|
272
|
+
/** A file as read: its project-relative path (with `/`) and its parsed JSON. */
|
|
273
|
+
export declare interface InputFile {
|
|
274
|
+
readonly file: string;
|
|
275
|
+
readonly content: unknown;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
export declare const ITEM_KINDS: readonly ["architecture", "feature", "framework", "integration", "migration", "operations", "security", "documentation", "research", "tooling"];
|
|
279
|
+
|
|
280
|
+
export declare interface LintInput {
|
|
281
|
+
readonly shape: ProgramShape;
|
|
282
|
+
readonly instances: ReadonlyArray<InputFile>;
|
|
283
|
+
readonly evidence?: ReadonlyArray<InputFile>;
|
|
284
|
+
readonly findings?: ReadonlyArray<InputFile>;
|
|
285
|
+
/** One closure record per plan (./closure). */
|
|
286
|
+
readonly closures?: ReadonlyArray<InputFile>;
|
|
287
|
+
/**
|
|
288
|
+
* The plans' source files as read, `sha256:` of their bytes. When given, a
|
|
289
|
+
* plan whose source changed since its decomposition — or is gone — is stale.
|
|
290
|
+
*/
|
|
291
|
+
readonly sources?: ReadonlyMap<string, string | null>;
|
|
292
|
+
/** The decision records by id (`ADR-<prefix>-NNN`), `sha256:` of their bytes. When given, a link to an unknown one is an error. */
|
|
293
|
+
readonly decisions?: ReadonlyMap<string, string>;
|
|
294
|
+
readonly clock: Clock;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
/** Lint the whole program; the diagnostics come sorted (./diagnostics). */
|
|
298
|
+
export declare const lintProgram: (input: LintInput) => LintResult;
|
|
299
|
+
|
|
300
|
+
export declare interface LintResult {
|
|
301
|
+
readonly program: Program;
|
|
302
|
+
readonly diagnostics: ReadonlyArray<Diagnostic>;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
export declare interface Locator {
|
|
306
|
+
/** The file, relative to the project root, with `/`. */
|
|
307
|
+
readonly file?: string;
|
|
308
|
+
readonly plan?: string;
|
|
309
|
+
readonly workItem?: string;
|
|
310
|
+
/** The field inside the object, e.g. `acceptance[1].evidenceRefs`. */
|
|
311
|
+
readonly path?: string;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
export declare const Manifest: Schema.Struct<{
|
|
315
|
+
schemaVersion: Schema.Literal<["voltro-plan-manifest/v1"]>;
|
|
316
|
+
prefix: Schema.filter<typeof Schema.String>;
|
|
317
|
+
/** The `schemaVersion` the plan instances carry. */
|
|
318
|
+
instanceVersion: Schema.filter<typeof Schema.String>;
|
|
319
|
+
repos: Schema.filter<Schema.Array$<Schema.filter<typeof Schema.String>>>;
|
|
320
|
+
instances: Schema.filter<Schema.Array$<Schema.filter<Schema.filter<typeof Schema.String>>>>;
|
|
321
|
+
evidence: Schema.optional<Schema.Array$<Schema.filter<Schema.filter<typeof Schema.String>>>>;
|
|
322
|
+
/** Where `voltro plan evidence add` writes: one `<plan number>.json` per plan; read as well. */
|
|
323
|
+
evidenceDir: Schema.optional<Schema.filter<Schema.filter<typeof Schema.String>>>;
|
|
324
|
+
/** Where `voltro plan close` keeps each plan's closure record (`<plan number>.json`). */
|
|
325
|
+
closureDir: Schema.optional<Schema.filter<Schema.filter<typeof Schema.String>>>;
|
|
326
|
+
/** The decision records: files named `ADR-<prefix>-NNN-….md`. Items link them; a changed one reopens their plans. */
|
|
327
|
+
adrDir: Schema.optional<Schema.filter<Schema.filter<typeof Schema.String>>>;
|
|
328
|
+
findings: Schema.optional<Schema.Array$<Schema.filter<Schema.filter<typeof Schema.String>>>>;
|
|
329
|
+
}>;
|
|
330
|
+
|
|
331
|
+
export declare type Manifest = Schema.Schema.Type<typeof Manifest>;
|
|
332
|
+
|
|
333
|
+
export declare const MANIFEST_SCHEMA_VERSION = "voltro-plan-manifest/v1";
|
|
334
|
+
|
|
335
|
+
export declare interface NextFilter {
|
|
336
|
+
readonly plan?: string;
|
|
337
|
+
readonly owner?: string;
|
|
338
|
+
readonly repo?: string;
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
export declare const nextItem: (program: Program, filter: NextFilter, lintBlocks: boolean) => NextResult;
|
|
342
|
+
|
|
343
|
+
export declare type NextResult = {
|
|
344
|
+
readonly outcome: 'item';
|
|
345
|
+
readonly workItem: WorkItem;
|
|
346
|
+
readonly why: ReadonlyArray<string>;
|
|
347
|
+
readonly file: string;
|
|
348
|
+
} | {
|
|
349
|
+
readonly outcome: 'complete';
|
|
350
|
+
} | {
|
|
351
|
+
readonly outcome: 'blocked';
|
|
352
|
+
readonly reason: string;
|
|
353
|
+
readonly prepare: WorkItem | null;
|
|
354
|
+
readonly file: string | null;
|
|
355
|
+
} | {
|
|
356
|
+
readonly outcome: 'invalid';
|
|
357
|
+
readonly reason: string;
|
|
358
|
+
};
|
|
359
|
+
|
|
360
|
+
/** The work item an acceptance check, evidence requirement, source, evidence or finding id belongs to, or null. */
|
|
361
|
+
export declare const ownerItemOf: (grammar: IdGrammar, id: string) => string | null;
|
|
362
|
+
|
|
363
|
+
export declare type Plan = PlanInstance['plan'];
|
|
364
|
+
|
|
365
|
+
export declare const PLAN_STATUSES: readonly ["proposed", "decomposing", "ready", "active", "verifying", "closure-1", "closure-2", "complete"];
|
|
366
|
+
|
|
367
|
+
export declare type PlanInstance = Schema.Schema.Type<ReturnType<typeof planInstanceSchema>>;
|
|
368
|
+
|
|
369
|
+
/** The Schema of one plan instance for a program. */
|
|
370
|
+
export declare const planInstanceSchema: (shape: ProgramShape) => Schema.Struct<{
|
|
371
|
+
schemaVersion: Schema.Literal<[string]>;
|
|
372
|
+
plan: Schema.Struct<{
|
|
373
|
+
id: Schema.filter<typeof Schema.String>;
|
|
374
|
+
number: Schema.filter<typeof Schema.String>;
|
|
375
|
+
title: Schema.filter<typeof Schema.String>;
|
|
376
|
+
source: Schema.filter<typeof Schema.String>;
|
|
377
|
+
sourceRevision: Schema.filter<typeof Schema.String>;
|
|
378
|
+
status: Schema.Literal<["proposed", "decomposing", "ready", "active", "verifying", "closure-1", "closure-2", "complete"]>;
|
|
379
|
+
decompositionComplete: typeof Schema.Boolean;
|
|
380
|
+
updatedAt: Schema.filter<typeof Schema.String>;
|
|
381
|
+
}>;
|
|
382
|
+
extraction: Schema.Struct<{
|
|
383
|
+
rulesVersion: Schema.filter<typeof Schema.String>;
|
|
384
|
+
sourceRevision: Schema.filter<typeof Schema.String>;
|
|
385
|
+
blockKinds: Schema.Array$<Schema.filter<typeof Schema.String>>;
|
|
386
|
+
extractedAt: Schema.filter<typeof Schema.String>;
|
|
387
|
+
}>;
|
|
388
|
+
workItems: Schema.Array$<Schema.Struct<{
|
|
389
|
+
id: Schema.filter<typeof Schema.String>;
|
|
390
|
+
title: Schema.filter<typeof Schema.String>;
|
|
391
|
+
ownerPlan: Schema.filter<typeof Schema.String>;
|
|
392
|
+
slice: Schema.filter<typeof Schema.String>;
|
|
393
|
+
kind: Schema.Literal<["architecture", "feature", "framework", "integration", "migration", "operations", "security", "documentation", "research", "tooling"]>;
|
|
394
|
+
priority: Schema.Literal<["P0", "P1", "P2", "P3"]>;
|
|
395
|
+
mandatory: typeof Schema.Boolean;
|
|
396
|
+
status: Schema.Literal<["proposed", "ready", "active", "blocked", "verified", "closed"]>;
|
|
397
|
+
owners: Schema.Array$<Schema.filter<typeof Schema.String>>;
|
|
398
|
+
repos: Schema.filter<Schema.Array$<Schema.Schema<string, string, never>>>;
|
|
399
|
+
sourceRefs: Schema.filter<Schema.Array$<Schema.Schema<{
|
|
400
|
+
readonly id: string;
|
|
401
|
+
readonly uri: string;
|
|
402
|
+
readonly locator: string;
|
|
403
|
+
readonly excerpt: string;
|
|
404
|
+
readonly lineHint?: number | undefined;
|
|
405
|
+
readonly contentHash: string;
|
|
406
|
+
readonly disposition: "owned-by" | "referenced-by" | "decision" | "non-goal";
|
|
407
|
+
readonly targetId?: string | undefined;
|
|
408
|
+
}, {
|
|
409
|
+
readonly id: string;
|
|
410
|
+
readonly uri: string;
|
|
411
|
+
readonly locator: string;
|
|
412
|
+
readonly excerpt: string;
|
|
413
|
+
readonly contentHash: string;
|
|
414
|
+
readonly disposition: "owned-by" | "referenced-by" | "decision" | "non-goal";
|
|
415
|
+
readonly lineHint?: number | undefined;
|
|
416
|
+
readonly targetId?: string | undefined;
|
|
417
|
+
}, never>>>;
|
|
418
|
+
dependsOn: Schema.filter<Schema.Array$<Schema.Schema<string, string, never>>>;
|
|
419
|
+
links: Schema.Struct<{
|
|
420
|
+
capabilities: Schema.Array$<Schema.filter<typeof Schema.String>>;
|
|
421
|
+
journeys: Schema.Array$<Schema.filter<typeof Schema.String>>;
|
|
422
|
+
adrs: Schema.filter<Schema.Array$<Schema.Schema<string, string, never>>>;
|
|
423
|
+
risks: Schema.Array$<Schema.filter<typeof Schema.String>>;
|
|
424
|
+
relatedTo: Schema.filter<Schema.Array$<Schema.Schema<string, string, never>>>;
|
|
425
|
+
}>;
|
|
426
|
+
acceptance: Schema.filter<Schema.Array$<Schema.Schema<{
|
|
427
|
+
readonly id: string;
|
|
428
|
+
readonly status: "pending" | "passed" | "failed";
|
|
429
|
+
readonly statement: string;
|
|
430
|
+
readonly evidenceRefs: readonly string[];
|
|
431
|
+
}, {
|
|
432
|
+
readonly id: string;
|
|
433
|
+
readonly status: "pending" | "passed" | "failed";
|
|
434
|
+
readonly statement: string;
|
|
435
|
+
readonly evidenceRefs: readonly string[];
|
|
436
|
+
}, never>>>;
|
|
437
|
+
evidenceRequirements: Schema.filter<Schema.Array$<Schema.Schema<{
|
|
438
|
+
readonly id: string;
|
|
439
|
+
readonly status: "open" | "satisfied" | "waived";
|
|
440
|
+
readonly statement: string;
|
|
441
|
+
readonly evidenceRefs: readonly string[];
|
|
442
|
+
readonly kinds: readonly ("commit" | "typecheck" | "unit-test" | "integration-test" | "e2e" | "browser" | "schema" | "migration" | "roundtrip" | "documentation" | "agent-guide" | "template" | "security" | "privacy" | "accessibility" | "rights" | "operations" | "performance" | "research" | "review" | "artifact")[];
|
|
443
|
+
readonly waiver?: {
|
|
444
|
+
readonly rationale: string;
|
|
445
|
+
readonly reviewer: string;
|
|
446
|
+
readonly expiresAt: string;
|
|
447
|
+
readonly compensatingControl: string;
|
|
448
|
+
} | undefined;
|
|
449
|
+
}, {
|
|
450
|
+
readonly id: string;
|
|
451
|
+
readonly status: "open" | "satisfied" | "waived";
|
|
452
|
+
readonly statement: string;
|
|
453
|
+
readonly evidenceRefs: readonly string[];
|
|
454
|
+
readonly kinds: readonly ("commit" | "typecheck" | "unit-test" | "integration-test" | "e2e" | "browser" | "schema" | "migration" | "roundtrip" | "documentation" | "agent-guide" | "template" | "security" | "privacy" | "accessibility" | "rights" | "operations" | "performance" | "research" | "review" | "artifact")[];
|
|
455
|
+
readonly waiver?: {
|
|
456
|
+
readonly rationale: string;
|
|
457
|
+
readonly reviewer: string;
|
|
458
|
+
readonly expiresAt: string;
|
|
459
|
+
readonly compensatingControl: string;
|
|
460
|
+
} | undefined;
|
|
461
|
+
}, never>>>;
|
|
462
|
+
evidenceRefs: Schema.filter<Schema.Array$<Schema.Schema<string, string, never>>>;
|
|
463
|
+
impactTags: Schema.filter<Schema.Array$<Schema.Schema<string, string, never>>>;
|
|
464
|
+
statusHistory: Schema.filter<Schema.Array$<Schema.Schema<{
|
|
465
|
+
readonly at: string;
|
|
466
|
+
readonly from: "proposed" | "ready" | "active" | "blocked" | "verified" | "closed" | null;
|
|
467
|
+
readonly evidenceRefs: readonly string[];
|
|
468
|
+
readonly to: "proposed" | "ready" | "active" | "blocked" | "verified" | "closed";
|
|
469
|
+
readonly reason: string;
|
|
470
|
+
readonly actor: string;
|
|
471
|
+
}, {
|
|
472
|
+
readonly at: string;
|
|
473
|
+
readonly from: "proposed" | "ready" | "active" | "blocked" | "verified" | "closed" | null;
|
|
474
|
+
readonly evidenceRefs: readonly string[];
|
|
475
|
+
readonly to: "proposed" | "ready" | "active" | "blocked" | "verified" | "closed";
|
|
476
|
+
readonly reason: string;
|
|
477
|
+
readonly actor: string;
|
|
478
|
+
}, never>>>;
|
|
479
|
+
blocker: Schema.optional<Schema.Struct<{
|
|
480
|
+
reason: Schema.filter<typeof Schema.String>;
|
|
481
|
+
owner: Schema.filter<typeof Schema.String>;
|
|
482
|
+
nextAction: Schema.filter<typeof Schema.String>;
|
|
483
|
+
recheckTrigger: Schema.filter<typeof Schema.String>;
|
|
484
|
+
since: Schema.filter<typeof Schema.String>;
|
|
485
|
+
}>>;
|
|
486
|
+
supersededBy: Schema.optional<Schema.filter<typeof Schema.String>>;
|
|
487
|
+
createdAt: Schema.filter<typeof Schema.String>;
|
|
488
|
+
updatedAt: Schema.filter<typeof Schema.String>;
|
|
489
|
+
}>>;
|
|
490
|
+
coverage: Schema.Struct<{
|
|
491
|
+
extractedSources: typeof Schema.Int;
|
|
492
|
+
disposedSources: typeof Schema.Int;
|
|
493
|
+
unmatchedSources: typeof Schema.Int;
|
|
494
|
+
duplicateSources: typeof Schema.Int;
|
|
495
|
+
sourceIdsHash: Schema.filter<typeof Schema.String>;
|
|
496
|
+
result: Schema.Literal<["complete", "incomplete"]>;
|
|
497
|
+
}>;
|
|
498
|
+
}>;
|
|
499
|
+
|
|
500
|
+
/** The two-digit plan number an id belongs to (`CMS-06-001` → `06`, `CMS-PLAN-06` → `06`), or null. */
|
|
501
|
+
export declare const planNumberOf: (id: string) => string | null;
|
|
502
|
+
|
|
503
|
+
/**
|
|
504
|
+
* The fingerprint a closure pass and a certificate are pinned to: the plan's
|
|
505
|
+
* instance, the evidence about its items, the findings against them, the
|
|
506
|
+
* decision records its items link (their content hash), and the
|
|
507
|
+
* state of every dependency outside the plan (`closed` counts as `verified`, so
|
|
508
|
+
* one plan's certificate does not move another's revision).
|
|
509
|
+
*/
|
|
510
|
+
export declare const planRevision: (instance: PlanInstance, evidence: ReadonlyArray<Evidence>, findings: ReadonlyArray<Finding>, statusOf?: (id: string) => string | undefined, decisions?: ReadonlyMap<string, string>) => string;
|
|
511
|
+
|
|
512
|
+
export declare interface PlanStatus {
|
|
513
|
+
readonly plan: string;
|
|
514
|
+
readonly title: string;
|
|
515
|
+
readonly file: string;
|
|
516
|
+
/** What the plan file says. */
|
|
517
|
+
readonly recorded: string;
|
|
518
|
+
/** What its items and its closure say: decomposing, ready, active, verifying, closure-1 (contract pass done) or complete (certified). */
|
|
519
|
+
readonly derived: 'decomposing' | 'ready' | 'active' | 'verifying' | 'closure-1' | 'complete';
|
|
520
|
+
/** The certificate it holds on its current revision, if any. */
|
|
521
|
+
readonly certificate: string | null;
|
|
522
|
+
readonly mandatory: StatusCounts;
|
|
523
|
+
readonly optional: StatusCounts;
|
|
524
|
+
readonly blocked: ReadonlyArray<{
|
|
525
|
+
readonly workItem: string;
|
|
526
|
+
readonly reason: string;
|
|
527
|
+
readonly owner: string;
|
|
528
|
+
readonly nextAction: string;
|
|
529
|
+
}>;
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
export declare const PRIORITIES: readonly ["P0", "P1", "P2", "P3"];
|
|
533
|
+
|
|
534
|
+
export declare interface Program {
|
|
535
|
+
readonly instances: ReadonlyArray<{
|
|
536
|
+
readonly file: string;
|
|
537
|
+
readonly instance: PlanInstance;
|
|
538
|
+
}>;
|
|
539
|
+
readonly items: ReadonlyMap<string, {
|
|
540
|
+
readonly file: string;
|
|
541
|
+
readonly item: WorkItem;
|
|
542
|
+
}>;
|
|
543
|
+
readonly evidence: ReadonlyArray<Evidence>;
|
|
544
|
+
readonly findings: ReadonlyArray<Finding>;
|
|
545
|
+
/** Each item's state as the evidence says (./state). */
|
|
546
|
+
readonly status: ReadonlyMap<string, WorkItemStatus>;
|
|
547
|
+
/** Why each not-verified item is not. */
|
|
548
|
+
readonly gaps: ReadonlyMap<string, ReadonlyArray<string>>;
|
|
549
|
+
/** Each plan's closure record, its current revision and where it stands in closure. */
|
|
550
|
+
readonly closures: ReadonlyMap<string, {
|
|
551
|
+
readonly file: string;
|
|
552
|
+
readonly record: ClosureFile;
|
|
553
|
+
}>;
|
|
554
|
+
readonly revisions: ReadonlyMap<string, string>;
|
|
555
|
+
readonly closure: ReadonlyMap<string, ClosureState>;
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
/** What a project declares next to its prefix: the repositories work may land in. */
|
|
559
|
+
export declare interface ProgramShape {
|
|
560
|
+
readonly grammar: IdGrammar;
|
|
561
|
+
readonly repos: ReadonlyArray<string>;
|
|
562
|
+
/** The `schemaVersion` its instances carry, e.g. `cms-execution/v1`. */
|
|
563
|
+
readonly instanceVersion: string;
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
export declare interface ProgramStatus {
|
|
567
|
+
readonly plans: ReadonlyArray<PlanStatus>;
|
|
568
|
+
readonly mandatory: StatusCounts;
|
|
569
|
+
readonly items: number;
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
export declare const programStatus: (program: Program) => ProgramStatus;
|
|
573
|
+
|
|
574
|
+
export declare type Severity = 'security' | 'error' | 'warning';
|
|
575
|
+
|
|
576
|
+
/** SHA-256 of `text` (UTF-8), as 64 lower-case hex digits. */
|
|
577
|
+
export declare const sha256Hex: (text: string) => string;
|
|
578
|
+
|
|
579
|
+
/** Severity, plan, work item, rule, then file and path — stable for the same diagnostics in any order. */
|
|
580
|
+
export declare const sortDiagnostics: (ds: ReadonlyArray<Diagnostic>) => ReadonlyArray<Diagnostic>;
|
|
581
|
+
|
|
582
|
+
export declare type StatusCounts = Readonly<Record<WorkItemStatus, number>>;
|
|
583
|
+
|
|
584
|
+
/** The edges a work item may take. */
|
|
585
|
+
export declare const TRANSITIONS: Readonly<Record<WorkItemStatus, ReadonlyArray<WorkItemStatus>>>;
|
|
586
|
+
|
|
587
|
+
/** Why an item is not verified; empty when it is. */
|
|
588
|
+
export declare const verificationGaps: (item: WorkItem, index: EvidenceIndex, statusOf: (id: string) => WorkItemStatus | undefined, clock: Clock) => ReadonlyArray<string>;
|
|
589
|
+
|
|
590
|
+
export declare const WORK_ITEM_STATUSES: readonly ["proposed", "ready", "active", "blocked", "verified", "closed"];
|
|
591
|
+
|
|
592
|
+
export declare type WorkItem = PlanInstance['workItems'][number];
|
|
593
|
+
|
|
594
|
+
export declare type WorkItemStatus = (typeof WORK_ITEM_STATUSES)[number];
|
|
595
|
+
|
|
596
|
+
export { }
|