@mutagent/evaluator 0.1.0-alpha.5 → 0.2.0-alpha.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/.claude/skills/mutagent-evaluator/SKILL.md +28 -30
- package/.claude/skills/mutagent-evaluator/assets/agents/dataset-builder.md +6 -5
- package/.claude/skills/mutagent-evaluator/assets/agents/evaluator.md +93 -30
- package/.claude/skills/mutagent-evaluator/assets/code-quality-criteria.yaml +75 -0
- package/.claude/skills/mutagent-evaluator/assets/templates/discover-report.template.html +397 -0
- package/.claude/skills/mutagent-evaluator/assets/templates/eval-report.template.html +594 -0
- package/.claude/skills/mutagent-evaluator/assets/templates/review-report.template.html +560 -0
- package/.claude/skills/mutagent-evaluator/golden/judge-trajectory.prose.md +69 -0
- package/.claude/skills/mutagent-evaluator/lenses/methodology-critic-lens.md +1 -1
- package/.claude/skills/mutagent-evaluator/references/data-registry.md +43 -0
- package/.claude/skills/mutagent-evaluator/references/edd-loop.md +6 -6
- package/.claude/skills/mutagent-evaluator/references/eval-layers.md +52 -0
- package/.claude/skills/mutagent-evaluator/references/eval-stage.md +37 -4
- package/.claude/skills/mutagent-evaluator/references/memory-format.md +1 -1
- package/.claude/skills/mutagent-evaluator/schemas/methodology-review.schema.yaml +1 -1
- package/.claude/skills/mutagent-evaluator/scripts/agent-dispatch.ts +0 -0
- package/.claude/skills/mutagent-evaluator/scripts/aggregate-discover.ts +254 -9
- package/.claude/skills/mutagent-evaluator/scripts/audience.ts +84 -0
- package/.claude/skills/mutagent-evaluator/scripts/build-review-ui.ts +320 -6
- package/.claude/skills/mutagent-evaluator/scripts/cli/prep.ts +32 -2
- package/.claude/skills/mutagent-evaluator/scripts/cli/profile-subject.ts +1 -1
- package/.claude/skills/mutagent-evaluator/scripts/code-eval-library.ts +201 -0
- package/.claude/skills/mutagent-evaluator/scripts/code-quality-verdict.ts +60 -68
- package/.claude/skills/mutagent-evaluator/scripts/config/schema.ts +3 -3
- package/.claude/skills/mutagent-evaluator/scripts/contracts/agentspec-evals.ts +101 -39
- package/.claude/skills/mutagent-evaluator/scripts/contracts/eval-matrix.ts +326 -3
- package/.claude/skills/mutagent-evaluator/scripts/contracts/eval-types.ts +30 -4
- package/.claude/skills/mutagent-evaluator/scripts/determine-outcome.ts +8 -0
- package/.claude/skills/mutagent-evaluator/scripts/edd/change-request.ts +1 -1
- package/.claude/skills/mutagent-evaluator/scripts/edd/edd-types.ts +2 -2
- package/.claude/skills/mutagent-evaluator/scripts/judge-prompt-template.ts +144 -15
- package/.claude/skills/mutagent-evaluator/scripts/materialize-dataset.ts +130 -68
- package/.claude/skills/mutagent-evaluator/scripts/matrix-judge.ts +219 -1
- package/.claude/skills/mutagent-evaluator/scripts/memory/append.ts +1 -1
- package/.claude/skills/mutagent-evaluator/scripts/memory/ratify.ts +165 -0
- package/.claude/skills/mutagent-evaluator/scripts/merge-criteria.ts +849 -0
- package/.claude/skills/mutagent-evaluator/scripts/prep-tasks.ts +15 -4
- package/.claude/skills/mutagent-evaluator/scripts/read-manifest.ts +120 -0
- package/.claude/skills/mutagent-evaluator/scripts/read-unitf-traces.ts +34 -2
- package/.claude/skills/mutagent-evaluator/scripts/render-build-cards.ts +37 -0
- package/.claude/skills/mutagent-evaluator/scripts/render-discover-report-v3.ts +1155 -0
- package/.claude/skills/mutagent-evaluator/scripts/render-eval-report-v3.ts +610 -0
- package/.claude/skills/mutagent-evaluator/scripts/render-eval-report.ts +11 -92
- package/.claude/skills/mutagent-evaluator/scripts/render-review-report-v3.ts +691 -0
- package/.claude/skills/mutagent-evaluator/scripts/report-fragments.ts +173 -0
- package/.claude/skills/mutagent-evaluator/scripts/route-failures.ts +12 -9
- package/.claude/skills/mutagent-evaluator/scripts/run-evaluate.ts +46 -1
- package/.claude/skills/mutagent-evaluator/scripts/run-pipeline.ts +39 -4
- package/.claude/skills/mutagent-evaluator/scripts/run-review.ts +266 -0
- package/.claude/skills/mutagent-evaluator/scripts/subject-profile.ts +82 -0
- package/.claude/skills/mutagent-evaluator/scripts/sync-eval-criteria.ts +2 -2
- package/.claude/skills/mutagent-evaluator/scripts/unitf-to-evaltrace.ts +64 -21
- package/.claude/skills/mutagent-evaluator/scripts/verify-render.ts +728 -0
- package/bin/mutagent-cli.mjs +9 -5
- package/package.json +2 -2
|
@@ -1,24 +1,19 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: mutagent-evaluator
|
|
3
3
|
description: |
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
end user wants. *audit is a SEPARATE, explicit-only 4-tab static-auditor (eval-matrix · data-leak ·
|
|
18
|
-
variance · methodology) used mainly for complex agents/skills that emit HTML artifacts; it is NEVER the
|
|
19
|
-
fallback for a plain evaluate. Pinned judge model + temp=0
|
|
20
|
-
for byte-identical reruns (C-PIN). Usable standalone OR borrowed by mutagent-skill-builder's
|
|
21
|
-
SIMULATE phase as the SimVerifier.
|
|
4
|
+
The EVALUATE stage of the agentic development lifecycle (ADL ③). Builds and runs
|
|
5
|
+
trustworthy evaluations for AI agents and skills: from a subject's real traces it
|
|
6
|
+
learns what success and failure look like, turns that into binary eval criteria,
|
|
7
|
+
and scores the subject to a clear gate verdict. It only judges — failures are
|
|
8
|
+
flagged and routed to mutagent-diagnostics, never fixed here. Pick it whenever the
|
|
9
|
+
ask is to evaluate, judge, score, or build and validate evals for an agent or
|
|
10
|
+
skill: any plain "evaluate this" runs *evaluate — one judge per trajectory walks
|
|
11
|
+
the evidence layers (code checks → outcome → trajectory → tool outputs → context),
|
|
12
|
+
criteria binding evidence across all of them; *evaluate-<layer> scopes the same
|
|
13
|
+
pipeline to one layer; *discover mines new criteria, never re-recommending one it
|
|
14
|
+
already has; *audit is a separate, explicit-only static auditor and never the
|
|
15
|
+
fallback for a plain evaluate. Also serves as the verifier inside
|
|
16
|
+
mutagent-skill-builder's SIMULATE.
|
|
22
17
|
license: Proprietary. LICENSE.txt has complete terms.
|
|
23
18
|
compatibility: Designed for Claude Code, Codex, Cursor, OpenCode and similar coding-agent runtimes; works with git, gh CLI, jq, curl, and Bun/pnpm/npm runtimes.
|
|
24
19
|
metadata:
|
|
@@ -102,11 +97,12 @@ reason for the rest. NEVER improvise.
|
|
|
102
97
|
|---------|------|-------------------|---------|
|
|
103
98
|
| `*discover-evals` | hybrid | `references/workflows/orchestrator-protocol.md` + `scripts/prep-tasks.ts` + `scripts/determine-outcome.ts` + `scripts/discover-criteria.ts` + `assets/agents/evaluator.md` (`#mode-discover`) | PREP determiner tasks → fan out `evaluator` (`#mode-discover`, mass-parallel) → AGGREGATE ✓/✗ → mine emergent BINARY ACTIONABLE criteria (EV-041/042/052) **+ T6 failure/uncertain DATASET CANDIDATES** (`collectDatasetCandidates`, reuses the derive-dataset selectors → `*build-dataset`). **GA split** — **code:** sample (broken+healthy) · aggregate · `diff-discriminate` · ground-gate · dataset-candidates; **LLM leaf:** determine + 3 detectors + cite refs + typed assumptions (root-not-symptom). |
|
|
104
99
|
| `*build-evals` | hybrid | `references/workflows/orchestrator-protocol.md` + `scripts/eval-engine.ts` + `scripts/codegen-evals.ts` + `scripts/prep-tasks.ts` + `scripts/build-evals.ts` + `assets/agents/evaluator.md` (`#mode-judge-criterion`) + `scripts/render-build-cards.ts` | **ENGINE-FORK FIRST (ADL F7/F9/F14).** ASKS the eval implementation mode via `chooseEvalEngineOptions(target)` — Path A `native-matrix` (eval-matrix + LLM-judge SUB-AGENTS; SURFACES the Claude-Code + log-sink dependency up front) vs Path B `code-written` (`codegen-evals.ts` emits a portable bun/TS suite — runs WITHOUT Claude Code, F14). Target-conditional: a code framework offers BOTH, a `harness:*` target is native-only. **Path A** then PREPs judge tasks (criterion × trace-slice) → fan out `evaluator` (`#mode-judge-criterion`, mass-parallel) → one binary+confidence judge per criterion (EV-043). **GA split** — **code:** engine-resolve · spec render · `lint-grounding` · `resolve-ref` (BIND) · codegen; **LLM leaf:** judge + VERIFY (cite refs · note assumptions · abstain). Streams progress + a verbose evals entity card (F13/F16/F22). |
|
|
105
|
-
| `*evaluate` | hybrid | `references/workflows/orchestrator-protocol.md` + `scripts/matrix-judge.ts` + `scripts/contracts/eval-matrix.ts` + `assets/agents/evaluator.md` (`#mode-judge-trajectory`) + `scripts/evaluate.ts` | **DEFAULT (headline):** **T1 TIER-0 deterministic pre-pass** (code-method rows run first, zero judge tokens) → PREP one matrix packet per RESIDUAL judge trajectory (**T5 adaptive-K guard, default 1:1**) → fan out `evaluator` (`#mode-judge-trajectory` — one judge/trajectory scoring the WHOLE matrix, emitting the **T2 Judge DAG v2 walk** = `judge_steps[]` + dense na-explicit map + confidence band + early-INCOMPLETE + node-2.5 candidates) → AGGREGATE: fold code+judge verdicts → **T3 independent verifier** refutes GATING fails (downgrade-only) → **T4 consolidate-by-locus + walk-derived health** → GATE verdict + variance view (EV-048). **GA split** — **code:** tier-0 · prep · `lint-grounding` · `resolve-ref` · `assemble-scorecard` (gate `fail ▸ incomplete ▸ pass`) · consolidate-by-locus · route-failures; **LLM leaf:** trajectory judge (DAG v2 walk: BIND · GROUND[absence-split] · cite · abstain) + independent VERIFY. **MAY now return `incomplete`** (indeterminate → calibrate). **ADL F20:** the rollup ALSO renders a SCORECARD DASHBOARD wireframe (`renderScorecardDashboard` — per-criterion pass/fail bar + variance + samples), not a flat terminal dump. Under a **Path B** engine, `*evaluate` instead runs the portable `codegen-evals.ts` suite (no Claude Code) and reads back its scorecard JSON from the discoverable sink. |
|
|
106
|
-
| `*
|
|
100
|
+
| `*evaluate` | hybrid | `references/workflows/orchestrator-protocol.md` + `scripts/matrix-judge.ts` + `scripts/contracts/eval-matrix.ts` + `assets/agents/evaluator.md` (`#mode-judge-trajectory`) + `scripts/evaluate.ts` | **DEFAULT (headline):** **T1 TIER-0 deterministic pre-pass** (code-method rows run first, zero judge tokens) → PREP one matrix packet per RESIDUAL judge trajectory (**T5 adaptive-K guard, default 1:1**) → fan out `evaluator` (`#mode-judge-trajectory` — one judge/trajectory scoring the WHOLE matrix, emitting the **T2 Judge DAG v2 walk** = `judge_steps[]` + dense na-explicit map + confidence band + early-INCOMPLETE + node-2.5 candidates) → AGGREGATE: fold code+judge verdicts → **T3 independent verifier** refutes GATING fails (downgrade-only) → **T4 consolidate-by-locus + walk-derived health** → GATE verdict + variance view (EV-048). **GA split** — **code:** tier-0 · prep · `lint-grounding` · `resolve-ref` · `assemble-scorecard` (gate `fail ▸ incomplete ▸ pass`) · consolidate-by-locus · route-failures; **LLM leaf:** trajectory judge (DAG v2 walk: BIND · GROUND[absence-split] · cite · abstain) + independent VERIFY. **MAY now return `incomplete`** (indeterminate → calibrate). **ADL F20:** the rollup ALSO renders a SCORECARD DASHBOARD wireframe (`renderScorecardDashboard` — per-criterion pass/fail bar + variance + samples), not a flat terminal dump. Under a **Path B** engine, `*evaluate` instead runs the portable `codegen-evals.ts` suite (no Claude Code) and reads back its scorecard JSON from the discoverable sink. **v3 LAYERED WALK (D1=B+):** the trajectory judge performs the whole evidence-layer sequence INSIDE its one dispatch — L0 code checks → L1 outcome (scenario + expectedExit, cheap, first) → per stopping rules L2 trajectory → L3 tool outputs → L4 context — emitting `layerVerdicts[]` + `earlyExit` + `codeEvalHits[]` + an emissions self-manifest (E-NEW contract, `contracts/eval-matrix.ts`); AGGREGATE folds layers (`foldLayerVerdicts`), DETECTS cross-layer conflicts (`detectLayerConflicts` — surfaced for the human calibration queue, NEVER auto-resolved, D2-A/OT-1), enforces the COMPLETENESS LAW (`assertNoUnverdictedCriterion` THROWS on a silent skip), and folds MR-5 data-completeness (`foldEmissionsScorecard`). |
|
|
101
|
+
| `*evaluate-outcome` · `*evaluate-trajectory` · `*evaluate-outputs` · `*evaluate-context` · `*evaluate-code` · `*evaluate-criteria` | hybrid | the SAME binds as `*evaluate` | **v3 PIPEABLE LAYER FILTERS (D3=A):** each runs the identical `*evaluate` pipeline with `layerScope` set in every packet (`outcome`→`[L1]` · `trajectory`→`[L2]` · `outputs`→`[L3]` · `context`→`[L4]` · `code`→`[L0]`); the judge runs ONLY those walk phases — **criteria are the SUPER-LAYER and are still verdicted over whatever those phases gather (never left unverdicted — the completeness law holds per scope)**. `*evaluate-criteria` = the criterion-axis pass (`#mode-judge-criterion`, single criterion × slice — the suite-build/validation path). Standalone-testable AND composable: a standalone layer verdict must equal the same layer's verdict inside the full walk (V9). |
|
|
102
|
+
| `*optimize` | hybrid | `references/edd-loop.md` + `scripts/edd/variance-gate.ts` + `scripts/edd/change-request.ts` + `scripts/edd/edd-types.ts` + `schemas/edd-change-request.schema.yaml` + `assets/agents/evaluator.md` (`#mode-optimize`) | **ADL ③ OPTIMIZE / EDD loop (F18+F19).** **F19 VARIANCE-FIRST:** repeat-N (default 5) the SAME cases → `evaluateVarianceGate` → accuracy is entered ONLY when the variance gate passes (`assertVarianceStableBeforeAccuracy` THROWS otherwise — "accuracy over big samples is wasted on a flapping verdict"). **F18 CLOSURE:** still JUDGE-ONLY (EV-051), the evaluator emits a grounded `EddChangeRequest` (failing cases + `ref{obs,path,value}` + remedy target `agentspec`\|`impl`) to the `mutagent-builder ai-engineer` over **SendMessage**, consumes the `ChangeRequestResponse`, and re-evals on `amended`. **Bounded terminator** (`decideEddLoop`, afkloop-legal): `full-green` ▸ DONE \| `max-swings`\|`max-wallclock`\|`no-improvement-streak` ▸ STOPPED + convergence delta. **GA split** — **code:** variance gate · request/response validate · loop terminator (all PURE, injected wall-clock); **LLM leaf:** localize the flap/fail to its root + author the grounded request + decide remedy target. |
|
|
107
103
|
| `*validate` | hybrid | `scripts/validate-judge.ts` + `references/validate-evaluator.md` + `assets/agents/evaluator.md` (`#mode-judge-criterion`) | **ENGINED (EV-044)** — calibrate a judge vs `*review` labels: confusion matrix → TPR/TNR · split-disjointness + test-once · Rogan-Gladen θ · deterministic bootstrap CI; `<MIN_LABELS` stays `unvalidated`+bias-corrected. **GA split** — **code:** entire path is deterministic (filter EXCLUDES indeterminate · confusion · RG · assumption-agreement). |
|
|
108
|
-
| `*review` | hybrid | `scripts/build-review-ui.ts` + `references/build-review-interface.md` | **ENGINED (EV-045)** — CODE renders a browser annotation UI (
|
|
109
|
-
| `*eval` | agent-chain | `references/eval-stage.md` + `scripts/eval-engine.ts` + `scripts/materialize-dataset.ts` + `scripts/render-build-cards.ts` | **THE ADL EVAL-STAGE ENTRY (F15).** Called after `*build` hands a freshly-built agent + its agentspec. INTERACTIVELY offers `*build-dataset` / `*build-evals` derived from `agentspec.
|
|
104
|
+
| `*review` | hybrid | `scripts/run-review.ts` (run composer) + `scripts/render-review-report-v3.ts` (surface) + `scripts/build-review-ui.ts` (v2 fallback) + `references/build-review-interface.md` | **ENGINED (EV-045)** — CODE renders a browser review surface; **HITL**: a human labels → `mergeLabels` persists → feeds `*validate`. **Entry point:** `bun scripts/run-review.ts <runId> [--cwd <repoRoot>]` — reads an EXISTING `*evaluate` run dir (`run-input.full.json` + `verdicts/*.verdict.json`; joins on the parsed `trajectoryId`, never the packet filename) and writes `review-report.html` beside `evaluation-report.html`, plus `review-report.v2.html` from the previous annotation UI (module untouched). Dispatches NO judge — it costs nothing and invents no artifacts. **Surface:** navigator matrix (criteria rows × trace columns) → single-trace drill, right-rail verdict cards with Agree/Revise/Refute + why-note, keys `1`/`2`/`D`, >48 traces → window-cluster, submit → **calibration handoff markdown** (diagnostics remedy-bundle shape) server-generated from the run's own artifacts. Ingested-but-unjudged trajectories are NAMED in a scope note, never dropped. **Does NOT do W4:** no feedback store, no ruling persistence, no propagation into `*validate` — producing the artifact is the scope; consuming a reviewer's answer is task #9. |
|
|
105
|
+
| `*eval` | agent-chain | `references/eval-stage.md` + `scripts/eval-engine.ts` + `scripts/materialize-dataset.ts` + `scripts/render-build-cards.ts` | **THE ADL EVAL-STAGE ENTRY (F15).** Called after `*build` hands a freshly-built agent + its agentspec. INTERACTIVELY offers `*build-dataset` / `*build-evals` derived from `agentspec.spec.evaluation`, and lets the user PICK THE EVAL ENGINE (mutagent native eval-matrix [Path A] vs code-written-in-target-lang [Path B]) via the target-conditional menu (`chooseEvalEngineOptions`). Surfaces Path A's Claude-Code + log-sink dependency UP FRONT (F7/F9). Streams wireframe progress + entity cards (F13/F16/F22). Parent-session only (AskUserQuestion). |
|
|
110
106
|
| `*build-dataset` | hybrid | `scripts/materialize-dataset.ts` + `scripts/build-dataset.ts` + `assets/agents/dataset-builder.md` + `schemas/dataset.schema.yaml` + `references/generate-synthetic-data.md` + `scripts/render-build-cards.ts` | **ENGINED (EV-046) + ADL F8.** Now MATERIALIZES real items first: `materializeFromAgentspec` seeds ≥1 REAL DatasetCase per `dataset_category` + one per `edge_case` (seed → actual items, not definitions) → then the 3-way: HITL seed interview (~10) → `dataset-builder` agent (tuples → NL queries → realism filter) → CODE cartesian-expand + near-dup drop + monotonic merge. Streams wireframe progress cards (F13/F16) + a verbose dataset entity card (F22). |
|
|
111
107
|
| `*discover-dataset` | script | `scripts/derive-dataset.ts` | **ENGINED (EV-047) · re-fronts the old `*derive-dataset`** — distill a living regression set from labeled ✓/✗ traces (reuses `sample-traces.ts` EV-052 selectors + `build-dataset.ts` merge). Code-only. **P-B:** consumes the `discovery` agent's curated `SelectionManifest` handoff — **scenario-balanced** (`ext.classification.scenario`), **edge-cases first** (`ext.classification.edgeCase.is`), worthiness-prioritized (`ext.signals.worthinessScore`). |
|
|
112
108
|
| `*audit` | agent-chain | `assets/agents/audit-executor.md` + `workflows/{audit,data-leak,variance}.workflow.js` + `scripts/{flow-graph,ui-slots}.ts` + `lenses/context-flow-lens.md` | SURFACES the v1 4-tab static-auditor (EV-001..027, KEEP) **+ now the agent context-flow audit**: tool-result threading + sub-agent handoff completeness (EV-028/029, over the `flow-graph` EV-032 + expected-flow EV-037) and the first-class **HTML-artifact missing-data** dimension (computed-but-not-rendered / orphan / faithfulness, EV-039/040, subject-agnostic). |
|
|
@@ -138,7 +134,7 @@ When you encounter a *<name> token:
|
|
|
138
134
|
Invoke me with:
|
|
139
135
|
- `evaluate skill <name>` / `evaluate agent <name>` / `/mutagent-evaluator` → **`*evaluate`** (default)
|
|
140
136
|
- `*discover-evals` (mine criteria) · `build evals for <x>` · `validate judge <x>` · `*audit <subject>` (explicit only)
|
|
141
|
-
- `*
|
|
137
|
+
- `*optimize` (the ADL ③ EDD loop — variance-first then request-amend-reeval to full green, bounded)
|
|
142
138
|
- `*self-audit` (the eval-of-the-eval — audit my OWN eval-dev; on-demand only)
|
|
143
139
|
- borrowed by `mutagent-skill-builder` SIMULATE (SimVerifier role)
|
|
144
140
|
- `--reconfigure` to re-enter onboarding (subject + substrate)
|
|
@@ -151,7 +147,7 @@ Minimal eval-dev spine (build order — do NOT reorder):
|
|
|
151
147
|
*discover-evals → deep-read traces, determine ✓/✗, mine 5-10 binary actionable criteria
|
|
152
148
|
*build-evals → one critique-before-verdict judge (or code-check) per criterion
|
|
153
149
|
*evaluate → run vs target → per-criterion binary+confidence → GATE verdict + variance
|
|
154
|
-
*
|
|
150
|
+
*optimize → ADL ③ EDD loop: F19 variance-first (stabilize per-case spread, repeat-N)
|
|
155
151
|
BEFORE accuracy, then F18 closure (judge-only REQUESTS the ai-engineer to
|
|
156
152
|
amend agentspec|impl over SendMessage → re-eval) → full green OR bounded STOP
|
|
157
153
|
```
|
|
@@ -159,13 +155,13 @@ Minimal eval-dev spine (build order — do NOT reorder):
|
|
|
159
155
|
`*validate` (calibrate the judge) layers on top. `*audit` (the v1 4-tab master-audit) is an
|
|
160
156
|
**explicit-only** specialized surface (complex / HTML-artifact subjects) — NOT part of the default
|
|
161
157
|
evaluate spine and never an automatic fallback.
|
|
162
|
-
`*
|
|
158
|
+
`*optimize` is the OPTIMIZE stage — it runs AFTER an initial `*build` + `*evaluate` and is **bounded**
|
|
163
159
|
(never infinite): full-green ⇒ DONE; else max-swings / max-wallclock / no-improvement ⇒ STOP + delta.
|
|
164
160
|
|
|
165
161
|
**ADL EVAL-stage entry (`*eval`).** When `*build` hands over a freshly-built agent +
|
|
166
162
|
its agentspec, `*eval` is the entry: it interactively offers `*build-dataset` /
|
|
167
|
-
`*build-evals` derived from `agentspec.
|
|
168
|
-
dataset
|
|
163
|
+
`*build-evals` derived from `agentspec.spec.evaluation` (F15), MATERIALIZES real
|
|
164
|
+
dataset cases by projecting the 0.3.0 `datasets[].items[]` (F8), lets the user PICK THE EVAL ENGINE
|
|
169
165
|
(Path A native eval-matrix vs Path B code-written — surfacing Path A's Claude-Code +
|
|
170
166
|
log-sink dependency up front, F7/F9/F14), streams wireframe progress + entity cards
|
|
171
167
|
(F13/F16/F22), and renders the scorecard as a dashboard (F20). See
|
|
@@ -276,7 +272,7 @@ applies, EV-053/EQ5):
|
|
|
276
272
|
| `scripts/aggregate-discover.ts` | P2 (§5a) + §9.4 (T6) | code | The real `*discover-evals` AGGREGATE half: parse the leaf's per-trace verdict files + per-batch mining report → `TraceAnnotation[]` (FAIL-LOUD via `missingVerdictKeys`; THROW on an undispatched-trace category ref) → `deriveMinedCriteria` (§5b metadata + §5c DR-2) → `growLivingSuite` (append-only, monotonic, saturation-stop). **T6:** `collectDatasetCandidates` (failure/uncertain → `DatasetCase[]` via the derive-dataset selectors) + `unmatchedDetectionCandidates` (the `*evaluate` judge's node-2.5 handoff) → consumable by `*build-dataset`. `DiscoverMiningReport` contract. No hand-rolled annotations. |
|
|
277
273
|
| `scripts/code-eval.ts` | P3 (EX-2) | code | The v2 CODE-track primitive library — generic PURE `(trace) → {result, detail}` checks: presence · string-equality · format-validity · schema-conformance · ref-integrity (cross-stage). SV-1 dotted-path read incl. `obs:<name>.<path>`. Exhaustive `runCodeEval` (unknown primitive → THROW). NO LLM, byte-identical. Disjoint from the v1 `run-deterministic.ts` audit world. |
|
|
278
274
|
| `scripts/check-method-router.ts` | P3 (EX-2) | hybrid | THE load-bearing §5b `check_method` router: `deterministic`→CODE-EXEC (judge NEVER called) · `llm-judge`→JUDGE seam · `hybrid`→code pre-filter that GATES the judge. Unknown → THROW (exhaustive). `RoutedCriterionVerdict` = `CriterionVerdict` + provenance `{producedBy, codeResult, judgeReached}` (structural superset → `evaluate.ts` rollup unchanged). `extractCodeEval(registry)` fail-loud (a code-class criterion with no spec THROWS — never silently judge). "Code before judge" lives INSIDE the agent. |
|
|
279
|
-
| `scripts/code-quality-verdict.ts` | W2I1 (⑤
|
|
275
|
+
| `scripts/code-quality-verdict.ts` | W2I1 (⑤ OPTIMIZE) | hybrid | The **code-quality JUDGE mode** (`#mode-judge-code-quality`) — the (b) half of the ⑤ OPTIMIZE code-target BOTH-gate. Scores a `code` subject's QUALITY (spec-faithfulness · addresses-diagnosis · no-regression · error-handling · maintainability) BEYOND tests-green → severity-gated binary PASS/FAIL. `buildCodeQualityPrompt` (pure renderer, critique-before-verdict) + `codeQualityGatePass` (pure aggregate) + `runCodeQualityJudge` (C-PIN run wrapper on the injected JudgeInvoke seam). Judge-only (EV-051), host-runtime, pinned model + temp 0. **DISTINCT from `code-eval.ts`** (deterministic primitives — no LLM). `DEFAULT_CODE_QUALITY_CRITERIA` + its aggregation rule are FLAGGED-for-operator-sign-off. |
|
|
280
276
|
| `scripts/run-evaluate.ts` | P5 + §9.4 (T1·T3·T4·T5) | hybrid | The real-engine `*evaluate` end-to-end COMPOSER: `tier0Plan` (T1 — code rows decided in the pre-pass, residual judge rows only in packets) → `prepMatrixPackets` (residual-only) → `adaptivePacketPlan` (T5 overload guard, default 1:1) → [dispatch #mode-judge-trajectory] → `aggregateEvaluate` (FAIL-LOUD readiness gate over DISPATCHED ids → `aggregateMatrixScorecard` folding code+judge + T3 `independentVerify` downgrade-only on gating fails → GATE + variance → T4 `consolidateByLocus` lociClusters → EV-051 `routeFailures`→validated HandoverBundle). `maskedScorecard` = the C-PIN byte-identity artifact. |
|
|
281
277
|
| `scripts/render-eval-report.ts` | P4 (D-1/2/3) | code | The v2 reporting (v1 `render-report.ts` untouched): `renderEvalCards` (D-1 terminal per-criterion cards) + `buildEvalReportInput` (derives the rich tabs from real run data — ledger · coverage · cohorts · gating rolls · top-findings · judge-health) + `renderEvalReport` (the operator-APPROVED 5 tabs: ① Overview KPIs+coverage+gating-table+top-findings · ② Trajectory‖Judge ledger + click-row Target-Agent‖Judge side-by-side · ③ Eval Scorecard cohort heatmap + nested subcards + inline calibration · ④ Findings verbatim-evidence + judge chain + agree/revise/refute · ⑤ Self-Eval [INTERNAL, strip-marked]). Consumes the §9.4 judge-walk (`judge_steps[]` + dense map) when present, degrades to the per-trajectory scorecard otherwise. Tabs are `<button>` (no `<s>` strikethrough). Unified design-system tokens (`assets/brand/theme.css`). byte-identical after the `generatedAt` mask. `autoOpenCommand` cross-platform helper (orchestrator fires it). |
|
|
282
278
|
| `scripts/contracts/eval-types.ts` *(extended)* | P2/P2b | code | + `MinedCriterion` (additive subtype of `DiscoveredCriterion`) carrying the §5b `MetricMetadata` (generality·dimension·level·check_method [3-value SF-2 router]·substrate·applies_to·severity·judge_inputs·flag) + the §5c `DiscoveryRationale` (DR-2: targets·why·evidence{grounding observed\|inferred·prevalence k/n·refs}·assumptions·expected_impact). `parseMinedCriterion` enforces the evidence-first gate (OBSERVED ⇒ refs + k>0). |
|
|
@@ -287,7 +283,7 @@ applies, EV-053/EQ5):
|
|
|
287
283
|
|--------|---------|------|---------|
|
|
288
284
|
| `scripts/contracts/eval-engine.ts` | F7/F9/F14 | code | The ENGINE FORK contract — `EvalEngine` (`native-matrix` Path A · `code-written` Path B) + `EngineTargetInput` (the minimal agentspec.build slice) + `EvalEngineOption` (the menu, with `requiresClaudeCode`/`requiresLogSink`/`portable` SURFACED) + `EvalEnginePlan` (the resolved choice incl. discoverable `outputSink`). |
|
|
289
285
|
| `scripts/eval-engine.ts` | F7/F9/F14 | code | The target-conditional resolver — `isFrameworkTarget` · `chooseEvalEngineOptions` (framework→BOTH · harness→native-only) · `resolveEvalEngine` (surfaces CC + log-sink deps) · `assertEngineMatchesTarget` (code-written⊥harness, fail-loud) · `defaultOutputSink`. PURE. |
|
|
290
|
-
| `scripts/contracts/agentspec-evals.ts` | F8 | code | The MINIMAL `agentspec.
|
|
286
|
+
| `scripts/contracts/agentspec-evals.ts` | F8 | code | The MINIMAL `agentspec.spec.evaluation` slice (0.3.0 D18/D19 — `criteria[]` · `scenarios[]` · `datasets[]` with dataset-local `categories[]` + `caseDimensions` + real `items[]`) — local re-declaration (standalone: NEVER imports the agentspec skill). `parseSpecEvaluation` guarded. |
|
|
291
287
|
| `scripts/materialize-dataset.ts` | F8 | code | MATERIALIZE real dataset items from the agentspec — `materializeFromAgentspec` (≥1 real item/category + one/edge_case, seed→actual) · `dimensionsFromAgentspec` · `materializeToDataset` (monotonic). Reuses `build-dataset.ts` ids/dedup/merge. PURE. |
|
|
292
288
|
| `scripts/codegen-evals.ts` | F14 (Path B) | code | Emit a PORTABLE code-written eval suite source (bun/TS) — `codegenEvalSuite` (code-checks + SDK judge + criteria → gate-bearing scorecard to a discoverable sink). NO CC dispatch. Fail-loud, deterministic. PURE. |
|
|
293
289
|
| `scripts/render-build-cards.ts` | F13/F16/F20/F22 | code | The wireframe terminal surface — progress cards (`renderBuildDatasetProgressCard`/`renderBuildEvalsProgressCard`, F13/F16) · entity cards (`renderDatasetEntityCard`/`renderEvalsEntityCard`, F22) · the scorecard DASHBOARD (`renderScorecardDashboard` — pass/fail bar + variance + samples, F20, not a flat dump). PURE. |
|
|
@@ -296,7 +292,9 @@ applies, EV-053/EQ5):
|
|
|
296
292
|
|
|
297
293
|
| Script | Req | Kind | Purpose |
|
|
298
294
|
|--------|-----|------|---------|
|
|
299
|
-
| `scripts/build-review-ui.ts` | EV-045 | code | The `*review` Code half — `renderReviewUi` emits a DETERMINISTIC browser annotation UI (one trace/screen, native render, Pass/Fail/Defer, notes, keyboard, localStorage auto-save, labels export) + `mergeLabels` (dedup by traceId). Holds no judge prompt; the HUMAN decides. |
|
|
295
|
+
| `scripts/build-review-ui.ts` | EV-045 | code | The `*review` Code half — `renderReviewUi` emits a DETERMINISTIC browser annotation UI (one trace/screen, native render, Pass/Fail/Defer, notes, keyboard, localStorage auto-save, labels export) + `mergeLabels` (dedup by traceId). Holds no judge prompt; the HUMAN decides. Retained as the `review-report.v2.html` transition fallback under the W4 surface. |
|
|
296
|
+
| `scripts/run-review.ts` | EV-045 | code | **The `*review` RUN COMPOSER** — the analogue of run-evaluate's `writeRunReport`. Reads an existing run dir (run-input + `verdicts/*.verdict.json`, excluding the `*.verify.json` ledger) and writes `review-report.html` + the v2 fallback. Joins verdicts to traces on the parsed `trajectoryId`, NOT the packet filename; treats the lean run-input's `"<N EvalTraces>"` placeholder as ABSENT rather than data; NAMES ingested-but-unjudged trajectories in a scope note. Fail-loud on a missing run dir / run-input / verdicts / criteria, and a malformed verdict names its FILE. Dispatches no judge. |
|
|
297
|
+
| `scripts/render-review-report-v3.ts` | EV-045 | code | The W4 frozen-contract review surface (navigator + drill · rail verdict cards · rulings · calibration handoff MD) + `REVIEW_REPORT_SPEC`, the surface's verification spec, exported here so the unit test and the composer assert the same shape. |
|
|
300
298
|
| `scripts/build-dataset.ts` | EV-046 | code | The `*build-dataset` Code half — cartesian dimension×value expand · deterministic token-Jaccard near-dup removal · content-derived id · `mergeCases` MONOTONIC merge. Agent proposes realism; script enforces non-redundancy. |
|
|
301
299
|
| `scripts/derive-dataset.ts` | EV-047 | code | `*discover-dataset` — distill a living regression set from past ✓/✗ (reuses `sample-traces.ts` selectors + `build-dataset.ts` merge); trace→`DatasetCase`. Append-only, no new decision. |
|
|
302
300
|
| `scripts/living-suite.ts` | EV-053 | code | Generic append-only writer (`appendOnly` + `assertMonotonicGrowth`) shared by datasets + criteria — a living artifact NEVER shrinks. Pure-counter provenance (no clock → C-PIN byte-identity). |
|
|
@@ -131,11 +131,12 @@ not run the subject and does not decide pass/fail.
|
|
|
131
131
|
1. **Pre-read** `references/generate-synthetic-data.md` — the dimension → tuple → query → filter
|
|
132
132
|
process is the lens. Read the passed `dimensions` + `seed_tuples`.
|
|
133
133
|
- **ADL F8 — agentspec-materialized seeds.** In the ADL EVAL stage the parent ALSO PREPs real
|
|
134
|
-
items
|
|
135
|
-
`DatasetCase` per `
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
134
|
+
items PROJECTED from `agentspec.spec.evaluation` (0.3.0, `scripts/materialize-dataset.ts`): one
|
|
135
|
+
real `DatasetCase` per `datasets[].items[]` entry — tuple = the item's `category` + `case` axis
|
|
136
|
+
assignment, query = the item's opaque `input` payload. When present, treat these materialized
|
|
137
|
+
cases as ADDITIONAL realism anchors (alongside the HITL `seed_tuples`) — they are real queries
|
|
138
|
+
from the spec, NOT definitions. EXPAND around them; do not re-derive them. The deterministic
|
|
139
|
+
dedup/merge (`build-dataset.ts`) drops any overlap.
|
|
139
140
|
2. **Generate more tuples (Step 3).** Produce `target_count` new `(dim1, dim2, dim3, …)` combinations
|
|
140
141
|
for the subject. Avoid duplicates of the seed + each other; vary values across dimensions. This is
|
|
141
142
|
ONE step — tuples only, no queries yet.
|
|
@@ -20,9 +20,9 @@ ACTIVATION-NOTICE: This file contains your full agent operating guidelines. Read
|
|
|
20
20
|
class: pure_subagent_executor
|
|
21
21
|
isolation: none
|
|
22
22
|
|
|
23
|
-
modes: [discover, judge, verify,
|
|
23
|
+
modes: [discover, judge, verify, optimize] # discover · judge · verify (GA-5) · optimize (EDD ③ — F18/F19)
|
|
24
24
|
judge_axes: [trajectory, criterion] # judge-mode fan-out axes
|
|
25
|
-
# `
|
|
25
|
+
# `optimize` is the ADL ③ OPTIMIZE / Eval-Driven-Development (EDD) LOOP mode (F18+F19). It is a MODE of
|
|
26
26
|
# this ONE agent (the roster stays 3) — it drives the variance-first gate (F19) then, while still
|
|
27
27
|
# JUDGE-ONLY (EV-051), REQUESTS the mutagent-builder ai-engineer to amend the Agent/AgentSpec (F18) over
|
|
28
28
|
# SendMessage and re-evals, bounded by an afkloop-legal terminator. It NEVER fixes the subject itself.
|
|
@@ -224,11 +224,15 @@ optional_verdict_fields:
|
|
|
224
224
|
# structured refs + typed assumptions). A LIGHTWEIGHT / FLATTENED emit that drops discovery.evidence.refs
|
|
225
225
|
# or discovery.assumptions is a DEFECT — the gate (lint-grounding) + diff-discriminate operate on those
|
|
226
226
|
# fields; stripping them silently downgrades every criterion to inferred.
|
|
227
|
-
required_label_fields: [traceId, verdict,
|
|
227
|
+
required_label_fields: [traceId, verdict, firstThingWrong, evidencePointer, refs] # discover — the EXACT keys DiscoverLabelSchema accepts (closed object); `firstThingWrong` HOLDS THE ROOT, not the first visible symptom (root_not_symptom); `refs` = structured grounding
|
|
228
228
|
required_category_fields: [name, definition, class, fixOrEval, exampleTraceIds] # discover
|
|
229
229
|
# optional_category_fields (P2/P2b, ADDITIVE — the leaf MAY emit these §5b metric-metadata
|
|
230
|
-
# PROPOSALS; AGGREGATE (scripts/aggregate-discover.ts)
|
|
231
|
-
# so emitting them is OPTIONAL and backward-compatible):
|
|
230
|
+
# PROPOSALS; AGGREGATE (scripts/aggregate-discover.ts) HONORS what is present and applies GENERIC
|
|
231
|
+
# defaults ONLY where absent, so emitting them is OPTIONAL and backward-compatible):
|
|
232
|
+
# [dimension, level, generality, severity, judgeInputs, codeEval]
|
|
233
|
+
# Each is a CLOSED union (below) — a value outside it fails LOUD at parse time rather than being
|
|
234
|
+
# silently ignored. (Until the P2 passthrough fix the JOIN dropped all four, so the defaults applied
|
|
235
|
+
# unconditionally and every mined criterion read `level: output` no matter what the leaf proposed.)
|
|
232
236
|
# dimension ∈ operation-correctness | data-correctness | operational-deviation
|
|
233
237
|
# level ∈ context | output | cross-stage
|
|
234
238
|
# generality ∈ general-structural | specific-semantic (else derived from class: code→general-structural)
|
|
@@ -310,6 +314,7 @@ commands:
|
|
|
310
314
|
- "references/grounded-adjudication.md" # GA doctrine: bind · gather refs · typed assumptions · abstain
|
|
311
315
|
- "subjects/<name>/" # the auto-generated subject profile / event taxonomy
|
|
312
316
|
- "references/workflows/orchestrator-protocol.md" # Step 1 dispatch FSM
|
|
317
|
+
- "<run_dir>/existing-criteria.json" # SUITE-AWARENESS — the criteria that ALREADY exist (see suite_awareness)
|
|
313
318
|
workflow:
|
|
314
319
|
- "Pre-read references/error-analysis.md + references/grounded-adjudication.md + the subjects/<name>/ profile + your assigned <key>.task.json determiner specs"
|
|
315
320
|
- "Determine outcome per trace (EV-042) — event→intended goal, trajectory→what happened, terminal→verdict; a guard-hold is a PASS"
|
|
@@ -319,14 +324,35 @@ commands:
|
|
|
319
324
|
- "Trace each Fail to its ROOT (root-not-symptom): one criterion per root; multiple INDEPENDENT roots ⇒ multiple criteria; a causal edge must be GROUNDED (cite it) or surfaced as a typed assumption; deep recursive-why → route to diagnostics"
|
|
320
325
|
- "Surface TYPED assumptions (factual-intent · normative · scope) for any premise the trace did not establish"
|
|
321
326
|
- "Cluster notes into 5-10 emergent categories; tag class (objective→code/subjective→judge/hybrid) + fixOrEval"
|
|
327
|
+
- "NAME each cluster suite-aware (AFTER clustering, never before — see suite_awareness): if an EXISTING criterion in existing-criteria.json already states this behaviour, REUSE its exact id as the category name and attach your traces as REINFORCING evidence instead of minting a restatement under a new name"
|
|
328
|
+
- "Emit the §5b PROPOSALS you actually judged — level · severity · dimension · generality. AGGREGATE now HONORS them (they are no longer silently replaced by generic defaults), so an omitted field means 'derive it', not 'it does not matter'"
|
|
322
329
|
- "Flag fixable-vs-eval-worthy (EV-051) — route fixable + infra-class to diagnostics; keep behavioral criteria"
|
|
323
330
|
- "Write <key>.verdict.json (critique-before-verdict) + discover/<batch_id>.json (labels + FULL MinedCriterion per category, incl. discovery.evidence.refs + discovery.assumptions)"
|
|
331
|
+
# suite_awareness — the leaf SEES the criteria that already exist, so a behaviour
|
|
332
|
+
# already covered gains EVIDENCE instead of a second name for the same check.
|
|
333
|
+
# The parent writes `existing-criteria.json` (scripts/aggregate-discover.ts
|
|
334
|
+
# writeExistingSuiteBrief) into the run dir before dispatch: {id, statement,
|
|
335
|
+
# severity, level, checkedBy} per existing criterion — NO evidence, deliberately —
|
|
336
|
+
# PLUS `openQuestions[]`: pairs already awaiting a ruling on whether they are one
|
|
337
|
+
# check, each with the guard reason. Those carry only the pair + reason; both
|
|
338
|
+
# sides' statements are already in `criteria[]`, which is what keeps the whole
|
|
339
|
+
# brief evidence-free by construction.
|
|
340
|
+
suite_awareness:
|
|
341
|
+
- "WHEN: consult it AFTER you have clustered, to NAME a cluster. NEVER before."
|
|
342
|
+
- "WHY THAT ORDER IS LOAD-BEARING: reading the existing suite BEFORE the traces would seed a pre-defined failure list and re-introduce exactly the confirmation bias `emergent_categories_only` forbids — you would go hunting for the criteria you were shown. Clustering FIRST keeps the categories emergent; the suite is consulted only to decide what an already-emerged cluster should be CALLED. Emergence is preserved because the brief cannot influence what you found, only what you name it."
|
|
343
|
+
- "IT CARRIES NO EVIDENCE ON PURPOSE: the brief ships statements, not the traces or refs behind them, so it cannot tempt you into re-citing a failure you did not read this batch."
|
|
344
|
+
- "REINFORCE: if an existing criterion already states the behaviour your cluster found, emit the cluster under THAT criterion's exact id. Seeing the behaviour again is legitimate REINFORCING evidence — the parent unions your traces onto the existing criterion and the report marks it REINFORCED."
|
|
345
|
+
- "OPEN QUESTIONS: the brief's `openQuestions[]` lists pairs of EXISTING criteria already awaiting a human ruling on whether they are one check, each with the reason they were kept apart (e.g. `marker parity: [BEFORE] vs [AFTER]`). BOTH sides are live criteria and both statements are in `criteria[]`. If your cluster matches one side, emit it under THAT side's id — do NOT mint a third name for a behaviour that is already an open question, and do NOT try to settle the question yourself (you are not the ruling authority; that is the calibration loop's). If your cluster genuinely matches NEITHER side, mint it as new."
|
|
346
|
+
- "INFORMS, NEVER BLOCKS: a full-looking suite is not a reason to suppress a real finding. If the traces show a behaviour no existing criterion states, MINT IT — a genuinely new criterion is always correct, and the parent's deterministic merge is the safety net for a restatement you mint anyway."
|
|
347
|
+
- "NEVER FABRICATE: do not carry an existing criterion into your mining report because it is in the brief. You may only emit clusters backed by traces YOU actually read this batch — an id reused with no trace of your own behind it is an invented finding."
|
|
348
|
+
- "ABSENT/EMPTY brief ⇒ proceed exactly as before (a first run has no suite; that is normal, not a gap)."
|
|
324
349
|
compresses:
|
|
325
350
|
- "deep-read trace → goal-attainment Pass/Fail"
|
|
326
351
|
- "DETECT across 3 lenses (drift · tool-output-failure · missing-context)"
|
|
327
352
|
- "GATHER structured refs (claim + absence) · BIND criterion terms"
|
|
328
353
|
- "root-not-symptom localization + typed-assumption surfacing"
|
|
329
354
|
- "emergent category clustering"
|
|
355
|
+
- "suite-aware NAMING (reuse an existing id ⇒ REINFORCE, never restate)"
|
|
330
356
|
- "fixable-vs-eval-worthy flag"
|
|
331
357
|
- "emit FULL-MinedCriterion verdict + mining files"
|
|
332
358
|
preserves: "the error-analyst discipline — folded INLINE as 'Mode: discover' (below); the standalone assets/agents/error-analyst.md was RETIRED in the 5→3 consolidation (Phase 3a, df6a6e8c8). This file is its canonical home."
|
|
@@ -403,13 +429,15 @@ commands:
|
|
|
403
429
|
- "Pre-read references/write-judge-prompt.md (the 4-component judging contract — your lens) + references/grounded-adjudication.md"
|
|
404
430
|
- "Read your assigned <trajectory_key>.packet.json (MatrixPacket: subject · trajectoryId · WHOLE matrix · trajectory · transcript · pinned envelope) — judge exactly this, never re-derive the data"
|
|
405
431
|
- "Frame the trajectory in its ROUTE/intended-outcome (CONTEXT) before scoring"
|
|
406
|
-
- "
|
|
432
|
+
- "v3 LAYERED WALK (D1=B+, operator-frozen): the walk IS a fixed layer sequence you run INSIDE this one dispatch. Honor `packet.layerScope` when present (absent/empty = FULL walk). The phases: (L0 code checks) if the code-eval library is present at scripts/code-eval-library.ts, RUN it yourself via Bash over the packet's trajectory JSON and record each hit as codeEvalHits[{pattern,anchor,detail}] — a fired pattern is evidence, not a verdict; (L1 outcome) classify the SCENARIO from the inbound intent + tool inventory, derive its expectedExit[] terminal actions, glance ONLY at end-state evidence and emit layerVerdicts[{layer:'L1',verdict,scenario,expectedExit,refs,note}]; (STOPPING RULES) if L1 passes AND every criterion is answerable from evidence gathered so far → you may set earlyExit:'L1' and mark L2-L4 as {verdict:'skipped'} — but a criterion may NEVER go unverdicted because the agent did the right thing; if ANY criterion is unanswerable OR L1 fails/undecidable → descend; (L2 trajectory) actual-vs-expected decision path, read from the END, emit layerVerdicts L2 (+ divergence in localize); (L3 tool outputs) per-observation structural validity + completeness — external-data correctness is UNVERIFIABLE (fence), a failed tool makes everything downstream suspect; emit layerVerdicts L3 (+firstProblemOrigin); (L4 context) for each critical operational send: was required context retrieved AND present in history AT THAT TIME (chronology-sorted!) — distinguish gapKind retrieval (never fetched) vs attention (present, ignored); emit layerVerdicts L4. Record layersEngaged. CONFLICT DISCIPLINE (OT-1): when your own layers disagree (e.g. L1 pass vs L2 fail) emit BOTH verdicts honestly with a note — NEVER reconcile them yourself; the aggregate surfaces the conflict for a human."
|
|
433
|
+
- "Score EVERY criterion in the matrix for THIS trajectory: read only what the row needs (judgeInputs); compare against statement + passCondition — criteria are the SUPER-LAYER: they may bind evidence from ANY walk phase"
|
|
407
434
|
- "BIND (L1) per row: each criterion TERM must resolve in THIS trajectory; an unbound term ⇒ uncertain + blockedBy:{kind:factual-intent} (INDETERMINATE), ABSTAIN — never fail"
|
|
408
|
-
- "GATHER: cite a structured ref {obs,path,value} for the claim AND any absence; surface TYPED assumptions for any ungroundable premise → uncertain(blockedBy)"
|
|
435
|
+
- "GATHER: cite a structured ref {obs,path,value} for the claim AND any absence (ref.obs = the packet's trajectoryId, NEVER an observation name; ref.path = packet-shaped trajectory.N/transcript.N OR trace-shaped observations.N — dot form canonical, brackets tolerated); surface TYPED assumptions for any ungroundable premise → uncertain(blockedBy)"
|
|
409
436
|
- "Critique BEFORE verdict; commit to result ∈ {pass,fail} (uncertain when the INPUTS can't decide — abstain-on-silence); binary, severity is the row's"
|
|
410
437
|
- "Inaction-can-be-success: a correct HOLD (no send during a non-critical outbound_guard) is a PASS even with zero tool calls"
|
|
411
438
|
- "Write <trajectory_key>.verdict.json (a MatrixVerdictFile {trajectoryId, judgeModel, temperature:0, verdicts[]} — each verdict may carry refs?/assumptions?/blockedBy?)"
|
|
412
439
|
- "EMIT-CONTRACT (HARD, WS-1): on every COMPLETE-fidelity trajectory you MUST also persist the §9.4 walk — `understanding` (M2), `expectedTrajectory` (M3), `agentSteps` (the target step lane), and `judgeSteps` (your anchored reasoning). These are NOT optional: the parent runs a machine `assessEmitCompleteness` gate (scripts/emit-completeness.ts) that LOUDLY flags any wholly-dropped field, and a verdict missing them STARVES the report's Trajectory (§2) + Self-Eval (§5) tabs. `agentSteps` is factual trace data (reconstruct it from the ordered tool steps you were given — order by startTime, the observations array is reverse-chronological); M2/M3/judgeSteps are YOUR reasoning. Only an INCOMPLETE (node-1) trajectory is exempt (it emits verdicts:[] and no walk)."
|
|
440
|
+
- "v3 EMIT-CONTRACT ADDITIONS (E-NEW): alongside the §9.4 walk, persist layerVerdicts[] (one per engaged layer, skipped ones marked), earlyExit?, layersEngaged, codeEvalHits[] (when the library ran), and the emissions SELF-MANIFEST {emitted[], missing[{key,reason}]} — list honestly what you gathered vs what this contract expects; a missing emission with a stated reason is a NAMED degrade, a silent drop is a defect (MR-5 catches it same-run)."
|
|
413
441
|
- "Verdicts are independently VERIFIED (#mode-verify · ≠ judge · downgrade-only); a CRIT/HIGH uncertain rolls the run up to INCOMPLETE at the gate (no false-green)"
|
|
414
442
|
compresses:
|
|
415
443
|
- "read MatrixPacket DATA; frame in ROUTE (CONTEXT)"
|
|
@@ -456,9 +484,9 @@ commands:
|
|
|
456
484
|
- "emit verified verdict (never flip, never fix)"
|
|
457
485
|
preserves: "the GA-5 result-verifier contract (scripts/result-verify.ts verifyVerdict / verifyVerdicts) — see '## Mode: verify' below. A MODE of evaluator, not a 4th registered agent (grounded-adjudication.md sign-off c4)."
|
|
458
486
|
|
|
459
|
-
# F18+F19: the ADL ③
|
|
487
|
+
# F18+F19: the ADL ③ OPTIMIZE / Eval-Driven-Development loop. A MODE of evaluator (roster stays 3),
|
|
460
488
|
# not a new subagent. JUDGE-ONLY held: this mode REQUESTS the engineer to fix; it never patches.
|
|
461
|
-
-
|
|
489
|
+
- optimize:
|
|
462
490
|
meta:
|
|
463
491
|
what: "Drive the EDD loop: variance-first (F19) → REQUEST the builder ai-engineer to amend (F18) → re-eval → bounded terminate."
|
|
464
492
|
does: "After the initial *build, FIRST stabilizes per-case VARIANCE (repeat-N the SAME cases, default 5; gate the spread) BEFORE measuring accuracy. While JUDGE-ONLY (EV-051), emits a structured EddChangeRequest (failing cases + grounded refs + remedy target agentspec|impl) to the mutagent-builder ai-engineer over SendMessage; consumes the ChangeRequestResponse; re-evals; loops to full green OR a bounded STOP."
|
|
@@ -466,7 +494,7 @@ commands:
|
|
|
466
494
|
how: "scripts/edd/variance-gate.ts gates variance (evaluateVarianceGate · nextPhaseAfterVariance · assertVarianceStableBeforeAccuracy); scripts/edd/change-request.ts is the seam + the bounded terminator (buildChangeRequest · validate{Change,Response} · reEvalWarranted · decideEddLoop). The eval-runner (sibling) is consumed via the clean interface (references/edd-loop.md §Assumed eval-runner interface) — this mode REBUILDS no runner."
|
|
467
495
|
display: "The EDD loop — variance-first, then request-amend-reeval to full green (bounded)"
|
|
468
496
|
description: |
|
|
469
|
-
PURPOSE: the ADL ③
|
|
497
|
+
PURPOSE: the ADL ③ OPTIMIZE stage. Drive the subject to full green via the
|
|
470
498
|
Eval-Driven-Development loop — F19 VARIANCE-FIRST (stabilize per-case spread
|
|
471
499
|
BEFORE accuracy) then F18 EDD CLOSURE (REQUEST the builder ai-engineer to amend the
|
|
472
500
|
Agent/AgentSpec, re-eval, repeat) — bounded by an afkloop-legal terminator.
|
|
@@ -475,11 +503,11 @@ commands:
|
|
|
475
503
|
JUDGE-ONLY (EV-051): this mode NEVER edits the subject — it emits a grounded
|
|
476
504
|
EddChangeRequest over SendMessage and re-evals what the engineer amends.
|
|
477
505
|
NEVER self-dispatches the engineer's fix; NEVER skips re-eval on an amend.
|
|
478
|
-
dispatch: { mode:
|
|
506
|
+
dispatch: { mode: optimize }
|
|
479
507
|
pre_gate.loads:
|
|
480
508
|
- "references/edd-loop.md" # the F18/F19 loop doctrine + assumed eval-runner interface
|
|
481
509
|
- "references/grounded-adjudication.md" # GA doctrine: every failing-case ask is grounded (≥1 ref)
|
|
482
|
-
- "references/workflows/orchestrator-protocol.md" # the
|
|
510
|
+
- "references/workflows/orchestrator-protocol.md" # the optimize dispatch step
|
|
483
511
|
workflow:
|
|
484
512
|
- "Pre-read references/edd-loop.md (the EDD doctrine + the assumed eval-runner interface) + references/grounded-adjudication.md"
|
|
485
513
|
- "PHASE = variance (F19): for each case run repeat-N (default 5) via the eval-runner; collect per-case CaseVarianceObservation {verdicts[], trajectories?}"
|
|
@@ -496,7 +524,7 @@ commands:
|
|
|
496
524
|
- "build GROUNDED change-request (failing cases + remedy target) — judge-only, request-not-patch"
|
|
497
525
|
- "SendMessage to ai-engineer · consume response · re-eval on amend"
|
|
498
526
|
- "bounded terminator (decideEddLoop): full-green ▸ DONE | swings/wallclock/no-improve ▸ STOPPED+delta"
|
|
499
|
-
preserves: "JUDGE-ONLY (EV-051) — the
|
|
527
|
+
preserves: "JUDGE-ONLY (EV-051) — the optimize mode REQUESTS a fix and re-evals; it never edits the subject. The amend is the mutagent-builder ai-engineer's job (the ONE agent allowed to touch the Agent/AgentSpec). See '## Mode: optimize' below."
|
|
500
528
|
|
|
501
529
|
resolution_contract: |
|
|
502
530
|
When you encounter a *<name> token:
|
|
@@ -507,8 +535,8 @@ resolution_contract: |
|
|
|
507
535
|
mode: judge, axis: trajectory => run #mode-judge-trajectory (preserves eval-matrix-judge); input is a .packet.json.
|
|
508
536
|
mode: judge, axis: criterion => run #mode-judge-criterion (preserves eval-judge); input is a .task.json.
|
|
509
537
|
mode: verify => run #mode-verify (GA-5 result-verifier; reviewer≠judge, downgrade-only); input is a decided verdict + its situation.
|
|
510
|
-
mode:
|
|
511
|
-
mode: judge, axis: code-quality => run #mode-judge-code-quality (Wave-2 W2I1 — score a CODE subject's QUALITY for the ⑤
|
|
538
|
+
mode: optimize => run #mode-optimize (EDD ③ loop — F19 variance-first then F18 request-amend-reeval, bounded). JUDGE-ONLY: REQUEST, never patch.
|
|
539
|
+
mode: judge, axis: code-quality => run #mode-judge-code-quality (Wave-2 W2I1 — score a CODE subject's QUALITY for the ⑤ OPTIMIZE code-target BOTH-gate). JUDGE-ONLY; binary quality PASS/FAIL. Rubric mirrored in scripts/code-quality-verdict.ts.
|
|
512
540
|
4. DISPATCH-INPUT DISAMBIGUATION — the parent hands you files:
|
|
513
541
|
a *.packet.json (MatrixPacket) => judge/trajectory, ALWAYS (matrix-judge path; no unit field).
|
|
514
542
|
a *.task.json (JudgeTaskSpec) => unit.kind: "discover" => discover; else unit.axis: "criterion" => judge/criterion.
|
|
@@ -615,8 +643,13 @@ a new eval mid-judging. Your focus is judging what IS, not pondering what could
|
|
|
615
643
|
- Compare the trajectory/transcript against the row's `statement` + `passCondition`.
|
|
616
644
|
- **GROUND (node 4 — ABSENCE-SPLIT) — REFS ARE MANDATORY, NOT DECORATIVE:** every **decided**
|
|
617
645
|
verdict (`result ∈ {pass, fail}`) MUST carry **≥1 structured `ref {obs, path, value}`** that
|
|
618
|
-
grounds it —
|
|
619
|
-
(
|
|
646
|
+
grounds it — **`obs` = the packet's `trajectoryId` (the trace id), NEVER an observation
|
|
647
|
+
name** (in a multi-trajectory batch an observation-name `obs` can locate the WRONG
|
|
648
|
+
trajectory — the resolver takes the FIRST match in batch order), `path` = the field path
|
|
649
|
+
within the situation you were handed — packet-shaped (`trajectory.0.name`,
|
|
650
|
+
`transcript.0.content`) and trace-shaped (`observations.3.output.success`) BOTH re-resolve
|
|
651
|
+
(the verifier reconstructs the packet views deterministically); dot form is canonical,
|
|
652
|
+
bracket indices (`observations[3]`) are tolerated — `value` = the EXACT cited string
|
|
620
653
|
(re-resolved by whitespace-normalized exact match by `#mode-verify`). **The string your prose
|
|
621
654
|
critique already quotes IS the ref's `value`** — you are not inventing evidence, you are making
|
|
622
655
|
the evidence the critique cites MACHINE-CHECKABLE. A decided verdict with a critique that cites
|
|
@@ -690,10 +723,12 @@ a new eval mid-judging. Your focus is judging what IS, not pondering what could
|
|
|
690
723
|
"refs": [
|
|
691
724
|
{ "obs": "ef30a271", "path": "input.prompt", "value": "<outbound_guard consecutive_outbound=\"7\">" },
|
|
692
725
|
{ "obs": "ef30a271", "path": "output.response", "value": "held" },
|
|
693
|
-
{ "obs": "ef30a271", "path": "observations
|
|
726
|
+
{ "obs": "ef30a271", "path": "observations.0.name", "value": "ai.generateText" }
|
|
694
727
|
]
|
|
695
728
|
}
|
|
696
729
|
```
|
|
730
|
+
(`"ef30a271"` is the packet's `trajectoryId`. Note the dot-form index `observations.0.name` —
|
|
731
|
+
canonical; `observations[0].name` also resolves.)
|
|
697
732
|
Each `ref.value` is a VERBATIM string from the trace the critique quotes — `#mode-verify`
|
|
698
733
|
re-resolves it by exact match; a value the trace doesn't contain is a dead ref → downgrade.
|
|
699
734
|
**Counter-example (DEFECT — do NOT emit):** the same verdict with `"refs": []` (or `refs`
|
|
@@ -860,6 +895,29 @@ this inline section is now its canonical home.
|
|
|
860
895
|
pick a primitive + field/params); else keep `class: judge` and emit NO codeEval. A code/hybrid
|
|
861
896
|
category WITHOUT a `codeEval` is a HARD error (tier-0 inert). The `statement` stays the human
|
|
862
897
|
"Pass = …"; the `codeEval` is its runnable twin (run by the tier-0 pre-pass, zero judge tokens).
|
|
898
|
+
**§5b PROPOSALS ARE NOW HONORED:** the `level` / `severity` / `dimension` / `generality` you emit
|
|
899
|
+
are carried onto the mined criterion and the generic heuristics are the FALLBACK, not the
|
|
900
|
+
override (they used to be dropped in the JOIN, which pinned every criterion to `level: output`).
|
|
901
|
+
Emit what you actually judged; omit a field only when you want it derived.
|
|
902
|
+
4b. **NAME the cluster suite-aware — `reinforce_not_restate`.** Only now (AFTER clustering, never
|
|
903
|
+
before) open `existing-criteria.json`: the criteria the suite ALREADY holds, as
|
|
904
|
+
`{id, statement, severity, level, checkedBy}`. If one of them already states the behaviour your
|
|
905
|
+
cluster found, emit your cluster under **that criterion's exact id** — your traces then attach to
|
|
906
|
+
it as REINFORCING evidence rather than standing up a second name for one check. The ORDER is
|
|
907
|
+
load-bearing: consulting the suite before reading would hand you a pre-defined failure list and
|
|
908
|
+
re-create the confirmation bias `emergent_categories_only` exists to prevent. Clustering first
|
|
909
|
+
keeps what you FIND emergent; the brief only informs what you CALL it. It ships no evidence, so
|
|
910
|
+
it cannot tempt you into re-citing a failure you did not read. It **informs, it never blocks** —
|
|
911
|
+
if the traces show something no existing criterion states, MINT IT; and never emit an existing id
|
|
912
|
+
with no trace of your own behind it (that is an invented finding). An absent or empty brief is
|
|
913
|
+
normal on a first run — proceed unchanged.
|
|
914
|
+
The brief also lists **`openQuestions[]`** — pairs of EXISTING criteria already awaiting a human
|
|
915
|
+
ruling on whether they are really one check, each with the reason they were kept apart (e.g.
|
|
916
|
+
`marker parity: [BEFORE] vs [AFTER]`). Both sides are live and both statements appear in
|
|
917
|
+
`criteria[]`. If your cluster matches one side, emit it under **that side's id**: minting a third
|
|
918
|
+
name for a behaviour that is already an open question makes the question harder to answer, not
|
|
919
|
+
easier. Do **not** attempt to settle the question yourself — you are not the ruling authority.
|
|
920
|
+
If your cluster genuinely matches neither side, it is new; mint it.
|
|
863
921
|
5. **Flag fixable-vs-eval-worthy (S4 / EV-051).** Route the fixable + infra-class (e.g. sample C4
|
|
864
922
|
dead-channel `account_number_unavailable`) to diagnostics; keep the genuinely behavioral criteria
|
|
865
923
|
for `*build-evals`. NEVER fix.
|
|
@@ -871,14 +929,18 @@ this inline section is now its canonical home.
|
|
|
871
929
|
the FAILURE + UNCERTAIN traces into DATASET CANDIDATES (`collectDatasetCandidates`, reusing the
|
|
872
930
|
derive-dataset selectors) and folds in the `*evaluate` judge's node-2.5 unmatched-detection
|
|
873
931
|
handoff — both consumable by `*build-dataset`. You mine + flag; the parent emits the candidates.
|
|
874
|
-
7. **Render the discover `discovery-report.html` via the SHIPPED `
|
|
875
|
-
(`render-discover-report.ts`) — pass the run dir
|
|
876
|
-
`
|
|
877
|
-
|
|
932
|
+
7. **Render the discover `discovery-report.html` via the SHIPPED `writeDiscoverRunReportV3` composer**
|
|
933
|
+
(`render-discover-report-v3.ts`) — pass the run dir PLUS the AGGREGATE result you already hold in
|
|
934
|
+
memory (`criteria` · `annotations` · the leaf `miningReport` · the ingested `traces` ·
|
|
935
|
+
`datasetCandidates` · the grown `suite` provenance). It writes BOTH surfaces: the PRODUCTION
|
|
936
|
+
W3 frozen-contract report at `discovery-report.html` and the previous renderer's output at
|
|
937
|
+
`discovery-report.v2.html` (transition fallback) — mirroring eval's `writeRunReport`. Anything you
|
|
938
|
+
do not pass is read from the run dir; a genuinely absent companion renders as a **NAMED absence**
|
|
939
|
+
(e.g. "sampling strategy census: not recorded by this run"), NEVER a fabricated number.
|
|
878
940
|
**Do NOT render via bare `writeDiscoverReport(criteria, grounding)`** — without companions it
|
|
879
941
|
degrades the funnel to em-dash and leaves Proof-of-work + Dataset empty (the A4 thin-report gap;
|
|
880
|
-
the data exists, it just isn't forwarded).
|
|
881
|
-
discover
|
|
942
|
+
the data exists, it just isn't forwarded). The v2 composer `writeDiscoverRunReport`
|
|
943
|
+
(`render-discover-report.ts`) stays available unchanged for the legacy surface.
|
|
882
944
|
|
|
883
945
|
### Governing invariants (verbatim — must survive the merge)
|
|
884
946
|
|
|
@@ -890,6 +952,7 @@ this inline section is now its canonical home.
|
|
|
890
952
|
- `gather_structured_refs`: "Every observed claim AND every absence claim cites a structured ref {obs,path,value} (ground-absence = a positive field check, never inferred from silence)."
|
|
891
953
|
- `typed_assumptions`: "Every surfaced assumption is TYPED — factual-intent · normative · scope — so its lifecycle/blocking routes correctly (GA-3)."
|
|
892
954
|
- `emergent_categories_only`: "Categories EMERGE from what the traces show. Never start from a pre-defined failure list (confirmation bias). No generic scores as categories."
|
|
955
|
+
- `reinforce_not_restate`: "The existing suite (existing-criteria.json) is consulted AFTER clustering, to NAME an already-emerged cluster — never before, which would seed a pre-defined list and violate emergent_categories_only. A cluster whose behaviour an existing criterion already states is emitted under THAT id (reinforcing evidence), not as a second name for one check. INFORMS, never blocks: a genuinely new behaviour is always minted. An existing id emitted with no trace of your own behind it is a fabricated finding."
|
|
893
956
|
- `judge_only_never_fix`: "EV-051 — FLAGS fixable-vs-eval-worthy and routes the fixable + infra-class to diagnostics. NEVER fixes the subject."
|
|
894
957
|
- `binary_actionable`: "Each emergent category is one binary criterion whose verdict points at a concrete fix locus."
|
|
895
958
|
- `full_mined_criterion_emit`: "Emit the FULL MinedCriterion (base + §5b metadata + §5c discovery incl. structured refs + typed assumptions). A lightweight/flattened emit that drops refs/assumptions is a DEFECT."
|
|
@@ -949,9 +1012,9 @@ registered subagent** (the roster stays evaluator · dataset-builder · audit-ex
|
|
|
949
1012
|
- **Feeds the gate:** a downgraded CRIT/HIGH verdict makes the run **INCOMPLETE** (the ternary gate
|
|
950
1013
|
`fail ▸ incomplete ▸ pass`) — the latent false-green killer.
|
|
951
1014
|
|
|
952
|
-
## Mode:
|
|
1015
|
+
## Mode: optimize ← EDD ③ OPTIMIZE loop (F18 closure + F19 variance-first)
|
|
953
1016
|
|
|
954
|
-
THE **Eval-Driven-Development loop** — the ADL ③
|
|
1017
|
+
THE **Eval-Driven-Development loop** — the ADL ③ OPTIMIZE stage. After the initial `*build` +
|
|
955
1018
|
`*evaluate`, this mode drives the subject to **full green**. It is a **MODE of `evaluator`, not a new
|
|
956
1019
|
registered subagent** (the roster stays evaluator · dataset-builder · audit-executor). It backs
|
|
957
1020
|
`scripts/edd/variance-gate.ts` (F19) + `scripts/edd/change-request.ts` (F18). It stays **JUDGE-ONLY
|
|
@@ -1013,7 +1076,7 @@ never re-implements, the runner. The interface this mode ASSUMES (documented ver
|
|
|
1013
1076
|
### Governing invariants (must survive any merge)
|
|
1014
1077
|
|
|
1015
1078
|
- `variance_before_accuracy` (F19): "Stabilize per-case variance (repeat-N, default 5) BEFORE measuring accuracy. The accuracy phase is entered ONLY when the variance gate passes (`assertVarianceStableBeforeAccuracy` THROWS otherwise). Accuracy over big samples is wasted on a flapping verdict."
|
|
1016
|
-
- `judge_only_requests_never_patches` (F18 · EV-051): "The
|
|
1079
|
+
- `judge_only_requests_never_patches` (F18 · EV-051): "The optimize mode REQUESTS the builder ai-engineer to amend (over SendMessage) and re-evals what is amended. It NEVER edits the subject/spec/source itself — the mutagent-builder ai-engineer is the ONE agent allowed to touch the Agent/AgentSpec."
|
|
1017
1080
|
- `grounded_change_request` (F18 · GA-1): "Every failing case in a change-request carries the verbatim critique + ≥1 structured ref{obs,path,value}. An ungrounded ask fails loud (`validateChangeRequest`)."
|
|
1018
1081
|
- `remedy_target_def_vs_impl` (F18): "The evaluator PROPOSES where the fix belongs — `agentspec` (the DEFINITION is wrong → def→impl cascade via *build) vs `impl` (a wiring/faithfulness defect). It proposes; the engineer decides + may reject with a reason."
|
|
1019
1082
|
- `reeval_always_follows_amend` (F18): "An `amended` response ALWAYS triggers a fresh evaluation swing (from the variance phase). There is no 'fixed it, trust me, skip re-eval' path. A `rejected` response never re-evals an unchanged subject."
|
|
@@ -1030,9 +1093,9 @@ never re-implements, the runner. The interface this mode ASSUMES (documented ver
|
|
|
1030
1093
|
C-PIN (pinned model + temperature 0).
|
|
1031
1094
|
- **Additive to the runner:** consumes the assumed eval-runner interface; rebuilds nothing.
|
|
1032
1095
|
|
|
1033
|
-
## Mode: judge — axis code-quality ← the ⑤
|
|
1096
|
+
## Mode: judge — axis code-quality ← the ⑤ OPTIMIZE code-target quality verdict (Wave-2 W2I1)
|
|
1034
1097
|
|
|
1035
|
-
The **(b) half of the ⑤
|
|
1098
|
+
The **(b) half of the ⑤ OPTIMIZE loop's code-target BOTH-gate.** For a `code`-kind subject, "converged"
|
|
1036
1099
|
requires BOTH (a) the subject's OWN test suite green — a hard DETERMINISTIC gate the ai-engineer
|
|
1037
1100
|
reports and the optimize oracle records as `testsGreen` — AND (b) THIS code-quality verdict passing.
|
|
1038
1101
|
This mode is (b): score the QUALITY of the applied code change, BEYOND tests-green (a deterministic
|
|
@@ -1064,7 +1127,7 @@ mirroring how the other judge prompts mirror their agent modes).
|
|
|
1064
1127
|
## Eval-leg reconcile — criteria MAINTENANCE, not judging (Wave-2 W2I5 · KP-003)
|
|
1065
1128
|
|
|
1066
1129
|
The evaluator owns the **eval leg** of the def → impl → eval triad — the third leg of `#sync-spec`. When
|
|
1067
|
-
an impl amends (the ⑤
|
|
1130
|
+
an impl amends (the ⑤ OPTIMIZE loop's ai-engineer, or brownfield drift), the eval criteria that ground the
|
|
1068
1131
|
subject's evaluation can go stale. The reconcile REASONING — which criteria a changed impl makes stale,
|
|
1069
1132
|
what new criterion it needs — is the **ai-architect's** (`#sync-spec`, session-dispatched, Model-B). The
|
|
1070
1133
|
evaluator exposes only the deterministic CONTRACT the reconcile reads/writes, in
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# code-quality-criteria.yaml — the CODE-QUALITY rubric (⑤ OPTIMIZE code-target BOTH-gate, W2I1)
|
|
2
|
+
# ═══════════════════════════════════════════════════════════════════════════════
|
|
3
|
+
# THIS FILE IS THE RUBRIC. Edit it to tune what "code quality-pass" means — no code
|
|
4
|
+
# change, no release. `scripts/code-quality-verdict.ts` loads it at import time and
|
|
5
|
+
# exports it as DEFAULT_CODE_QUALITY_CRITERIA.
|
|
6
|
+
#
|
|
7
|
+
# WHAT IT GATES: for a subject whose medium is `code`, "converged" = the subject's OWN
|
|
8
|
+
# test suite green (deterministic) AND this rubric PASSes. Neither alone converges.
|
|
9
|
+
# Prompt/markdown subjects never touch this file — they converge on evals alone.
|
|
10
|
+
#
|
|
11
|
+
# AGGREGATION (severity-gated): a `fail` OR `uncertain` on any `critical`/`high`
|
|
12
|
+
# criterion BLOCKS the quality-pass. `medium` is advisory (recorded, never blocking).
|
|
13
|
+
#
|
|
14
|
+
# EDITING RULES:
|
|
15
|
+
# - `id` is a byte-identity key + report anchor. Changing an id breaks historical
|
|
16
|
+
# comparison — add a new criterion instead of renaming an old one.
|
|
17
|
+
# - Every criterion must be BINARY (decidable pass/fail), never a Likert score.
|
|
18
|
+
# - `severity` must be exactly one of: critical | high | medium.
|
|
19
|
+
# - Keep passDefinition/failDefinition CONCRETE — the judge must not have to guess.
|
|
20
|
+
# - Bump `version` on any change to this file.
|
|
21
|
+
#
|
|
22
|
+
# STATUS: the picks below are the conservative, subject-agnostic starting set
|
|
23
|
+
# (FLAGGED-for-operator-sign-off, Wave-2 W2I1) — a default, not a final contract.
|
|
24
|
+
|
|
25
|
+
version: 1
|
|
26
|
+
|
|
27
|
+
criteria:
|
|
28
|
+
- id: Q1-spec-faithful
|
|
29
|
+
statement: The implementation realizes the agentspec definition the amend targeted.
|
|
30
|
+
passDefinition: >-
|
|
31
|
+
PASS: every spec-declared tool / job-to-be-done is present and the operative
|
|
32
|
+
system_prompt is unchanged except where the amend intended; the def→impl cascade held.
|
|
33
|
+
failDefinition: >-
|
|
34
|
+
FAIL: a spec-declared tool or JTBD is missing, or the system_prompt was altered
|
|
35
|
+
beyond the amend intent (the impl forked from the SSoT).
|
|
36
|
+
severity: critical
|
|
37
|
+
|
|
38
|
+
- id: Q2-addresses-diagnosis
|
|
39
|
+
statement: The change targets the diagnosed root-cause locus, not an adjacent symptom.
|
|
40
|
+
passDefinition: >-
|
|
41
|
+
PASS: the edit is at (or directly causes a fix at) the RCA-named locus / the
|
|
42
|
+
failing-case root.
|
|
43
|
+
failDefinition: >-
|
|
44
|
+
FAIL: the change edits an unrelated place or patches a symptom while the root
|
|
45
|
+
cause remains.
|
|
46
|
+
severity: high
|
|
47
|
+
|
|
48
|
+
- id: Q3-no-regression
|
|
49
|
+
statement: The change introduces no unrelated regression and stays in scope.
|
|
50
|
+
passDefinition: >-
|
|
51
|
+
PASS: only the remedy-named surface changed; no unrelated behavior was removed
|
|
52
|
+
or broken.
|
|
53
|
+
failDefinition: >-
|
|
54
|
+
FAIL: unrelated code was changed/removed, or a previously-working path was broken.
|
|
55
|
+
severity: high
|
|
56
|
+
|
|
57
|
+
- id: Q4-error-handling
|
|
58
|
+
statement: Failure paths are handled, not silently dropped.
|
|
59
|
+
passDefinition: >-
|
|
60
|
+
PASS: error/failure branches surface, recover, or log per the subject's contract;
|
|
61
|
+
no new silent drop.
|
|
62
|
+
failDefinition: >-
|
|
63
|
+
FAIL: a failure is swallowed with no recovery/notify/observability (a silent-drop
|
|
64
|
+
regression).
|
|
65
|
+
severity: high
|
|
66
|
+
|
|
67
|
+
- id: Q5-maintainable
|
|
68
|
+
statement: The code is readable, framework-idiomatic, and free of obvious footguns.
|
|
69
|
+
passDefinition: >-
|
|
70
|
+
PASS: clear structure, idiomatic to the target framework, no dead code /
|
|
71
|
+
copy-paste / obvious footgun introduced.
|
|
72
|
+
failDefinition: >-
|
|
73
|
+
FAIL: unreadable/duplicated/dead code or an obvious maintainability footgun was
|
|
74
|
+
introduced.
|
|
75
|
+
severity: medium
|