fix(scorer-gated-skill-edits): close two unclear-agent-instruction gaps from retro #343 - #1453
Conversation
…ps from retro #343 Add a cross-reference sweep sub-step to step 3 (Propose bounded edits) requiring every ordinal/count citation in a target skill's own references/ and evals/<skill>/ docs to be checked and fixed in the same patch when an edit changes the item they cite. Add a named-fixture corroboration rule to step 5/7 and two new Stop boundaries requiring a "restraint check" or similar log claim to name a fixture actually, independently dispatched, never substituted with an unrelated fixture's evidence. Both close unclear-agent-instruction repairs issue #343's retrospective found; ground each in that incident via two new references/worked-example.md sections. Blind spot pass: none of the 7 selection-split fixtures probe either rule, so no live measured gate run was performed this iteration -- disclosed in evals/scorer-gated-skill-edits/split.md per this repository's own established precedent (gitapex#406) for a corpus-coverage gap on a prose-only procedure edit. Closes #1444 Refs #343 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016aYGizS5BFra1n6WzLyqKd
…standardized ## Iteration:/### heading form The prior commit's evals/scorer-gated-skill-edits/split.md entry used inline bold labels instead of the ## Iteration: <issue>, <title> heading plus ### Precondition and splits / ### Blind spot pass / ### Classification / ### Gate result / ### Transfer check / ### Rejected-edit log / ### Verdict subsection form every other evals/*/split.md file in this repository already standardized on (per issue #928's T2-T6 migration). Missed the ### Transfer check subsection gitapex_gate_transfer_check_disclosure.py requires on every '## Iteration:' entry, repo-wide -- restructured to match, with an honest "not run, no behavioral output to compare" Transfer check disclosure (this edit changes the skill's own procedure text, not a target skill's behavior). Verified: gitapex_gate_transfer_check_disclosure.py (both the single-file and default whole-repo glob invocations) and the full 40-gate local preflight, both PASS. Refs #1444, #343 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016aYGizS5BFra1n6WzLyqKd
|
Important
This repository does not receive automatic reviews because it has fewer than 10 stars. ⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #1453 +/- ##
=======================================
Coverage 99.57% 99.57%
=======================================
Files 127 127
Lines 22539 22539
Branches 2766 2766
=======================================
Hits 22443 22443
Misses 96 96 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
Root cause, established by direct log inspection: the workflow correctly detects this PR touches This is not this PR's own defect: this PR adds no code, touches no Per this repository's own CI-triage convention, standing down here rather than widening this PR to debug Generated by Claude Code |
… affect pruning-only eligibility Independent review (drafting-a-pr-to-merge Step 8, PR #1453) found the new step 3 cross-reference-sweep sub-step sits immediately after the pruning-only eligibility definition without stating whether fixing a stale ordinal/count citation elsewhere counts as the "reword" that would disqualify an otherwise deletion-only candidate. State explicitly that this sweep-and-fix is mechanical citation upkeep, not new behavior, so it does not by itself change the edit's ordinary/pruning-only classification. A second candidate finding from the same review (the "Kept-edit log entry"/"Kept-edit entries" wording introduced by this branch's own commits is stale post-#928 terminology) was independently verified and rejected: evals/evaluating-skill-quality/split.md -- this repository's own largest, most actively maintained split.md -- still uses "Kept-edit log"/"Kept-edit log entry" as live descriptive prose at its own most recent entries (lines 4197, 4374), well after the #928 migration. Only the literal "## Kept-edit log" heading was retired in favor of "## Iteration:"; the descriptive phrase remains current usage this diff's own wording matches, not a stale term. Verified: gitapex_check_skill_shape.py (47/47), ASCII-only, and gitapex_gate_skill_branch_fixture_coverage.py (unchanged PASS -- no new Stop-boundary bullet or dispatch branch added by this clarification). Refs #1444, #343 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016aYGizS5BFra1n6WzLyqKd
…kill's own portable content skills/scorer-gated-skill-edits is declared portability: Mixed, so its own SKILL.md and references/worked-example.md are meant to travel with a vendored copy of this skill into another repository -- a bare issue citation would dangle there, resolving to an unrelated issue (or nothing) in the target repository's own tracker. Reworded the three citations this branch's own commits introduced to a plain "A real incident: ..." lead-in, preserving the narrative and rationale without naming a repository-local issue number. evals/scorer-gated-skill-edits/split.md is left unchanged: it is this repository's own internal audit log, not part of the skill's portable content, and every entry in it (here and in every sibling split.md) cites issue numbers by established convention. Verified: gitapex_check_skill_shape.py (47/47) and ASCII-only, both against the candidate. Refs #1444, #343 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016aYGizS5BFra1n6WzLyqKd
Summary
Closes two
unclear-agent-instructiongaps issue #343's own retrospective found (a stale cross-reference/ordinal after a bounded edit, and a "restraint check" log entry substituting unrelated dispatches for the named fixture) by extendingskills/scorer-gated-skill-edits/SKILL.md's own Procedure and Stop boundaries -- the shared gate every skill's iterative edit goes through, per issue #1444's own scoping decision.Facts
unclear-agent-instructionby issue chore(retrospective): merge retrospective for PR #335 #343's own text, meaning no deterministic gate could have caught them -- confirmed by direct re-read of issue chore(retrospective): merge retrospective for PR #335 #343's own body before implementing.skills/scorer-gated-skill-edits/SKILL.mdgoverns exactly the workflow both defects occurred in (step 3 "Propose bounded edits", step 5 "Log rejected edits", step 7 "Record the run") -- confirmed by direct read.git diff bc77e90..origin/main(fetched mid-implementation) showedscorer-gated-skill-edits/SKILL.mdhad just gained a new step 8 (issue chore(retrospective): merge retrospective for PR #216 #218's retrospective) -- re-synced onto that before editing so this PR's diff lands cleanly against it, not a stale base.python3 skills/evaluating-skill-quality/scripts/gitapex_check_skill_shape.py skills/scorer-gated-skill-edits: 47/47 checks pass on the candidate, includingbody-length(456/500 lines),anchor-targets-resolve, andno-step-location-contradiction.uv run python3 -m pytest -q --no-cov: 6700 passed, 1 failed (test_gitapex_scan_harden_checkout_pin_drift.py::test_repository_workflows_are_drift_free) -- reproduced identically on unmodifiedbc77e90(stashed my changes and re-ran), so this is a pre-existing shallow-clone artifact in this sandbox, not a regression from this diff. Full history was then fetched (git fetch --unshallow) and the local 40-gate preflight's ownharden-checkout-pin-driftentry (the same check) passed afterward..github/scripts/gitapex_gate_skill_branch_fixture_coverage.py, run directly against the real before/after content and the realevals/scorer-gated-skill-edits/tasks/*.yamlcount (15 files, viagit ls-tree): the two new Stop-boundary bullets bring this skill's own decision-branch count to 13;PASS(15 >= 13) -- no new fixture required by that gate's own absolute count-comparison rule..github/scripts/gitapex_gate_transfer_check_disclosure.py(default whole-repo glob):PASS-- the newevals/scorer-gated-skill-edits/split.mdentry (this file's first ever## Iteration:entry) discloses a non-empty### Transfer checksubsection in the standardized post-feat(evals): move split.md machine-read facts to split.json and unify both markdown conventions #928 heading form.python3 .github/scripts/gitapex_gate_local_preflight.py: all 40 wired gates PASS on the final candidate.evals/scorer-gated-skill-edits/'s own selection split has 7 fixtures (split.json); read all 7 directly -- none probes ordinal/count cross-reference staleness or named-fixture corroboration integrity, so no live measured gate run could register a score change from this edit either way.Assumptions
scorer-gated-skill-edits/SKILL.md's current step numbering or Stop-boundary bullet text -- checked.github/workflows/scorer-gated-keep-gate.yml's own step references directly; unaffected, since this diff is purely additive (no step renumbered, no existing bullet reworded)..github/scripts/gitapex_gate_skill_branch_fixture_coverage.pyandgitapex_gate_transfer_check_disclosure.pyCI gates are wired to fire on this PR's diff (both are.github/scripts/*.pygates whose applicability is diff-computed by their own calling workflow) -- not independently confirmed against this specific PR's live CI run at the time of opening, only against local invocation with the equivalent inputs.Risk / blast radius
skills/scorer-gated-skill-edits/SKILL.md(prose-only: one sub-step under step 3, one sentence in step 5, one paragraph in step 7, two new Stop-boundary bullets) andreferences/worked-example.md(two new illustrative sections). No script, schema, or CI workflow file changed.evals/scorer-gated-skill-edits/split.mdgains its first-ever## Iteration:entry, disclosed asNOT MEASUREDrather than a falseKEEP-- does not claim a measured result the corpus cannot support.description:frontmatter change (no new trigger/routing surface), no new script, no new dispatch branch (the two new Stop-boundary bullets are plainNever ...prose rules, not a"token" ->dispatch shape) -- confirmed directly viadispatch_branch_counterin the fixture-coverage gate script, which found 0 dispatch-branch matches in either bullet.scorer-gated-skill-editsreads the new step 3/step 5/step 7/Stop-boundary text and still gets it wrong -- the same residual risk this repository's own issue fix(evaluating-skill-quality): Contract discipline's precondition enumeration has drifted stale from SKILL.md steps 2/4 #406 precedent already disclosed for the identical remediation shape (a prose Stop-boundary addition, not a deterministic gate).Rollback
git revertthe two commits on this branch; no schema, generated-file, or state migration is involved. The two commits are independently revertible (the second is a pure restructuring of the first's ownsplit.mdaddition, touching no other file).Verification
Acceptance Criteria Map, restated verbatim from issue #1444 (independently re-verified against the live repository before implementation -- see the
Re-verified:marker on that issue):references/directory orevals/<skill>/docs cite, the edit is not complete until every such cross-reference has been checked and updated in the same patchreferences/directory andevals/<skill>/docs for ordinal/count language referencing the changed item; add a matching Stop-boundary bulletResults, row by row
skills/scorer-gated-skill-edits/SKILL.mdstep 3 now reads: "When the edit changes an enumerated or ordinal item that the target skill's ownreferences/directory (or itsevals/<skill>/docs) cites elsewhere ... grep that skill's ownreferences/directory andevals/<skill>/docs for every such reference to the changed item before scoring, and fix each one found in the same patch, not a follow-up," now attributed to "a real incident" rather than a bare issue-number citation (see the Independent review verdict's follow-up-commit note below), and cross-referencing a newreferences/worked-example.md"Cross-reference sweep before scoring" section that narrates the real incident. A matching Stop-boundary bullet added.known_gaps, step 7) instead of implying indirect coverage." A matchingreferences/worked-example.md"Restraint-check corroboration must be a real dispatch" section narrates the real incident. Distinct from feat(evaluating-skill-quality,battle-testing-a-skill,scorer-gated-skill-edits): forbid subagent fallback and require a fix-or-handoff code block when isolation cannot be verified #1410's isolation-mechanism Stop boundary (confirmed by direct re-read of both): feat(evaluating-skill-quality,battle-testing-a-skill,scorer-gated-skill-edits): forbid subagent fallback and require a fix-or-handoff code block when isolation cannot be verified #1410 governs whether the dispatch mechanism itself is contamination-free; this rule governs whether the claimed fixture was the one actually dispatched -- orthogonal concerns, not a duplicate.Commands run (all against the final candidate):
python3 skills/evaluating-skill-quality/scripts/gitapex_check_skill_shape.py skills/scorer-gated-skill-edits: 47/47 PASS.python3 skills/evaluating-skill-quality/scripts/gitapex_scan_execution_requirements_drift.py skills/scorer-gated-skill-edits: no drift.uv run python3 -m pytest -q --no-cov: 6700 passed, 1 pre-existing/environmental failure (see Facts).LC_ALL=C grep -nP '[^ -~\t]' <every changed file>: clean (ASCII-only).python3 skills/outward-artifact-preflight/scripts/gitapex_scan_provenance.py --file <every changed file>: PASS, no candidate provenance markers..github/scripts/gitapex_gate_skill_branch_fixture_coverage.py(real before/after content, real fixture count): PASS..github/scripts/gitapex_gate_transfer_check_disclosure.py(both single-file and default whole-repo glob): PASS.python3 .github/scripts/gitapex_gate_local_preflight.py(all 41 wired local gates): all PASS.Skill audit evidence
battle-testing-a-skill: WAIVED: this diff touches onlyscorer-gated-skill-edits/SKILL.md(prose across steps 3/5/7 plus two new Stop-boundary bullets) and itsreferences/worked-example.md. Nodescription:frontmatter change (no new trigger/routing surface), no new script, no new dispatch branch (confirmed: 0 matches for the dispatch-branch pattern in either new bullet, pergitapex_gate_skill_branch_fixture_coverage.py's owndispatch_branch_counter). The two new Stop boundaries are narrow, mechanically-scoped process rules, each paired with a concrete worked-example section grounding it in a real incident so its meaning is unambiguous by construction -- the same mitigation this file's other Stop boundaries already use (e.g. the git-stash-race boundary cites its own worked-example section). Unlike feat(evaluating-skill-quality): implement #218's remaining 3 gate proposals #1426's WAIVED precedent for this same file, this diff does add Stop boundaries, so verified instead via the deterministic shape checker's full pass (47/47, includingno-step-location-contradiction, which specifically checks for a "step N" reference asserted to run in two contradicting locations -- directly relevant to the step 3/5/7 cross-references this diff adds) and a manual read-through cross-checking every new sentence against every existing step/Stop-boundary for contradiction or duplication.evaluating-skill-quality: WAIVED: same reasoning as above -- proportionate to a small, prose-only, non-code addition to an already-mature governance skill, verified via this repository's own deterministic tooling rather than a fresh isolated dispatch. Residual risk disclosed: an isolated adversarial review of the new prose's own clarity was not run; if a future review surfaces ambiguity in the new Stop-boundary wording, fix it then.adversarial-coverage-mapping: WAIVED:scorer-gated-skill-editsis a gate/verification skill by nature (security-relevant by the workflow's own keyword heuristic), but this diff adds no new attack surface -- two prose Stop-boundary rules with no automated action and no code-path change, matching PR feat(evaluating-skill-quality): implement #218's remaining 3 gate proposals #1426's own reasoning for the same file.checker-script-adversarial-review: N/A -- noskills/*/scripts/*.py,evals/scripts/*.py, or.github/scripts/*.pyfile touched by this PR.deterministic-gate-quality: N/A -- no deterministic gate/checker script added or modified; the two existing gates this PR's own diff was checked against (gitapex_gate_skill_branch_fixture_coverage.py,gitapex_gate_transfer_check_disclosure.py) were read and run against this diff's real inputs, not modified.defeat-test-disclosure: N/A -- no new test-backed detection logic added; this PR is a skill-instruction (prose) change with no code to defeat-test.Checklist
references/worked-example.mdsections are the documentation)evals/scorer-gated-skill-edits/split.md-- that entry discloses a### Transfer checksubsection (see Facts; verified viagitapex_gate_transfer_check_disclosure.py)scorer-gated-skill-edits/SKILL.md--evals/scorer-gated-skill-edits/tasks/*.yaml's existing 15 fixtures already meet or exceed the resulting 13-branch decision-branch count (see Facts; verified viagitapex_gate_skill_branch_fixture_coverage.pyagainst the real before/after content), so no new fixture was required by that gate's own ruleMerge gate: independent review
This PR is also subject to the
independent-review-pendingrequired status check. It stays pending/failing until a## Independent review verdictsection naming this PR's current head commit is recorded in this body --drafting-a-pr-to-merge's own Step 8 records it once its independent review completes. Not pre-filled here.Independent review verdict
Outer layer: did not run. Neither Anthropic's "Claude Code Review" GitHub App nor GitHub Copilot's automated PR review is confirmed configured/reachable for this repository in this environment (matching PR #1426's own same-day precedent for this same repository). CodeRabbit and Devin both left automated comments on this PR; both explicitly disclosed they skipped review (CodeRabbit: "This repository does not receive automatic reviews because it has fewer than 10 stars"; Devin: "Full review skipped: trial expired and no credits remaining") -- neither is a substitute for this step's own outer layer, and neither produced a findings-bearing verdict to fold in here.
Inner layer: mandatory, ran against this PR's full diff (
reviewing-an-artifact, low effort) at commit079dc46d. The target is mixed (twoskills/scorer-gated-skill-edits/files plus one ordinaryevals/scorer-gated-skill-edits/split.mddoc), so per that skill's own Step 0 theSKILL.md/references/worked-example.mdportion was deferred to a dedicated pass applyingevaluating-skill-quality's own review spirit (a fresh, isolatedAgent-tool subagent with no memory of this session's own authoring), andevals/scorer-gated-skill-edits/split.mdwas independently classifiedsafeunder Step 1 (a narrative log entry -- prose only, no code, no security-tier signal) and correctly skipped Steps 2-5 per that skill's own rule.The deferred pass returned two candidate findings, both independently verified (Step 3's own FABRICATED pre-check plus counterfactual check) rather than accepted at face value:
9ef849ee): the new step 3 cross-reference-sweep sub-step sat immediately after the pruning-only eligibility definition without stating whether fixing a stale ordinal/count citation elsewhere counts as the "reword" that disqualifies an otherwise deletion-only candidate from pruning-only status. Fixed by stating explicitly that this sweep-and-fix is mechanical citation upkeep, not new behavior, and does not by itself change that classification.gitapex_gate_transfer_check_disclosure.py's docstring (the literal## Kept-edit logheading was retired in favor of## Iteration:). Independently re-verified againstevals/evaluating-skill-quality/split.md-- this repository's own largest, most actively maintainedsplit.md-- which still uses "Kept-edit log"/"Kept-edit log entry" as live descriptive prose at its own most recent entries, well after the feat(evals): move split.md machine-read facts to split.json and unify both markdown conventions #928 migration. Only the literal heading was retired; the descriptive phrase this diff's own wording matches remains current usage, so this finding did not hold and no change was made for it.No finding survives against commit
079dc46d. Re-verified after the fix:gitapex_check_skill_shape.py(47/47), ASCII-only, andgitapex_gate_skill_branch_fixture_coverage.py(unchanged PASS -- the clarifying sentence added no new Stop-boundary bullet or dispatch branch).Follow-up commit
729d1da8(this section's own current head,52efa180after a base-branch merge): per explicit operator instruction, removed the three repository-local issue-number citations ("Issue#343: ...") this branch's own commits had introduced intoskills/scorer-gated-skill-edits/SKILL.mdandreferences/worked-example.md-- this skill declaresportability: Mixed, and a bare issue citation in its own portable content would dangle once vendored into another repository's tracker. A purely mechanical text substitution (the lead-in phrase only; no change to the narrative, the rule, or any Stop boundary), verified by direct diff inspection (confirmed viagrepthat no issue-number citation this branch introduced remains, and thatevals/scorer-gated-skill-edits/split.md-- an internal audit log, not portable skill content -- was correctly left untouched) plusgitapex_check_skill_shape.py(47/47) and ASCII-only, rather than a fresh isolated subagent dispatch -- disclosed as a deliberate proportionality judgment for a wording-only change, not an oversight.Limitation, disclosed rather than glossed: the deferred pass's single
Agent-tool subagent dispatch is prompt-level isolation (no memory of this session's own authoring), not the formal positive/negative sentinel-control isolation verificationevaluating-skill-quality's ownreferences/adversarial-self-audit.mddescribes for confirming no project instruction file leaked in -- not run here, disclosed rather than assumed equivalent, matching PR #1426's own identical disclosure for the same class of dispatch.Related Issue
Closes #1444
Refs #343