fix(grade-codebase): grade liveness, not presence — close the false-A gap#43
Open
markhazlett wants to merge 3 commits into
Open
fix(grade-codebase): grade liveness, not presence — close the false-A gap#43markhazlett wants to merge 3 commits into
markhazlett wants to merge 3 commits into
Conversation
… gap A repo with a stale .ai/ context folder (untouched for months, referenced from CLAUDE.md) scored an A because every D1 signal was a presence/format check. The rubric named the quality questions in its judgment column but never forced the skill to test them, so presence floated to an A. Systemic fix — separate 'configured' from 'enforced/current/honest': - Rubric D1: split signals into presence vs. liveness probes (verify 3+ doc claims against the code, freshness vs. code churn, feedback-loop mechanism); instruct the grader to follow references into .ai/ etc. - Rubric section 4: present-but-misleading scores BELOW absent; a D1 of D/F caps the overall grade at C (compounding-context rule); presence alone caps at C without verified liveness. - Rubric section 5: reframe the judgment column as required liveness probes spanning D1/D2/D4/D6/D7/D8/D10 (assert-anything, gate-enforced, lockfile-in-sync, used-not-installed, canonical-actually-canonical). - Rubric section 6: add red flags 15-18 (stale/misleading context, gate configured-but-not-enforced, trivial test suite, lockfile drift). - Skill: new mandatory step 4 'Run liveness probes' + liveness-probes.md sub-file; honesty rule against awarding A without running the probe. - Template: liveness-probe results block per dimension. - Section 8: document the remaining calibration gap (no golden fixture). Bump VERSION 0.14.1 -> 0.14.2.
…lse-A guard Closes the calibration gap documented in rubric §8: until now the liveness probes were validated only by manual spot-check, so a regression that re-opened the false-A would go unnoticed. Adds three deliberately-rigged negative-case fixtures under .claude/skills/grade-codebase/fixtures/, each targeting one liveness probe / red flag: - stale-context/ — CLAUDE.md (+ referenced .ai/) cites paths and commands the code contradicts (no services/, no Makefile, no src/db/client.ts). Must grade D1 = D/F, overall capped at C (§6 #15). - empty-suite/ — vitest suite is green but all skip/todo + expect(true); never calls the functions under test. Must grade D2 <= C (§6 #17). - disabled-gate/ — CI defines lint/typecheck jobs but continue-on-error and || true swallow the exit codes. Must grade D4 <= C (§6 #16). Each fixture ships an EXPECTED.md stating the model-graded assertion. Two validation layers: - bin/test-grade-fixtures (new): mechanically guards that each fixture *remains a valid negative* — fails loud if an edit neuters one. This is the regression guard for the calibration set itself; it does not run the model. - A model-graded /grade-codebase full run against each fixture is the dogfood that confirms the skill marks it down (documented in the fixtures README and each EXPECTED.md). Remaining open work (noted in §8): wire the model-graded expectation into bin/skill-eval as a trajectory eval, and exercise the freshness probe (needs git history the plain-dir fixtures don't have). Bump VERSION 0.14.2 -> 0.14.3.
Conflicts: - VERSION: take main's 0.22.1 line, bump to 0.22.2 (this branch's content delta is small relative to main's 70+ commits since the divergence). - Path conflicts: main moved skills/ to top-level (.claude/skills is now a symlink). All new files added on this branch (fixtures/, liveness-probes.md, bin/test-grade-fixtures) relocate to the canonical skills/ path; git tracks them as renames so history is preserved. Adjustments made during the merge: - bin/test-grade-fixtures: paths updated to skills/grade-codebase/fixtures/ (the canonical location, not the symlink); the disabled-gate enforcement check is tightened to match `continue-on-error: true` only when it's a real YAML key and `|| true` only on a `run:` line — previously the same patterns inside a comment also counted, which is dishonest. - bin/tests/test-grade-fixtures.test.sh: new wrapper so the regression test is picked up by bin/test-all (which main added). Validators after merge: - bin/test-frontmatter: 33/33 pass - bin/test-grade-fixtures: 3/3 fixtures valid negatives - bin/test-terminal-states: 4/4 pass - bin/test-all: 13 passed / 8 failed — same as origin/main; the 8 failures are pre-existing on main and unrelated to this branch.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
Running
/grade-codebaseon a real repo returned an A despite the repo having no skills and its agent context living in a global.ai/folder that hadn't been touched in months (referenced fromCLAUDE.md, with no feedback loop for learnings). That's a false positive the skill should never produce.Root cause
Every D1 signal was a presence/format check (
test -f,wc -l, grep for section headers, grep for placeholders). A stale-but-well-formatted context doc passes all of them. The rubric named the quality questions ("is AGENTS.md useful vs. a stub", "are flags used vs. installed", "is the canonical example actually canonical") in its §5 judgment column — but the skill never had to test them, and they were capped at 50%. So presence floated all the way to an A.The same disease ran through the whole rubric: it graded configured, never enforced/current/honest.
Fix — separate "configured" from "enforced/current/honest", and force the skill to probe the latter
Rubric:
.ai/,docs/agent/, etc. and grade that content.continue-on-error; is the lockfile in sync; are flags/loggers used vs. installed; is the canonical example actually canonical).skip/todo/no-assert), lockfile drift.Skill (
SKILL.md+ newliveness-probes.md):not verified, never a pass.Template: per-dimension liveness-probe results block so the verification evidence is surfaced, separate from configuration presence.
Calibration fixtures (the §8 follow-up, now built)
Three deliberately-rigged negative-case mini-repos under
.claude/skills/grade-codebase/fixtures/, each targeting one probe / red flag, each with anEXPECTED.mdstating the grade it must receive:stale-context/CLAUDE.md(+ referenced.ai/) cites paths/commands the code contradictsempty-suite/skip/todo+expect(true), never calls the code under testdisabled-gate/continue-on-error/|| trueTwo validation layers:
bin/test-grade-fixtures(new) mechanically guards that each fixture remains a valid negative — fails loud if an edit neuters one (verified: simulating an enforced gate makes it fail). This is the regression guard for the calibration set itself; it does not run the model./grade-codebase fullrun against each fixture is the dogfood that confirms the skill marks it down.VERSION0.14.1 → 0.14.3.Remaining open work (tracked in rubric §8)
bin/skill-evalas a trajectory eval, so a future rubric/skill edit that re-opens the false-A fails automatically (currently the model-graded layer is a manual dogfood).Process note
This change was run back through
/write-skill(the audit that surfaced the bloated body + missing discovery layer in an earlier commit). The skill istier: flexible, so the rigid-skill requirements (subagent baseline, rationalization table,eval.yaml) don't apply.Test plan
bin/test-frontmatter— 32/32 passbin/test-grade-fixtures— 3/3 fixtures valid negatives; fail-path verifiedwc -w SKILL.md= 699 (< 700 hard ceiling)REQUIRED SUB-FILEreferences resolve to files on disk/grade-codebase fullagainst each fixture; confirm the grade matches itsEXPECTED.mdbin/skill-evalas an automated trajectory evalhttps://claude.ai/code/session_011uDsxgUQ6b68bvRsbtSsvX