iterate-kernel 0.1.0-draft.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.md +56 -0
- package/dist/canonical-json.d.ts +21 -0
- package/dist/canonical-json.d.ts.map +1 -0
- package/dist/canonical-json.js +31 -0
- package/dist/canonical-json.js.map +1 -0
- package/dist/decision-log-entry.d.ts +34 -0
- package/dist/decision-log-entry.d.ts.map +1 -0
- package/dist/decision-log-entry.js +17 -0
- package/dist/decision-log-entry.js.map +1 -0
- package/dist/decision-log.d.ts +142 -0
- package/dist/decision-log.d.ts.map +1 -0
- package/dist/decision-log.js +288 -0
- package/dist/decision-log.js.map +1 -0
- package/dist/dimension-context.d.ts +402 -0
- package/dist/dimension-context.d.ts.map +1 -0
- package/dist/dimension-context.js +226 -0
- package/dist/dimension-context.js.map +1 -0
- package/dist/errors.d.ts +15 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +18 -0
- package/dist/errors.js.map +1 -0
- package/dist/evidence-decision.d.ts +44 -0
- package/dist/evidence-decision.d.ts.map +1 -0
- package/dist/evidence-decision.js +88 -0
- package/dist/evidence-decision.js.map +1 -0
- package/dist/evidence-pack.d.ts +1884 -0
- package/dist/evidence-pack.d.ts.map +1 -0
- package/dist/evidence-pack.js +243 -0
- package/dist/evidence-pack.js.map +1 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +19 -0
- package/dist/index.js.map +1 -0
- package/dist/parse.d.ts +22 -0
- package/dist/parse.d.ts.map +1 -0
- package/dist/parse.js +53 -0
- package/dist/parse.js.map +1 -0
- package/dist/recipe-config.d.ts +48 -0
- package/dist/recipe-config.d.ts.map +1 -0
- package/dist/recipe-config.js +20 -0
- package/dist/recipe-config.js.map +1 -0
- package/dist/schemas.d.ts +11 -0
- package/dist/schemas.d.ts.map +1 -0
- package/dist/schemas.js +19 -0
- package/dist/schemas.js.map +1 -0
- package/package.json +84 -0
- package/schemas/decision-log-entry.schema.json +45 -0
- package/schemas/evidence-pack.schema.json +359 -0
- package/schemas/recipe-config.schema.json +36 -0
|
@@ -0,0 +1,402 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
/**
|
|
3
|
+
* Dimension context: what a run *said* it would review, set against what it
|
|
4
|
+
* actually recorded.
|
|
5
|
+
*
|
|
6
|
+
* WHY THIS LIVES IN THE KERNEL. The two shells keep losing the same
|
|
7
|
+
* information in the same two places — a compaction summary that keeps the
|
|
8
|
+
* story and drops which dimensions were covered, and a run report that lists
|
|
9
|
+
* findings without saying which planned dimension had *none*. Both are
|
|
10
|
+
* arithmetic over two lists the caller already holds. Doing it here means both
|
|
11
|
+
* shells report the same numbers for the same run, and it is checkable against
|
|
12
|
+
* a fixture instead of argued about in review.
|
|
13
|
+
*
|
|
14
|
+
* WHY THERE IS NO LIST OF DIMENSIONS IN HERE. The dimension ids are a
|
|
15
|
+
* *vocabulary*, and the vocabulary is owned by the iterate config
|
|
16
|
+
* (`config/config.schema.json` `$defs.dimension.enum`, kept in lockstep with
|
|
17
|
+
* `config/dimensions.yaml` and the wizard constants by
|
|
18
|
+
* `tests/test_dimension_lock.py` across six sources). A hard-coded copy in this
|
|
19
|
+
* package would be a seventh source that CI does not compare against the other
|
|
20
|
+
* six — the exact failure that lock exists to prevent. So the caller passes the
|
|
21
|
+
* ids it was configured with, and this module only does the accounting. A
|
|
22
|
+
* dimension the engine adds tomorrow works here without a kernel release; a
|
|
23
|
+
* dimension that is *not* in the caller's list is reported as unplanned, not
|
|
24
|
+
* silently accepted.
|
|
25
|
+
*
|
|
26
|
+
* WHAT THIS REFUSES TO DO. It never infers coverage. Coverage is a count of
|
|
27
|
+
* recorded decisions against a planned dimension, and a dimension with no
|
|
28
|
+
* decisions is `unverified` — never "probably fine", never dropped. Ordering is
|
|
29
|
+
* the caller's planned order, and unplanned ids follow sorted, so the same
|
|
30
|
+
* inputs produce the same bytes in any language.
|
|
31
|
+
*/
|
|
32
|
+
/** Ids are kebab-case, non-empty, and bounded — validated, never enumerated. */
|
|
33
|
+
export declare const DIMENSION_ID_PATTERN: RegExp;
|
|
34
|
+
export declare const DIMENSION_ID_MAX_LENGTH = 64;
|
|
35
|
+
export declare const DIMENSION_LABEL_MAX_LENGTH = 256;
|
|
36
|
+
/** A `focus` blob is prose copied from config; bounded so it cannot become a payload. */
|
|
37
|
+
export declare const DIMENSION_FOCUS_MAX_LENGTH = 4096;
|
|
38
|
+
export declare const DIMENSION_MIN_PLANNED = 1;
|
|
39
|
+
export declare const DIMENSION_MAX_PLANNED = 64;
|
|
40
|
+
/**
|
|
41
|
+
* One dimension the run declared it would review, as configured. `id` is the
|
|
42
|
+
* vocabulary key; `label` and `focus` are the human-facing text from the same
|
|
43
|
+
* config entry, carried through so a report can name the dimension without
|
|
44
|
+
* re-reading the config.
|
|
45
|
+
*/
|
|
46
|
+
export declare const PlannedDimensionSchema: z.ZodObject<{
|
|
47
|
+
id: z.ZodString;
|
|
48
|
+
label: z.ZodOptional<z.ZodString>;
|
|
49
|
+
focus: z.ZodOptional<z.ZodString>;
|
|
50
|
+
}, "strict", z.ZodTypeAny, {
|
|
51
|
+
id: string;
|
|
52
|
+
label?: string | undefined;
|
|
53
|
+
focus?: string | undefined;
|
|
54
|
+
}, {
|
|
55
|
+
id: string;
|
|
56
|
+
label?: string | undefined;
|
|
57
|
+
focus?: string | undefined;
|
|
58
|
+
}>;
|
|
59
|
+
export type PlannedDimension = z.infer<typeof PlannedDimensionSchema>;
|
|
60
|
+
/**
|
|
61
|
+
* What the engine recorded for one dimension. `decisions` is a count of ledger
|
|
62
|
+
* entries, not a list: the point of this structure is to survive compaction,
|
|
63
|
+
* and a list of hashes would be the thing compaction drops. `operationIds` is
|
|
64
|
+
* the optional back-pointer to the evidence, capped small for the same reason.
|
|
65
|
+
*/
|
|
66
|
+
export declare const DIMENSION_MAX_OPERATION_IDS = 32;
|
|
67
|
+
export declare const DimensionEvidenceSchema: z.ZodObject<{
|
|
68
|
+
decisions: z.ZodNumber;
|
|
69
|
+
operationIds: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
70
|
+
}, "strict", z.ZodTypeAny, {
|
|
71
|
+
decisions: number;
|
|
72
|
+
operationIds?: string[] | undefined;
|
|
73
|
+
}, {
|
|
74
|
+
decisions: number;
|
|
75
|
+
operationIds?: string[] | undefined;
|
|
76
|
+
}>;
|
|
77
|
+
export type DimensionEvidence = z.infer<typeof DimensionEvidenceSchema>;
|
|
78
|
+
/**
|
|
79
|
+
* A dimension's state, and the only three words this module will use:
|
|
80
|
+
*
|
|
81
|
+
* - `verified` — planned, and the engine recorded at least one decision
|
|
82
|
+
* - `unverified` — planned, and the engine recorded none
|
|
83
|
+
* - `unplanned` — recorded, but the run never declared it
|
|
84
|
+
*
|
|
85
|
+
* There is no `skipped` and no `passed`. Those are judgements about *why* a
|
|
86
|
+
* dimension is empty, and the engine is the only thing entitled to make one;
|
|
87
|
+
* a reporter that guesses is how "we reviewed correctness" ends up in a summary
|
|
88
|
+
* when nothing was checked.
|
|
89
|
+
*/
|
|
90
|
+
export declare const DimensionStatusSchema: z.ZodEnum<["verified", "unverified", "unplanned"]>;
|
|
91
|
+
export type DimensionStatus = z.infer<typeof DimensionStatusSchema>;
|
|
92
|
+
export declare const DimensionContextEntrySchema: z.ZodObject<{
|
|
93
|
+
id: z.ZodString;
|
|
94
|
+
status: z.ZodEnum<["verified", "unverified", "unplanned"]>;
|
|
95
|
+
label: z.ZodOptional<z.ZodString>;
|
|
96
|
+
focus: z.ZodOptional<z.ZodString>;
|
|
97
|
+
evidence: z.ZodObject<{
|
|
98
|
+
decisions: z.ZodNumber;
|
|
99
|
+
operationIds: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
100
|
+
}, "strict", z.ZodTypeAny, {
|
|
101
|
+
decisions: number;
|
|
102
|
+
operationIds?: string[] | undefined;
|
|
103
|
+
}, {
|
|
104
|
+
decisions: number;
|
|
105
|
+
operationIds?: string[] | undefined;
|
|
106
|
+
}>;
|
|
107
|
+
}, "strict", z.ZodTypeAny, {
|
|
108
|
+
status: "verified" | "unverified" | "unplanned";
|
|
109
|
+
evidence: {
|
|
110
|
+
decisions: number;
|
|
111
|
+
operationIds?: string[] | undefined;
|
|
112
|
+
};
|
|
113
|
+
id: string;
|
|
114
|
+
label?: string | undefined;
|
|
115
|
+
focus?: string | undefined;
|
|
116
|
+
}, {
|
|
117
|
+
status: "verified" | "unverified" | "unplanned";
|
|
118
|
+
evidence: {
|
|
119
|
+
decisions: number;
|
|
120
|
+
operationIds?: string[] | undefined;
|
|
121
|
+
};
|
|
122
|
+
id: string;
|
|
123
|
+
label?: string | undefined;
|
|
124
|
+
focus?: string | undefined;
|
|
125
|
+
}>;
|
|
126
|
+
export type DimensionContextEntry = z.infer<typeof DimensionContextEntrySchema>;
|
|
127
|
+
/**
|
|
128
|
+
* The per-dimension summary plus the counts a caller asserts out loud. The
|
|
129
|
+
* totals are stored rather than recomputed by every consumer so that a
|
|
130
|
+
* consumer that reports `verified: 3` and one that iterates the entries cannot
|
|
131
|
+
* disagree — a disagreement there is a bug in one of them, and this is where it
|
|
132
|
+
* becomes visible.
|
|
133
|
+
*/
|
|
134
|
+
export declare const DimensionContextTotalsSchema: z.ZodObject<{
|
|
135
|
+
planned: z.ZodNumber;
|
|
136
|
+
verified: z.ZodNumber;
|
|
137
|
+
unverified: z.ZodNumber;
|
|
138
|
+
unplanned: z.ZodNumber;
|
|
139
|
+
decisions: z.ZodNumber;
|
|
140
|
+
}, "strict", z.ZodTypeAny, {
|
|
141
|
+
decisions: number;
|
|
142
|
+
verified: number;
|
|
143
|
+
unverified: number;
|
|
144
|
+
unplanned: number;
|
|
145
|
+
planned: number;
|
|
146
|
+
}, {
|
|
147
|
+
decisions: number;
|
|
148
|
+
verified: number;
|
|
149
|
+
unverified: number;
|
|
150
|
+
unplanned: number;
|
|
151
|
+
planned: number;
|
|
152
|
+
}>;
|
|
153
|
+
export type DimensionContextTotals = z.infer<typeof DimensionContextTotalsSchema>;
|
|
154
|
+
export declare const DimensionContextSchema: z.ZodObject<{
|
|
155
|
+
planned: z.ZodArray<z.ZodObject<{
|
|
156
|
+
id: z.ZodString;
|
|
157
|
+
status: z.ZodEnum<["verified", "unverified", "unplanned"]>;
|
|
158
|
+
label: z.ZodOptional<z.ZodString>;
|
|
159
|
+
focus: z.ZodOptional<z.ZodString>;
|
|
160
|
+
evidence: z.ZodObject<{
|
|
161
|
+
decisions: z.ZodNumber;
|
|
162
|
+
operationIds: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
163
|
+
}, "strict", z.ZodTypeAny, {
|
|
164
|
+
decisions: number;
|
|
165
|
+
operationIds?: string[] | undefined;
|
|
166
|
+
}, {
|
|
167
|
+
decisions: number;
|
|
168
|
+
operationIds?: string[] | undefined;
|
|
169
|
+
}>;
|
|
170
|
+
}, "strict", z.ZodTypeAny, {
|
|
171
|
+
status: "verified" | "unverified" | "unplanned";
|
|
172
|
+
evidence: {
|
|
173
|
+
decisions: number;
|
|
174
|
+
operationIds?: string[] | undefined;
|
|
175
|
+
};
|
|
176
|
+
id: string;
|
|
177
|
+
label?: string | undefined;
|
|
178
|
+
focus?: string | undefined;
|
|
179
|
+
}, {
|
|
180
|
+
status: "verified" | "unverified" | "unplanned";
|
|
181
|
+
evidence: {
|
|
182
|
+
decisions: number;
|
|
183
|
+
operationIds?: string[] | undefined;
|
|
184
|
+
};
|
|
185
|
+
id: string;
|
|
186
|
+
label?: string | undefined;
|
|
187
|
+
focus?: string | undefined;
|
|
188
|
+
}>, "many">;
|
|
189
|
+
unplanned: z.ZodArray<z.ZodObject<{
|
|
190
|
+
id: z.ZodString;
|
|
191
|
+
status: z.ZodEnum<["verified", "unverified", "unplanned"]>;
|
|
192
|
+
label: z.ZodOptional<z.ZodString>;
|
|
193
|
+
focus: z.ZodOptional<z.ZodString>;
|
|
194
|
+
evidence: z.ZodObject<{
|
|
195
|
+
decisions: z.ZodNumber;
|
|
196
|
+
operationIds: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
197
|
+
}, "strict", z.ZodTypeAny, {
|
|
198
|
+
decisions: number;
|
|
199
|
+
operationIds?: string[] | undefined;
|
|
200
|
+
}, {
|
|
201
|
+
decisions: number;
|
|
202
|
+
operationIds?: string[] | undefined;
|
|
203
|
+
}>;
|
|
204
|
+
}, "strict", z.ZodTypeAny, {
|
|
205
|
+
status: "verified" | "unverified" | "unplanned";
|
|
206
|
+
evidence: {
|
|
207
|
+
decisions: number;
|
|
208
|
+
operationIds?: string[] | undefined;
|
|
209
|
+
};
|
|
210
|
+
id: string;
|
|
211
|
+
label?: string | undefined;
|
|
212
|
+
focus?: string | undefined;
|
|
213
|
+
}, {
|
|
214
|
+
status: "verified" | "unverified" | "unplanned";
|
|
215
|
+
evidence: {
|
|
216
|
+
decisions: number;
|
|
217
|
+
operationIds?: string[] | undefined;
|
|
218
|
+
};
|
|
219
|
+
id: string;
|
|
220
|
+
label?: string | undefined;
|
|
221
|
+
focus?: string | undefined;
|
|
222
|
+
}>, "many">;
|
|
223
|
+
totals: z.ZodObject<{
|
|
224
|
+
planned: z.ZodNumber;
|
|
225
|
+
verified: z.ZodNumber;
|
|
226
|
+
unverified: z.ZodNumber;
|
|
227
|
+
unplanned: z.ZodNumber;
|
|
228
|
+
decisions: z.ZodNumber;
|
|
229
|
+
}, "strict", z.ZodTypeAny, {
|
|
230
|
+
decisions: number;
|
|
231
|
+
verified: number;
|
|
232
|
+
unverified: number;
|
|
233
|
+
unplanned: number;
|
|
234
|
+
planned: number;
|
|
235
|
+
}, {
|
|
236
|
+
decisions: number;
|
|
237
|
+
verified: number;
|
|
238
|
+
unverified: number;
|
|
239
|
+
unplanned: number;
|
|
240
|
+
planned: number;
|
|
241
|
+
}>;
|
|
242
|
+
}, "strict", z.ZodTypeAny, {
|
|
243
|
+
unplanned: {
|
|
244
|
+
status: "verified" | "unverified" | "unplanned";
|
|
245
|
+
evidence: {
|
|
246
|
+
decisions: number;
|
|
247
|
+
operationIds?: string[] | undefined;
|
|
248
|
+
};
|
|
249
|
+
id: string;
|
|
250
|
+
label?: string | undefined;
|
|
251
|
+
focus?: string | undefined;
|
|
252
|
+
}[];
|
|
253
|
+
planned: {
|
|
254
|
+
status: "verified" | "unverified" | "unplanned";
|
|
255
|
+
evidence: {
|
|
256
|
+
decisions: number;
|
|
257
|
+
operationIds?: string[] | undefined;
|
|
258
|
+
};
|
|
259
|
+
id: string;
|
|
260
|
+
label?: string | undefined;
|
|
261
|
+
focus?: string | undefined;
|
|
262
|
+
}[];
|
|
263
|
+
totals: {
|
|
264
|
+
decisions: number;
|
|
265
|
+
verified: number;
|
|
266
|
+
unverified: number;
|
|
267
|
+
unplanned: number;
|
|
268
|
+
planned: number;
|
|
269
|
+
};
|
|
270
|
+
}, {
|
|
271
|
+
unplanned: {
|
|
272
|
+
status: "verified" | "unverified" | "unplanned";
|
|
273
|
+
evidence: {
|
|
274
|
+
decisions: number;
|
|
275
|
+
operationIds?: string[] | undefined;
|
|
276
|
+
};
|
|
277
|
+
id: string;
|
|
278
|
+
label?: string | undefined;
|
|
279
|
+
focus?: string | undefined;
|
|
280
|
+
}[];
|
|
281
|
+
planned: {
|
|
282
|
+
status: "verified" | "unverified" | "unplanned";
|
|
283
|
+
evidence: {
|
|
284
|
+
decisions: number;
|
|
285
|
+
operationIds?: string[] | undefined;
|
|
286
|
+
};
|
|
287
|
+
id: string;
|
|
288
|
+
label?: string | undefined;
|
|
289
|
+
focus?: string | undefined;
|
|
290
|
+
}[];
|
|
291
|
+
totals: {
|
|
292
|
+
decisions: number;
|
|
293
|
+
verified: number;
|
|
294
|
+
unverified: number;
|
|
295
|
+
unplanned: number;
|
|
296
|
+
planned: number;
|
|
297
|
+
};
|
|
298
|
+
}>;
|
|
299
|
+
export type DimensionContext = z.infer<typeof DimensionContextSchema>;
|
|
300
|
+
/** What a caller supplies: the plan, plus what the engine recorded per id. */
|
|
301
|
+
export declare const DimensionContextInputSchema: z.ZodObject<{
|
|
302
|
+
planned: z.ZodArray<z.ZodObject<{
|
|
303
|
+
id: z.ZodString;
|
|
304
|
+
label: z.ZodOptional<z.ZodString>;
|
|
305
|
+
focus: z.ZodOptional<z.ZodString>;
|
|
306
|
+
}, "strict", z.ZodTypeAny, {
|
|
307
|
+
id: string;
|
|
308
|
+
label?: string | undefined;
|
|
309
|
+
focus?: string | undefined;
|
|
310
|
+
}, {
|
|
311
|
+
id: string;
|
|
312
|
+
label?: string | undefined;
|
|
313
|
+
focus?: string | undefined;
|
|
314
|
+
}>, "many">;
|
|
315
|
+
recorded: z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
316
|
+
decisions: z.ZodNumber;
|
|
317
|
+
operationIds: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
318
|
+
}, "strict", z.ZodTypeAny, {
|
|
319
|
+
decisions: number;
|
|
320
|
+
operationIds?: string[] | undefined;
|
|
321
|
+
}, {
|
|
322
|
+
decisions: number;
|
|
323
|
+
operationIds?: string[] | undefined;
|
|
324
|
+
}>>;
|
|
325
|
+
}, "strict", z.ZodTypeAny, {
|
|
326
|
+
planned: {
|
|
327
|
+
id: string;
|
|
328
|
+
label?: string | undefined;
|
|
329
|
+
focus?: string | undefined;
|
|
330
|
+
}[];
|
|
331
|
+
recorded: Record<string, {
|
|
332
|
+
decisions: number;
|
|
333
|
+
operationIds?: string[] | undefined;
|
|
334
|
+
}>;
|
|
335
|
+
}, {
|
|
336
|
+
planned: {
|
|
337
|
+
id: string;
|
|
338
|
+
label?: string | undefined;
|
|
339
|
+
focus?: string | undefined;
|
|
340
|
+
}[];
|
|
341
|
+
recorded: Record<string, {
|
|
342
|
+
decisions: number;
|
|
343
|
+
operationIds?: string[] | undefined;
|
|
344
|
+
}>;
|
|
345
|
+
}>;
|
|
346
|
+
export type DimensionContextInput = z.infer<typeof DimensionContextInputSchema>;
|
|
347
|
+
export declare const DIMENSION_CONTEXT_CODES: {
|
|
348
|
+
readonly duplicate: "KERNEL_E_DIMENSION_DUPLICATE";
|
|
349
|
+
readonly empty: "KERNEL_E_DIMENSION_EMPTY";
|
|
350
|
+
};
|
|
351
|
+
export type KernelDimensionCode = (typeof DIMENSION_CONTEXT_CODES)[keyof typeof DIMENSION_CONTEXT_CODES];
|
|
352
|
+
/**
|
|
353
|
+
* Every failure carries `code` + `message` + `remedy`, matching
|
|
354
|
+
* `KernelDecisionLogError`: whoever catches this must be able to act on it
|
|
355
|
+
* without reading this file.
|
|
356
|
+
*/
|
|
357
|
+
export declare class KernelDimensionError extends Error {
|
|
358
|
+
readonly code: KernelDimensionCode;
|
|
359
|
+
readonly dimension?: string;
|
|
360
|
+
readonly remedy: string;
|
|
361
|
+
constructor(code: KernelDimensionCode, message: string, remedy: string, dimension?: string);
|
|
362
|
+
}
|
|
363
|
+
/**
|
|
364
|
+
* Build the dimension context.
|
|
365
|
+
*
|
|
366
|
+
* The rules, stated so a second implementation can be written against this
|
|
367
|
+
* paragraph rather than against the TypeScript:
|
|
368
|
+
*
|
|
369
|
+
* 1. `planned` entries appear in `context.planned` in the caller's order.
|
|
370
|
+
* Their status is `verified` when `recorded[id].decisions >= 1`, else
|
|
371
|
+
* `unverified`. `evidence` is the recorded value verbatim, defaulting to
|
|
372
|
+
* `{ decisions: 0 }` when the id is absent — an absent id and a recorded
|
|
373
|
+
* zero are the same fact, and both mean `unverified`.
|
|
374
|
+
* 2. An id present in `recorded` but not in `planned` becomes one `unplanned`
|
|
375
|
+
* entry, status `unplanned`, sorted by id ascending (UTF-16 code unit
|
|
376
|
+
* order, the same rule `canonicalJson` uses). This is the case that must
|
|
377
|
+
* not be dropped: the engine checked something the run never declared.
|
|
378
|
+
* 3. `totals.decisions` is the sum over planned entries **plus** unplanned
|
|
379
|
+
* ones — every recorded decision, counted once. `totals.planned` is the
|
|
380
|
+
* length of the planned list, so `verified + unverified === planned`
|
|
381
|
+
* always holds and a caller can assert it.
|
|
382
|
+
* 4. A duplicate id in `planned` throws. Silently keeping the last one would
|
|
383
|
+
* make the planned count disagree with the list a caller printed, which is
|
|
384
|
+
* the class of quiet drift this whole structure exists to catch.
|
|
385
|
+
*/
|
|
386
|
+
export declare function dimensionContext(input: DimensionContextInput): DimensionContext;
|
|
387
|
+
/**
|
|
388
|
+
* The one-line form a compaction summary or a report header can carry: it
|
|
389
|
+
* states coverage as counts, so the reader learns what was *not* checked
|
|
390
|
+
* without the reporter having to characterise it.
|
|
391
|
+
*
|
|
392
|
+
* `3/5 dimensions verified, 2 unverified (security, ui-ux), 1 unplanned (tech-debt), 12 decisions`
|
|
393
|
+
*
|
|
394
|
+
* The unverified ids are named because a bare "2 unverified" is a number
|
|
395
|
+
* nobody can act on; the unplanned ones are named because an undeclared
|
|
396
|
+
* dimension is a finding about the plan, not about the code. A run with nothing
|
|
397
|
+
* verified still produces a sentence — `0/5 dimensions verified, 5 unverified
|
|
398
|
+
* (…), 0 decisions` is a legitimate and useful line, which is why this never
|
|
399
|
+
* collapses to an empty string.
|
|
400
|
+
*/
|
|
401
|
+
export declare function formatDimensionContext(context: DimensionContext): string;
|
|
402
|
+
//# sourceMappingURL=dimension-context.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dimension-context.d.ts","sourceRoot":"","sources":["../src/dimension-context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH,gFAAgF;AAChF,eAAO,MAAM,oBAAoB,QAA+B,CAAC;AACjE,eAAO,MAAM,uBAAuB,KAAK,CAAC;AAE1C,eAAO,MAAM,0BAA0B,MAAM,CAAC;AAC9C,yFAAyF;AACzF,eAAO,MAAM,0BAA0B,OAAO,CAAC;AAE/C,eAAO,MAAM,qBAAqB,IAAI,CAAC;AACvC,eAAO,MAAM,qBAAqB,KAAK,CAAC;AAExC;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB;;;;;;;;;;;;EAIjC,CAAC;AACH,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAEtE;;;;;GAKG;AACH,eAAO,MAAM,2BAA2B,KAAK,CAAC;AAE9C,eAAO,MAAM,uBAAuB;;;;;;;;;EAGlC,CAAC;AACH,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAC;AAGxE;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,qBAAqB,oDAAkD,CAAC;AACrF,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAEpE,eAAO,MAAM,2BAA2B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAMtC,CAAC;AACH,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,2BAA2B,CAAC,CAAC;AAEhF;;;;;;GAMG;AACH,eAAO,MAAM,4BAA4B;;;;;;;;;;;;;;;;;;EAMvC,CAAC;AACH,MAAM,MAAM,sBAAsB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,4BAA4B,CAAC,CAAC;AAElF,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAIjC,CAAC;AACH,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAEtE,8EAA8E;AAC9E,eAAO,MAAM,2BAA2B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAMtC,CAAC;AACH,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,2BAA2B,CAAC,CAAC;AAEhF,eAAO,MAAM,uBAAuB;;;CAG1B,CAAC;AAEX,MAAM,MAAM,mBAAmB,GAAG,CAAC,OAAO,uBAAuB,CAAC,CAAC,MAAM,OAAO,uBAAuB,CAAC,CAAC;AAEzG;;;;GAIG;AACH,qBAAa,oBAAqB,SAAQ,KAAK;IAC7C,QAAQ,CAAC,IAAI,EAAE,mBAAmB,CAAC;IACnC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;gBAEZ,IAAI,EAAE,mBAAmB,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM;CAO3F;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,qBAAqB,GAAG,gBAAgB,CA4D/E;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,gBAAgB,GAAG,MAAM,CAexE"}
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
/**
|
|
3
|
+
* Dimension context: what a run *said* it would review, set against what it
|
|
4
|
+
* actually recorded.
|
|
5
|
+
*
|
|
6
|
+
* WHY THIS LIVES IN THE KERNEL. The two shells keep losing the same
|
|
7
|
+
* information in the same two places — a compaction summary that keeps the
|
|
8
|
+
* story and drops which dimensions were covered, and a run report that lists
|
|
9
|
+
* findings without saying which planned dimension had *none*. Both are
|
|
10
|
+
* arithmetic over two lists the caller already holds. Doing it here means both
|
|
11
|
+
* shells report the same numbers for the same run, and it is checkable against
|
|
12
|
+
* a fixture instead of argued about in review.
|
|
13
|
+
*
|
|
14
|
+
* WHY THERE IS NO LIST OF DIMENSIONS IN HERE. The dimension ids are a
|
|
15
|
+
* *vocabulary*, and the vocabulary is owned by the iterate config
|
|
16
|
+
* (`config/config.schema.json` `$defs.dimension.enum`, kept in lockstep with
|
|
17
|
+
* `config/dimensions.yaml` and the wizard constants by
|
|
18
|
+
* `tests/test_dimension_lock.py` across six sources). A hard-coded copy in this
|
|
19
|
+
* package would be a seventh source that CI does not compare against the other
|
|
20
|
+
* six — the exact failure that lock exists to prevent. So the caller passes the
|
|
21
|
+
* ids it was configured with, and this module only does the accounting. A
|
|
22
|
+
* dimension the engine adds tomorrow works here without a kernel release; a
|
|
23
|
+
* dimension that is *not* in the caller's list is reported as unplanned, not
|
|
24
|
+
* silently accepted.
|
|
25
|
+
*
|
|
26
|
+
* WHAT THIS REFUSES TO DO. It never infers coverage. Coverage is a count of
|
|
27
|
+
* recorded decisions against a planned dimension, and a dimension with no
|
|
28
|
+
* decisions is `unverified` — never "probably fine", never dropped. Ordering is
|
|
29
|
+
* the caller's planned order, and unplanned ids follow sorted, so the same
|
|
30
|
+
* inputs produce the same bytes in any language.
|
|
31
|
+
*/
|
|
32
|
+
/** Ids are kebab-case, non-empty, and bounded — validated, never enumerated. */
|
|
33
|
+
export const DIMENSION_ID_PATTERN = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
|
|
34
|
+
export const DIMENSION_ID_MAX_LENGTH = 64;
|
|
35
|
+
export const DIMENSION_LABEL_MAX_LENGTH = 256;
|
|
36
|
+
/** A `focus` blob is prose copied from config; bounded so it cannot become a payload. */
|
|
37
|
+
export const DIMENSION_FOCUS_MAX_LENGTH = 4096;
|
|
38
|
+
export const DIMENSION_MIN_PLANNED = 1;
|
|
39
|
+
export const DIMENSION_MAX_PLANNED = 64;
|
|
40
|
+
/**
|
|
41
|
+
* One dimension the run declared it would review, as configured. `id` is the
|
|
42
|
+
* vocabulary key; `label` and `focus` are the human-facing text from the same
|
|
43
|
+
* config entry, carried through so a report can name the dimension without
|
|
44
|
+
* re-reading the config.
|
|
45
|
+
*/
|
|
46
|
+
export const PlannedDimensionSchema = z.strictObject({
|
|
47
|
+
id: z.string().regex(DIMENSION_ID_PATTERN).max(DIMENSION_ID_MAX_LENGTH),
|
|
48
|
+
label: z.string().min(1).max(DIMENSION_LABEL_MAX_LENGTH).optional(),
|
|
49
|
+
focus: z.string().max(DIMENSION_FOCUS_MAX_LENGTH).optional()
|
|
50
|
+
});
|
|
51
|
+
/**
|
|
52
|
+
* What the engine recorded for one dimension. `decisions` is a count of ledger
|
|
53
|
+
* entries, not a list: the point of this structure is to survive compaction,
|
|
54
|
+
* and a list of hashes would be the thing compaction drops. `operationIds` is
|
|
55
|
+
* the optional back-pointer to the evidence, capped small for the same reason.
|
|
56
|
+
*/
|
|
57
|
+
export const DIMENSION_MAX_OPERATION_IDS = 32;
|
|
58
|
+
export const DimensionEvidenceSchema = z.strictObject({
|
|
59
|
+
decisions: z.number().int().min(0),
|
|
60
|
+
operationIds: z.array(z.string().min(1)).max(DIMENSION_MAX_OPERATION_IDS).optional()
|
|
61
|
+
});
|
|
62
|
+
/**
|
|
63
|
+
* A dimension's state, and the only three words this module will use:
|
|
64
|
+
*
|
|
65
|
+
* - `verified` — planned, and the engine recorded at least one decision
|
|
66
|
+
* - `unverified` — planned, and the engine recorded none
|
|
67
|
+
* - `unplanned` — recorded, but the run never declared it
|
|
68
|
+
*
|
|
69
|
+
* There is no `skipped` and no `passed`. Those are judgements about *why* a
|
|
70
|
+
* dimension is empty, and the engine is the only thing entitled to make one;
|
|
71
|
+
* a reporter that guesses is how "we reviewed correctness" ends up in a summary
|
|
72
|
+
* when nothing was checked.
|
|
73
|
+
*/
|
|
74
|
+
export const DimensionStatusSchema = z.enum(["verified", "unverified", "unplanned"]);
|
|
75
|
+
export const DimensionContextEntrySchema = z.strictObject({
|
|
76
|
+
id: z.string().regex(DIMENSION_ID_PATTERN).max(DIMENSION_ID_MAX_LENGTH),
|
|
77
|
+
status: DimensionStatusSchema,
|
|
78
|
+
label: z.string().min(1).max(DIMENSION_LABEL_MAX_LENGTH).optional(),
|
|
79
|
+
focus: z.string().max(DIMENSION_FOCUS_MAX_LENGTH).optional(),
|
|
80
|
+
evidence: DimensionEvidenceSchema
|
|
81
|
+
});
|
|
82
|
+
/**
|
|
83
|
+
* The per-dimension summary plus the counts a caller asserts out loud. The
|
|
84
|
+
* totals are stored rather than recomputed by every consumer so that a
|
|
85
|
+
* consumer that reports `verified: 3` and one that iterates the entries cannot
|
|
86
|
+
* disagree — a disagreement there is a bug in one of them, and this is where it
|
|
87
|
+
* becomes visible.
|
|
88
|
+
*/
|
|
89
|
+
export const DimensionContextTotalsSchema = z.strictObject({
|
|
90
|
+
planned: z.number().int().min(0),
|
|
91
|
+
verified: z.number().int().min(0),
|
|
92
|
+
unverified: z.number().int().min(0),
|
|
93
|
+
unplanned: z.number().int().min(0),
|
|
94
|
+
decisions: z.number().int().min(0)
|
|
95
|
+
});
|
|
96
|
+
export const DimensionContextSchema = z.strictObject({
|
|
97
|
+
planned: z.array(DimensionContextEntrySchema),
|
|
98
|
+
unplanned: z.array(DimensionContextEntrySchema),
|
|
99
|
+
totals: DimensionContextTotalsSchema
|
|
100
|
+
});
|
|
101
|
+
/** What a caller supplies: the plan, plus what the engine recorded per id. */
|
|
102
|
+
export const DimensionContextInputSchema = z.strictObject({
|
|
103
|
+
planned: z.array(PlannedDimensionSchema).min(DIMENSION_MIN_PLANNED).max(DIMENSION_MAX_PLANNED),
|
|
104
|
+
recorded: z.record(z.string().regex(DIMENSION_ID_PATTERN).max(DIMENSION_ID_MAX_LENGTH), DimensionEvidenceSchema)
|
|
105
|
+
});
|
|
106
|
+
export const DIMENSION_CONTEXT_CODES = {
|
|
107
|
+
duplicate: "KERNEL_E_DIMENSION_DUPLICATE",
|
|
108
|
+
empty: "KERNEL_E_DIMENSION_EMPTY"
|
|
109
|
+
};
|
|
110
|
+
/**
|
|
111
|
+
* Every failure carries `code` + `message` + `remedy`, matching
|
|
112
|
+
* `KernelDecisionLogError`: whoever catches this must be able to act on it
|
|
113
|
+
* without reading this file.
|
|
114
|
+
*/
|
|
115
|
+
export class KernelDimensionError extends Error {
|
|
116
|
+
code;
|
|
117
|
+
dimension;
|
|
118
|
+
remedy;
|
|
119
|
+
constructor(code, message, remedy, dimension) {
|
|
120
|
+
super(`${code}: ${message}`);
|
|
121
|
+
this.name = "KernelDimensionError";
|
|
122
|
+
this.code = code;
|
|
123
|
+
this.remedy = remedy;
|
|
124
|
+
if (dimension !== undefined)
|
|
125
|
+
this.dimension = dimension;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Build the dimension context.
|
|
130
|
+
*
|
|
131
|
+
* The rules, stated so a second implementation can be written against this
|
|
132
|
+
* paragraph rather than against the TypeScript:
|
|
133
|
+
*
|
|
134
|
+
* 1. `planned` entries appear in `context.planned` in the caller's order.
|
|
135
|
+
* Their status is `verified` when `recorded[id].decisions >= 1`, else
|
|
136
|
+
* `unverified`. `evidence` is the recorded value verbatim, defaulting to
|
|
137
|
+
* `{ decisions: 0 }` when the id is absent — an absent id and a recorded
|
|
138
|
+
* zero are the same fact, and both mean `unverified`.
|
|
139
|
+
* 2. An id present in `recorded` but not in `planned` becomes one `unplanned`
|
|
140
|
+
* entry, status `unplanned`, sorted by id ascending (UTF-16 code unit
|
|
141
|
+
* order, the same rule `canonicalJson` uses). This is the case that must
|
|
142
|
+
* not be dropped: the engine checked something the run never declared.
|
|
143
|
+
* 3. `totals.decisions` is the sum over planned entries **plus** unplanned
|
|
144
|
+
* ones — every recorded decision, counted once. `totals.planned` is the
|
|
145
|
+
* length of the planned list, so `verified + unverified === planned`
|
|
146
|
+
* always holds and a caller can assert it.
|
|
147
|
+
* 4. A duplicate id in `planned` throws. Silently keeping the last one would
|
|
148
|
+
* make the planned count disagree with the list a caller printed, which is
|
|
149
|
+
* the class of quiet drift this whole structure exists to catch.
|
|
150
|
+
*/
|
|
151
|
+
export function dimensionContext(input) {
|
|
152
|
+
const seen = new Set();
|
|
153
|
+
for (const dimension of input.planned) {
|
|
154
|
+
if (seen.has(dimension.id)) {
|
|
155
|
+
throw new KernelDimensionError(DIMENSION_CONTEXT_CODES.duplicate, `dimension ${JSON.stringify(dimension.id)} is planned more than once`, "give each planned dimension exactly one entry; the totals are computed from this list", dimension.id);
|
|
156
|
+
}
|
|
157
|
+
seen.add(dimension.id);
|
|
158
|
+
}
|
|
159
|
+
const plannedEntries = input.planned.map((dimension) => {
|
|
160
|
+
const evidence = input.recorded[dimension.id] ?? { decisions: 0 };
|
|
161
|
+
return {
|
|
162
|
+
id: dimension.id,
|
|
163
|
+
status: evidence.decisions >= 1 ? "verified" : "unverified",
|
|
164
|
+
...(dimension.label !== undefined ? { label: dimension.label } : {}),
|
|
165
|
+
...(dimension.focus !== undefined ? { focus: dimension.focus } : {}),
|
|
166
|
+
evidence
|
|
167
|
+
};
|
|
168
|
+
});
|
|
169
|
+
const unplannedIds = Object.keys(input.recorded)
|
|
170
|
+
.filter((id) => !seen.has(id))
|
|
171
|
+
.sort();
|
|
172
|
+
const unplannedEntries = unplannedIds.map((id) => {
|
|
173
|
+
const evidence = input.recorded[id];
|
|
174
|
+
if (evidence === undefined) {
|
|
175
|
+
// Unreachable while `recorded`'s values are validated, but the alternative
|
|
176
|
+
// is a non-null assertion on a value this function then hands to a
|
|
177
|
+
// consumer as fact.
|
|
178
|
+
throw new KernelDimensionError(DIMENSION_CONTEXT_CODES.empty, `recorded dimension ${JSON.stringify(id)} has no evidence`, "every key in `recorded` must carry an evidence object");
|
|
179
|
+
}
|
|
180
|
+
return { id, status: "unplanned", evidence };
|
|
181
|
+
});
|
|
182
|
+
const verified = plannedEntries.filter((entry) => entry.status === "verified").length;
|
|
183
|
+
const decisions = [...plannedEntries, ...unplannedEntries].reduce((total, entry) => total + entry.evidence.decisions, 0);
|
|
184
|
+
return {
|
|
185
|
+
planned: plannedEntries,
|
|
186
|
+
unplanned: unplannedEntries,
|
|
187
|
+
totals: {
|
|
188
|
+
planned: plannedEntries.length,
|
|
189
|
+
verified,
|
|
190
|
+
unverified: plannedEntries.length - verified,
|
|
191
|
+
unplanned: unplannedEntries.length,
|
|
192
|
+
decisions
|
|
193
|
+
}
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* The one-line form a compaction summary or a report header can carry: it
|
|
198
|
+
* states coverage as counts, so the reader learns what was *not* checked
|
|
199
|
+
* without the reporter having to characterise it.
|
|
200
|
+
*
|
|
201
|
+
* `3/5 dimensions verified, 2 unverified (security, ui-ux), 1 unplanned (tech-debt), 12 decisions`
|
|
202
|
+
*
|
|
203
|
+
* The unverified ids are named because a bare "2 unverified" is a number
|
|
204
|
+
* nobody can act on; the unplanned ones are named because an undeclared
|
|
205
|
+
* dimension is a finding about the plan, not about the code. A run with nothing
|
|
206
|
+
* verified still produces a sentence — `0/5 dimensions verified, 5 unverified
|
|
207
|
+
* (…), 0 decisions` is a legitimate and useful line, which is why this never
|
|
208
|
+
* collapses to an empty string.
|
|
209
|
+
*/
|
|
210
|
+
export function formatDimensionContext(context) {
|
|
211
|
+
const { totals } = context;
|
|
212
|
+
const parts = [`${totals.verified}/${totals.planned} dimensions verified`];
|
|
213
|
+
if (totals.unverified > 0) {
|
|
214
|
+
const ids = context.planned
|
|
215
|
+
.filter((entry) => entry.status === "unverified")
|
|
216
|
+
.map((entry) => entry.id);
|
|
217
|
+
parts.push(`${totals.unverified} unverified (${ids.join(", ")})`);
|
|
218
|
+
}
|
|
219
|
+
if (totals.unplanned > 0) {
|
|
220
|
+
const ids = context.unplanned.map((entry) => entry.id);
|
|
221
|
+
parts.push(`${totals.unplanned} unplanned (${ids.join(", ")})`);
|
|
222
|
+
}
|
|
223
|
+
parts.push(`${totals.decisions} ${totals.decisions === 1 ? "decision" : "decisions"}`);
|
|
224
|
+
return parts.join(", ");
|
|
225
|
+
}
|
|
226
|
+
//# sourceMappingURL=dimension-context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dimension-context.js","sourceRoot":"","sources":["../src/dimension-context.ts"],"names":[],"mappings":"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"}
|
package/dist/errors.d.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export interface KernelSchemaIssue {
|
|
2
|
+
readonly path: string;
|
|
3
|
+
readonly message: string;
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Thrown by every parse* function in this package when the input does not
|
|
7
|
+
* conform to the schema. `code` is stable and machine-readable; `issues`
|
|
8
|
+
* carries one entry per violation with a JSON-path-like location.
|
|
9
|
+
*/
|
|
10
|
+
export declare class KernelSchemaError extends Error {
|
|
11
|
+
readonly code = "KERNEL_E_SCHEMA";
|
|
12
|
+
readonly issues: readonly KernelSchemaIssue[];
|
|
13
|
+
constructor(label: string, issues: readonly KernelSchemaIssue[]);
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED;;;;GAIG;AACH,qBAAa,iBAAkB,SAAQ,KAAK;IAC1C,QAAQ,CAAC,IAAI,qBAAqB;IAClC,QAAQ,CAAC,MAAM,EAAE,SAAS,iBAAiB,EAAE,CAAC;gBAElC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,iBAAiB,EAAE;CAQhE"}
|