@gaunt-sloth/batch 2.0.0-alpha.24 → 2.0.0-alpha.26
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 +8 -6
- package/dist/BatchRunner.d.ts +20 -0
- package/dist/BatchRunner.js +28 -2
- package/dist/BatchRunner.js.map +1 -1
- package/dist/blindExport.d.ts +88 -0
- package/dist/blindExport.js +129 -0
- package/dist/blindExport.js.map +1 -0
- package/dist/classification.d.ts +52 -0
- package/dist/classification.js +140 -0
- package/dist/classification.js.map +1 -0
- package/dist/classificationRender.d.ts +24 -0
- package/dist/classificationRender.js +96 -0
- package/dist/classificationRender.js.map +1 -0
- package/dist/classificationReport.d.ts +11 -0
- package/dist/classificationReport.js +60 -0
- package/dist/classificationReport.js.map +1 -0
- package/dist/classificationTypes.d.ts +311 -0
- package/dist/classificationTypes.js +40 -0
- package/dist/classificationTypes.js.map +1 -0
- package/dist/evalCompare.d.ts +108 -0
- package/dist/evalCompare.js +246 -0
- package/dist/evalCompare.js.map +1 -0
- package/dist/evalRunner.d.ts +34 -3
- package/dist/evalRunner.js +259 -9
- package/dist/evalRunner.js.map +1 -1
- package/dist/evalSuite.d.ts +12 -2
- package/dist/evalSuite.js +534 -8
- package/dist/evalSuite.js.map +1 -1
- package/dist/evalTypes.d.ts +358 -5
- package/dist/evalTypes.js +98 -0
- package/dist/evalTypes.js.map +1 -1
- package/dist/index.d.ts +15 -1
- package/dist/index.js +14 -1
- package/dist/index.js.map +1 -1
- package/dist/metrics.d.ts +50 -0
- package/dist/metrics.js +433 -0
- package/dist/metrics.js.map +1 -0
- package/dist/pipelineCli.js +1 -1
- package/dist/pipelineCli.js.map +1 -1
- package/dist/raterTarget.d.ts +94 -0
- package/dist/raterTarget.js +328 -0
- package/dist/raterTarget.js.map +1 -0
- package/dist/reporters/reporterTypes.d.ts +9 -0
- package/dist/reporters/textReporter.js +21 -0
- package/dist/reporters/textReporter.js.map +1 -1
- package/dist/types.d.ts +14 -2
- package/dist/types.js +14 -2
- package/dist/types.js.map +1 -1
- package/dist/workflow/runWorkflow.d.ts +1 -1
- package/dist/workflow/runWorkflow.js +2 -2
- package/dist/workflow/runWorkflow.js.map +1 -1
- package/package.json +3 -3
package/dist/evalTypes.js
CHANGED
|
@@ -4,4 +4,102 @@
|
|
|
4
4
|
* Kept as our own constant (not imported) since review's is private to that module and coupled to
|
|
5
5
|
* middleware/tool-call/artifact-store plumbing that doesn't fit a plain structured-output call. */
|
|
6
6
|
export const DEFAULT_EVAL_PASS_THRESHOLD = 6;
|
|
7
|
+
/**
|
|
8
|
+
* BATCH-25 Half B — the stable marker a `rater` rationale carries when the §8 hardline floor refuses
|
|
9
|
+
* the command: the one gradeable form of "this never reaches a shell, whatever the rater said".
|
|
10
|
+
*
|
|
11
|
+
* It is a RATIONALE marker rather than a label or an action on purpose. The floor is not a rung
|
|
12
|
+
* decision: it fires at execution time inside the shell tool, under every rung, after the approvals
|
|
13
|
+
* gate has already returned. It therefore has no representation in the rater's label/action
|
|
14
|
+
* vocabulary, and inventing one here would be this package forming an opinion about a mechanism it
|
|
15
|
+
* does not own. Instead it lands in the text, where a `forced_by: hardline-floor` case (or a plain
|
|
16
|
+
* `must_contain`) grades it.
|
|
17
|
+
*
|
|
18
|
+
* It lives in this module rather than beside its producer so the SUITE PARSER can desugar
|
|
19
|
+
* `forced_by:` without importing `raterTarget.js` — which would pull `@gaunt-sloth/agent` and core's
|
|
20
|
+
* rater into the module graph of every suite parse.
|
|
21
|
+
*/
|
|
22
|
+
export const HARDLINE_REFUSAL_MARKER = 'hardline floor: refused';
|
|
23
|
+
/**
|
|
24
|
+
* BATCH-25 Half B — the deterministic mechanisms of the approvals gate that a case can assert fired,
|
|
25
|
+
* spelled EXACTLY as the approvals corpus spells them in its own `forced_by` / `floor_refuses`
|
|
26
|
+
* fields, so transcribing a corpus case is a copy rather than a translation.
|
|
27
|
+
*
|
|
28
|
+
* ## Why this exists (the I1 finding)
|
|
29
|
+
*
|
|
30
|
+
* A model-free case cannot be graded on its `action`. With no verdict, core's decision mapping
|
|
31
|
+
* substitutes its fail-closed one and returns the SAME action for every command at a rated rung —
|
|
32
|
+
* `ls -la`, `rm -rf /` and `rm -rf $(echo /)` are indistinguishable. `expect_action: escalate` on a
|
|
33
|
+
* deterministic case therefore passes for a directory listing, and would still pass with the floor
|
|
34
|
+
* and both preflights deleted: a constant, not a regression gate.
|
|
35
|
+
*
|
|
36
|
+
* What DOES discriminate is **which deterministic mechanism fired**, which the target reports in the
|
|
37
|
+
* rationale, and which is exactly what the corpus records. So a deterministic case asserts that.
|
|
38
|
+
*/
|
|
39
|
+
export const FORCED_BY_MECHANISMS = [
|
|
40
|
+
'hardline-floor',
|
|
41
|
+
'ambiguity-preflight',
|
|
42
|
+
'script-env-leak-preflight',
|
|
43
|
+
];
|
|
44
|
+
/** The prefix a rationale carries for a decision a preflight forced, followed by the mechanism. */
|
|
45
|
+
export const FORCED_BY_MARKER = 'forced by';
|
|
46
|
+
/**
|
|
47
|
+
* The exact substring a `forced_by: <mechanism>` assertion looks for in the rationale. The floor's
|
|
48
|
+
* is {@link HARDLINE_REFUSAL_MARKER} — the marker it already emits — so there is one marker per
|
|
49
|
+
* mechanism and no second spelling of the same claim.
|
|
50
|
+
*/
|
|
51
|
+
export const FORCED_BY_ASSERTIONS = {
|
|
52
|
+
'hardline-floor': HARDLINE_REFUSAL_MARKER,
|
|
53
|
+
'ambiguity-preflight': `${FORCED_BY_MARKER}: ambiguity-preflight`,
|
|
54
|
+
'script-env-leak-preflight': `${FORCED_BY_MARKER}: script-env-leak-preflight`,
|
|
55
|
+
};
|
|
56
|
+
/**
|
|
57
|
+
* Which of {@link FORCED_BY_MECHANISMS} are **preflights of the decision mapping** — the ones that
|
|
58
|
+
* can only be observed by handing the gate a rating for them to OVERRIDE.
|
|
59
|
+
*
|
|
60
|
+
* **This is the single statement of the rule, and everything else reads it through
|
|
61
|
+
* {@link mechanismNeedsPermissiveRating}.** It is kept here, next to the mechanism list, rather than
|
|
62
|
+
* in `raterTarget.js`, so the runner can consult it without pulling `@gaunt-sloth/agent` and core's
|
|
63
|
+
* rater into the module graph — and it is pinned by a unit test to equal the target's own probe
|
|
64
|
+
* table, so the two cannot drift.
|
|
65
|
+
*
|
|
66
|
+
* ## Why the floor is not on this list (measured, CFG-28)
|
|
67
|
+
*
|
|
68
|
+
* The two preflights live INSIDE `mapVerdictToAction`, and CFG-28 narrowed them to raise only an
|
|
69
|
+
* outcome that sits below the deterministic floor. Give that mapping no verdict and it substitutes
|
|
70
|
+
* core's fail-closed one, which is *at* the floor — so no preflight rewrites anything, every command
|
|
71
|
+
* comes back with the identical placeholder sentence, and the assertion is a constant again. Handing
|
|
72
|
+
* it a permissive rating is not a hypothetical: **overriding a permissive rating is the entire job of
|
|
73
|
+
* a preflight**, so it is the one path on which the mechanism is real.
|
|
74
|
+
*
|
|
75
|
+
* The §8 hardline floor is the opposite by design. The corpus defines `floor_refuses` as a refusal
|
|
76
|
+
* *at execution time*, "regardless of the rating, the approval, or the allow-list", and explicitly
|
|
77
|
+
* "a SEPARATE assertion from `action`". The target reads it from `checkHardline`, which never sees a
|
|
78
|
+
* verdict — so a rating cannot change the answer, and supplying one buys nothing. It also costs:
|
|
79
|
+
* `mapVerdictToAction` does not consult the floor, so a permissive rating on `rm -rf /` returns
|
|
80
|
+
* `approve`, which would move the action column of **5 of the corpus's 6 `fl-*` cases** off the
|
|
81
|
+
* `escalate` they author. Measured over all 22 deterministic corpus cases; see the fix-round-2
|
|
82
|
+
* section of `handoff/task-1-report.md`.
|
|
83
|
+
*
|
|
84
|
+
* ## The property that makes this self-justifying
|
|
85
|
+
*
|
|
86
|
+
* When the claimed preflight really does fire, the rating does not move the action — every corpus
|
|
87
|
+
* case that claims one (`ob-02`…`ob-05`, `el-01`, `el-02`) is `escalate` with or without it. When it
|
|
88
|
+
* does not fire, the marker and the action go red **together**. That is the discrimination, not a
|
|
89
|
+
* side effect of it.
|
|
90
|
+
*/
|
|
91
|
+
export const PREFLIGHT_MECHANISMS = [
|
|
92
|
+
'ambiguity-preflight',
|
|
93
|
+
'script-env-leak-preflight',
|
|
94
|
+
];
|
|
95
|
+
/**
|
|
96
|
+
* Must a round claiming this mechanism be driven with a permissive rating for the mechanism to be
|
|
97
|
+
* observable at all? See {@link PREFLIGHT_MECHANISMS} for the whole rule and why the floor is
|
|
98
|
+
* excluded. `undefined` (the round claims no mechanism) is `false`: an ordinary `model_free` case
|
|
99
|
+
* must keep going through the gate with no verdict, or its action would change.
|
|
100
|
+
*/
|
|
101
|
+
export function mechanismNeedsPermissiveRating(mechanism) {
|
|
102
|
+
return (mechanism !== undefined &&
|
|
103
|
+
PREFLIGHT_MECHANISMS.includes(mechanism));
|
|
104
|
+
}
|
|
7
105
|
//# sourceMappingURL=evalTypes.js.map
|
package/dist/evalTypes.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"evalTypes.js","sourceRoot":"","sources":["../src/evalTypes.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"evalTypes.js","sourceRoot":"","sources":["../src/evalTypes.ts"],"names":[],"mappings":"AAgBA;;;;mGAImG;AACnG,MAAM,CAAC,MAAM,2BAA2B,GAAG,CAAC,CAAC;AAE7C;;;;;;;;;;;;;;GAcG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG,yBAAyB,CAAC;AAEjE;;;;;;;;;;;;;;;GAeG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG;IAClC,gBAAgB;IAChB,qBAAqB;IACrB,2BAA2B;CACnB,CAAC;AAKX,mGAAmG;AACnG,MAAM,CAAC,MAAM,gBAAgB,GAAG,WAAW,CAAC;AAE5C;;;;GAIG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAsC;IACrE,gBAAgB,EAAE,uBAAuB;IACzC,qBAAqB,EAAE,GAAG,gBAAgB,uBAAuB;IACjE,2BAA2B,EAAE,GAAG,gBAAgB,6BAA6B;CAC9E,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG;IAClC,qBAAqB;IACrB,2BAA2B;CACoB,CAAC;AAWlD;;;;;GAKG;AACH,MAAM,UAAU,8BAA8B,CAAC,SAAwC;IACrF,OAAO,CACL,SAAS,KAAK,SAAS;QACtB,oBAAqD,CAAC,QAAQ,CAAC,SAAS,CAAC,CAC3E,CAAC;AACJ,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -4,7 +4,7 @@ export { parseOverFile } from '#src/parseOver.js';
|
|
|
4
4
|
export { runBatchMatrix, buildBatchSummary } from '#src/BatchRunner.js';
|
|
5
5
|
export { writeBatchOutput } from '#src/output.js';
|
|
6
6
|
export type { BatchRunnerOptions, BatchSummary, CellResult, CellRunOutcome, MatrixCell, MatrixRow, RunCellFn, ToolResultRecord, } from '#src/types.js';
|
|
7
|
-
export {
|
|
7
|
+
export { DEFAULT_CELL_CONCURRENCY } from '#src/types.js';
|
|
8
8
|
export { parseEvalSuite } from '#src/evalSuite.js';
|
|
9
9
|
export { runDeterministicChecks } from '#src/deterministicChecks.js';
|
|
10
10
|
export { judgeEvalCase, buildJudgeMessages, EvalVerdictSchema, EVAL_JUDGE_DEFAULT_TIMEOUT_MS, } from '#src/judge.js';
|
|
@@ -14,9 +14,23 @@ export { writeEvalOutput } from '#src/evalOutput.js';
|
|
|
14
14
|
export type { AdkAgentTarget, AgUiAgentTarget, DeterministicCheckResult, EvalCase, EvalCaseResult, EvalExpectation, EvalSuite, EvalSuiteSummary, EvalTarget, GthAgentTarget, EvalTurn, EvalTurnResult, JudgeFn, JudgeOutcome, JudgeVerdict, RunConversationFn, TurnRunOutcome, } from '#src/evalTypes.js';
|
|
15
15
|
export type { RunEvalSuiteOptions } from '#src/evalRunner.js';
|
|
16
16
|
export { DEFAULT_EVAL_PASS_THRESHOLD } from '#src/evalTypes.js';
|
|
17
|
+
export { extractClassificationValue, buildConfusionMatrix, collectTags, readRaw, } from '#src/classification.js';
|
|
18
|
+
export { buildClassificationReport } from '#src/classificationReport.js';
|
|
19
|
+
export { computeMetric, parseMetricPredicate, evaluatePredicate, evaluatePredicates, formatTally, } from '#src/metrics.js';
|
|
20
|
+
export { renderClassificationReport, renderConfusionMatrix, renderMetric, } from '#src/classificationRender.js';
|
|
21
|
+
export { buildBlindExport, diffRelabel, renderRelabelDiff } from '#src/blindExport.js';
|
|
22
|
+
export type { BlindExport, BlindExportCase, RelabelDiff, RelabelEntry } from '#src/blindExport.js';
|
|
23
|
+
export { expandSweep, deepMerge, renderComparison, diffRuns, renderRunDiff, } from '#src/evalCompare.js';
|
|
24
|
+
export type { ComparisonColumn, RunDiff, RunDiffEntry, SweepCell } from '#src/evalCompare.js';
|
|
25
|
+
export { UNRECOGNIZED_LABEL, NO_EXPECTATION } from '#src/classificationTypes.js';
|
|
26
|
+
export type { ClassificationExtractor, ClassifiedCell, EvalCaseClassification, EvalClassificationReport, EvalClassificationSpec, EvalConfusionMatrix, EvalMetricCoverage, EvalMetricResult, EvalMetricSpec, EvalMetricTally, MetricField, MetricPredicate, } from '#src/classificationTypes.js';
|
|
27
|
+
export type { ClassifyOutcome, ClassifyRequest, EvalSweep, EvalSweepValue, RaterTarget, RunClassifyFn, } from '#src/evalTypes.js';
|
|
28
|
+
export { buildRaterClassifier, HARDLINE_REFUSAL_MARKER, NO_RATING_CALL_MARKER, } from '#src/raterTarget.js';
|
|
29
|
+
export type { RaterClassifierOptions } from '#src/raterTarget.js';
|
|
17
30
|
export { resolveReporters, availableReporterNames } from '#src/reporters/registry.js';
|
|
18
31
|
export { driveReporters } from '#src/reporters/drive.js';
|
|
19
32
|
export { createTextReporter } from '#src/reporters/textReporter.js';
|
|
20
33
|
export type { EvalReporter, EvalReporterFactory, EvalRunContext, NamedReporter, } from '#src/reporters/reporterTypes.js';
|
|
21
34
|
export { runWorkflow } from '#src/workflow/runWorkflow.js';
|
|
35
|
+
export { DEFAULT_WORKFLOW_CONCURRENCY } from '#src/types.js';
|
|
22
36
|
export type { WorkflowAgentOptions, WorkflowContext, RunWorkflowOptions, } from '#src/workflow/runWorkflow.js';
|
package/dist/index.js
CHANGED
|
@@ -3,7 +3,7 @@ export { bindCellContent } from '#src/interpolate.js';
|
|
|
3
3
|
export { parseOverFile } from '#src/parseOver.js';
|
|
4
4
|
export { runBatchMatrix, buildBatchSummary } from '#src/BatchRunner.js';
|
|
5
5
|
export { writeBatchOutput } from '#src/output.js';
|
|
6
|
-
export {
|
|
6
|
+
export { DEFAULT_CELL_CONCURRENCY } from '#src/types.js';
|
|
7
7
|
// BATCH-2 — `gth eval`'s suite parsing, deterministic checks, judge, runner, and output writer.
|
|
8
8
|
export { parseEvalSuite } from '#src/evalSuite.js';
|
|
9
9
|
export { runDeterministicChecks } from '#src/deterministicChecks.js';
|
|
@@ -11,6 +11,18 @@ export { judgeEvalCase, buildJudgeMessages, EvalVerdictSchema, EVAL_JUDGE_DEFAUL
|
|
|
11
11
|
export { runEvalSuite } from '#src/evalRunner.js';
|
|
12
12
|
export { writeEvalOutput } from '#src/evalOutput.js';
|
|
13
13
|
export { DEFAULT_EVAL_PASS_THRESHOLD } from '#src/evalTypes.js';
|
|
14
|
+
// BATCH-25 — the classifier eval facility: label/action assertions, the confusion matrix, declared
|
|
15
|
+
// metrics with corpus-wide denominators, blind export, and the sweep/run-over-run comparison.
|
|
16
|
+
export { extractClassificationValue, buildConfusionMatrix, collectTags, readRaw, } from '#src/classification.js';
|
|
17
|
+
export { buildClassificationReport } from '#src/classificationReport.js';
|
|
18
|
+
export { computeMetric, parseMetricPredicate, evaluatePredicate, evaluatePredicates, formatTally, } from '#src/metrics.js';
|
|
19
|
+
export { renderClassificationReport, renderConfusionMatrix, renderMetric, } from '#src/classificationRender.js';
|
|
20
|
+
export { buildBlindExport, diffRelabel, renderRelabelDiff } from '#src/blindExport.js';
|
|
21
|
+
export { expandSweep, deepMerge, renderComparison, diffRuns, renderRunDiff, } from '#src/evalCompare.js';
|
|
22
|
+
export { UNRECOGNIZED_LABEL, NO_EXPECTATION } from '#src/classificationTypes.js';
|
|
23
|
+
// BATCH-25 Half B — the `rater` target: the one implementation of the `RunClassifyFn` seam, which
|
|
24
|
+
// drives gth's own approvals rater over a corpus of commands.
|
|
25
|
+
export { buildRaterClassifier, HARDLINE_REFUSAL_MARKER, NO_RATING_CALL_MARKER, } from '#src/raterTarget.js';
|
|
14
26
|
// BATCH-19 — the `gth eval` reporter facility (A1 seam). These are the public plugin contract an
|
|
15
27
|
// out-of-core `@gaunt-sloth/eval-reporter-*` package implements, exported from the package root so a
|
|
16
28
|
// reporter package can type its factory against ONE import.
|
|
@@ -20,4 +32,5 @@ export { createTextReporter } from '#src/reporters/textReporter.js';
|
|
|
20
32
|
// BATCH-3 — the `gth workflow` host: runs a local JS orchestration script that drives one or more
|
|
21
33
|
// LLM calls through a small WorkflowContext.
|
|
22
34
|
export { runWorkflow } from '#src/workflow/runWorkflow.js';
|
|
35
|
+
export { DEFAULT_WORKFLOW_CONCURRENCY } from '#src/types.js';
|
|
23
36
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxE,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAWlD,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxE,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAWlD,OAAO,EAAE,wBAAwB,EAAE,MAAM,eAAe,CAAC;AAEzD,gGAAgG;AAChG,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,EACL,aAAa,EACb,kBAAkB,EAClB,iBAAiB,EACjB,6BAA6B,GAC9B,MAAM,eAAe,CAAC;AAEvB,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAqBrD,OAAO,EAAE,2BAA2B,EAAE,MAAM,mBAAmB,CAAC;AAEhE,mGAAmG;AACnG,8FAA8F;AAC9F,OAAO,EACL,0BAA0B,EAC1B,oBAAoB,EACpB,WAAW,EACX,OAAO,GACR,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,yBAAyB,EAAE,MAAM,8BAA8B,CAAC;AACzE,OAAO,EACL,aAAa,EACb,oBAAoB,EACpB,iBAAiB,EACjB,kBAAkB,EAClB,WAAW,GACZ,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,0BAA0B,EAC1B,qBAAqB,EACrB,YAAY,GACb,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAEvF,OAAO,EACL,WAAW,EACX,SAAS,EACT,gBAAgB,EAChB,QAAQ,EACR,aAAa,GACd,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAwBjF,kGAAkG;AAClG,8DAA8D;AAC9D,OAAO,EACL,oBAAoB,EACpB,uBAAuB,EACvB,qBAAqB,GACtB,MAAM,qBAAqB,CAAC;AAG7B,iGAAiG;AACjG,qGAAqG;AACrG,4DAA4D;AAC5D,OAAO,EAAE,gBAAgB,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAC;AACtF,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AACzD,OAAO,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AAQpE,kGAAkG;AAClG,6CAA6C;AAC7C,OAAO,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAC3D,OAAO,EAAE,4BAA4B,EAAE,MAAM,eAAe,CAAC"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import type { ClassifiedCell, EvalClassificationSpec, EvalMetricResult, EvalMetricSpec, EvalMetricTally, MetricPredicate } from '#src/classificationTypes.js';
|
|
2
|
+
/**
|
|
3
|
+
* Parse ONE predicate string. Predicates come as a LIST and are ANDed; there is no `or`, no nesting
|
|
4
|
+
* and no parentheses — see {@link MetricPredicate} for why that limit is deliberate.
|
|
5
|
+
*
|
|
6
|
+
* Accepted forms:
|
|
7
|
+
* - `expected.label != safe` · `actual.action == approve`
|
|
8
|
+
* - `actual.label == expected.label` (field-to-field — this is how accuracy is written)
|
|
9
|
+
* - `expected.label in [destructive, catastrophic, attack]` · `actual.action not in [approve]`
|
|
10
|
+
* - `has_tag(injection)` · `not has_tag(negotiation)`
|
|
11
|
+
*
|
|
12
|
+
* The literal `none` matches a cell where the field is absent.
|
|
13
|
+
*
|
|
14
|
+
* Every literal is validated against the suite's declared enum. That check is the point: a typo'd
|
|
15
|
+
* value would make the predicate unsatisfiable and the metric a permanent, trusted zero.
|
|
16
|
+
*
|
|
17
|
+
* @throws Error with an actionable message (the offending text, the field, and the declared enum).
|
|
18
|
+
*/
|
|
19
|
+
export declare function parseMetricPredicate(raw: string, spec: EvalClassificationSpec, where: string): MetricPredicate;
|
|
20
|
+
/** Evaluate ONE predicate against one cell. */
|
|
21
|
+
export declare function evaluatePredicate(predicate: MetricPredicate, cell: ClassifiedCell): boolean;
|
|
22
|
+
/** All predicates in a list must hold (ANDed). An empty list is vacuously true — that is what "the
|
|
23
|
+
* whole corpus" means for an absent `over:`. */
|
|
24
|
+
export declare function evaluatePredicates(predicates: MetricPredicate[], cell: ClassifiedCell): boolean;
|
|
25
|
+
/**
|
|
26
|
+
* Compute one declared metric over the corpus — overall and per tag — together with everything that
|
|
27
|
+
* bounds what it can see.
|
|
28
|
+
*
|
|
29
|
+
* The denominator is every SCORED cell satisfying `over` (every scored cell when `over` is absent).
|
|
30
|
+
* The numerator is the cells in that denominator that also satisfy `where`.
|
|
31
|
+
*
|
|
32
|
+
* Warnings, in the order they matter:
|
|
33
|
+
* - **numerator outside the denominator** — the throwaway's exact bug shape: cases that satisfy what
|
|
34
|
+
* the metric is counting but sit outside what it divides by, so the metric cannot see them;
|
|
35
|
+
* - **subset denominator** — fired on the evaluated count, so it catches both a narrowing `over:`
|
|
36
|
+
* and cells lost to SUT failures;
|
|
37
|
+
* - **excluded cells** — cells that never produced a classification at all;
|
|
38
|
+
* - **empty denominator** — the metric measured nothing, so its value is `null` rather than a
|
|
39
|
+
* flattering zero.
|
|
40
|
+
*
|
|
41
|
+
* @param cells Every cell in the suite, scored and unscored alike (the unscored ones are what make
|
|
42
|
+
* the coverage numbers honest).
|
|
43
|
+
*/
|
|
44
|
+
export declare function computeMetric(spec: EvalMetricSpec, cells: ClassifiedCell[], tags: string[]): EvalMetricResult;
|
|
45
|
+
/** True when this metric's thresholds are absolute COUNTS rather than fractions. The two forms are
|
|
46
|
+
* mutually exclusive per metric (enforced at parse time), so one flag decides the whole reading. */
|
|
47
|
+
export declare function isCountGate(spec: EvalMetricSpec): boolean;
|
|
48
|
+
/** Format a tally for human output: `3/29 (10.3%)`, or `n/a (0 cases)` for an empty denominator —
|
|
49
|
+
* which must never render as `0.0%`. */
|
|
50
|
+
export declare function formatTally(tally: EvalMetricTally): string;
|