@aldus-runtime/regression 0.2.0-next.5 → 0.2.0-next.50
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/dist/corpus.d.ts +26 -3
- package/dist/corpus.d.ts.map +1 -1
- package/dist/corpus.js +106 -4
- package/dist/corpus.js.map +1 -1
- package/dist/errors.d.ts +10 -0
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +10 -0
- package/dist/errors.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/metrics.d.ts +21 -0
- package/dist/metrics.d.ts.map +1 -1
- package/dist/metrics.js +6 -0
- package/dist/metrics.js.map +1 -1
- package/package.json +3 -3
- package/src/corpus.ts +118 -4
- package/src/errors.ts +10 -0
- package/src/index.ts +2 -0
- package/src/metrics.ts +28 -0
package/dist/corpus.d.ts
CHANGED
|
@@ -120,7 +120,8 @@ export declare const defectCorpusSchema: z.ZodObject<{
|
|
|
120
120
|
}, z.core.$strip>;
|
|
121
121
|
labelledAt: z.ZodISODateTime;
|
|
122
122
|
}, z.core.$strip>>;
|
|
123
|
-
|
|
123
|
+
metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
124
|
+
}, z.core.$strict>;
|
|
124
125
|
/** @see defectCorpusSchema */
|
|
125
126
|
export type DefectCorpus = z.infer<typeof defectCorpusSchema>;
|
|
126
127
|
/** One finding an evaluator reported. */
|
|
@@ -140,6 +141,7 @@ export declare const evaluatorOutcomeSchema: z.ZodObject<{
|
|
|
140
141
|
severity: z.ZodOptional<z.ZodString>;
|
|
141
142
|
confidence: z.ZodOptional<z.ZodNumber>;
|
|
142
143
|
}, z.core.$strip>>;
|
|
144
|
+
siteMetricsMeasurable: z.ZodOptional<z.ZodBoolean>;
|
|
143
145
|
}, z.core.$strip>;
|
|
144
146
|
/** @see evaluatorOutcomeSchema */
|
|
145
147
|
export type EvaluatorOutcome = z.infer<typeof evaluatorOutcomeSchema>;
|
|
@@ -162,13 +164,34 @@ export declare const evaluatorRunSchema: z.ZodObject<{
|
|
|
162
164
|
severity: z.ZodOptional<z.ZodString>;
|
|
163
165
|
confidence: z.ZodOptional<z.ZodNumber>;
|
|
164
166
|
}, z.core.$strip>>;
|
|
167
|
+
siteMetricsMeasurable: z.ZodOptional<z.ZodBoolean>;
|
|
165
168
|
}, z.core.$strip>>;
|
|
166
169
|
executedAt: z.ZodISODateTime;
|
|
167
|
-
|
|
170
|
+
metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
171
|
+
}, z.core.$strict>;
|
|
168
172
|
/** @see evaluatorRunSchema */
|
|
169
173
|
export type EvaluatorRun = z.infer<typeof evaluatorRunSchema>;
|
|
170
174
|
/** Schema version this package stamps on records it constructs. */
|
|
171
|
-
export declare const REGRESSION_SCHEMA_VERSION = "1.
|
|
175
|
+
export declare const REGRESSION_SCHEMA_VERSION = "1.15";
|
|
176
|
+
/** How a record's declared schema version relates to the one this runtime implements. */
|
|
177
|
+
export type SchemaVersionRelation = "older" | "same" | "newer";
|
|
178
|
+
/**
|
|
179
|
+
* Compare a record's declared schema version against {@link REGRESSION_SCHEMA_VERSION}.
|
|
180
|
+
*
|
|
181
|
+
* Exported because the two directions are not the same kind of question. **Newer** is soundness
|
|
182
|
+
* and belongs here: this runtime cannot know what a later version's fields mean, so it refuses.
|
|
183
|
+
* **Older** is policy and belongs to the caller — whether a run from an earlier version is
|
|
184
|
+
* comparable to today's depends on what changed between them, which this package cannot know
|
|
185
|
+
* either. What it can do is stop every caller reimplementing the comparison, which is the part
|
|
186
|
+
* that would drift.
|
|
187
|
+
*
|
|
188
|
+
* A record must be readable in order to be upgraded, so this is deliberately a question a caller
|
|
189
|
+
* can ask *before* parsing, and an older record still parses.
|
|
190
|
+
*
|
|
191
|
+
* @param recordVersion - The `schemaVersion` field of a record, `MAJOR.MINOR` (ADR-0003).
|
|
192
|
+
* @throws {AldusError} `ALDUS_CORPUS_MALFORMED` if `recordVersion` is not `MAJOR.MINOR`.
|
|
193
|
+
*/
|
|
194
|
+
export declare function compareSchemaVersion(recordVersion: string): SchemaVersionRelation;
|
|
172
195
|
/**
|
|
173
196
|
* Validate a corpus and check the uniqueness constraint Zod cannot express.
|
|
174
197
|
*
|
package/dist/corpus.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"corpus.d.ts","sourceRoot":"","sources":["../src/corpus.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAGH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAOxB;;;;;;GAMG;AACH,eAAO,MAAM,eAAe,aAA6B,CAAC;AAE1D;;;;;;GAMG;AACH,eAAO,MAAM,aAAa,aAA6B,CAAC;AAExD;;;;;;GAMG;AACH,eAAO,MAAM,eAAe,uCAAmE,CAAC;AAEhG,2BAA2B;AAC3B,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AAE9D,wDAAwD;AACxD,eAAO,MAAM,kBAAkB;;;;iBASuB,CAAC;AAEvD,8BAA8B;AAC9B,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAE9D;;;;;;;GAOG;AACH,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;iBA2DzB,CAAC;AAEL,4BAA4B;AAC5B,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAE1D,gDAAgD;AAChD,eAAO,MAAM,kBAAkB
|
|
1
|
+
{"version":3,"file":"corpus.d.ts","sourceRoot":"","sources":["../src/corpus.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAGH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAOxB;;;;;;GAMG;AACH,eAAO,MAAM,eAAe,aAA6B,CAAC;AAE1D;;;;;;GAMG;AACH,eAAO,MAAM,aAAa,aAA6B,CAAC;AAExD;;;;;;GAMG;AACH,eAAO,MAAM,eAAe,uCAAmE,CAAC;AAEhG,2BAA2B;AAC3B,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AAE9D,wDAAwD;AACxD,eAAO,MAAM,kBAAkB;;;;iBASuB,CAAC;AAEvD,8BAA8B;AAC9B,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAE9D;;;;;;;GAOG;AACH,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;iBA2DzB,CAAC;AAEL,4BAA4B;AAC5B,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAE1D,gDAAgD;AAChD,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBA0C3B,CAAC;AAEL,8BAA8B;AAC9B,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAE9D,yCAAyC;AACzC,eAAO,MAAM,sBAAsB;;;;iBAS2B,CAAC;AAE/D,kCAAkC;AAClC,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAEtE,6CAA6C;AAC7C,eAAO,MAAM,sBAAsB;;;;;;;;;iBA4B2B,CAAC;AAE/D,kCAAkC;AAClC,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAEtE;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;kBAyB3B,CAAC;AAEL,8BAA8B;AAC9B,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAE9D,mEAAmE;AACnE,eAAO,MAAM,yBAAyB,SAAiB,CAAC;AAExD,yFAAyF;AACzF,MAAM,MAAM,qBAAqB,GAAG,OAAO,GAAG,MAAM,GAAG,OAAO,CAAC;AAE/D;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,oBAAoB,CAAC,aAAa,EAAE,MAAM,GAAG,qBAAqB,CAqBjF;AAwBD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,YAAY,CAkC9D;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,YAAY,CAgC9D"}
|
package/dist/corpus.js
CHANGED
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
*
|
|
19
19
|
* Zod is the single source of truth; TypeScript types are inferred (ADR-0002).
|
|
20
20
|
*/
|
|
21
|
-
import { actorRefSchema, SCHEMA_VERSION } from "@aldus-runtime/core";
|
|
21
|
+
import { actorRefSchema, schemaVersionString, SCHEMA_VERSION } from "@aldus-runtime/core";
|
|
22
22
|
import { z } from "zod";
|
|
23
23
|
import { RegressionErrorCodes, regressionError } from "./errors.js";
|
|
24
24
|
/** A short opaque identifier. */
|
|
@@ -128,14 +128,38 @@ export const defectCaseSchema = z
|
|
|
128
128
|
export const defectCorpusSchema = z
|
|
129
129
|
.object({
|
|
130
130
|
/** Schema version of this record (ADR-0003). */
|
|
131
|
-
schemaVersion:
|
|
131
|
+
schemaVersion: schemaVersionString,
|
|
132
132
|
/** Identity of this corpus. */
|
|
133
133
|
corpusId: identifier,
|
|
134
134
|
/** Human-readable purpose. */
|
|
135
135
|
description: z.string().max(2000).optional(),
|
|
136
136
|
/** The labelled cases. */
|
|
137
137
|
cases: z.array(defectCaseSchema).max(100_000),
|
|
138
|
+
/**
|
|
139
|
+
* Adopter-owned data carried with this record.
|
|
140
|
+
*
|
|
141
|
+
* A declared extension point, because strictness without one is a rule with no exit. Refusing
|
|
142
|
+
* an undeclared key is right — a record from a later runtime whose added fields vanish hands
|
|
143
|
+
* the caller an object that looks complete and is not. But that argument is about *the
|
|
144
|
+
* runtime's* future fields, and it was applied to an adopter's own data, which is a different
|
|
145
|
+
* category and had a real pattern behind it: the provenance of a label belongs beside the
|
|
146
|
+
* label, in the same file, versioned together, because a label whose source lives in another
|
|
147
|
+
* file is one refactor away from a label with no source.
|
|
148
|
+
*
|
|
149
|
+
* So the two cases are separated rather than collapsed. An unknown key is refused; a declared
|
|
150
|
+
* one is **preserved through the parse**, which the previous sibling-key arrangement could not
|
|
151
|
+
* do — it survived only because readers went around the parser to the raw JSON.
|
|
152
|
+
*
|
|
153
|
+
* Core never interprets this. Same shape as `WorkflowEvent.details` and
|
|
154
|
+
* `SpendReservationTransition.detail` (§4.2: adopter-shaped concepts are opaque here).
|
|
155
|
+
*/
|
|
156
|
+
metadata: z.record(z.string(), z.unknown()).optional(),
|
|
138
157
|
})
|
|
158
|
+
// Strict: an unknown key is refused, not stripped. Without this a record from a later runtime
|
|
159
|
+
// parses and its added fields vanish, handing the caller an object that looks complete and is
|
|
160
|
+
// not. See SCHEMA_VERSION_UNSUPPORTED — the version check and this are the same guarantee, one
|
|
161
|
+
// for a declared newer version and one for an undeclared newer shape.
|
|
162
|
+
.strict()
|
|
139
163
|
.meta({
|
|
140
164
|
id: "DefectCorpus",
|
|
141
165
|
title: "DefectCorpus",
|
|
@@ -161,8 +185,27 @@ export const evaluatorOutcomeSchema = z
|
|
|
161
185
|
caseId: identifier,
|
|
162
186
|
/** Whether the evaluator flagged the subject. */
|
|
163
187
|
flagged: z.boolean(),
|
|
164
|
-
/**
|
|
188
|
+
/**
|
|
189
|
+
* The defect occurrences it enumerated. Empty when not flagged, **and also empty when the
|
|
190
|
+
* evaluator flagged without enumerating** (#140).
|
|
191
|
+
*
|
|
192
|
+
* An empty list under `flagged: true` is therefore not a contradiction and must not be
|
|
193
|
+
* repaired by inventing an entry. A wrapped legacy evaluator reports that it had something to
|
|
194
|
+
* say and not how much; fabricating one finding would make its report count as one defect,
|
|
195
|
+
* which is the statistic this distinction exists to protect.
|
|
196
|
+
*/
|
|
165
197
|
findings: z.array(evaluatorFindingSchema).max(256),
|
|
198
|
+
/**
|
|
199
|
+
* Whether site-level metrics are computable for this case (#140).
|
|
200
|
+
*
|
|
201
|
+
* `false` when the evaluator flagged without enumerating, or when a report could not be mapped
|
|
202
|
+
* to this case's subject scope at all. Site-level precision and recall are then **unmeasurable
|
|
203
|
+
* rather than zero**, and a metric that silently treated an unenumerated flag as zero findings
|
|
204
|
+
* would report perfect precision for an evaluator nobody measured.
|
|
205
|
+
*
|
|
206
|
+
* Absent means measurable, which is what every record written before this field meant.
|
|
207
|
+
*/
|
|
208
|
+
siteMetricsMeasurable: z.boolean().optional(),
|
|
166
209
|
})
|
|
167
210
|
.meta({ id: "EvaluatorOutcome", title: "EvaluatorOutcome" });
|
|
168
211
|
/**
|
|
@@ -174,7 +217,7 @@ export const evaluatorOutcomeSchema = z
|
|
|
174
217
|
export const evaluatorRunSchema = z
|
|
175
218
|
.object({
|
|
176
219
|
/** Schema version of this record (ADR-0003). */
|
|
177
|
-
schemaVersion:
|
|
220
|
+
schemaVersion: schemaVersionString,
|
|
178
221
|
/** Which evaluator produced these outcomes. */
|
|
179
222
|
evaluatorId: identifier,
|
|
180
223
|
/** Version of the evaluator. Metrics from different versions are not comparable. */
|
|
@@ -185,7 +228,10 @@ export const evaluatorRunSchema = z
|
|
|
185
228
|
outcomes: z.array(evaluatorOutcomeSchema).max(100_000),
|
|
186
229
|
/** When the run was executed. */
|
|
187
230
|
executedAt: z.iso.datetime({ offset: true }),
|
|
231
|
+
/** @see defectCorpusSchema.metadata */
|
|
232
|
+
metadata: z.record(z.string(), z.unknown()).optional(),
|
|
188
233
|
})
|
|
234
|
+
.strict()
|
|
189
235
|
.meta({
|
|
190
236
|
id: "EvaluatorRun",
|
|
191
237
|
title: "EvaluatorRun",
|
|
@@ -195,6 +241,60 @@ export const evaluatorRunSchema = z
|
|
|
195
241
|
});
|
|
196
242
|
/** Schema version this package stamps on records it constructs. */
|
|
197
243
|
export const REGRESSION_SCHEMA_VERSION = SCHEMA_VERSION;
|
|
244
|
+
/**
|
|
245
|
+
* Compare a record's declared schema version against {@link REGRESSION_SCHEMA_VERSION}.
|
|
246
|
+
*
|
|
247
|
+
* Exported because the two directions are not the same kind of question. **Newer** is soundness
|
|
248
|
+
* and belongs here: this runtime cannot know what a later version's fields mean, so it refuses.
|
|
249
|
+
* **Older** is policy and belongs to the caller — whether a run from an earlier version is
|
|
250
|
+
* comparable to today's depends on what changed between them, which this package cannot know
|
|
251
|
+
* either. What it can do is stop every caller reimplementing the comparison, which is the part
|
|
252
|
+
* that would drift.
|
|
253
|
+
*
|
|
254
|
+
* A record must be readable in order to be upgraded, so this is deliberately a question a caller
|
|
255
|
+
* can ask *before* parsing, and an older record still parses.
|
|
256
|
+
*
|
|
257
|
+
* @param recordVersion - The `schemaVersion` field of a record, `MAJOR.MINOR` (ADR-0003).
|
|
258
|
+
* @throws {AldusError} `ALDUS_CORPUS_MALFORMED` if `recordVersion` is not `MAJOR.MINOR`.
|
|
259
|
+
*/
|
|
260
|
+
export function compareSchemaVersion(recordVersion) {
|
|
261
|
+
const parse = (value) => {
|
|
262
|
+
const match = /^(0|[1-9]\d*)\.(0|[1-9]\d*)$/.exec(value);
|
|
263
|
+
if (match === null) {
|
|
264
|
+
// Path and code only — never the received value (contract §19.2).
|
|
265
|
+
throw regressionError(RegressionErrorCodes.CORPUS_MALFORMED, "A schema version must be MAJOR.MINOR.", {
|
|
266
|
+
category: "validation",
|
|
267
|
+
details: { issues: [{ path: "schemaVersion", code: "invalid_format" }] },
|
|
268
|
+
});
|
|
269
|
+
}
|
|
270
|
+
return [Number(match[1]), Number(match[2])];
|
|
271
|
+
};
|
|
272
|
+
const [recordMajor, recordMinor] = parse(recordVersion);
|
|
273
|
+
const [runtimeMajor, runtimeMinor] = parse(REGRESSION_SCHEMA_VERSION);
|
|
274
|
+
if (recordMajor !== runtimeMajor)
|
|
275
|
+
return recordMajor > runtimeMajor ? "newer" : "older";
|
|
276
|
+
if (recordMinor !== runtimeMinor)
|
|
277
|
+
return recordMinor > runtimeMinor ? "newer" : "older";
|
|
278
|
+
return "same";
|
|
279
|
+
}
|
|
280
|
+
/**
|
|
281
|
+
* Refuse a record declaring a version this runtime does not implement.
|
|
282
|
+
*
|
|
283
|
+
* Only `newer` is refused. An older record parses, and {@link compareSchemaVersion} is how a
|
|
284
|
+
* caller decides whether to trust it.
|
|
285
|
+
*/
|
|
286
|
+
function assertSchemaVersionSupported(recordVersion, record) {
|
|
287
|
+
if (compareSchemaVersion(recordVersion) !== "newer")
|
|
288
|
+
return;
|
|
289
|
+
throw regressionError(RegressionErrorCodes.SCHEMA_VERSION_UNSUPPORTED, `A ${record} declares a schema version newer than this runtime implements. Its fields cannot ` +
|
|
290
|
+
"be interpreted here, and the schema discards what it does not declare, so accepting it " +
|
|
291
|
+
"would return a record that looks complete and is not.", {
|
|
292
|
+
category: "validation",
|
|
293
|
+
// The runtime's own version is this package's constant, not received input, so naming it is
|
|
294
|
+
// not a value leak. The record's version is not named (contract §19.2).
|
|
295
|
+
details: { runtimeSchemaVersion: REGRESSION_SCHEMA_VERSION, relation: "newer" },
|
|
296
|
+
});
|
|
297
|
+
}
|
|
198
298
|
/**
|
|
199
299
|
* Validate a corpus and check the uniqueness constraint Zod cannot express.
|
|
200
300
|
*
|
|
@@ -214,6 +314,7 @@ export function parseDefectCorpus(input) {
|
|
|
214
314
|
},
|
|
215
315
|
});
|
|
216
316
|
}
|
|
317
|
+
assertSchemaVersionSupported(result.data.schemaVersion, "corpus");
|
|
217
318
|
const seen = new Set();
|
|
218
319
|
for (const entry of result.data.cases) {
|
|
219
320
|
if (seen.has(entry.caseId)) {
|
|
@@ -242,6 +343,7 @@ export function parseEvaluatorRun(input) {
|
|
|
242
343
|
},
|
|
243
344
|
});
|
|
244
345
|
}
|
|
346
|
+
assertSchemaVersionSupported(result.data.schemaVersion, "run");
|
|
245
347
|
const seen = new Set();
|
|
246
348
|
for (const outcome of result.data.outcomes) {
|
|
247
349
|
if (seen.has(outcome.caseId)) {
|
package/dist/corpus.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"corpus.js","sourceRoot":"","sources":["../src/corpus.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"corpus.js","sourceRoot":"","sources":["../src/corpus.ts"],"names":[],"mappings":"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"}
|
package/dist/errors.d.ts
CHANGED
|
@@ -32,6 +32,16 @@ export declare const RegressionErrorCodes: {
|
|
|
32
32
|
readonly BLIND_SPOT_DUPLICATE: "ALDUS_BLIND_SPOT_DUPLICATE";
|
|
33
33
|
/** A promotion policy is internally inconsistent — a threshold outside its valid range. */
|
|
34
34
|
readonly POLICY_INVALID: "ALDUS_POLICY_INVALID";
|
|
35
|
+
/**
|
|
36
|
+
* A record declares a schema version newer than this runtime implements.
|
|
37
|
+
*
|
|
38
|
+
* Refused rather than accepted, because this runtime cannot know what a later version's fields
|
|
39
|
+
* mean and the schemas discard what they do not declare. Accepting one returns an object that
|
|
40
|
+
* looks complete and is not — a read path answering wrongly with no signal, which is worse than
|
|
41
|
+
* refusing. Whether an *older* record is comparable is the caller's policy, not this package's:
|
|
42
|
+
* see `compareSchemaVersion`.
|
|
43
|
+
*/
|
|
44
|
+
readonly SCHEMA_VERSION_UNSUPPORTED: "ALDUS_SCHEMA_VERSION_UNSUPPORTED";
|
|
35
45
|
};
|
|
36
46
|
/** @see RegressionErrorCodes */
|
|
37
47
|
export type RegressionErrorCode = (typeof RegressionErrorCodes)[keyof typeof RegressionErrorCodes];
|
package/dist/errors.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,UAAU,EAAE,KAAK,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAErE,oDAAoD;AACpD,eAAO,MAAM,oBAAoB;IAC/B,+DAA+D;aAC/D,gBAAgB,EAAE,wBAAwB;IAC1C,gDAAgD;aAChD,qBAAqB,EAAE,6BAA6B;IACpD,8EAA8E;aAC9E,oBAAoB,EAAE,4BAA4B;IAClD,6DAA6D;aAC7D,iBAAiB,EAAE,yBAAyB;IAC5C;;;;;;OAMG;aACH,mBAAmB,EAAE,2BAA2B;IAChD,mFAAmF;aACnF,2BAA2B,EAAE,mCAAmC;IAChE,6CAA6C;aAC7C,oBAAoB,EAAE,4BAA4B;IAClD,6CAA6C;aAC7C,oBAAoB,EAAE,4BAA4B;IAClD,2FAA2F;aAC3F,cAAc,EAAE,sBAAsB;
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,UAAU,EAAE,KAAK,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAErE,oDAAoD;AACpD,eAAO,MAAM,oBAAoB;IAC/B,+DAA+D;aAC/D,gBAAgB,EAAE,wBAAwB;IAC1C,gDAAgD;aAChD,qBAAqB,EAAE,6BAA6B;IACpD,8EAA8E;aAC9E,oBAAoB,EAAE,4BAA4B;IAClD,6DAA6D;aAC7D,iBAAiB,EAAE,yBAAyB;IAC5C;;;;;;OAMG;aACH,mBAAmB,EAAE,2BAA2B;IAChD,mFAAmF;aACnF,2BAA2B,EAAE,mCAAmC;IAChE,6CAA6C;aAC7C,oBAAoB,EAAE,4BAA4B;IAClD,6CAA6C;aAC7C,oBAAoB,EAAE,4BAA4B;IAClD,2FAA2F;aAC3F,cAAc,EAAE,sBAAsB;IACtC;;;;;;;;OAQG;aACH,0BAA0B,EAAE,kCAAkC;CACtD,CAAC;AAEX,gCAAgC;AAChC,MAAM,MAAM,mBAAmB,GAAG,CAAC,OAAO,oBAAoB,CAAC,CAAC,MAAM,OAAO,oBAAoB,CAAC,CAAC;AAEnG,sEAAsE;AACtE,wBAAgB,eAAe,CAC7B,IAAI,EAAE,mBAAmB,EACzB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE;IAAE,QAAQ,EAAE,aAAa,CAAC;IAAC,SAAS,CAAC,EAAE,OAAO,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,GAC3F,UAAU,CAEZ"}
|
package/dist/errors.js
CHANGED
|
@@ -32,6 +32,16 @@ export const RegressionErrorCodes = {
|
|
|
32
32
|
BLIND_SPOT_DUPLICATE: "ALDUS_BLIND_SPOT_DUPLICATE",
|
|
33
33
|
/** A promotion policy is internally inconsistent — a threshold outside its valid range. */
|
|
34
34
|
POLICY_INVALID: "ALDUS_POLICY_INVALID",
|
|
35
|
+
/**
|
|
36
|
+
* A record declares a schema version newer than this runtime implements.
|
|
37
|
+
*
|
|
38
|
+
* Refused rather than accepted, because this runtime cannot know what a later version's fields
|
|
39
|
+
* mean and the schemas discard what they do not declare. Accepting one returns an object that
|
|
40
|
+
* looks complete and is not — a read path answering wrongly with no signal, which is worse than
|
|
41
|
+
* refusing. Whether an *older* record is comparable is the caller's policy, not this package's:
|
|
42
|
+
* see `compareSchemaVersion`.
|
|
43
|
+
*/
|
|
44
|
+
SCHEMA_VERSION_UNSUPPORTED: "ALDUS_SCHEMA_VERSION_UNSUPPORTED",
|
|
35
45
|
};
|
|
36
46
|
/** Construct an {@link AldusError} with a regression-harness code. */
|
|
37
47
|
export function regressionError(code, message, options) {
|
package/dist/errors.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,UAAU,EAAsB,MAAM,qBAAqB,CAAC;AAErE,oDAAoD;AACpD,MAAM,CAAC,MAAM,oBAAoB,GAAG;IAClC,+DAA+D;IAC/D,gBAAgB,EAAE,wBAAwB;IAC1C,gDAAgD;IAChD,qBAAqB,EAAE,6BAA6B;IACpD,8EAA8E;IAC9E,oBAAoB,EAAE,4BAA4B;IAClD,6DAA6D;IAC7D,iBAAiB,EAAE,yBAAyB;IAC5C;;;;;;OAMG;IACH,mBAAmB,EAAE,2BAA2B;IAChD,mFAAmF;IACnF,2BAA2B,EAAE,mCAAmC;IAChE,6CAA6C;IAC7C,oBAAoB,EAAE,4BAA4B;IAClD,6CAA6C;IAC7C,oBAAoB,EAAE,4BAA4B;IAClD,2FAA2F;IAC3F,cAAc,EAAE,sBAAsB;
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,UAAU,EAAsB,MAAM,qBAAqB,CAAC;AAErE,oDAAoD;AACpD,MAAM,CAAC,MAAM,oBAAoB,GAAG;IAClC,+DAA+D;IAC/D,gBAAgB,EAAE,wBAAwB;IAC1C,gDAAgD;IAChD,qBAAqB,EAAE,6BAA6B;IACpD,8EAA8E;IAC9E,oBAAoB,EAAE,4BAA4B;IAClD,6DAA6D;IAC7D,iBAAiB,EAAE,yBAAyB;IAC5C;;;;;;OAMG;IACH,mBAAmB,EAAE,2BAA2B;IAChD,mFAAmF;IACnF,2BAA2B,EAAE,mCAAmC;IAChE,6CAA6C;IAC7C,oBAAoB,EAAE,4BAA4B;IAClD,6CAA6C;IAC7C,oBAAoB,EAAE,4BAA4B;IAClD,2FAA2F;IAC3F,cAAc,EAAE,sBAAsB;IACtC;;;;;;;;OAQG;IACH,0BAA0B,EAAE,kCAAkC;CACtD,CAAC;AAKX,sEAAsE;AACtE,MAAM,UAAU,eAAe,CAC7B,IAAyB,EACzB,OAAe,EACf,OAA4F;IAE5F,OAAO,IAAI,UAAU,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;AAChD,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
*
|
|
18
18
|
* @packageDocumentation
|
|
19
19
|
*/
|
|
20
|
-
export { REGRESSION_SCHEMA_VERSION, defectCaseSchema, defectCorpusSchema, evaluatorFindingSchema, evaluatorOutcomeSchema, evaluatorRunSchema, findingCategory, humanFindingSchema, parseDefectCorpus, parseEvaluatorRun, scopeDimensions, severityLevel, type DefectCase, type DefectCorpus, type EvaluatorFinding, type EvaluatorOutcome, type EvaluatorRun, type HumanFinding, type ScopeDimensions, } from "./corpus.js";
|
|
20
|
+
export { REGRESSION_SCHEMA_VERSION, defectCaseSchema, compareSchemaVersion, defectCorpusSchema, evaluatorFindingSchema, evaluatorOutcomeSchema, evaluatorRunSchema, findingCategory, humanFindingSchema, parseDefectCorpus, parseEvaluatorRun, scopeDimensions, severityLevel, type DefectCase, type DefectCorpus, type EvaluatorFinding, type EvaluatorOutcome, type EvaluatorRun, type HumanFinding, type ScopeDimensions, type SchemaVersionRelation, } from "./corpus.js";
|
|
21
21
|
export { WHOLE_CORPUS_SLICE, deriveScopeSelectors, observedDimensions, scopeKey, scopeLabel, scopeMatches, type ScopeSelector, } from "./scope.js";
|
|
22
22
|
export { DEFAULT_CORRECTION_HARM_WEIGHTS, DEFAULT_PROMOTION_THRESHOLDS, assertPolicyValid, correctionHarm, defaultPromotionPolicy, severityWeight, type CorrectionHarmWeights, type PolicyOrigin, type PromotionPolicy, type PromotionThresholds, type SeverityWeights, } from "./policy.js";
|
|
23
23
|
export { compareRun, type CaseComparison, type CaseVerdict, type CompareOptions, type ComparisonReport, type SliceMetrics, } from "./metrics.js";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAGH,OAAO,EACL,yBAAyB,EACzB,gBAAgB,EAChB,kBAAkB,EAClB,sBAAsB,EACtB,sBAAsB,EACtB,kBAAkB,EAClB,eAAe,EACf,kBAAkB,EAClB,iBAAiB,EACjB,iBAAiB,EACjB,eAAe,EACf,aAAa,EACb,KAAK,UAAU,EACf,KAAK,YAAY,EACjB,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EACrB,KAAK,YAAY,EACjB,KAAK,YAAY,EACjB,KAAK,eAAe,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAGH,OAAO,EACL,yBAAyB,EACzB,gBAAgB,EAChB,oBAAoB,EACpB,kBAAkB,EAClB,sBAAsB,EACtB,sBAAsB,EACtB,kBAAkB,EAClB,eAAe,EACf,kBAAkB,EAClB,iBAAiB,EACjB,iBAAiB,EACjB,eAAe,EACf,aAAa,EACb,KAAK,UAAU,EACf,KAAK,YAAY,EACjB,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EACrB,KAAK,YAAY,EACjB,KAAK,YAAY,EACjB,KAAK,eAAe,EACpB,KAAK,qBAAqB,GAC3B,MAAM,aAAa,CAAC;AAGrB,OAAO,EACL,kBAAkB,EAClB,oBAAoB,EACpB,kBAAkB,EAClB,QAAQ,EACR,UAAU,EACV,YAAY,EACZ,KAAK,aAAa,GACnB,MAAM,YAAY,CAAC;AAGpB,OAAO,EACL,+BAA+B,EAC/B,4BAA4B,EAC5B,iBAAiB,EACjB,cAAc,EACd,sBAAsB,EACtB,cAAc,EACd,KAAK,qBAAqB,EAC1B,KAAK,YAAY,EACjB,KAAK,eAAe,EACpB,KAAK,mBAAmB,EACxB,KAAK,eAAe,GACrB,MAAM,aAAa,CAAC;AAGrB,OAAO,EACL,UAAU,EACV,KAAK,cAAc,EACnB,KAAK,WAAW,EAChB,KAAK,cAAc,EACnB,KAAK,gBAAgB,EACrB,KAAK,YAAY,GAClB,MAAM,cAAc,CAAC;AAGtB,OAAO,EACL,mBAAmB,EACnB,iBAAiB,EACjB,mBAAmB,EACnB,eAAe,EACf,KAAK,SAAS,EACd,KAAK,eAAe,GACrB,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EACL,eAAe,EACf,8BAA8B,EAC9B,KAAK,kBAAkB,EACvB,KAAK,sBAAsB,EAC3B,KAAK,gBAAgB,EACrB,KAAK,YAAY,GAClB,MAAM,gBAAgB,CAAC;AAGxB,OAAO,EAAE,aAAa,EAAE,mBAAmB,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAGxF,OAAO,EAAE,oBAAoB,EAAE,eAAe,EAAE,KAAK,mBAAmB,EAAE,MAAM,aAAa,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
* @packageDocumentation
|
|
19
19
|
*/
|
|
20
20
|
// --- Defect corpus (§12.1, §12.3, §24) --------------------------------------------------------
|
|
21
|
-
export { REGRESSION_SCHEMA_VERSION, defectCaseSchema, defectCorpusSchema, evaluatorFindingSchema, evaluatorOutcomeSchema, evaluatorRunSchema, findingCategory, humanFindingSchema, parseDefectCorpus, parseEvaluatorRun, scopeDimensions, severityLevel, } from "./corpus.js";
|
|
21
|
+
export { REGRESSION_SCHEMA_VERSION, defectCaseSchema, compareSchemaVersion, defectCorpusSchema, evaluatorFindingSchema, evaluatorOutcomeSchema, evaluatorRunSchema, findingCategory, humanFindingSchema, parseDefectCorpus, parseEvaluatorRun, scopeDimensions, severityLevel, } from "./corpus.js";
|
|
22
22
|
// --- Scope slicing (§12.1) --------------------------------------------------------------------
|
|
23
23
|
export { WHOLE_CORPUS_SLICE, deriveScopeSelectors, observedDimensions, scopeKey, scopeLabel, scopeMatches, } from "./scope.js";
|
|
24
24
|
// --- Promotion policy (§12.1, §25.9; ADR-0010) ------------------------------------------------
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,iGAAiG;AACjG,OAAO,EACL,yBAAyB,EACzB,gBAAgB,EAChB,kBAAkB,EAClB,sBAAsB,EACtB,sBAAsB,EACtB,kBAAkB,EAClB,eAAe,EACf,kBAAkB,EAClB,iBAAiB,EACjB,iBAAiB,EACjB,eAAe,EACf,aAAa,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,iGAAiG;AACjG,OAAO,EACL,yBAAyB,EACzB,gBAAgB,EAChB,oBAAoB,EACpB,kBAAkB,EAClB,sBAAsB,EACtB,sBAAsB,EACtB,kBAAkB,EAClB,eAAe,EACf,kBAAkB,EAClB,iBAAiB,EACjB,iBAAiB,EACjB,eAAe,EACf,aAAa,GASd,MAAM,aAAa,CAAC;AAErB,iGAAiG;AACjG,OAAO,EACL,kBAAkB,EAClB,oBAAoB,EACpB,kBAAkB,EAClB,QAAQ,EACR,UAAU,EACV,YAAY,GAEb,MAAM,YAAY,CAAC;AAEpB,iGAAiG;AACjG,OAAO,EACL,+BAA+B,EAC/B,4BAA4B,EAC5B,iBAAiB,EACjB,cAAc,EACd,sBAAsB,EACtB,cAAc,GAMf,MAAM,aAAa,CAAC;AAErB,iGAAiG;AACjG,OAAO,EACL,UAAU,GAMX,MAAM,cAAc,CAAC;AAEtB,iGAAiG;AACjG,OAAO,EACL,mBAAmB,EACnB,iBAAiB,EACjB,mBAAmB,EACnB,eAAe,GAGhB,MAAM,iBAAiB,CAAC;AAEzB,iGAAiG;AACjG,OAAO,EACL,eAAe,EACf,8BAA8B,GAK/B,MAAM,gBAAgB,CAAC;AAExB,iGAAiG;AACjG,OAAO,EAAE,aAAa,EAAE,mBAAmB,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAExF,iGAAiG;AACjG,OAAO,EAAE,oBAAoB,EAAE,eAAe,EAA4B,MAAM,aAAa,CAAC"}
|
package/dist/metrics.d.ts
CHANGED
|
@@ -44,6 +44,19 @@ export interface CaseComparison {
|
|
|
44
44
|
* negative — it did catch the case — but a promotion reader should see it.
|
|
45
45
|
*/
|
|
46
46
|
categoryMismatch: boolean;
|
|
47
|
+
/**
|
|
48
|
+
* Whether site-level comparison means anything for this case (#140).
|
|
49
|
+
*
|
|
50
|
+
* `false` when the evaluator flagged without enumerating what it found — a wrapped legacy
|
|
51
|
+
* evaluator reporting that it had something to say, and nothing about how much or where.
|
|
52
|
+
*
|
|
53
|
+
* The case-level verdict is still sound: a flag is a flag, and §12's precision and recall over
|
|
54
|
+
* *cases* are computable. What is not computable is anything per site, and the previous code
|
|
55
|
+
* quietly answered it anyway — with no evaluator categories to compare, `categoryMismatch` came
|
|
56
|
+
* out `false`, which reads as *the categories agreed*. An evaluator nobody measured would have
|
|
57
|
+
* scored a clean sheet.
|
|
58
|
+
*/
|
|
59
|
+
siteMetricsMeasurable: boolean;
|
|
47
60
|
/** Harm a spurious flag would cause here; zero unless this is a false positive. */
|
|
48
61
|
unnecessaryCorrectionHarm: number;
|
|
49
62
|
}
|
|
@@ -68,6 +81,14 @@ export interface SliceMetrics {
|
|
|
68
81
|
trueNegatives: number;
|
|
69
82
|
/** True positives found under the wrong category (contract §12.3). */
|
|
70
83
|
categoryMismatches: number;
|
|
84
|
+
/**
|
|
85
|
+
* Cases whose site-level metrics are unmeasurable (#140).
|
|
86
|
+
*
|
|
87
|
+
* Reported rather than folded in, because a slice where this is large is a slice whose
|
|
88
|
+
* category agreement means much less than the other numbers suggest. Zero is the honest value
|
|
89
|
+
* only when it is true.
|
|
90
|
+
*/
|
|
91
|
+
unmeasurableSiteMetrics: number;
|
|
71
92
|
/** `truePositives / defectiveCases`; `undefined` when there are no defective cases. */
|
|
72
93
|
recall: number | undefined;
|
|
73
94
|
/** `falsePositives / cleanCases`; `undefined` when there are no clean cases. */
|
package/dist/metrics.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"metrics.d.ts","sourceRoot":"","sources":["../src/metrics.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAc,YAAY,EAAoB,YAAY,EAAE,MAAM,aAAa,CAAC;AAE5F,OAAO,EAAkC,KAAK,eAAe,EAAE,MAAM,aAAa,CAAC;AACnF,OAAO,EAKL,KAAK,aAAa,EACnB,MAAM,YAAY,CAAC;AAEpB,wDAAwD;AACxD,MAAM,MAAM,WAAW;AACrB,kDAAkD;AAChD,cAAc;AAChB,+DAA+D;GAC7D,eAAe;AACjB,+DAA+D;GAC7D,eAAe;AACjB,mDAAmD;GACjD,cAAc,CAAC;AAEnB,6DAA6D;AAC7D,MAAM,WAAW,cAAc;IAC7B,gBAAgB;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,yBAAyB;IACzB,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACxC,uBAAuB;IACvB,OAAO,EAAE,WAAW,CAAC;IACrB,gEAAgE;IAChE,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7B,wCAAwC;IACxC,cAAc,EAAE,MAAM,CAAC;IACvB;;;;;;OAMG;IACH,gBAAgB,EAAE,OAAO,CAAC;IAC1B,mFAAmF;IACnF,yBAAyB,EAAE,MAAM,CAAC;CACnC;AAED,4CAA4C;AAC5C,MAAM,WAAW,YAAY;IAC3B,mBAAmB;IACnB,QAAQ,EAAE,aAAa,CAAC;IACxB,gCAAgC;IAChC,GAAG,EAAE,MAAM,CAAC;IACZ,gCAAgC;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,wCAAwC;IACxC,cAAc,EAAE,MAAM,CAAC;IACvB,oCAAoC;IACpC,UAAU,EAAE,MAAM,CAAC;IACnB,4CAA4C;IAC5C,SAAS,EAAE,MAAM,CAAC;IAClB,wBAAwB;IACxB,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;IACtB,sEAAsE;IACtE,kBAAkB,EAAE,MAAM,CAAC;IAC3B,uFAAuF;IACvF,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,gFAAgF;IAChF,iBAAiB,EAAE,MAAM,GAAG,SAAS,CAAC;IACtC,6FAA6F;IAC7F,sBAAsB,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3C,gEAAgE;IAChE,8BAA8B,EAAE,MAAM,CAAC;IACvC,8DAA8D;IAC9D,yBAAyB,EAAE,MAAM,CAAC;IAClC,2EAA2E;IAC3E,6BAA6B,EAAE,MAAM,GAAG,SAAS,CAAC;IAClD;;;;;OAKG;IACH,wBAAwB,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7C,gEAAgE;IAChE,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;CAC5B;AAED,qFAAqF;AACrF,MAAM,WAAW,gBAAgB;IAC/B,0BAA0B;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,4EAA4E;IAC5E,gBAAgB,EAAE,MAAM,CAAC;IACzB,+BAA+B;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB;;;;;;OAMG;IACH,WAAW,EAAE,YAAY,CAAC;IAC1B,2EAA2E;IAC3E,MAAM,EAAE,SAAS,YAAY,EAAE,CAAC;IAChC,+DAA+D;IAC/D,WAAW,EAAE,SAAS,cAAc,EAAE,CAAC;IACvC,+DAA+D;IAC/D,kBAAkB,EAAE,SAAS,MAAM,EAAE,CAAC;CACvC;
|
|
1
|
+
{"version":3,"file":"metrics.d.ts","sourceRoot":"","sources":["../src/metrics.ts"],"names":[],"mappings":"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"}
|
package/dist/metrics.js
CHANGED
|
@@ -39,6 +39,10 @@ function compareCase(entry, outcome, policy) {
|
|
|
39
39
|
severity: entry.severity,
|
|
40
40
|
severityWeight: weight,
|
|
41
41
|
categoryMismatch,
|
|
42
|
+
// A flag with nothing enumerated. Not a contradiction to be repaired by inventing a finding —
|
|
43
|
+
// that would make one report count as one defect, which is exactly the statistic #140 exists
|
|
44
|
+
// to protect.
|
|
45
|
+
siteMetricsMeasurable: outcome?.siteMetricsMeasurable ?? !(flagged && (outcome?.findings ?? []).length === 0),
|
|
42
46
|
unnecessaryCorrectionHarm: harm,
|
|
43
47
|
};
|
|
44
48
|
}
|
|
@@ -72,6 +76,8 @@ function summarise(selector, comparisons, labellers) {
|
|
|
72
76
|
falsePositives,
|
|
73
77
|
trueNegatives,
|
|
74
78
|
categoryMismatches: comparisons.filter((comparison) => comparison.categoryMismatch).length,
|
|
79
|
+
unmeasurableSiteMetrics: comparisons.filter((comparison) => !comparison.siteMetricsMeasurable)
|
|
80
|
+
.length,
|
|
75
81
|
recall: defectiveCases === 0 ? undefined : truePositives / defectiveCases,
|
|
76
82
|
falsePositiveRate: cleanCases === 0 ? undefined : falsePositives / cleanCases,
|
|
77
83
|
severityWeightedRecall: defectiveWeight === 0 ? undefined : caughtWeight / defectiveWeight,
|
package/dist/metrics.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"metrics.js","sourceRoot":"","sources":["../src/metrics.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACpE,OAAO,EAAE,cAAc,EAAE,cAAc,EAAwB,MAAM,aAAa,CAAC;AACnF,OAAO,EACL,oBAAoB,EACpB,QAAQ,EACR,YAAY,EACZ,kBAAkB,GAEnB,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"metrics.js","sourceRoot":"","sources":["../src/metrics.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aldus-runtime/regression",
|
|
3
|
-
"version": "0.2.0-next.
|
|
3
|
+
"version": "0.2.0-next.50",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Aldus Regression Harness — defect corpora, scope-aware evaluator metrics, blind-spot registry, and evaluator promotion evidence.",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -33,11 +33,11 @@
|
|
|
33
33
|
"typecheck:test": "tsc -p tsconfig.test.json"
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
|
-
"@aldus-runtime/core": "0.2.0-next.
|
|
36
|
+
"@aldus-runtime/core": "0.2.0-next.50",
|
|
37
37
|
"zod": "^4.4.3"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
|
-
"@aldus-runtime/testkit": "0.2.0-next.
|
|
40
|
+
"@aldus-runtime/testkit": "0.2.0-next.50",
|
|
41
41
|
"@types/node": "^26.2.0",
|
|
42
42
|
"typescript": "^7.0.2",
|
|
43
43
|
"vitest": "^4.1.10"
|
package/src/corpus.ts
CHANGED
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
* Zod is the single source of truth; TypeScript types are inferred (ADR-0002).
|
|
20
20
|
*/
|
|
21
21
|
|
|
22
|
-
import { actorRefSchema, SCHEMA_VERSION } from "@aldus-runtime/core";
|
|
22
|
+
import { actorRefSchema, schemaVersionString, SCHEMA_VERSION } from "@aldus-runtime/core";
|
|
23
23
|
import { z } from "zod";
|
|
24
24
|
|
|
25
25
|
import { RegressionErrorCodes, regressionError } from "./errors.js";
|
|
@@ -148,14 +148,38 @@ export type DefectCase = z.infer<typeof defectCaseSchema>;
|
|
|
148
148
|
export const defectCorpusSchema = z
|
|
149
149
|
.object({
|
|
150
150
|
/** Schema version of this record (ADR-0003). */
|
|
151
|
-
schemaVersion:
|
|
151
|
+
schemaVersion: schemaVersionString,
|
|
152
152
|
/** Identity of this corpus. */
|
|
153
153
|
corpusId: identifier,
|
|
154
154
|
/** Human-readable purpose. */
|
|
155
155
|
description: z.string().max(2000).optional(),
|
|
156
156
|
/** The labelled cases. */
|
|
157
157
|
cases: z.array(defectCaseSchema).max(100_000),
|
|
158
|
+
/**
|
|
159
|
+
* Adopter-owned data carried with this record.
|
|
160
|
+
*
|
|
161
|
+
* A declared extension point, because strictness without one is a rule with no exit. Refusing
|
|
162
|
+
* an undeclared key is right — a record from a later runtime whose added fields vanish hands
|
|
163
|
+
* the caller an object that looks complete and is not. But that argument is about *the
|
|
164
|
+
* runtime's* future fields, and it was applied to an adopter's own data, which is a different
|
|
165
|
+
* category and had a real pattern behind it: the provenance of a label belongs beside the
|
|
166
|
+
* label, in the same file, versioned together, because a label whose source lives in another
|
|
167
|
+
* file is one refactor away from a label with no source.
|
|
168
|
+
*
|
|
169
|
+
* So the two cases are separated rather than collapsed. An unknown key is refused; a declared
|
|
170
|
+
* one is **preserved through the parse**, which the previous sibling-key arrangement could not
|
|
171
|
+
* do — it survived only because readers went around the parser to the raw JSON.
|
|
172
|
+
*
|
|
173
|
+
* Core never interprets this. Same shape as `WorkflowEvent.details` and
|
|
174
|
+
* `SpendReservationTransition.detail` (§4.2: adopter-shaped concepts are opaque here).
|
|
175
|
+
*/
|
|
176
|
+
metadata: z.record(z.string(), z.unknown()).optional(),
|
|
158
177
|
})
|
|
178
|
+
// Strict: an unknown key is refused, not stripped. Without this a record from a later runtime
|
|
179
|
+
// parses and its added fields vanish, handing the caller an object that looks complete and is
|
|
180
|
+
// not. See SCHEMA_VERSION_UNSUPPORTED — the version check and this are the same guarantee, one
|
|
181
|
+
// for a declared newer version and one for an undeclared newer shape.
|
|
182
|
+
.strict()
|
|
159
183
|
.meta({
|
|
160
184
|
id: "DefectCorpus",
|
|
161
185
|
title: "DefectCorpus",
|
|
@@ -190,8 +214,27 @@ export const evaluatorOutcomeSchema = z
|
|
|
190
214
|
caseId: identifier,
|
|
191
215
|
/** Whether the evaluator flagged the subject. */
|
|
192
216
|
flagged: z.boolean(),
|
|
193
|
-
/**
|
|
217
|
+
/**
|
|
218
|
+
* The defect occurrences it enumerated. Empty when not flagged, **and also empty when the
|
|
219
|
+
* evaluator flagged without enumerating** (#140).
|
|
220
|
+
*
|
|
221
|
+
* An empty list under `flagged: true` is therefore not a contradiction and must not be
|
|
222
|
+
* repaired by inventing an entry. A wrapped legacy evaluator reports that it had something to
|
|
223
|
+
* say and not how much; fabricating one finding would make its report count as one defect,
|
|
224
|
+
* which is the statistic this distinction exists to protect.
|
|
225
|
+
*/
|
|
194
226
|
findings: z.array(evaluatorFindingSchema).max(256),
|
|
227
|
+
/**
|
|
228
|
+
* Whether site-level metrics are computable for this case (#140).
|
|
229
|
+
*
|
|
230
|
+
* `false` when the evaluator flagged without enumerating, or when a report could not be mapped
|
|
231
|
+
* to this case's subject scope at all. Site-level precision and recall are then **unmeasurable
|
|
232
|
+
* rather than zero**, and a metric that silently treated an unenumerated flag as zero findings
|
|
233
|
+
* would report perfect precision for an evaluator nobody measured.
|
|
234
|
+
*
|
|
235
|
+
* Absent means measurable, which is what every record written before this field meant.
|
|
236
|
+
*/
|
|
237
|
+
siteMetricsMeasurable: z.boolean().optional(),
|
|
195
238
|
})
|
|
196
239
|
.meta({ id: "EvaluatorOutcome", title: "EvaluatorOutcome" });
|
|
197
240
|
|
|
@@ -207,7 +250,7 @@ export type EvaluatorOutcome = z.infer<typeof evaluatorOutcomeSchema>;
|
|
|
207
250
|
export const evaluatorRunSchema = z
|
|
208
251
|
.object({
|
|
209
252
|
/** Schema version of this record (ADR-0003). */
|
|
210
|
-
schemaVersion:
|
|
253
|
+
schemaVersion: schemaVersionString,
|
|
211
254
|
/** Which evaluator produced these outcomes. */
|
|
212
255
|
evaluatorId: identifier,
|
|
213
256
|
/** Version of the evaluator. Metrics from different versions are not comparable. */
|
|
@@ -218,7 +261,10 @@ export const evaluatorRunSchema = z
|
|
|
218
261
|
outcomes: z.array(evaluatorOutcomeSchema).max(100_000),
|
|
219
262
|
/** When the run was executed. */
|
|
220
263
|
executedAt: z.iso.datetime({ offset: true }),
|
|
264
|
+
/** @see defectCorpusSchema.metadata */
|
|
265
|
+
metadata: z.record(z.string(), z.unknown()).optional(),
|
|
221
266
|
})
|
|
267
|
+
.strict()
|
|
222
268
|
.meta({
|
|
223
269
|
id: "EvaluatorRun",
|
|
224
270
|
title: "EvaluatorRun",
|
|
@@ -234,6 +280,70 @@ export type EvaluatorRun = z.infer<typeof evaluatorRunSchema>;
|
|
|
234
280
|
/** Schema version this package stamps on records it constructs. */
|
|
235
281
|
export const REGRESSION_SCHEMA_VERSION = SCHEMA_VERSION;
|
|
236
282
|
|
|
283
|
+
/** How a record's declared schema version relates to the one this runtime implements. */
|
|
284
|
+
export type SchemaVersionRelation = "older" | "same" | "newer";
|
|
285
|
+
|
|
286
|
+
/**
|
|
287
|
+
* Compare a record's declared schema version against {@link REGRESSION_SCHEMA_VERSION}.
|
|
288
|
+
*
|
|
289
|
+
* Exported because the two directions are not the same kind of question. **Newer** is soundness
|
|
290
|
+
* and belongs here: this runtime cannot know what a later version's fields mean, so it refuses.
|
|
291
|
+
* **Older** is policy and belongs to the caller — whether a run from an earlier version is
|
|
292
|
+
* comparable to today's depends on what changed between them, which this package cannot know
|
|
293
|
+
* either. What it can do is stop every caller reimplementing the comparison, which is the part
|
|
294
|
+
* that would drift.
|
|
295
|
+
*
|
|
296
|
+
* A record must be readable in order to be upgraded, so this is deliberately a question a caller
|
|
297
|
+
* can ask *before* parsing, and an older record still parses.
|
|
298
|
+
*
|
|
299
|
+
* @param recordVersion - The `schemaVersion` field of a record, `MAJOR.MINOR` (ADR-0003).
|
|
300
|
+
* @throws {AldusError} `ALDUS_CORPUS_MALFORMED` if `recordVersion` is not `MAJOR.MINOR`.
|
|
301
|
+
*/
|
|
302
|
+
export function compareSchemaVersion(recordVersion: string): SchemaVersionRelation {
|
|
303
|
+
const parse = (value: string): readonly [number, number] => {
|
|
304
|
+
const match = /^(0|[1-9]\d*)\.(0|[1-9]\d*)$/.exec(value);
|
|
305
|
+
if (match === null) {
|
|
306
|
+
// Path and code only — never the received value (contract §19.2).
|
|
307
|
+
throw regressionError(
|
|
308
|
+
RegressionErrorCodes.CORPUS_MALFORMED,
|
|
309
|
+
"A schema version must be MAJOR.MINOR.",
|
|
310
|
+
{
|
|
311
|
+
category: "validation",
|
|
312
|
+
details: { issues: [{ path: "schemaVersion", code: "invalid_format" }] },
|
|
313
|
+
},
|
|
314
|
+
);
|
|
315
|
+
}
|
|
316
|
+
return [Number(match[1]), Number(match[2])] as const;
|
|
317
|
+
};
|
|
318
|
+
const [recordMajor, recordMinor] = parse(recordVersion);
|
|
319
|
+
const [runtimeMajor, runtimeMinor] = parse(REGRESSION_SCHEMA_VERSION);
|
|
320
|
+
if (recordMajor !== runtimeMajor) return recordMajor > runtimeMajor ? "newer" : "older";
|
|
321
|
+
if (recordMinor !== runtimeMinor) return recordMinor > runtimeMinor ? "newer" : "older";
|
|
322
|
+
return "same";
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
/**
|
|
326
|
+
* Refuse a record declaring a version this runtime does not implement.
|
|
327
|
+
*
|
|
328
|
+
* Only `newer` is refused. An older record parses, and {@link compareSchemaVersion} is how a
|
|
329
|
+
* caller decides whether to trust it.
|
|
330
|
+
*/
|
|
331
|
+
function assertSchemaVersionSupported(recordVersion: string, record: "corpus" | "run"): void {
|
|
332
|
+
if (compareSchemaVersion(recordVersion) !== "newer") return;
|
|
333
|
+
throw regressionError(
|
|
334
|
+
RegressionErrorCodes.SCHEMA_VERSION_UNSUPPORTED,
|
|
335
|
+
`A ${record} declares a schema version newer than this runtime implements. Its fields cannot ` +
|
|
336
|
+
"be interpreted here, and the schema discards what it does not declare, so accepting it " +
|
|
337
|
+
"would return a record that looks complete and is not.",
|
|
338
|
+
{
|
|
339
|
+
category: "validation",
|
|
340
|
+
// The runtime's own version is this package's constant, not received input, so naming it is
|
|
341
|
+
// not a value leak. The record's version is not named (contract §19.2).
|
|
342
|
+
details: { runtimeSchemaVersion: REGRESSION_SCHEMA_VERSION, relation: "newer" },
|
|
343
|
+
},
|
|
344
|
+
);
|
|
345
|
+
}
|
|
346
|
+
|
|
237
347
|
/**
|
|
238
348
|
* Validate a corpus and check the uniqueness constraint Zod cannot express.
|
|
239
349
|
*
|
|
@@ -258,6 +368,8 @@ export function parseDefectCorpus(input: unknown): DefectCorpus {
|
|
|
258
368
|
);
|
|
259
369
|
}
|
|
260
370
|
|
|
371
|
+
assertSchemaVersionSupported(result.data.schemaVersion, "corpus");
|
|
372
|
+
|
|
261
373
|
const seen = new Set<string>();
|
|
262
374
|
for (const entry of result.data.cases) {
|
|
263
375
|
if (seen.has(entry.caseId)) {
|
|
@@ -296,6 +408,8 @@ export function parseEvaluatorRun(input: unknown): EvaluatorRun {
|
|
|
296
408
|
);
|
|
297
409
|
}
|
|
298
410
|
|
|
411
|
+
assertSchemaVersionSupported(result.data.schemaVersion, "run");
|
|
412
|
+
|
|
299
413
|
const seen = new Set<string>();
|
|
300
414
|
for (const outcome of result.data.outcomes) {
|
|
301
415
|
if (seen.has(outcome.caseId)) {
|
package/src/errors.ts
CHANGED
|
@@ -34,6 +34,16 @@ export const RegressionErrorCodes = {
|
|
|
34
34
|
BLIND_SPOT_DUPLICATE: "ALDUS_BLIND_SPOT_DUPLICATE",
|
|
35
35
|
/** A promotion policy is internally inconsistent — a threshold outside its valid range. */
|
|
36
36
|
POLICY_INVALID: "ALDUS_POLICY_INVALID",
|
|
37
|
+
/**
|
|
38
|
+
* A record declares a schema version newer than this runtime implements.
|
|
39
|
+
*
|
|
40
|
+
* Refused rather than accepted, because this runtime cannot know what a later version's fields
|
|
41
|
+
* mean and the schemas discard what they do not declare. Accepting one returns an object that
|
|
42
|
+
* looks complete and is not — a read path answering wrongly with no signal, which is worse than
|
|
43
|
+
* refusing. Whether an *older* record is comparable is the caller's policy, not this package's:
|
|
44
|
+
* see `compareSchemaVersion`.
|
|
45
|
+
*/
|
|
46
|
+
SCHEMA_VERSION_UNSUPPORTED: "ALDUS_SCHEMA_VERSION_UNSUPPORTED",
|
|
37
47
|
} as const;
|
|
38
48
|
|
|
39
49
|
/** @see RegressionErrorCodes */
|
package/src/index.ts
CHANGED
|
@@ -22,6 +22,7 @@
|
|
|
22
22
|
export {
|
|
23
23
|
REGRESSION_SCHEMA_VERSION,
|
|
24
24
|
defectCaseSchema,
|
|
25
|
+
compareSchemaVersion,
|
|
25
26
|
defectCorpusSchema,
|
|
26
27
|
evaluatorFindingSchema,
|
|
27
28
|
evaluatorOutcomeSchema,
|
|
@@ -39,6 +40,7 @@ export {
|
|
|
39
40
|
type EvaluatorRun,
|
|
40
41
|
type HumanFinding,
|
|
41
42
|
type ScopeDimensions,
|
|
43
|
+
type SchemaVersionRelation,
|
|
42
44
|
} from "./corpus.js";
|
|
43
45
|
|
|
44
46
|
// --- Scope slicing (§12.1) --------------------------------------------------------------------
|
package/src/metrics.ts
CHANGED
|
@@ -54,6 +54,19 @@ export interface CaseComparison {
|
|
|
54
54
|
* negative — it did catch the case — but a promotion reader should see it.
|
|
55
55
|
*/
|
|
56
56
|
categoryMismatch: boolean;
|
|
57
|
+
/**
|
|
58
|
+
* Whether site-level comparison means anything for this case (#140).
|
|
59
|
+
*
|
|
60
|
+
* `false` when the evaluator flagged without enumerating what it found — a wrapped legacy
|
|
61
|
+
* evaluator reporting that it had something to say, and nothing about how much or where.
|
|
62
|
+
*
|
|
63
|
+
* The case-level verdict is still sound: a flag is a flag, and §12's precision and recall over
|
|
64
|
+
* *cases* are computable. What is not computable is anything per site, and the previous code
|
|
65
|
+
* quietly answered it anyway — with no evaluator categories to compare, `categoryMismatch` came
|
|
66
|
+
* out `false`, which reads as *the categories agreed*. An evaluator nobody measured would have
|
|
67
|
+
* scored a clean sheet.
|
|
68
|
+
*/
|
|
69
|
+
siteMetricsMeasurable: boolean;
|
|
57
70
|
/** Harm a spurious flag would cause here; zero unless this is a false positive. */
|
|
58
71
|
unnecessaryCorrectionHarm: number;
|
|
59
72
|
}
|
|
@@ -79,6 +92,14 @@ export interface SliceMetrics {
|
|
|
79
92
|
trueNegatives: number;
|
|
80
93
|
/** True positives found under the wrong category (contract §12.3). */
|
|
81
94
|
categoryMismatches: number;
|
|
95
|
+
/**
|
|
96
|
+
* Cases whose site-level metrics are unmeasurable (#140).
|
|
97
|
+
*
|
|
98
|
+
* Reported rather than folded in, because a slice where this is large is a slice whose
|
|
99
|
+
* category agreement means much less than the other numbers suggest. Zero is the honest value
|
|
100
|
+
* only when it is true.
|
|
101
|
+
*/
|
|
102
|
+
unmeasurableSiteMetrics: number;
|
|
82
103
|
/** `truePositives / defectiveCases`; `undefined` when there are no defective cases. */
|
|
83
104
|
recall: number | undefined;
|
|
84
105
|
/** `falsePositives / cleanCases`; `undefined` when there are no clean cases. */
|
|
@@ -159,6 +180,11 @@ function compareCase(
|
|
|
159
180
|
severity: entry.severity,
|
|
160
181
|
severityWeight: weight,
|
|
161
182
|
categoryMismatch,
|
|
183
|
+
// A flag with nothing enumerated. Not a contradiction to be repaired by inventing a finding —
|
|
184
|
+
// that would make one report count as one defect, which is exactly the statistic #140 exists
|
|
185
|
+
// to protect.
|
|
186
|
+
siteMetricsMeasurable:
|
|
187
|
+
outcome?.siteMetricsMeasurable ?? !(flagged && (outcome?.findings ?? []).length === 0),
|
|
162
188
|
unnecessaryCorrectionHarm: harm,
|
|
163
189
|
};
|
|
164
190
|
}
|
|
@@ -206,6 +232,8 @@ function summarise(
|
|
|
206
232
|
falsePositives,
|
|
207
233
|
trueNegatives,
|
|
208
234
|
categoryMismatches: comparisons.filter((comparison) => comparison.categoryMismatch).length,
|
|
235
|
+
unmeasurableSiteMetrics: comparisons.filter((comparison) => !comparison.siteMetricsMeasurable)
|
|
236
|
+
.length,
|
|
209
237
|
recall: defectiveCases === 0 ? undefined : truePositives / defectiveCases,
|
|
210
238
|
falsePositiveRate: cleanCases === 0 ? undefined : falsePositives / cleanCases,
|
|
211
239
|
severityWeightedRecall: defectiveWeight === 0 ? undefined : caughtWeight / defectiveWeight,
|