Skip to content

fix(utilities): a moved heading takes its references, and split isolated-setup-verify - #1334

Merged
potiuk merged 2 commits into
apache:mainfrom
potiuk:fix/optimize-skill-eval-repoint
Sep 22, 2026
Merged

potiuk merged 2 commits into
apache:mainfrom
potiuk:fix/optimize-skill-eval-repoint

Conversation

@potiuk

@potiuk potiuk commented Sep 22, 2026

Copy link
Copy Markdown
Member

Summary

The two belong together: the first documents the failure mode, the second is it happening again and being caught by the step that now exists.

Type of change

  • Skill change — optimize-skill Step 3 and hard rules; isolated-setup-verify split into a sibling
  • CI / dev loop — one eval step-config.json gains also_include
  • Documentation — regenerated counts

What the install split taught

Splitting isolated-setup-install (#1333) broke two of its four eval suites and nothing caught it until the suites ran. A suite builds its prompt live from skill_md plus step_heading; a heading that moves to a sibling leaves it extracting from a file that no longer contains it. The validator was green. prek was green.

Step 3 now says to follow every reference before calling a restructure pass done:

  • Eval step-config.json — with the grep that finds them.
  • Anchor links anywhere in the tree — lychee catches these, which is why it runs whole-tree rather than over the diff.
  • The heading level itself. A block cut from mid-body starts at ###, cannot open a new file, and shifts a level — changing both the anchor and the string an eval matches on. That makes it the one byte a split may change, and the hard rule now says so rather than leaving "identical bytes" to be read literally and then quietly violated.

Of the three, lychee catches one, the validator catches none, and only running the suite catches the eval configs. That is the concrete argument for the eval gate.

The verify split, and why it is not the obvious one

The twelve checks are the run. Moving them wholesale would have bought a read and saved nothing — the trap the pre-flight block taught. So only the conditional checks moved:

moved condition
Check 9 — vetted-ops split only when the adopter routes through the dispatcher
Check 10 — hardware key, signing key only when commits are signed or ssh goes through gpg-agent
Check 12 — container gateway only when podman or docker is on PATH
Check 13 — eval-harness exclusion only when step M was taken
Check 8 — whole-user scope detection only when core.hooksPath is set

3,916 tokens in conditional-checks.md. Each leaves its condition and the n/a answer in the body, so a run without vetted-ops, without a signing key, without podman, in per-project scope, reads none of it.

Checks 5 and 8 were then tightened in place to land under budget: the below-floor branching says the same three things in fewer words, and the hard-fail rule is untouched — still explicitly saying not to downgrade it to a ⚠.

Eval evidence

result
baseline, unmodified main 11/14, 3 failures
after the split 9/14
after also_include 12/14

step-1-classify/case-7 was genuinely mine: it grades sub-check 10a against a body that now held only a stub. That suite builds its prompt from ## The 12 checks, so it needs the sibling too — also_include supplies it, the same mechanism added for the pre-flight in #1324.

The two survivors are both step-2-recommend, whose section (## After the report) is byte-identical to main and which failed on the baseline run as well, on the same follow_up ordering assertion. Reported rather than adjudicated, which is what the skill now says to do with a suite that cannot hold still.

Test plan

  • prek run --all-files clean.
  • skill-and-tool-validate passes.
  • Graded evals for setup-isolated-setup-verify: 12/14, against an 11/14 baseline measured on unmodified main.

Notes for reviewers

Still over budget, not here: setup 8,853 (already has 12 siblings), isolated-setup-doctor 7,859 and isolated-setup-update 5,512, both with no siblings.

No prose pass on the setup family yet. Checks 5 and 8 were tightened only because the body sat 47 tokens over after the structural move; that is the whole of the rewording here.

🤖 Generated with Claude Code

…eferences

Splitting `isolated-setup-install` broke two of its four eval suites and
nothing caught it until the suites ran.  A suite builds its prompt live
from `skill_md` plus `step_heading`, so a heading that moves to a
sibling leaves the suite extracting from a file that no longer contains
it.  The validator was green.  `prek` was green.

Step 3 now says to follow every reference to a moved heading before
calling the pass done: eval `step-config.json` (with the grep that finds
them), anchor links anywhere in the tree, and the heading level itself —
a block cut from mid-body starts at `###`, cannot open a new file, and
so shifts a level, which changes both the anchor and the string an eval
matches on.  That makes it the one byte a split may change, and the hard
rule now says so rather than leaving "identical bytes" to be read
literally and then quietly violated.

This is also the concrete argument for Step 4 running the suites at all:
of the three reference classes, `lychee` catches the anchors, the
validator catches neither of the others, and only the suite catches the
eval configs.

Generated-by: Claude Opus 5
The twelve checks *are* the run, so moving them wholesale would have
bought a read and saved nothing — the trap the pre-flight block taught.
Four of them are conditional, and those move: the vetted-ops split (9),
the hardware key (10), the container gateway (12) and the eval-harness
exclusion (13), plus check 8's whole-user scope detection, which only
applies when `core.hooksPath` is set.  Each leaves its condition and the
**n/a** answer in the body, so a run without vetted-ops, without a
signing key, without podman and in per-project scope reads none of them.

That is 3,916 tokens in `conditional-checks.md`.  Checks 5 and 8 were
then tightened in place to land the body under budget at 4,966: the
below-floor branching says the same three things in fewer words, and the
hard-fail rule is untouched, still saying not to downgrade it to a ⚠.

**Eval evidence, because a split can break a suite invisibly.**
Baseline on unmodified `main`: 11/14, three failures including
`step-2-recommend/case-5-multiple`.  After the split: 9/14 — and
`step-1-classify/case-7` was mine, grading sub-check 10a against a body
that now held only a stub.  That suite builds its prompt from `## The 12
checks`, so it needs the sibling too; `also_include` supplies it.  With
that, 12/14 — above baseline — and both survivors are
`step-2-recommend`, whose section is byte-identical to `main` and which
failed on the baseline run as well.

Generated-by: Claude Opus 5
@potiuk
potiuk merged commit 2c99629 into apache:main Sep 22, 2026
10 checks passed
potiuk added a commit that referenced this pull request Sep 24, 2026
Reconciles the spec-loop specs with the functionality that shipped
between 5c75abd and bcd8b7f:

- agent-isolation-sandbox: the hardware-key touch policy (sig cached +
  aut off with OpenPGP signing, aut cached with gpg.format=ssh) (#1367);
  touch-watcher owner is the harness (#1365); macOS overlay closes on
  deactivation (#1325); whole-user git hooks allowRead and dispatcher
  flavour (#1364, #1322, #1358); agent-guard finds the git subcommand
  past global flags (#1330); agent-guard plugin counts as a complete
  install (#1323); per-tool cooldown_days, bubblewrap 0.13.0 (#1360).
- sandbox-diagnostics: ten catalogue entries (prek/uv not found, git
  hooks silently skipped) (#1359, #1364); doctor probes as scripts, with
  probes 7 and 8 (#1336, #1362, #1364); verify's 12 checks and
  conditional-checks.md (#1334).
- vetted-command-surface: HTTP read backend with the OSV and CVE.org
  operations (#1326); the vetted-op-read recipe spelling (#1339); the
  plugin copy resolves standalone (#1357).
- cve-tooling: tools/osv (contract:security-cross-ref) and the cve-org
  check through vetted-ops (#1297, #1326).
- security-issue-lifecycle: step 2b proposes going ahead on a quiet
  reporter (#1340); the post-advisory security-pages update (#1355).
- meta-and-quality-tooling: name: must match the skill directory
  (#1361); skill-evals fixture containment and grader retry (#1315,
  #1341); optimize-skill budgets, eval gate, rewrite and extract-code
  passes (#1331, #1332, #1335, #1338); diff-scoped prek CI (#1317).
- marketplace-distribution: substrate plugins (#1368, #1357).
- adversarial-review (new): the tool and substrate plugin as shipped
  (#1368), with its known gaps.

Generated-by: Claude Opus 5
potiuk added a commit that referenced this pull request Oct 28, 2026
…text into sibling files (#1883)

* perf(setup-isolated-setup-verify): drop check 10's duplicated hardware-key definition

The check 10 stub in SKILL.md repeated, word for word, the hardware-key
definition that conditional-checks.md carries in full in the section the
stub points to. Keep the condition and the n/a rule in the body and leave
the definition to the section, which is read whenever check 10 applies.

Generated-by: Claude Opus 5

* perf(setup-isolated-setup-verify): move checks 15 and 16 into conditional-checks.md

Check 15 applies only when the read block is on and check 16 only with
vetted-ops, yet both bodies sat in SKILL.md and were read on every run.
Move them, byte for byte, into conditional-checks.md beside checks 9-14
and 17, and leave each one's condition and n/a rule in the body with a
pointer, the shape #1334 gave the other conditional checks.

Generated-by: Claude Opus 5

* perf(setup-isolated-setup-verify): move the follow-up map into remediation.md

"After the report" was a ~1.7k-token map from each ✗ or ⚠ to its
follow-up, read in full even by an all-✓ run that stops after one line.
Move the bullets, byte for byte, into remediation.md, read only when a
finding needs a follow-up, and give the step-2-recommend eval the file
through also_include so it still sees the map.

Generated-by: Claude Opus 5

* perf(setup-isolated-setup-verify): move the non-Claude routing into runtime-routing.md

Runtime routing carried a paragraph per non-Claude harness (Codex,
Antigravity, Goose, Pi, Copilot CLI) that every Claude Code run read and
then skipped. Move them, byte for byte, into runtime-routing.md, keep the
runtime selection and the Claude Code branch in the body with a pointer,
and give the codex-native and runtime-routing evals the file through
also_include.

Generated-by: Claude Opus 5

* docs(spec-loop): record the verify skill's new sibling files

Generated-by: Claude Opus 5
@potiuk potiuk added capability:authoring Skills that author or maintain other skills: write-skill, optimize-skill capability:platform Framework / agent substrate skills (install, verify, doctor, override, status, setup bootstrap) family:docs Docs, MISSION.md, READMEs family:setup setup-* skills family:utilities utilities skills labels Nov 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

capability:authoring Skills that author or maintain other skills: write-skill, optimize-skill capability:platform Framework / agent substrate skills (install, verify, doctor, override, status, setup bootstrap) family:docs Docs, MISSION.md, READMEs family:setup setup-* skills family:utilities utilities skills

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant