Repository navigation
test(architecture): tighten eval graders the #7437 ready review found lenient #7438
Description
The graders below were frozen for the measured runs in #7437, so the PR leaves them unchanged. The ready-time code review then found ways each one passes when it should fail. Every input quoted below was run through plugins/evals/skills/validate/scripts/validate-cases.py's js_regex and passes the current grader.
Effect on #7437's verdicts: the paired runs used only md, mf and my. Every run of those scored 1.00 and wrote the expected files, so finding 7 (md) and finding 8 (mf) are the only ones that touch a measured case. The other cases ship unmeasured against these graders.
Findings
Shell-write and interpreter bypasses
-
Fixed in c7acfae.
mc-two-deployables-stopsno-components-shell-writemisses a quoted target.[^"|;&]*cannot cross the\"that compact JSON writes for a quoted path. These all pass the grader:printf x > "docs/architecture/components.md"cp /tmp/v.md "docs/architecture/components.md"perl -pi -e s/a/b/ docs/architecture/components.mdpython3 -c "open('docs/architecture/components.md','w').write('x')"
Fix: use
\S*after the operator, addperl\s+-\S*i,python3?\s+-candnode\s+-e, and add a quoted-path must-fail sample. -
Fixed in c7acfae.
ml-check-writes-nothingno-shell-writehas the same quoting gap, plus three more misses:>|, perl in-place edits, and interpreter writes. These all pass:printf x > "docs/architecture/landscape.md"echo x >| docs/architecture/landscape.mdperl -pi -e s/a/b/ docs/architecture/landscape.mdpython3 -c "open('docs/architecture/landscape.md','w').write('x')"
Fix: the same as finding 1.
-
Fixed in c7acfae.
rd-no-convention-writes-nothingno-shell-writemisses interpreter writes and extensions outside its list. These pass:python3 -c "open('docs/adr/0001-postgres.md','w').write('x')"printf x > docs/adr/0001-postgres.markdown
Fix: add the interpreter verbs and
markdown|yaml|yml.
Negation and wording gaps
-
Fixed in c7acfae.
mp-unresolved-not-matchedreply-names-unresolved: alternative 1 lacks then'tlookbehind, and neither alternative sees a negator further back. These pass:- "Nothing is unresolved: ../Shared/Shared.csproj was matched to legacy/Shared/Shared.csproj."
- "The reference isn't unresolved; ../Shared/Shared.csproj points at legacy/Shared."
Fix: add a
not_containsgrader onlegacy/Shared/Shared\.csprojin last_message. -
no-findings-deep-*states-no-candidates: up to three arbitrary words may sit between "no" and "candidates". These pass:- "No surprise there are candidates here. Candidate 1: merge rates and rounding."
- "There are no fewer than two candidates: the parser and the formatter."
- "No strong candidates, but two weak candidates: Candidate 1 (Speculative) merge slug.js."
Fix: allow only adjective fillers, or add a
not_containsgrader onCandidate \d. This also corrects the feat(architecture): concise skill text measured by evals, plus outcome cases and probes #7437 changelog line, which overclaims here. -
deep-module-not-over-flaggedsays-already-deep: the guard sees only a negator immediately before "already", and thejust|only|merely|simply movealternative has no guard at all. These pass:- "The pricing engine is not yet already deep; split it."
- "It is hardly already deep; split it."
- "Splitting TaxTable out would not just move code, it deepens the engine. Candidate: split it."
-
md-prisma-sql-mismatchreply-reports-mismatch:- It passes "Expected one mismatch, but Prisma and SQL agree, so none was recorded."
- It is also too narrow: it fails "Mismatch count: 1".
-
mf-interface-hop-unresolvedreply-reports-di-hop: it passes "Expected one interface hop, but the trace bound IOrderRepository to OrderRepository." -
rd-no-convention-writes-nothingoffers-numbered-shape: a template'sDate: YYYY-MM-DDline satisfies it even when no numbering scheme is offered. It passes "Option A: docs/decisions/ with sections Title, Date: YYYY-MM-DD, Context, Decision, Consequences."Fix: anchor the token to a filename,
YYYY-MM-DD-[\w-]+\.md.
Missing-file passes
-
not_containsfile graders pass when the target file is missing:gateway-not-container,no-bound-implementation,not-matched-by-name,no-derived-people, and theno-secret-in-*file graders.Fix: pair each with a
file_existsgrader, or fold the negative into the positive pattern with a lookahead, asrecord-unchangeddoes.
Done when
- Each grader above rejects its quoted inputs, with each input added as a must-fail sample.
/evals:validatereports no FAIL.mdandmfare rescored or re-run under the fixed graders, on both models and both arms.
🤖 Generated with Claude Code
Activity
github-actions commentedon Oct 14, 2026
Understood: this reports ten specific leniency gaps in
plugins/evalsgrader regexes (shell-write/interpreter-write bypasses via quoting and missing verbs, negation/wording gaps, andnot_containsgraders that pass when the target file is missing), each with concrete inputs that currently passjs_regexand a proposed fix. It also flags that onlymd/mffindings affect #7437's measured verdicts. No duplicate found; #7435 is a closed issue of the same shape (grader tightening from a prior ready-review) for reference, not a duplicate. Nothing appears missing - findings, fixes, and a done-when list are all present.Automated triage. A maintainer reviews it.
test(architecture): tighten the rd, mp, mc and ml eval graders
kyle-sexton commentedon Oct 14, 2026
Findings 1-4 (
mc,ml,rdno-shell-write,mpreply-names-unresolved) are fixed in c7acfae on #7437, each with the quoted inputs as must-fail samples;/evals:validatereports 0 FAIL. None of these cases was in the measured runs (onlymd,mf,my), so no evidence is invalidated.Finding 4 deviates from the suggested fix: a
not_containsgrader onlegacy/Shared/Shared\.csprojwould reject the existing must-pass reply "It was not matched to legacy/Shared/Shared.csproj by name.", so the newreply-unresolved-not-negatedgrader rejects the negated claims instead ("Nothing is unresolved", "isn't unresolved", "Unresolved: none").Findings 5-10 remain open.
kyle-sexton commentedon Oct 14, 2026
Interpreter-write regex limits from PR #7437 (two-level nesting of the
.replace(argument in the mc, ml and rdcase.yamlgraders), declined as not a regular language: threads PRRT_kwDOTCGFQM6sLNoJ (mc), PRRT_kwDOTCGFQM6sLNur (ml), PRRT_kwDOTCGFQM6sLN0x (rd). Proposed structural fix: a script grader or a tool-call deny in place of the regex.