[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6DF1BQJMENSP4N23A2ZRAXF":3,"skill-same:01M6DF1BQJMENSP4N23A2ZRAXF":75},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":23,"publishedAt":44,"linkOnly":45,"markdownContent":46,"markdownBody":47,"frontMatter":48,"refName":49,"commitSha":50,"skillDirectory":51,"forksCount":14,"repositoryHtmlUrl":52,"repositoryHomepageUrl":6,"ownerHtmlUrl":53,"ownerBlogUrl":6,"ownerDescription":6,"updatedAt":54,"install":55,"resources":68},"01M6DF1BQJMENSP4N23A2ZRAXF","two-tier-verify",null,"Use when repeated code edits are triggering a full test-suite rerun each iteration and burning tokens\u002Ftime, or before any commit. Splits verification into a cheap INNER loop per edit (only the affected\u002Frelated tests plus type-check and lint on touched files) and a single OUTER loop at the commit boundary (full suite plus coverage plus held-out E2E\u002Fgolden-journey plus a scoped mutation check). Gives concrete jest\u002Fvitest\u002Fplaywright and pytest command recipes and the decision rule for which tier to run. NOT a replacement for the golden-journey done-signal (see seed-golden-journey); NOT for one-off single-file scripts where a full run is already trivial.","Prekzursil\u002Fagent-skills-toolchain","Prekzursil","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F54636077?v=4","01M6DACZ1PCQHD99SCR1YXG28B","Andrei Mihai Visalon","01M6DACZ670WZF535V3WYYSS4Z",0,"MIT","https:\u002F\u002Fgithub.com\u002FPrekzursil\u002Fagent-skills-toolchain\u002Fblob\u002Fmain\u002Fskills\u002Ftwo-tier-verify\u002FSKILL.md",[18],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000008","测试与质量","SCENARIO","使用场景",[24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43],"two tier verify","verify","only","tests","tokens","iteration","mutation","time","done","journey","files","code","single-file","use","coverage","decision","loop","vitest","e2e","file","2026-11-10 10:12:30",false,"---\nname: two-tier-verify\ndescription: Use when repeated code edits are triggering a full test-suite rerun each iteration and burning tokens\u002Ftime, or before any commit. Splits verification into a cheap INNER loop per edit (only the affected\u002Frelated tests plus type-check and lint on touched files) and a single OUTER loop at the commit boundary (full suite plus coverage plus held-out E2E\u002Fgolden-journey plus a scoped mutation check). Gives concrete jest\u002Fvitest\u002Fplaywright and pytest command recipes and the decision rule for which tier to run. NOT a replacement for the golden-journey done-signal (see seed-golden-journey); NOT for one-off single-file scripts where a full run is already trivial.\n---\n\n# two-tier-verify\n\nThe default agentic edit loop is `edit → rerun the WHOLE suite → read all output → edit again`.\nThat is the single biggest token\u002Ftime sink in long repair sessions — ProjDevBench measured\n**~4.81M tokens per problem**, dominated by re-running and re-reading tests that the last edit\ncould not possibly have affected. Test-impact selection (Ekstazi \u002F Microsoft TIA \u002F CloudBees)\ncuts test time **32–70%** by running only the tests reachable from the change.\n\nThe fix is to **split verification into two tiers** and never confuse them:\n\n- **INNER loop** — runs after *every* edit. Fast, narrow, cheap. Only the tests related to the\n  files you touched, plus a type-check and a lint on those files. This is your iteration signal.\n- **OUTER loop** — runs *once*, at the commit boundary (and before a PR). Slow, total, external.\n  Full suite + coverage threshold + the held-out E2E\u002Fgolden-journey + a scoped mutation check.\n  This is your merge signal.\n\n**Law:** the INNER loop is for *iterating*; it is never a done-signal. Only a green OUTER loop\nauthorizes a commit. Related-test selection is fast precisely because it is blind to seams it\ncan't reach — so it can go green while an integration path is broken. That gap is exactly what\nthe OUTER loop's full suite + golden-journey exist to close.\n\n## The two tiers\n\n| | INNER (per edit) | OUTER (per commit) |\n|---|---|---|\n| Frequency | every edit \u002F iteration | once, at the commit\u002FPR boundary |\n| Target | tests **related to changed files** only | **full** suite |\n| Also runs | type-check + lint on touched files | coverage threshold + held-out E2E\u002Fgolden-journey + scoped mutation check |\n| Budget | seconds (aim \u003C 30s) | minutes — pay it once |\n| Role | iteration feedback | **merge gate \u002F done-signal** |\n| On failure | fix, re-run INNER | map failure back to the change, drop to INNER |\n\n## Decision rule — which tier, when\n\n1. **After each edit → INNER.** Run related-tests + type + lint on the touched files. Loop here\n   until green. Do NOT run the full suite between edits.\n2. **At the commit boundary → OUTER, exactly once.** Full suite + coverage + golden-journey +\n   mutation micro-check. Only a green OUTER run authorizes the commit.\n3. **Escalate INNER → OUTER early** (run the full suite now, not at the boundary) when the change\n   can fan out past what related-test selection can see:\n   - a **shared\u002Fcore\u002Fbase module**, a widely-imported util, or a public interface changed;\n   - **config \u002F build \u002F dependency \u002F CI \u002F test-infra** edits (`package.json`, `pyproject.toml`,\n     `tsconfig`, `jest.config`, `conftest.py`, lockfiles) — impact selection can't model these;\n   - the related-test set came back **empty or suspiciously small** for a real code change\n     (selection missed it — trust the full suite instead).\n4. **Never cite the INNER result as \"done.\"** \"Related tests pass\" ≠ \"the app works.\" The\n   done-signal lives in the OUTER loop (full suite + golden-journey), per seed-golden-journey.\n\n> **Neighbour — `smallest-check-ladder`** states this same split as four rungs: L0 lint\u002Ftypecheck\n> the edited file, L1 impacted tests, L2 full suite, L3 e2e against the built artifact. INNER here\n> is its L0+L1; OUTER is its L2+L3. Go there for the rung-by-rung selector commands and the \"name\n> the rung you actually reached\" honesty rails; stay here for the decision rule and the\n> per-framework recipes below.\n\n## Command recipes — JS \u002F TS (jest, vitest, playwright)\n\n**INNER (per edit):**\n```bash\n# jest — run only tests that import the changed file(s):\nnpx jest --findRelatedTests src\u002Ffoo.ts src\u002Fbar.ts --coverage=false --bail\n#   or, git-driven, all tests related to files changed vs HEAD:\nnpx jest -o --coverage=false            # --onlyChanged\n\n# vitest — run only tests related to the changed files:\nnpx vitest related src\u002Ffoo.ts --run     # --run = single pass, not watch\n#   or git-driven since HEAD:\nnpx vitest run --changed\n\n# type-check + lint on what you touched (the \"AST\" gate):\nnpx tsc --noEmit --incremental           # fast type gate (whole project, cached)\nnpx eslint src\u002Ffoo.ts src\u002Fbar.ts --max-warnings=0\n\n# Electron\u002Fweb E2E in the INNER loop: run ONE spec, never the whole E2E suite:\nnpx playwright test e2e\u002Fthat-one.spec.ts --project=chromium\n```\n\n**OUTER (per commit):**\n```bash\nnpx jest --coverage                      # full suite + coverage\n# (or vitest: npx vitest run --coverage)\n# enforce the project's threshold — .coverage-thresholds.json is the SSOT if present:\n#   jest reads coverageThreshold from config; fail the commit if it drops.\nnpx playwright test                      # full E2E incl. the held-out golden-journey\nnpx stryker run --mutate src\u002Ffoo.ts,src\u002Fbar.ts   # mutation MICRO-check, scoped to the change\n```\n\n## Command recipes — Python (pytest)\n\n**INNER (per edit):**\n```bash\n# affected module only:\npytest tests\u002Ftest_foo.py -q -x\n# test-impact selection across the repo (tracks which tests hit which lines):\npip install pytest-testmon && pytest --testmon -q     # reruns only impacted tests\n# or fail-fast on last failures while iterating:\npytest --lf -q          # last-failed;  --ff = failed-first\n\n# type + lint on the touched files (the \"AST\" gate):\nmypy src\u002Ffoo.py         # or: pyright src\u002Ffoo.py\nruff check src\u002Ffoo.py\n```\n\n**OUTER (per commit):**\n```bash\npytest --cov=src --cov-report=term-missing        # full suite + coverage\n# enforce threshold (SSOT = .coverage-thresholds.json if present):\npytest --cov=src --cov-fail-under=\u003Cthreshold>\n# held-out acceptance (kept out of the default select, e.g. an e2e marker):\npytest -m e2e                                     # the golden-journey \u002F acceptance run\n# mutation MICRO-check, scoped to the changed module:\nmutmut run --paths-to-mutate src\u002Ffoo.py           # or cosmic-ray for a targeted config\n```\n\n## Mapping an OUTER failure back to the change\n\nThe OUTER loop runs on an accumulation of edits, so a failure isn't self-locating. Recover the\nseam without re-running everything:\n```bash\ngit diff --name-only \u003Clast-green-outer>..HEAD     # the files in play\n# re-run just the failing test against the suspect files:\nnpx jest --findRelatedTests \u003Csuspect-file> -t \"\u003Cfailing test name>\"\npytest tests\u002Ftest_x.py::test_y -q\n# still ambiguous over many commits? bisect the failing test only:\ngit bisect start HEAD \u003Clast-green-outer>\ngit bisect run npx jest -t \"\u003Cfailing test name>\"\n```\nThen drop back to the INNER loop on the located file until it's green, and re-run OUTER once.\n\n## Caveats\n\n- **Selection ≠ safety.** `--findRelatedTests` \u002F `vitest related` \u002F `--testmon` follow static or\n  recorded import graphs; they miss runtime seams (subprocess spawns, IPC, file\u002FDB side effects,\n  mocked boundaries). That blind spot is *why* the OUTER loop keeps the held-out golden-journey —\n  it exercises the real A→B→C path the selection can't model.\n- **Type-check is project-wide by nature.** TS types cross files, so `tsc --noEmit` can't be a\n  single-file op — use `--incremental` so it's still cheap in the INNER loop.\n- **Coverage is an OUTER-only metric.** Never gate an inner edit on coverage %; it's a\n  commit-boundary threshold, and it is necessary-but-not-sufficient (see seed-golden-journey).\n- **Mutation is a micro-check, not a suite.** Scope it to the changed files (`--mutate \u003Cfile>`);\n  a full-tree mutation run belongs in CI, not the commit loop.\n- **Config\u002Fdep\u002Ftest-infra edits void selection** — always OUTER (rule 3).\n\n## Three ways a green OUTER loop still lies (each measured, not hypothesised)\n\nThe OUTER loop is the merge signal, but it is measured against *your* working tree, on *your*\nbox, by *your* tests. Each of those three is a place a green has been wrong here.\n\n### 1. WORKING-TREE green ≠ CLONE green\n\nMeasured: a suite reported **3,910 passed** in the working tree and **31 collection errors** from\na fresh clone of the *same commit*. The gap is everything the tree has that the commit does not —\nuntracked files, stale `__pycache__`, an editable install, a local `conftest.py`, a path that only\nresolves because of where you happen to be standing. CI checks out a clone, so the clone is the\none that counts.\n\n```bash\ngit clone --no-hardlinks \"C:\u002FUsers\u002Fyou\u002Fsource\u002F\u003Crepo>\" \u002Ftmp\u002Fclonecheck   # Windows-style path:\ncd \u002Ftmp\u002Fclonecheck && git checkout \u003Csha> && \u003Cinstall> && \u003Cfull suite>   #   MSYS mangles \u002Fc\u002F...\n```\n\nDo this before any \"ready to merge\" claim on a repo whose suite you have never run cold. Note the\npath form: use `C:\u002FUsers\u002F...`, not `\u002Fc\u002FUsers\u002F...` — and do **not** set `MSYS_NO_PATHCONV=1`\nglobally to work around it, because that suppresses the conversion the clone path itself needs\nand the clone then silently does not happen.\n\n### 2. LOCAL formatter green ≠ CI formatter green (CRLF vs LF)\n\nYour working tree is CRLF; git stores LF; CI checks out LF. Formatters make different decisions\non the two forms — measured: `ruff format --check` said *\"1 file already formatted\"* locally while\nCI said *\"Would reformat\"* for the same commit. Verify against the **stored blob**:\n\n```bash\ngit show \u003Crev>:\u003Cpath>          # LF, exactly what CI checks out\ngit cat-file -p \"$(git rev-parse \u003Crev>:\u003Cpath>)\"\n```\n\n**Never `git archive` for this.** Re-measured on two files in this repo, with a control proving\nall routes are byte-identical after LF-normalisation (so the delta is purely EOL, not content):\n`git show` and `git cat-file -p` → 7,487 B \u002F **0 CRLF**; `git archive` + `tar -x` and the working\ntree → 7,627 B \u002F **140 CRLF**. `git archive` applies export-time EOL conversion and hands back\nexactly the bytes you were trying to look past. Pin the tool version too (`uvx ruff@\u003Cpinned>`) —\na local 0.15.22 and a CI 0.15.17 format differently.\n\n### 3. A green SUITE is not a green DETECTOR\n\nA gate that has never gone red is indistinguishable from a no-op. Two in-repo instruments exist\nfor this and are worth naming because they are otherwise unreachable — neither is referenced by\nany skill, hook, or (for the first) any CI job:\n\n- **`tools\u002Fdetector-self-test\u002F`** — the both-states harness: run a probe against the KNOWN-BROKEN\n  state and require it to FIRE there before its silence counts as \"fixed\".\n- **`tools\u002Fmeasure-guard\u002F`** — `suitefloor` (a run below its declared minimum test count FAILS\n  regardless of exit code — it is the §1 clone-vs-tree gap turned into a gate), `refcheck`,\n  `wudeps`, `jsonparse` and `vendordrift` are executed by `.github\u002Fworkflows\u002Fquality.yml`\n  (`:114`, `:439-443`). **`blobread` is NOT** — grep it and you get exactly one hit,\n  `quality.yml:416`, which is a *comment*. It is the §2 wrong-bytes reader and it is available\n  as a library today, not as a gate. Naming a tool in a CI comment is not running it; count the\n  step, not the mention.\n\nThe mutation micro-check in the OUTER loop is the same idea applied to the tests: revert a real\nbug and require the suite to go red. One of six mutations surviving is a genuine hole, not noise.\n","# two-tier-verify\n\nThe default agentic edit loop is `edit → rerun the WHOLE suite → read all output → edit again`.\nThat is the single biggest token\u002Ftime sink in long repair sessions — ProjDevBench measured\n**~4.81M tokens per problem**, dominated by re-running and re-reading tests that the last edit\ncould not possibly have affected. Test-impact selection (Ekstazi \u002F Microsoft TIA \u002F CloudBees)\ncuts test time **32–70%** by running only the tests reachable from the change.\n\nThe fix is to **split verification into two tiers** and never confuse them:\n\n- **INNER loop** — runs after *every* edit. Fast, narrow, cheap. Only the tests related to the\n  files you touched, plus a type-check and a lint on those files. This is your iteration signal.\n- **OUTER loop** — runs *once*, at the commit boundary (and before a PR). Slow, total, external.\n  Full suite + coverage threshold + the held-out E2E\u002Fgolden-journey + a scoped mutation check.\n  This is your merge signal.\n\n**Law:** the INNER loop is for *iterating*; it is never a done-signal. Only a green OUTER loop\nauthorizes a commit. Related-test selection is fast precisely because it is blind to seams it\ncan't reach — so it can go green while an integration path is broken. That gap is exactly what\nthe OUTER loop's full suite + golden-journey exist to close.\n\n## The two tiers\n\n| | INNER (per edit) | OUTER (per commit) |\n|---|---|---|\n| Frequency | every edit \u002F iteration | once, at the commit\u002FPR boundary |\n| Target | tests **related to changed files** only | **full** suite |\n| Also runs | type-check + lint on touched files | coverage threshold + held-out E2E\u002Fgolden-journey + scoped mutation check |\n| Budget | seconds (aim \u003C 30s) | minutes — pay it once |\n| Role | iteration feedback | **merge gate \u002F done-signal** |\n| On failure | fix, re-run INNER | map failure back to the change, drop to INNER |\n\n## Decision rule — which tier, when\n\n1. **After each edit → INNER.** Run related-tests + type + lint on the touched files. Loop here\n   until green. Do NOT run the full suite between edits.\n2. **At the commit boundary → OUTER, exactly once.** Full suite + coverage + golden-journey +\n   mutation micro-check. Only a green OUTER run authorizes the commit.\n3. **Escalate INNER → OUTER early** (run the full suite now, not at the boundary) when the change\n   can fan out past what related-test selection can see:\n   - a **shared\u002Fcore\u002Fbase module**, a widely-imported util, or a public interface changed;\n   - **config \u002F build \u002F dependency \u002F CI \u002F test-infra** edits (`package.json`, `pyproject.toml`,\n     `tsconfig`, `jest.config`, `conftest.py`, lockfiles) — impact selection can't model these;\n   - the related-test set came back **empty or suspiciously small** for a real code change\n     (selection missed it — trust the full suite instead).\n4. **Never cite the INNER result as \"done.\"** \"Related tests pass\" ≠ \"the app works.\" The\n   done-signal lives in the OUTER loop (full suite + golden-journey), per seed-golden-journey.\n\n> **Neighbour — `smallest-check-ladder`** states this same split as four rungs: L0 lint\u002Ftypecheck\n> the edited file, L1 impacted tests, L2 full suite, L3 e2e against the built artifact. INNER here\n> is its L0+L1; OUTER is its L2+L3. Go there for the rung-by-rung selector commands and the \"name\n> the rung you actually reached\" honesty rails; stay here for the decision rule and the\n> per-framework recipes below.\n\n## Command recipes — JS \u002F TS (jest, vitest, playwright)\n\n**INNER (per edit):**\n```bash\n# jest — run only tests that import the changed file(s):\nnpx jest --findRelatedTests src\u002Ffoo.ts src\u002Fbar.ts --coverage=false --bail\n#   or, git-driven, all tests related to files changed vs HEAD:\nnpx jest -o --coverage=false            # --onlyChanged\n\n# vitest — run only tests related to the changed files:\nnpx vitest related src\u002Ffoo.ts --run     # --run = single pass, not watch\n#   or git-driven since HEAD:\nnpx vitest run --changed\n\n# type-check + lint on what you touched (the \"AST\" gate):\nnpx tsc --noEmit --incremental           # fast type gate (whole project, cached)\nnpx eslint src\u002Ffoo.ts src\u002Fbar.ts --max-warnings=0\n\n# Electron\u002Fweb E2E in the INNER loop: run ONE spec, never the whole E2E suite:\nnpx playwright test e2e\u002Fthat-one.spec.ts --project=chromium\n```\n\n**OUTER (per commit):**\n```bash\nnpx jest --coverage                      # full suite + coverage\n# (or vitest: npx vitest run --coverage)\n# enforce the project's threshold — .coverage-thresholds.json is the SSOT if present:\n#   jest reads coverageThreshold from config; fail the commit if it drops.\nnpx playwright test                      # full E2E incl. the held-out golden-journey\nnpx stryker run --mutate src\u002Ffoo.ts,src\u002Fbar.ts   # mutation MICRO-check, scoped to the change\n```\n\n## Command recipes — Python (pytest)\n\n**INNER (per edit):**\n```bash\n# affected module only:\npytest tests\u002Ftest_foo.py -q -x\n# test-impact selection across the repo (tracks which tests hit which lines):\npip install pytest-testmon && pytest --testmon -q     # reruns only impacted tests\n# or fail-fast on last failures while iterating:\npytest --lf -q          # last-failed;  --ff = failed-first\n\n# type + lint on the touched files (the \"AST\" gate):\nmypy src\u002Ffoo.py         # or: pyright src\u002Ffoo.py\nruff check src\u002Ffoo.py\n```\n\n**OUTER (per commit):**\n```bash\npytest --cov=src --cov-report=term-missing        # full suite + coverage\n# enforce threshold (SSOT = .coverage-thresholds.json if present):\npytest --cov=src --cov-fail-under=\u003Cthreshold>\n# held-out acceptance (kept out of the default select, e.g. an e2e marker):\npytest -m e2e                                     # the golden-journey \u002F acceptance run\n# mutation MICRO-check, scoped to the changed module:\nmutmut run --paths-to-mutate src\u002Ffoo.py           # or cosmic-ray for a targeted config\n```\n\n## Mapping an OUTER failure back to the change\n\nThe OUTER loop runs on an accumulation of edits, so a failure isn't self-locating. Recover the\nseam without re-running everything:\n```bash\ngit diff --name-only \u003Clast-green-outer>..HEAD     # the files in play\n# re-run just the failing test against the suspect files:\nnpx jest --findRelatedTests \u003Csuspect-file> -t \"\u003Cfailing test name>\"\npytest tests\u002Ftest_x.py::test_y -q\n# still ambiguous over many commits? bisect the failing test only:\ngit bisect start HEAD \u003Clast-green-outer>\ngit bisect run npx jest -t \"\u003Cfailing test name>\"\n```\nThen drop back to the INNER loop on the located file until it's green, and re-run OUTER once.\n\n## Caveats\n\n- **Selection ≠ safety.** `--findRelatedTests` \u002F `vitest related` \u002F `--testmon` follow static or\n  recorded import graphs; they miss runtime seams (subprocess spawns, IPC, file\u002FDB side effects,\n  mocked boundaries). That blind spot is *why* the OUTER loop keeps the held-out golden-journey —\n  it exercises the real A→B→C path the selection can't model.\n- **Type-check is project-wide by nature.** TS types cross files, so `tsc --noEmit` can't be a\n  single-file op — use `--incremental` so it's still cheap in the INNER loop.\n- **Coverage is an OUTER-only metric.** Never gate an inner edit on coverage %; it's a\n  commit-boundary threshold, and it is necessary-but-not-sufficient (see seed-golden-journey).\n- **Mutation is a micro-check, not a suite.** Scope it to the changed files (`--mutate \u003Cfile>`);\n  a full-tree mutation run belongs in CI, not the commit loop.\n- **Config\u002Fdep\u002Ftest-infra edits void selection** — always OUTER (rule 3).\n\n## Three ways a green OUTER loop still lies (each measured, not hypothesised)\n\nThe OUTER loop is the merge signal, but it is measured against *your* working tree, on *your*\nbox, by *your* tests. Each of those three is a place a green has been wrong here.\n\n### 1. WORKING-TREE green ≠ CLONE green\n\nMeasured: a suite reported **3,910 passed** in the working tree and **31 collection errors** from\na fresh clone of the *same commit*. The gap is everything the tree has that the commit does not —\nuntracked files, stale `__pycache__`, an editable install, a local `conftest.py`, a path that only\nresolves because of where you happen to be standing. CI checks out a clone, so the clone is the\none that counts.\n\n```bash\ngit clone --no-hardlinks \"C:\u002FUsers\u002Fyou\u002Fsource\u002F\u003Crepo>\" \u002Ftmp\u002Fclonecheck   # Windows-style path:\ncd \u002Ftmp\u002Fclonecheck && git checkout \u003Csha> && \u003Cinstall> && \u003Cfull suite>   #   MSYS mangles \u002Fc\u002F...\n```\n\nDo this before any \"ready to merge\" claim on a repo whose suite you have never run cold. Note the\npath form: use `C:\u002FUsers\u002F...`, not `\u002Fc\u002FUsers\u002F...` — and do **not** set `MSYS_NO_PATHCONV=1`\nglobally to work around it, because that suppresses the conversion the clone path itself needs\nand the clone then silently does not happen.\n\n### 2. LOCAL formatter green ≠ CI formatter green (CRLF vs LF)\n\nYour working tree is CRLF; git stores LF; CI checks out LF. Formatters make different decisions\non the two forms — measured: `ruff format --check` said *\"1 file already formatted\"* locally while\nCI said *\"Would reformat\"* for the same commit. Verify against the **stored blob**:\n\n```bash\ngit show \u003Crev>:\u003Cpath>          # LF, exactly what CI checks out\ngit cat-file -p \"$(git rev-parse \u003Crev>:\u003Cpath>)\"\n```\n\n**Never `git archive` for this.** Re-measured on two files in this repo, with a control proving\nall routes are byte-identical after LF-normalisation (so the delta is purely EOL, not content):\n`git show` and `git cat-file -p` → 7,487 B \u002F **0 CRLF**; `git archive` + `tar -x` and the working\ntree → 7,627 B \u002F **140 CRLF**. `git archive` applies export-time EOL conversion and hands back\nexactly the bytes you were trying to look past. Pin the tool version too (`uvx ruff@\u003Cpinned>`) —\na local 0.15.22 and a CI 0.15.17 format differently.\n\n### 3. A green SUITE is not a green DETECTOR\n\nA gate that has never gone red is indistinguishable from a no-op. Two in-repo instruments exist\nfor this and are worth naming because they are otherwise unreachable — neither is referenced by\nany skill, hook, or (for the first) any CI job:\n\n- **`tools\u002Fdetector-self-test\u002F`** — the both-states harness: run a probe against the KNOWN-BROKEN\n  state and require it to FIRE there before its silence counts as \"fixed\".\n- **`tools\u002Fmeasure-guard\u002F`** — `suitefloor` (a run below its declared minimum test count FAILS\n  regardless of exit code — it is the §1 clone-vs-tree gap turned into a gate), `refcheck`,\n  `wudeps`, `jsonparse` and `vendordrift` are executed by `.github\u002Fworkflows\u002Fquality.yml`\n  (`:114`, `:439-443`). **`blobread` is NOT** — grep it and you get exactly one hit,\n  `quality.yml:416`, which is a *comment*. It is the §2 wrong-bytes reader and it is available\n  as a library today, not as a gate. Naming a tool in a CI comment is not running it; count the\n  step, not the mention.\n\nThe mutation micro-check in the OUTER loop is the same idea applied to the tests: revert a real\nbug and require the suite to go red. One of six mutations surviving is a genuine hole, not noise.\n",{"name":5,"description":7},"main","a298c929b6cbd662e1fce54302ce520d5ceea1a5","skills\u002Ftwo-tier-verify","https:\u002F\u002Fgithub.com\u002FPrekzursil\u002Fagent-skills-toolchain","https:\u002F\u002Fgithub.com\u002FPrekzursil","2026-11-02 14:30:57",{"source":8,"skillName":5,"commands":56,"prompt":66,"zipAvailable":67},[57,60,63],{"tool":58,"command":59},"npx","npx skills add Prekzursil\u002Fagent-skills-toolchain --skill two-tier-verify",{"tool":61,"command":62},"bunx","bunx skills add Prekzursil\u002Fagent-skills-toolchain --skill two-tier-verify",{"tool":64,"command":65},"pnpm","pnpm dlx skills add Prekzursil\u002Fagent-skills-toolchain --skill two-tier-verify","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002FPrekzursil\u002Fagent-skills-toolchain\u002Fblob\u002Fmain\u002Fskills\u002Ftwo-tier-verify\u002FSKILL.md",true,[69],{"path":70,"resourceType":71,"resourceTypeDesc":72,"sizeBytes":73,"sourceHtmlUrl":74},"README.md","REFERENCE","参考文档",2077,"https:\u002F\u002Fgithub.com\u002FPrekzursil\u002Fagent-skills-toolchain\u002Fblob\u002Fmain\u002Fskills\u002Ftwo-tier-verify\u002FREADME.md",[76,96,124,148,162,178],{"skillNo":77,"name":78,"nameZh":6,"description":79,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":80,"categories":81,"keywords":82,"publishedAt":44},"01M6DF7D7478R55P46REYH4QAC","clarify-requirements","Resolve genuine pre-execution ambiguity by scanning repo context, generating 1-6 grounded options, and asking 1-3 focused questions via AskUserQuestion. NOT for mid-task use (injection risk); NOT when the goal is already unambiguous; use to disambiguate vague prompts before any file edits.","https:\u002F\u002Fgithub.com\u002FPrekzursil\u002Fagent-skills-toolchain\u002Fblob\u002Fmain\u002Ftools\u002Fworkspace-hooks\u002Fskills\u002Fclarify-requirements\u002FSKILL.md",[],[83,84,85,86,87,88,89,90,91,37,92,93,94,95,43],"clarify requirements","clarify","requirements","risk","options","task","prompts","goal","scanning","context","repo","injection","execution",{"skillNo":97,"name":98,"nameZh":6,"description":99,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":100,"categories":101,"keywords":105,"publishedAt":44},"01M6DF79CA4BHJS66J8EZDBPWJ","openmm-md","Run FREE, open-source, Windows-native GPU molecular dynamics via the openmm-md MCP (OpenMM + CUDA on the local NVIDIA GPU). Use for protein \u002F protein-ligand MD when you want a free stack or are on Windows without a Schrodinger license. Covers the full workflow (prepare, solvate, minimize, equilibrate, production, analyze, mmgbsa) AND an honest decision guide vs Schrodinger Desmond, including how to run Desmond legitimately on Linux or a cloud GPU with a real license. This is a deliberately LESSER free alternative and does NOT replace the schrodinger MCP tools. Do NOT use it to pick a free tool when a validated FEP+, WaterMap, IFD-MD, or Prime MM-GBSA result is actually required.","https:\u002F\u002Fgithub.com\u002FPrekzursil\u002Fagent-skills-toolchain\u002Fblob\u002Fmain\u002Ftools\u002Fmcp\u002Fopenmm-md-mcp\u002Fskill\u002Fopenmm-md\u002FSKILL.md",[102],{"categoryNo":103,"categoryName":104,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000023","Skill与智能体开发",[106,107,39,108,109,110,111,112,113,114,115,116,117,118,37,119,120,121,122,123],"openmm md","how","pick","linux","analyze","tool","stack","open","NVIDIA","gpu","license","workflow","windows","free","molecular dynamics","local","do","MCP",{"skillNo":125,"name":126,"nameZh":6,"description":127,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":128,"categories":129,"keywords":134,"publishedAt":44},"01M6DF76C1MG85VEWP8VZCBNMN","visual-review","Take screenshots of web pages and UI using Playwright for visual review and iteration","https:\u002F\u002Fgithub.com\u002FPrekzursil\u002Fagent-skills-toolchain\u002Fblob\u002Fmain\u002Ftools\u002Feditor\u002Fmetaswarm\u002Fskills\u002Fvisual-review\u002FSKILL.md",[130,133],{"categoryNo":131,"categoryName":132,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000003","演示文稿",{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},[135,136,137,138,139,140,29,141,142,143,107,144,145,146,147],"review","visual","visual review","pages","web","false","take","check","slides","ui","screenshot","playwright","screenshots",{"skillNo":149,"name":150,"nameZh":6,"description":151,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":152,"categories":153,"keywords":154,"publishedAt":44},"01M6DF73AQVCBZKEN0YXEX9FXP","status","Diagnostic status report — shows metaswarm installation state, project setup, and potential issues","https:\u002F\u002Fgithub.com\u002FPrekzursil\u002Fagent-skills-toolchain\u002Fblob\u002Fmain\u002Ftools\u002Feditor\u002Fmetaswarm\u002Fskills\u002Fstatus\u002FSKILL.md",[],[150,155,156,157,158,159,160,161],"setup","report","project","installation","project setup","issues","state",{"skillNo":163,"name":164,"nameZh":6,"description":165,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":166,"categories":167,"keywords":169,"publishedAt":44},"01M6DF6X6C2XB0P6GX76P7TTYV","start","Use when starting work on any task, when the user mentions metaswarm, or when the user wants to begin tracked development work","https:\u002F\u002Fgithub.com\u002FPrekzursil\u002Fagent-skills-toolchain\u002Fblob\u002Fmain\u002Ftools\u002Feditor\u002Fmetaswarm\u002Fskills\u002Fstart\u002FSKILL.md",[168],{"categoryNo":103,"categoryName":104,"taxonomyType":21,"taxonomyTypeDesc":22},[164,170,88,171,172,173,37,174,175,176,177],"start issue","issue","ready","work on issue","user","work","work on","development",{"skillNo":179,"name":155,"nameZh":6,"description":180,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":181,"categories":182,"keywords":183,"publishedAt":44},"01M6DF6QMJ9AJKFKHHKRT005PQ","Interactive project setup — detects your project, configures metaswarm, writes project-local files","https:\u002F\u002Fgithub.com\u002FPrekzursil\u002Fagent-skills-toolchain\u002Fblob\u002Fmain\u002Ftools\u002Feditor\u002Fmetaswarm\u002Fskills\u002Fsetup\u002FSKILL.md",[],[155,157,121,34,159,184],"interactive"]