[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M74ZHTPFFN3CV8PJMKDPZVC1":3,"skill-same:01M74ZHTPFFN3CV8PJMKDPZVC1":62},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":15,"categories":16,"keywords":17,"publishedAt":18,"linkOnly":19,"markdownContent":20,"markdownBody":21,"frontMatter":22,"refName":35,"commitSha":36,"skillDirectory":37,"forksCount":38,"repositoryHtmlUrl":39,"repositoryHomepageUrl":40,"ownerHtmlUrl":41,"ownerBlogUrl":6,"ownerDescription":6,"updatedAt":42,"install":43,"resources":55},"01M74ZHTPFFN3CV8PJMKDPZVC1","harness-doctor",null,"Scans a project's harness structure (.claude\u002F directory, CLAUDE.md, rules, agents) to diagnose complexity, drift, missing files, and broken references, then suggests improvements. `--lint` flag adds language-pattern scan (self-marketing, cushion words, version brags). Triggered by \"harness check\", \"structure diagnosis\", \"CLAUDE.md audit\".","chrono-meta\u002Fforge-harness","chrono-meta","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F151837060?v=4","01M74ZDXK87ES4B30NKYSEH3MS","01M74ZDXM0F1NMYK7BS7PYR54G",33,"MIT","https:\u002F\u002Fgithub.com\u002Fchrono-meta\u002Fforge-harness\u002Fblob\u002Fmain\u002Fplugins\u002Ffh-meta\u002Fskills\u002Fharness-doctor\u002FSKILL.md",[],[],"2026-11-12 13:55:43",false,"---\nname: harness-doctor\ndescription: Scans a project's harness structure (.claude\u002F directory, CLAUDE.md, rules, agents) to diagnose complexity, drift, missing files, and broken references, then suggests improvements. `--lint` flag adds language-pattern scan (self-marketing, cushion words, version brags). Triggered by \"harness check\", \"structure diagnosis\", \"CLAUDE.md audit\".\nuser-invocable: true\nallowed-tools: [\"Read\", \"Bash\", \"Glob\", \"Grep\"]\nmodel: sonnet\ncomplexity_routing:\n  base: sonnet\n  high: opus\n  escalate_when:\n    - cold_start\n    - cross_project\n---\n\n# harness-doctor — Harness Structure Diagnosis + Prescription\n\n\"A good harness gets simpler over time. If it's getting more complex, something is wrong.\"\n\nDiagnoses harness structural health across 5 layers and proposes M\u002FS\u002FR prescriptions:\n\n1. **L1 Structural completeness** — required file existence (CLAUDE.md · .claudeignore · .claude\u002F)\n2. **L2 Complexity** — current state vs. simplification principle (line count · unused files · duplicate definitions)\n3. **L3 Drift** — rule vs. actual pattern mismatch (broken references · stale files · conflicting rules)\n4. **L4 Connection diagnosis** *(FH environment only)* — meta hub ↔ field project reference consistency\n5. **L5 Pattern analysis** *(FH environment only)* — skill activity · call context appropriateness · effect metrics\n\n---\n\n## Execution Steps\n\n### Step 1. Confirm Diagnostic Target\n\nCheck current cwd harness file structure and determine if FH environment (tracks\u002F + knowledge\u002F + plugins\u002F all present).\n\n### Step 2. L1 — Structural Completeness\n\n| File | When Missing |\n|---|---|\n| `CLAUDE.md` | **M-tier** — harness entry impossible |\n| `.claudeignore` | S-tier — context-doctor execution recommended |\n| `.claude\u002F` directory | M-tier (when rule files exist) |\n\n### Step 2-E. L1-E — ETCLOVG Layer Coverage *(functional-layer lens — orthogonal to the file-presence table above)*\n\nA harness is not only files; it is **seven functional layers** (ETCLOVG — arXiv:2606.06324, a component\ntaxonomy *orthogonal* to FH's 6-axis process model; cross-audit\n`tracks\u002F_audit\u002Fsession_2026_06_19_harnessfix-etclovg-cross-audit.md`). FH adopts only the **taxonomy as a\ncoverage lens** — not the paper's scoring model. A **coverage checklist, not a mandate**: not every\nharness needs all seven (a read-only doc harness needs no Execution or Governance). For each layer ask\n\"is there an asset covering it?\"; surface gaps, let the human judge if each is real for *this* harness.\n\n> **Orthogonal-sister ledger (same adoption rule — anchor only, no scoring model imported)**:\n> GRACE (arXiv:2607.09175, cross-audit `tracks\u002F_audit\u002Fsession_2026_07_24_grace-context-rubric.md`,\n> operator-local record) — typed-semantic-graph **scoped verification** for the **C (Context) layer's\n> maintenance path**: edits validated only within the modified node's local typed neighborhood. Cite\n> when a C-layer gap involves *how context updates are verified*, not just whether context assets exist.\n\n| Layer | Covers | Typical FH asset | If the gap is judged real → priority hint |\n|---|---|---|---|\n| **E** Execution | isolated\u002Freproducible env, bounded autonomy | Agent-dispatch isolation · goal-quench budget | advisory |\n| **T** Tooling | tool discovery \u002F selection \u002F gating | mcp_tool_gating · plugin-recommender | advisory |\n| **C** Context | what the model sees: card, memory, retrieval | session card · CATALOG · context-doctor | advisory |\n| **L** Lifecycle | loops, retries, orchestration, termination | agent-composer · goal-quench | advisory |\n| **O** Observability | traces \u002F logs \u002F cost to diagnose failures | subagent_invocations_log · audit logs · activity log | advisory |\n| **V** Verification | readiness · intermediate · final · regression checks | 4-axis gate (steel\u002Fphantom\u002Fregression_guard) | higher-stakes |\n| **G** Governance | permissions · approvals · audit trails | HITL gates · public-surface gate | higher-stakes |\n\n**Relationship to the Harness-Defect Taxonomy (below)**: ETCLOVG = *component coverage* (is the layer\npresent?); the Defect Taxonomy = *failure modes* (is a present layer degrading?). Orthogonal — coverage vs health.\n\n**Check class**: judged (advisory) — the presence test is mechanical, but \"is this gap real for this\nharness's purpose?\" is a judged call, **paired** with the human review at Step 7's M-tier gate. **Never\nauto-tier a missing layer into the M\u002FS\u002FR report** — the priority column is a *hint only if a human\nconfirms the gap*, never a verdict the report emits on its own; surface each gap tagged \"(human-confirm)\".\n(FH's own weak layer is **Observability** — retrospective audit only, no runtime layer; named in the cross-audit.)\n\n### Step 3. L2 — Complexity Diagnosis\n\n**Scope the instrument first — field vs meta** (CLAUDE.md §Identity Core Axis): a **field harness** must get\n\"simpler over time\" (complexity = warning signal), so raw size is a real signal there. A **meta-harness**\n(the FH hub itself) *optimizes* rather than simplifies — **complexity earns its scope**, and the doctrine's\nred flags are **orphaned, redundant, and decorative units, not size**. Applying the field rule to a\nmeta-harness produces a false M-tier on healthy growth.\n\n**Scope is mechanical, never self-declared** — else any repo dodges the line rows by calling itself meta\n(the self-label loophole CLAUDE.md already names for \"docs-only\" at the Irreversibility gate). A target is\n**meta** iff its root holds **all three**: `tracks\u002F` **and** `knowledge\u002F` **and** `plugins\u002F` (Step 1's FH-environment\ntest). Anything else is **field** — including a repo that merely *contains* skills or a `.claude\u002F` dir:\n\n**The test is rooted at the TARGET, never at cwd.** FH's own default mode diagnoses a field project\n*without* switching cwd (CLAUDE.md §Agent Dispatch — \"Direct edit … no cwd switch needed\"), so a bare\n`[ -d tracks ]` run from the hub misclassifies **every** field target as meta and silently deletes the\nfield rows — a permissive misread reachable through the harness's own recommended workflow. Always pass\nthe target path explicitly:\n\n```bash\n# meta iff all three exist AT THE TARGET ROOT — otherwise field. TARGET is required, never implied by cwd.\nTARGET=\"${1:?pass the target root explicitly — cwd is not the target}\"\n[ -d \"$TARGET\u002Ftracks\" ] && [ -d \"$TARGET\u002Fknowledge\" ] && [ -d \"$TARGET\u002Fplugins\" ] \\\n  && echo \"scope: meta ($TARGET)\" || echo \"scope: field ($TARGET)\"\n```\n\nScope is a **coarse instrument-selector, not a security boundary**: `[ -d ]` tests existence, not contents,\nso three empty dirs would flip field→meta. That is acceptable here (the operator names the target; there is\nno adversary picking it) — but it means scope must never gate anything that matters on its own, only *which\nsize instrument* is read. The footprint rows below apply to **both** scopes and are the actual verdict.\n\n| Check | Verdict |\n|---|---|\n| **Field\u002Fproject** CLAUDE.md 100~200 lines | S-tier warning |\n| **Field\u002Fproject** CLAUDE.md 200+ lines | M-tier — separation or reduction needed |\n| **Field\u002Fproject** 15+ `##` sections in CLAUDE.md | S-tier warning |\n| **Meta-harness (FH hub)** CLAUDE.md — raw line \u002F section count | **Not a verdict.** Judge by the always-loaded footprint rows below (char-based = actual token cost) + the doctrine's red flags (orphaned · redundant · decorative). Report the count as context only |\n| **Meta-harness — residency ledger** (the positive instrument that replaces the disabled line-count rows) | For each `##` section record **trigger class** (intent \u002F file \u002F ambient) + **backstop** (a hook or script path that must be **grep-verified to exist AND to be wired**, or the literal `none-by-nature`). Tier ONLY these: **M** = a section claiming a mechanical floor whose script is referenced by no hook (a prose-invoked \"floor\" is not a floor) · **S** = `file`-triggered *with* a verified backstop but still resident (splittable — name the destination glob) · **S** = duplicated verbatim in another section · **R** = orphaned\u002Fdecorative. A section that is intent- or ambient-triggered with `none-by-nature` is **PASS, not a finding** — moving it would be fail-open. Never tier a section on its size |\n| **Meta-harness** growth since last run: decompose into *new sections* vs *existing-section growth* (mechanical — diff `##` section names + line counts vs the prior run's commit; **first run \u002F no prior commit → report both as n\u002Fa, no tier**) | **Tier is decided by the two counts alone**: **S-tier iff existing-section growth > new-section growth** (the file is thickening faster than it is gaining capability); otherwise advisory, no tier. Report both numbers **and** the new sections' names — the names are *reporting output for the human*, never an input to the tier. Do not judge \"was this growth capability-bearing?\" per line |\n| SKILL.md > 300 lines AND no `SKILL_detail.md` | S-tier — propose `\u002Fsalience-splitter` (governance-semantic split, not compression) |\n| Rules files unreferenced in CLAUDE.md | R-tier |\n| **Called but content-blind** — a gate · check · lane that IS invoked (has callers) but returns the same verdict whatever its input (the third «decorative» shape, after «no caller» and «caller ignores the result»; arXiv:2610.41604) | S-tier. Detector is the existing revert\u002Fmutation probe, not a new scanner: feed one known-positive and one known-negative input and confirm the verdict differs. Same verdict for both → decorative. Reading the code is not the test — a check that greps for its own hook reference passes this row while its verdict never moves |\n| Always-loaded footprint > 40k chars (see scan below for what counts) | S-tier — **lever depends on where the chars live**: rules\u002Fdetail still auto-loading → relocate to a non-loaded dir (e.g. `knowledge\u002Fshared\u002Frules\u002F`), pointers stay in CLAUDE.md · narrative inside CLAUDE.md → `\u002Fsalience-splitter` · **behavioral content only, nothing left to relocate** → capability-level (merge\u002Fretire a governance unit) |\n| **Memory-index footprint** — the session's auto-loaded memory index (`~\u002F.claude\u002Fprojects\u002F\u003Cslug>\u002Fmemory\u002FMEMORY.md`), reported as **its own line, never summed into the row above** | S-tier > 10k chars — **different residency, different lever**: this one is `\u002Fmemory-hygiene` (archive closed items to `MEMORY_archive.md`, tighten hooks to one line), NOT `\u002Fsalience-splitter`. Summing it into the CLAUDE.md row would mis-route the lever, which is exactly what the row above ties to \"where the chars live\". **Blind spot this closes (2026-07-20, measured)**: a fresh top-level `\u002Fcontext` showed **Memory files = 41.7k of 68.8k resident tokens (61%)**, of which `MEMORY.md` alone was **14.1k — 55% the size of CLAUDE.md (25.5k)** — and the footprint scan below counted **none of it**. The instrument was optimising the smaller half of the surface it claimed to measure |\n| Always-loaded footprint > 80k chars | M-tier — same lever selection, mandatory, **and never self-discharged** (see below) |\n| **Pointer-illusion**: a CLAUDE.md \"detail\u002Fdetailed procedure\" pointer whose target is itself an always-loaded `.claude\u002Frules\u002F*.md` | S-tier — the split saves zero context (rules\u002F auto-loads regardless); move the target out of auto-load, keep the pointer |\n| weekly_audit 14~30 days elapsed | S-tier |\n| weekly_audit 30+ days elapsed | M-tier |\n\n**Per-unit ≠ aggregate — do not slide between them.** \"Every section earns its scope\" (the per-unit\ndoctrine test) and \"the always-loaded total is affordable\" (the budget test) are **different questions, and\nboth can be true at once**. A meta-harness can pass the red-flag test on every single section and still be\nover its footprint budget. So a per-unit PASS never discharges the footprint rows — and conversely, a\nfootprint M-tier is *not* evidence that some section failed to earn its scope. When footprint is over\nbudget but every unit earns its scope, the remaining lever is **capability-level** — merge or retire a\ngovernance unit — **not** a salience split, which by construction only moves narrative and returns ~nothing\nwhen the content is behavioral.\n\n**Any scan-derived count must be calibrated before it is reported.** Before a number from a scan\n(broken refs, INACTIVE skills, footprint chars, orphan counts, coverage) enters the report, run it\nagainst **one known-positive and one known-negative** and record both outcomes; then **hand-verify the\nsingle case the scan is most confident about**. If either step is skipped the number ships labeled\n`UNCALIBRATED` and may not ground a tier. `not found` is reported as `UNMEASURED`, never as `0` — a\nscan that dies mid-run reports a low number, and low numbers read as PASS.\nOrigin (2026-07-20, three instrument defects in one session): a footprint scan omitted 61% of the\nresident surface it claimed to measure · a size ratio was used as a proxy for content coverage · an\nASCII-token scanner run over a Korean corpus produced ~96% false positives and a \"70%\" figure that was\npublished to three records before one hand-check reduced it to 3 items. **Suspect the instrument before\nthe target whenever a value is impossible** (all-pass, all-fail, or a self-scan that fails to detect the\nrunning tool itself). Full procedure: `knowledge\u002Fshared\u002Fharness-core\u002Fmeasurement-integrity-checklist.md\n§Instrument-Calibration`.\n\n**Every M\u002FS-tier must cite the row it fired — verbatim, from this file.** Write the finding as\n`M-n · \u003Cverbatim row text or its threshold> · \u003Cmeasured value>`. If you cannot quote the row, **you do not\nhave a finding** — downgrade to an observation. Origin (2026-07-20, instrument defect n+4, the *fourth* in\na single run): a run fired `M-1 · CLAUDE.md 816 lines — exceeds the FH threshold of 500`. The string `500`\ndid not occur anywhere in this file at the time (a later grep finds 2 — both in this narrative, added by\nthis very post-mortem; the self-referential claim drifted and is corrected here rather than re-asserted).\n🟥 **And that grep was scoped wrong**: it searched this file only. The 500 was NOT invented from nothing —\n`docs\u002Fplatform_sustainability.md` carried it as a live standard until 2026-08-20, contradicting this row.\nThe lesson is not \"the run hallucinated\" but **\"the absence check was run against the wrong corpus\"**\n([[feedback_absence_measurement_needs_control]] — a no-hit grep is evidence only when its scope covers\nwhere the thing would actually live). The meta-harness row it claimed to read says raw\nline count is **\"Not a verdict.\"** So the run invented a threshold *and* fired a row this skill explicitly\ndisables for meta-harnesses — the exact recurrence of the 2026-07-15 inversion documented below, which had\nalready been patched *in the skill*. The patch held; the **run** ignored it. A verdict grounded in a\ncitation that cannot be quoted is the same defect class as a phantom reference, and it propagates: a\ndownstream sidecar judgment inherited the fabricated 500 and reasoned from it until a grep caught it.\n\n**No M-tier in this skill is ever self-discharged — not just the footprint one.** \"The cost is priced \u002F\naccepted\", \"it's all necessary\", \"over budget but fine\" are **not** verdicts this skill may reach on its\nown: an M-tier stands in the report and is closed only by an explicit operator acknowledgment logged to\n`tracks\u002F_meta\u002F` (same shape as any other logged override). This is **row-agnostic on purpose** — the\nrationale (a run under ship pressure prices away the one row that fired) is not specific to footprint, so\nscoping the prohibition to a single row would leave every other M-tier open to the same silent PASS. That\nis the default-toward-PASS class `field_verdict_crossfamily_gate.md` exists to catch, committed inside the\ndiagnostic that names it. **Report it; do not price it.**\n\n> Origin (2026-07-15, dogfood): a run read FH's CLAUDE.md at 891 lines, fired the raw-count M-tier, and\n> prescribed `\u002Fsalience-splitter`. Measurement inverted both halves: **+244 of the +381 30-day growth (64%)\n> was 6 new governance sections**, each behavioral and salience-passing (two — Voice\u002FTone, Envelope-Boundary —\n> had been *promoted* to always-loaded precisely because memory-only placement made them miss), and actually\n> running the splitter on 4 sections yielded **−27 lines \u002F −3.2k chars (−3.7%)** — confirming salience-splitter's\n> own Target Selection rule (\"splitting a file with only behavioral content adds structure without governance\n> value\"). The **footprint** row meanwhile fired M-tier correctly and had been M since 06-15. Two rows measured\n> the same property; the worse instrument drove the verdict. The line-count rows are now field-scoped.\n\nAlways-loaded + pointer-illusion checks are mechanical (found 2026-07-12 — FH itself shipped ~50k chars of rules\u002F behind \"detail pointers\" that saved nothing; the meta-harness blind spot this row closes):\n\n```bash\n# always-loaded footprint (chars). Counts every file the session loads before turn 1:\n#   CLAUDE.md + CLAUDE.local.md + rules files lacking paths: frontmatter + their DIRECT @-imports.\n# EVERY path is rooted at $TARGET — the same root the scope test used. Reading from cwd instead\n# measures whichever harness you happen to be standing in (usually the hub, while diagnosing a\n# field target) — a wrong-target measurement that reports the hub's number as the target's.\nTARGET=\"${1:?pass the target root explicitly — cwd is not the target}\"\n# MEMORY-INDEX (reported SEPARATELY — see the memory-index row above; do NOT add it to T).\n# It is auto-loaded every session but lives outside $TARGET, so the $TARGET-rooted sum below is\n# structurally blind to it. Measured 2026-07-20: it was 55% the size of CLAUDE.md and invisible here.\nMEMSLUG=$(printf '%s' \"$TARGET\" | sed 's|^\u002F||; s|\u002F|-|g')\nMEMIDX=\"$HOME\u002F.claude\u002Fprojects\u002F-$MEMSLUG\u002Fmemory\u002FMEMORY.md\"\nif [ -f \"$MEMIDX\" ]; then\n  echo \"memory-index: $(wc -c \u003C \"$MEMIDX\") chars — $MEMIDX  (lever: \u002Fmemory-hygiene, NOT salience-splitter)\"\nelse\n  echo \"memory-index: not found at $MEMIDX — report as UNMEASURED, not as 0 (a missing file is not an empty one)\"\nfi\nT=0\nfor f in \"$TARGET\u002FCLAUDE.md\" \"$TARGET\u002FCLAUDE.local.md\"; do\n  [ -f \"$f\" ] && T=$((T + $(wc -c \u003C \"$f\")))\ndone\n# find | while, not a glob: an unmatched glob aborts under zsh, and a here-string of \"\" still yields\n# one empty line -> head -5 \"\" errors and the sum breaks. A scan that dies mid-run reports a LOW\n# number (= toward PASS), so guard the empty case explicitly.\nwhile IFS= read -r f; do\n  [ -n \"$f\" ] || continue\n  head -5 \"$f\" | grep -q '^paths:' || T=$((T + $(wc -c \u003C \"$f\")))\ndone \u003C \u003C(find \"$TARGET\u002F.claude\u002Frules\" -name '*.md' 2>\u002Fdev\u002Fnull)\n# DIRECT @-imports only (not transitive — a nested import chain is a named residual below).\n# Resolve against the IMPORTING FILE's own dir first, then ~\u002F.claude\u002F. SUM into T — never\n# print-and-ask-the-reader-to-add: a scan that delegates arithmetic re-introduces the judgment\n# it exists to remove, and the omission points toward PASS.\nfor f in \"$TARGET\u002FCLAUDE.md\" \"$TARGET\u002FCLAUDE.local.md\"; do\n  [ -f \"$f\" ] || continue\n  d=$(dirname \"$f\")\n  for i in $(grep -oE '^@[A-Za-z0-9_.\u002F-]+' \"$f\" 2>\u002Fdev\u002Fnull | sed 's\u002F^@\u002F\u002F'); do\n    for c in \"$d\u002F$i\" \"$HOME\u002F.claude\u002F$i\"; do\n      [ -f \"$c\" ] && { T=$((T + $(wc -c \u003C \"$c\"))); echo \"  +import $c: $(wc -c \u003C \"$c\") chars\"; break; }\n    done\n  done\ndone\necho \"always-loaded TOTAL ($TARGET): $T chars\"\n# Verdict: the HIGHEST tripped threshold wins — 80k supersedes 40k. Reporting only the\n# S-tier row while >80k is a silent FAIL->CONDITIONAL_PASS downgrade.\n[ \"$T\" -gt 80000 ] && echo \"  => M-tier (>80k)\" || { [ \"$T\" -gt 40000 ] && echo \"  => S-tier (>40k)\" || echo \"  => footprint ok\"; }\n# pointer-illusion: CLAUDE.md pointers targeting still-auto-loaded rules files (any filename shape)\ngrep -oE '\\.claude\u002Frules\u002F[A-Za-z0-9_.\u002F-]+\\.md' \"$TARGET\u002FCLAUDE.md\" 2>\u002Fdev\u002Fnull | sort -u | while read -r p; do\n  [ -f \"$TARGET\u002F$p\" ] && echo \"ILLUSION: $p (pointed-to AND always-loaded)\"\ndone\n```\n\n**Named residuals of this scan** (all documented, none silent): **transitive imports are not followed** —\nan import chain `CLAUDE.md → A.md → B.md` counts A but not B, so a deep chain under-counts *toward PASS*;\n**`head -5 … grep '^paths:'`** is a proxy, not a frontmatter parser — an incidental early `paths:` line\nfalsely excludes an always-loaded rule (toward PASS), while a `paths:` below line 5 over-counts (toward\nFAIL, the safe direction); and the scope test reads directory *existence*, so three empty dirs flip\nfield→meta (acceptable: the operator names the target, and the footprint rows apply to **both** scopes\nregardless — but it does skip the field-only line rows).\n\n\u003C!-- Context-File Taxonomy check removed 2026-07-22\u002F23 (#153 → weekly-audit #6 decision): consumer\n     re-measure = 0 skills read role:\u002Ftype: from these files; measured FP 99\u002F161 (61%) un-narrowed,\n     19\u002F26 (73%) after narrowing; origin citation was mis-attributed (SPECULATIVE, no primary source).\n     Decorative unit per doctrine — FP figures preserved in the removal commit message as the\n     regression anchor. Re-adding requires a named consumer first. -->\n\n### Step 3-L. Language Lint (`--lint` mode only)\n\n> Activate with `\u002Fharness-doctor --lint` or when harvest-loop surfaces a P10-series signal. Skipped in standard runs.\n\nGrep-based scan of SKILL.md, agent `.md`, and doc files for self-marketing language patterns. Outputs replacement suggestions — no automatic edits.\n\n**Detection patterns**:\n\n| Pattern | Examples | Replacement direction |\n|---|---|---|\n| Self-declarations of quality | \"industry-leading\", \"the world's first\", \"core skill\", \"best\" | Delete — no external evidence |\n| Version \u002F iteration labels | \"v0.3\", \"22nd naming round\", \"26th iteration\", \"(added 2026-05-24)\" | Remove (git history manages versioning) |\n| Cushion language | \"easily\", \"instantly\", \"seamlessly\", \"without burden\", \"fully automated\" | Replace with behavior-based description |\n| Owner self-reference loops | \"validated by our team\", \"proven internally\" | Delete or replace with external evidence |\n| Marketing word stacking | 3+ adjectives in one sentence | Reduce to functional description |\n| Spec-only artifacts | SKILL.md or agent file missing `Done When` section | Add observable output criteria |\n\n**Scan targets**:\n```bash\nfind {FH_ROOT}\u002Fplugins -name \"SKILL.md\" | sort\nfind {FH_ROOT}\u002F.claude\u002Fagents -name \"*.md\" | sort\nfind {FH_ROOT}\u002Fdocs -name \"*.md\" 2>\u002Fdev\u002Fnull | sort\n```\n\n**Detection commands**:\n```bash\n# version \u002F iteration labels\ngrep -n \"v[0-9]\\+\\.[0-9]\\|[0-9]\\+th\\|[0-9]\\+th iteration\\|prototype [0-9]\\+\" {file}\n# cushion language\ngrep -n \"fully\\|instantly\\|full coverage\\|automatically\\|conveniently\\|easily\\|without burden\\|seamlessly\" {file}\n# self-declaration patterns\ngrep -n \"core skill\\|world's first\\|best\\|most\\|top\\|industry-leading\" {file}\n```\n\n**Output format** (per file):\n```\nFile: {path}\n  L{N}: \"{original text}\"\n  → Suggested: \"{replacement}\" (reason: {pattern type})\n  → Or: remove (reason: {pattern type})\n```\n\n**Lint findings** feed into Step 7 report as a separate \"Language Quality\" section — not mixed into structural M\u002FS\u002FR tiers. Lint findings are advisory: HIGH (spec-only = missing Done When, treat as S-tier) \u002F LOW (language patterns, R-tier).\n\n---\n\n### Step 4. L3 — Drift Diagnosis\n\n| Check | Tier |\n|---|---|\n| Broken local file references in CLAUDE.md | M-tier |\n| .claude\u002Frules files unmodified 90+ days | R-tier |\n| settings.json JSON syntax error | M-tier |\n| Hooks in settings.json (PostToolUse\u002FStop) that don't fire in Agent View | S-tier or M-tier |\n| Public-surface FH recommendation or default changed — no N-shot measurement evidence traceable in session records or PR body | S-tier |\n| Pre-commit-adjacent gate reads the working tree (cat\u002Fglob of a *tracked* path) with no `--staged`\u002F`--cached`\u002F`git show :` on that path, when its verdict is about *what's committed* | S-tier |\n\nHook divergence verdict: 0 hooks = Normal · 1+ hooks (session-end\u002FStop) = S-tier · 1+ hooks (PostToolUse file writes or external API) = M-tier (data loss risk in Agent View).\n\n**Index-vs-worktree gate lint** (2026-06-21, gate-locality corollary — `[[feedback_gate_locality_principle]]`):\na gate whose verdict is about *what is being committed* must read the **staged index**\n(`git ls-files --cached` \u002F `git show :path`), not the working tree (`cat`\u002Fglob of a tracked file) —\nelse it false-PASSes a commit whose staged content ≠ disk (origin: `count_check.sh` read the worktree\nwhile the pre-commit hook fired on the index; the sibling `regression_guard` already used `--staged`,\nso the lesson existed but was non-local). Mechanical scan — in the pre-commit hook + the scripts it\ninvokes (+ `scripts\u002F*-check.sh`): flag a `cat`\u002F`\u003C`\u002Fglob read of a tracked path with no\n`--staged`\u002F`--cached`\u002F`git show :` on that path. **Conditional (NOT universal)**: a gate whose verdict is\nabout what *runs\u002Fdeploys* (pre-push tests, build, an auto-fixer that rewrites the worktree) correctly\nreads the working tree — a line-level `# worktree-intentional:` comment suppresses the flag. FP surface\n(isolated-critic): display\u002Flog reads and untracked generated files are not violations → keep advisory\n(S-tier, never M).\n\n### Step 5. L4 — Connection Diagnosis *(FH only)*\n\n- Tracks with no sync in 30+ days → R-tier\n- CATALOG.md: 5+ open items in recent 5 sessions → S-tier\n- Field project CLAUDE.md missing → S-tier\n- **Knowledge cross-ref lint**: `knowledge\u002F**\u002F*.md` with no CATALOG.md entry → S-tier\n  (index orphan — unfindable via CATALOG-first search); with no inbound reference from\n  any CLAUDE.md \u002F rules \u002F SKILL.md \u002F knowledge doc → R-tier (orphan page).\n  Mechanical: `grep -L` filenames against CATALOG.md, then `grep -rl` for inbound refs.\n\n### Step 6. L5 — Pattern Analysis *(FH only)*\n\n**L5-A Skill Activity** (grep-based on session records):\n\n| State | Criteria | Tier |\n|---|---|---|\n| ACTIVE | 2+ times in 30 days | Normal |\n| LOW_ACTIVE | 1 time in 30 days | R-tier |\n| INACTIVE_30D | 0 times in 30 days | S-tier |\n| INACTIVE_90D | 0 times in 90 days | M-tier |\n\n**L5-B Call Context Appropriateness**: Keyword grep for known misuse patterns (hub-persona-auditor in code PR context · sim-conductor without onboarding · harness-doctor self-loop). Report as \"suspected (false positive possible)\" — no LLM call.\n\n**L5-C Effect Metrics**:\n\n| Metric | OK condition | Tier if failing |\n|---|---|---|\n| E1 CLAUDE.md lines | Decrease or ±10 | E1_WARN if +50 lines |\n| E2 Complexity ratio | ≤100 lines\u002Fskill | E2_WARN (≤200) \u002F E2_FAIL (>200) |\n| E3 CATALOG open consumption | ≥50% in 30 days | — |\n| E4 harvest signals | ≥3 in 30 days | — |\n| E5 SKILL.md change | Within 14 days | — |\n| E6 Cold audit | Within 30 days | E6_WARN |\n| E7 Evolution-loop observability | Asset edits have edit_manifest predictions | E7_WARN = S-tier |\n\n**HHS** (Harness Health Score): Each OK condition = +1 point (7 max). HHS ≥ 4 = Healthy · 2~3 = Caution · ≤1 = Critical.\n\n> **Detail**: See `SKILL_detail.md §L5-Detail` — bash scripts for L5-A, L5-B, L5-C\u002FE metrics — read when running L5 pattern analysis.\n\n---\n\n## Harness-Defect Taxonomy (frontier cross-check)\n\n| Defect class | FH detectable signals | Tier |\n|---|---|:---:|\n| **Context Drift** | Stale paths in CLAUDE.md (L3) · rules unmodified 90+ days (L3) · CLAUDE.md over threshold (L2) | S |\n| **Schema Misalignment** | Plugin count drift · SKILL.md missing `Done When` (undocumented contract) | M |\n| **State Degradation** | tracks\u002F no sync 30+ days (L4) · INACTIVE_90D skills (L5-A) · orphaned memory entries | M |\n| **Agentic Laziness** *(runtime)* | Completion claims without per-item evidence — \"all N done\" with no enumerable list in session records \u002F PR bodies · Done When lacking any mandatory-pass condition | S |\n| **Self-Preferential Bias** *(runtime)* | judged-class check without a named adversarial pairing (gate-rejectable for new skills; scan existing for backfill) · a self-graded verdict cited as sole completion evidence | M |\n| **Goal Drift** *(runtime)* | Long session with S\u002FA-tier work but no pre-compaction completion log (`fh_completed_*` missing) · early-stated constraints absent from card\u002Fmanifest at close | S |\n| **Comprehension Debt** *(runtime\u002Foperator)* | Merged FH-asset change with no CATALOG entry · edit_manifest `validation_status: pending` backlog piling up unverified · session closed with work done but zero card delta | S |\n| **Evidence Gap** *(FH self-dev)* | Public-surface FH recommendation or default changed with no N-shot measurement evidence traceable in session records or PR history (L3 check) | S |\n\nSignal in 2+ classes → escalate one tier.\nRows 1–3 = structural (2026-06-02 frontier diagnosis). Rows 4–6 = runtime behavioral, agent-side —\nnamed from dynamic-workflows discourse (2026-06). Row 7 = runtime, operator-side — named from\nloop-engineering discourse (Osmani, 2026-06): loop output outpacing operator understanding. FH\ncountermeasures already exist and are what the signals check for: golden probes + multi-persona\ncoverage (laziness) · judged-pairing rule (bias) · pre-compaction completion log + card-last guard\n(drift) · CATALOG 3-line summaries + manifest predict-verify + card protocol (comprehension debt).\n\n---\n\n### Step 7. M\u002FS\u002FR Prescription Report Output\n\n```\n## harness-doctor Diagnostic Results\n\n### 🟥 M-tier (Immediate Action)\n### 🟧 S-tier (Strongly Recommended)\n### 🟩 R-tier (Recommended)\n\n---\n## ETCLOVG Layer Coverage (L1-E)\n- Covered: [layers with an asset, e.g. E·T·C·L·V·G]\n- Gaps (surfaced, never auto-tiered — each \"(human-confirm)\"): [e.g. \"O Observability (human-confirm) — retrospective audit only, no runtime layer\"] or \"full coverage\"\n\n---\n## L5 Pattern Analysis\n- Activity (L5-A): [list]\n- Context appropriateness (L5-B): [suspected misuse or \"no issues\"]\n- Effect metrics (L5-C): E1=[result] \u002F E3=[result] \u002F E5=[result]\n\n---\n## Language Quality (`--lint` mode only)\n- HIGH (spec-only — missing Done When): [list or \"none\"]\n- LOW (language patterns): [file: L{N}: \"{text}\" → {suggestion}]\n\nDiagnostic scope: L1 (+L1-E ETCLOVG coverage) ~L3 [· L4 · L5 (FH only)] [· --lint]\n```\n\nM-tier 0 → output \"Structure healthy. Maintaining simplification trend.\"\n\n**M-tier Immediate Human Gate**: If 1+ M-tier found → pause, surface options: (a) AI proceeds to Step 8 \u002F (b) human review first \u002F (c) abort. Do not auto-apply prescriptions that could close a self-referential loop.\n\n### Step 8. harvest-loop Integration *(when tracks\u002F_audit\u002F exists)*\n\nWhen 1+ M-tier found → propose adding `## Harness Structure Check (harness-doctor)` section to latest weekly_audit file.\n\n### Step 9. Eval-First Quantitative Gate *(v0.x → v1 promotion only)*\n\n**Thresholds** (measured over 5 sim-conductor runs): Tool Selection Accuracy > 0.90 · Multi-Step Coherence > 0.85 · Clarification Rate \u003C 0.30.\n\n### Step 10. Regression Guard *(when SKILL.md \u002F rules \u002F CLAUDE.md modified)*\n\nVerifies that prescription application didn't strip operational content. Run after prescription applied, at pre-merge gate, or when harvest-loop Step 4 detects file changes.\n\n| Check | Tier |\n|:---:|:---:|\n| F1 Frontmatter integrity | M |\n| F2 Critical section preservation (Execution Steps · Done When · Triggers) | M |\n| F3 Code block count not reduced by 4+ | S |\n| F4 Operational keyword preservation (M-tier\u002FS-tier\u002FWave\u002FStep\u002FDone When) | M if ≥50% drop · S if 20~49% |\n| F5 Cross-reference paths resolve | M |\n| F6 Line reduction ≥30% | S |\n| F7 Bash block syntax (bash -n parse) | M if net increase in bad blocks |\n\nVerdict: ✅ PASS (0M 0S) · ⚠️ REVIEW (0M 1+S) · ❌ BLOCK (1+M) · ⏭️ SKIP (검사 대상 0 — **PASS 가 아니다**).\n\nImplementation: `bash templates\u002Fregression_guard.sh` (compare vs main) or `bash templates\u002Fregression_guard.sh BASE HEAD`.\n**Verdict 는 종료코드가 아니라 typed 채널로 읽어라** — `exit 0` 은 pass 와 skip 둘 다다(2026-07-23):\n`REGRESSION_GUARD_RESULT_FILE=\u002Ftmp\u002Frg.$$ bash templates\u002Fregression_guard.sh …` 후 파일의\n`result=pass|review|block|skip` 를 판정에 쓴다. `skip` = 미검사 — PASS 로 보고하지 말고 \"Axis 1\n해당 없음(대상 파일 0)\" 으로 보고한다.\n\n> **Detail**: See `SKILL_detail.md §Step-1-3` — bash scripts for Steps 1~6 (L1~L4 diagnostics) — read when running the diagnostic commands.\n\n### Step 11. PR Change Consistency Check *(triggered on \"PR\" \u002F \"push\" \u002F branch with FH changes)*\n\nDetect changed files vs main → category-based consistency checks:\n\n| Category | What's checked |\n|---|---|\n| SKILL.md changes | Plugin description count drift · README skill table · CATALOG entry |\n| Agent file changes | README agent count · agent_cards.json count sync |\n| knowledge\u002Fshared\u002F changes | CATALOG coverage |\n| README.md changed | Stale org\u002Fversion references |\n| AGENTS.md \u002F CLAUDE.md changed | Agent count cross-reference sanity |\n\nVerdict: ✅ CONSISTENT · 🟧 INCONSISTENT (fix before push) · 🟩 REVIEW (intent check).\n\n**Auto-propose** (non-blocking) when \"PR\", \"push\", \"merge\" detected in session.\n\n> **Detail**: See `SKILL_detail.md §Step11` — bash scripts for each consistency check category — read when running PR change verification.\n\n---\n\n## Done When\n\n| Stage | Completion |\n|---|---|\n| Step 7 M\u002FS\u002FR prescription report output | ✅ Diagnosis complete |\n| Step 2-E ETCLOVG coverage line in report (covered layers + gaps, or \"full coverage\") | ✅ Layer-coverage lens applied |\n| M-tier 0 + \"Structure healthy\" output | ✅ Diagnosis complete (no prescription needed) |\n| Step 8 weekly_audit section proposed | ✅ Integration proposal complete |\n| Step 9 Eval-First verdict output (when requested) | ✅ Promotion verdict complete |\n| Step 10 Regression Guard verdict (PASS\u002FREVIEW\u002FBLOCK) | ✅ Post-fix verification complete |\n| Step 11 PR consistency check verdict | ✅ PR pre-push verification complete |\n\n**This skill Done When = \"prescription report output complete\".** Actual resolution of M\u002FS\u002FR items belongs to user or follow-up work.\n\n**Check classes** (`harness_6axis_framework.md` §Axis 5): report-output completions above = mandatory-pass (report exists or not). M\u002FS\u002FR tier *assignments* = judged — paired with verify-bidirectional when the user challenges a tier.\n\nVerdict: PASS (M-tier 0, \"Structure healthy\") | CONDITIONAL_PASS (S\u002FR remain, no M) | FAIL (1+ M-tier found) | ESCALATE (structural ambiguity before prescription can be issued)\n\n**Three-Doctor Loop chain** (auto-propose after prescription report):\n- M-tier + context\u002Ftoken waste → propose `\u002Fcontext-doctor`\n- M-tier + user-facing behavior changes → propose `\u002Fsim-conductor Area A`\n- SKILL.md S-tier (> 300 lines, no SKILL_detail.md) → auto-propose `\u002Fsalience-splitter`: `\"I see [skill] SKILL.md is [N] lines with no SKILL_detail.md. Want me to run \u002Fsalience-splitter?\"`\n- Both → propose full Three-Doctor Loop: context-doctor → sim-conductor Area A\n\n---\n\n## Trigger Phrases\n\n- `\u002Fharness-doctor` · \"harness diagnosis\" · \"harness structure check\" · \"CLAUDE.md audit\"\n- `\u002Fharness-doctor --lint` · \"check FH files for marketing language\" · \"description diet\" · \"remove marketing language\" (→ Step 3-L)\n- \"my Claude settings seem off\" · \"something that used to work doesn't anymore\" · \"skill isn't triggering\"\n- \"PR 올려줘\" · \"PR check\" · \"변경사항 영향 범위\" (→ Step 11)\n\nNo auto-firing — only executes when user explicitly invokes. Step 11 exception: propose as one-liner when \"PR\"\u002F\"push\"\u002F\"merge\" detected.\n\n## Failure Fallback\n\nOn Claude API \u002F MCP failure → refer to [`references\u002Ffallback-guide.md`](..\u002F..\u002Freferences\u002Ffallback-guide.md).\n\n---\n\n## Three-Doctor Loop Integration\n\nharness-doctor = **current structure diagnostician**. context-doctor = context collapse. sim-conductor = future behavior prediction. Together: diagnose → prescribe → re-diagnose closed loop.\n","# harness-doctor — Harness Structure Diagnosis + Prescription\n\n\"A good harness gets simpler over time. If it's getting more complex, something is wrong.\"\n\nDiagnoses harness structural health across 5 layers and proposes M\u002FS\u002FR prescriptions:\n\n1. **L1 Structural completeness** — required file existence (CLAUDE.md · .claudeignore · .claude\u002F)\n2. **L2 Complexity** — current state vs. simplification principle (line count · unused files · duplicate definitions)\n3. **L3 Drift** — rule vs. actual pattern mismatch (broken references · stale files · conflicting rules)\n4. **L4 Connection diagnosis** *(FH environment only)* — meta hub ↔ field project reference consistency\n5. **L5 Pattern analysis** *(FH environment only)* — skill activity · call context appropriateness · effect metrics\n\n---\n\n## Execution Steps\n\n### Step 1. Confirm Diagnostic Target\n\nCheck current cwd harness file structure and determine if FH environment (tracks\u002F + knowledge\u002F + plugins\u002F all present).\n\n### Step 2. L1 — Structural Completeness\n\n| File | When Missing |\n|---|---|\n| `CLAUDE.md` | **M-tier** — harness entry impossible |\n| `.claudeignore` | S-tier — context-doctor execution recommended |\n| `.claude\u002F` directory | M-tier (when rule files exist) |\n\n### Step 2-E. L1-E — ETCLOVG Layer Coverage *(functional-layer lens — orthogonal to the file-presence table above)*\n\nA harness is not only files; it is **seven functional layers** (ETCLOVG — arXiv:2606.06324, a component\ntaxonomy *orthogonal* to FH's 6-axis process model; cross-audit\n`tracks\u002F_audit\u002Fsession_2026_06_19_harnessfix-etclovg-cross-audit.md`). FH adopts only the **taxonomy as a\ncoverage lens** — not the paper's scoring model. A **coverage checklist, not a mandate**: not every\nharness needs all seven (a read-only doc harness needs no Execution or Governance). For each layer ask\n\"is there an asset covering it?\"; surface gaps, let the human judge if each is real for *this* harness.\n\n> **Orthogonal-sister ledger (same adoption rule — anchor only, no scoring model imported)**:\n> GRACE (arXiv:2607.09175, cross-audit `tracks\u002F_audit\u002Fsession_2026_07_24_grace-context-rubric.md`,\n> operator-local record) — typed-semantic-graph **scoped verification** for the **C (Context) layer's\n> maintenance path**: edits validated only within the modified node's local typed neighborhood. Cite\n> when a C-layer gap involves *how context updates are verified*, not just whether context assets exist.\n\n| Layer | Covers | Typical FH asset | If the gap is judged real → priority hint |\n|---|---|---|---|\n| **E** Execution | isolated\u002Freproducible env, bounded autonomy | Agent-dispatch isolation · goal-quench budget | advisory |\n| **T** Tooling | tool discovery \u002F selection \u002F gating | mcp_tool_gating · plugin-recommender | advisory |\n| **C** Context | what the model sees: card, memory, retrieval | session card · CATALOG · context-doctor | advisory |\n| **L** Lifecycle | loops, retries, orchestration, termination | agent-composer · goal-quench | advisory |\n| **O** Observability | traces \u002F logs \u002F cost to diagnose failures | subagent_invocations_log · audit logs · activity log | advisory |\n| **V** Verification | readiness · intermediate · final · regression checks | 4-axis gate (steel\u002Fphantom\u002Fregression_guard) | higher-stakes |\n| **G** Governance | permissions · approvals · audit trails | HITL gates · public-surface gate | higher-stakes |\n\n**Relationship to the Harness-Defect Taxonomy (below)**: ETCLOVG = *component coverage* (is the layer\npresent?); the Defect Taxonomy = *failure modes* (is a present layer degrading?). Orthogonal — coverage vs health.\n\n**Check class**: judged (advisory) — the presence test is mechanical, but \"is this gap real for this\nharness's purpose?\" is a judged call, **paired** with the human review at Step 7's M-tier gate. **Never\nauto-tier a missing layer into the M\u002FS\u002FR report** — the priority column is a *hint only if a human\nconfirms the gap*, never a verdict the report emits on its own; surface each gap tagged \"(human-confirm)\".\n(FH's own weak layer is **Observability** — retrospective audit only, no runtime layer; named in the cross-audit.)\n\n### Step 3. L2 — Complexity Diagnosis\n\n**Scope the instrument first — field vs meta** (CLAUDE.md §Identity Core Axis): a **field harness** must get\n\"simpler over time\" (complexity = warning signal), so raw size is a real signal there. A **meta-harness**\n(the FH hub itself) *optimizes* rather than simplifies — **complexity earns its scope**, and the doctrine's\nred flags are **orphaned, redundant, and decorative units, not size**. Applying the field rule to a\nmeta-harness produces a false M-tier on healthy growth.\n\n**Scope is mechanical, never self-declared** — else any repo dodges the line rows by calling itself meta\n(the self-label loophole CLAUDE.md already names for \"docs-only\" at the Irreversibility gate). A target is\n**meta** iff its root holds **all three**: `tracks\u002F` **and** `knowledge\u002F` **and** `plugins\u002F` (Step 1's FH-environment\ntest). Anything else is **field** — including a repo that merely *contains* skills or a `.claude\u002F` dir:\n\n**The test is rooted at the TARGET, never at cwd.** FH's own default mode diagnoses a field project\n*without* switching cwd (CLAUDE.md §Agent Dispatch — \"Direct edit … no cwd switch needed\"), so a bare\n`[ -d tracks ]` run from the hub misclassifies **every** field target as meta and silently deletes the\nfield rows — a permissive misread reachable through the harness's own recommended workflow. Always pass\nthe target path explicitly:\n\n```bash\n# meta iff all three exist AT THE TARGET ROOT — otherwise field. TARGET is required, never implied by cwd.\nTARGET=\"${1:?pass the target root explicitly — cwd is not the target}\"\n[ -d \"$TARGET\u002Ftracks\" ] && [ -d \"$TARGET\u002Fknowledge\" ] && [ -d \"$TARGET\u002Fplugins\" ] \\\n  && echo \"scope: meta ($TARGET)\" || echo \"scope: field ($TARGET)\"\n```\n\nScope is a **coarse instrument-selector, not a security boundary**: `[ -d ]` tests existence, not contents,\nso three empty dirs would flip field→meta. That is acceptable here (the operator names the target; there is\nno adversary picking it) — but it means scope must never gate anything that matters on its own, only *which\nsize instrument* is read. The footprint rows below apply to **both** scopes and are the actual verdict.\n\n| Check | Verdict |\n|---|---|\n| **Field\u002Fproject** CLAUDE.md 100~200 lines | S-tier warning |\n| **Field\u002Fproject** CLAUDE.md 200+ lines | M-tier — separation or reduction needed |\n| **Field\u002Fproject** 15+ `##` sections in CLAUDE.md | S-tier warning |\n| **Meta-harness (FH hub)** CLAUDE.md — raw line \u002F section count | **Not a verdict.** Judge by the always-loaded footprint rows below (char-based = actual token cost) + the doctrine's red flags (orphaned · redundant · decorative). Report the count as context only |\n| **Meta-harness — residency ledger** (the positive instrument that replaces the disabled line-count rows) | For each `##` section record **trigger class** (intent \u002F file \u002F ambient) + **backstop** (a hook or script path that must be **grep-verified to exist AND to be wired**, or the literal `none-by-nature`). Tier ONLY these: **M** = a section claiming a mechanical floor whose script is referenced by no hook (a prose-invoked \"floor\" is not a floor) · **S** = `file`-triggered *with* a verified backstop but still resident (splittable — name the destination glob) · **S** = duplicated verbatim in another section · **R** = orphaned\u002Fdecorative. A section that is intent- or ambient-triggered with `none-by-nature` is **PASS, not a finding** — moving it would be fail-open. Never tier a section on its size |\n| **Meta-harness** growth since last run: decompose into *new sections* vs *existing-section growth* (mechanical — diff `##` section names + line counts vs the prior run's commit; **first run \u002F no prior commit → report both as n\u002Fa, no tier**) | **Tier is decided by the two counts alone**: **S-tier iff existing-section growth > new-section growth** (the file is thickening faster than it is gaining capability); otherwise advisory, no tier. Report both numbers **and** the new sections' names — the names are *reporting output for the human*, never an input to the tier. Do not judge \"was this growth capability-bearing?\" per line |\n| SKILL.md > 300 lines AND no `SKILL_detail.md` | S-tier — propose `\u002Fsalience-splitter` (governance-semantic split, not compression) |\n| Rules files unreferenced in CLAUDE.md | R-tier |\n| **Called but content-blind** — a gate · check · lane that IS invoked (has callers) but returns the same verdict whatever its input (the third «decorative» shape, after «no caller» and «caller ignores the result»; arXiv:2610.41604) | S-tier. Detector is the existing revert\u002Fmutation probe, not a new scanner: feed one known-positive and one known-negative input and confirm the verdict differs. Same verdict for both → decorative. Reading the code is not the test — a check that greps for its own hook reference passes this row while its verdict never moves |\n| Always-loaded footprint > 40k chars (see scan below for what counts) | S-tier — **lever depends on where the chars live**: rules\u002Fdetail still auto-loading → relocate to a non-loaded dir (e.g. `knowledge\u002Fshared\u002Frules\u002F`), pointers stay in CLAUDE.md · narrative inside CLAUDE.md → `\u002Fsalience-splitter` · **behavioral content only, nothing left to relocate** → capability-level (merge\u002Fretire a governance unit) |\n| **Memory-index footprint** — the session's auto-loaded memory index (`~\u002F.claude\u002Fprojects\u002F\u003Cslug>\u002Fmemory\u002FMEMORY.md`), reported as **its own line, never summed into the row above** | S-tier > 10k chars — **different residency, different lever**: this one is `\u002Fmemory-hygiene` (archive closed items to `MEMORY_archive.md`, tighten hooks to one line), NOT `\u002Fsalience-splitter`. Summing it into the CLAUDE.md row would mis-route the lever, which is exactly what the row above ties to \"where the chars live\". **Blind spot this closes (2026-07-20, measured)**: a fresh top-level `\u002Fcontext` showed **Memory files = 41.7k of 68.8k resident tokens (61%)**, of which `MEMORY.md` alone was **14.1k — 55% the size of CLAUDE.md (25.5k)** — and the footprint scan below counted **none of it**. The instrument was optimising the smaller half of the surface it claimed to measure |\n| Always-loaded footprint > 80k chars | M-tier — same lever selection, mandatory, **and never self-discharged** (see below) |\n| **Pointer-illusion**: a CLAUDE.md \"detail\u002Fdetailed procedure\" pointer whose target is itself an always-loaded `.claude\u002Frules\u002F*.md` | S-tier — the split saves zero context (rules\u002F auto-loads regardless); move the target out of auto-load, keep the pointer |\n| weekly_audit 14~30 days elapsed | S-tier |\n| weekly_audit 30+ days elapsed | M-tier |\n\n**Per-unit ≠ aggregate — do not slide between them.** \"Every section earns its scope\" (the per-unit\ndoctrine test) and \"the always-loaded total is affordable\" (the budget test) are **different questions, and\nboth can be true at once**. A meta-harness can pass the red-flag test on every single section and still be\nover its footprint budget. So a per-unit PASS never discharges the footprint rows — and conversely, a\nfootprint M-tier is *not* evidence that some section failed to earn its scope. When footprint is over\nbudget but every unit earns its scope, the remaining lever is **capability-level** — merge or retire a\ngovernance unit — **not** a salience split, which by construction only moves narrative and returns ~nothing\nwhen the content is behavioral.\n\n**Any scan-derived count must be calibrated before it is reported.** Before a number from a scan\n(broken refs, INACTIVE skills, footprint chars, orphan counts, coverage) enters the report, run it\nagainst **one known-positive and one known-negative** and record both outcomes; then **hand-verify the\nsingle case the scan is most confident about**. If either step is skipped the number ships labeled\n`UNCALIBRATED` and may not ground a tier. `not found` is reported as `UNMEASURED`, never as `0` — a\nscan that dies mid-run reports a low number, and low numbers read as PASS.\nOrigin (2026-07-20, three instrument defects in one session): a footprint scan omitted 61% of the\nresident surface it claimed to measure · a size ratio was used as a proxy for content coverage · an\nASCII-token scanner run over a Korean corpus produced ~96% false positives and a \"70%\" figure that was\npublished to three records before one hand-check reduced it to 3 items. **Suspect the instrument before\nthe target whenever a value is impossible** (all-pass, all-fail, or a self-scan that fails to detect the\nrunning tool itself). Full procedure: `knowledge\u002Fshared\u002Fharness-core\u002Fmeasurement-integrity-checklist.md\n§Instrument-Calibration`.\n\n**Every M\u002FS-tier must cite the row it fired — verbatim, from this file.** Write the finding as\n`M-n · \u003Cverbatim row text or its threshold> · \u003Cmeasured value>`. If you cannot quote the row, **you do not\nhave a finding** — downgrade to an observation. Origin (2026-07-20, instrument defect n+4, the *fourth* in\na single run): a run fired `M-1 · CLAUDE.md 816 lines — exceeds the FH threshold of 500`. The string `500`\ndid not occur anywhere in this file at the time (a later grep finds 2 — both in this narrative, added by\nthis very post-mortem; the self-referential claim drifted and is corrected here rather than re-asserted).\n🟥 **And that grep was scoped wrong**: it searched this file only. The 500 was NOT invented from nothing —\n`docs\u002Fplatform_sustainability.md` carried it as a live standard until 2026-08-20, contradicting this row.\nThe lesson is not \"the run hallucinated\" but **\"the absence check was run against the wrong corpus\"**\n([[feedback_absence_measurement_needs_control]] — a no-hit grep is evidence only when its scope covers\nwhere the thing would actually live). The meta-harness row it claimed to read says raw\nline count is **\"Not a verdict.\"** So the run invented a threshold *and* fired a row this skill explicitly\ndisables for meta-harnesses — the exact recurrence of the 2026-07-15 inversion documented below, which had\nalready been patched *in the skill*. The patch held; the **run** ignored it. A verdict grounded in a\ncitation that cannot be quoted is the same defect class as a phantom reference, and it propagates: a\ndownstream sidecar judgment inherited the fabricated 500 and reasoned from it until a grep caught it.\n\n**No M-tier in this skill is ever self-discharged — not just the footprint one.** \"The cost is priced \u002F\naccepted\", \"it's all necessary\", \"over budget but fine\" are **not** verdicts this skill may reach on its\nown: an M-tier stands in the report and is closed only by an explicit operator acknowledgment logged to\n`tracks\u002F_meta\u002F` (same shape as any other logged override). This is **row-agnostic on purpose** — the\nrationale (a run under ship pressure prices away the one row that fired) is not specific to footprint, so\nscoping the prohibition to a single row would leave every other M-tier open to the same silent PASS. That\nis the default-toward-PASS class `field_verdict_crossfamily_gate.md` exists to catch, committed inside the\ndiagnostic that names it. **Report it; do not price it.**\n\n> Origin (2026-07-15, dogfood): a run read FH's CLAUDE.md at 891 lines, fired the raw-count M-tier, and\n> prescribed `\u002Fsalience-splitter`. Measurement inverted both halves: **+244 of the +381 30-day growth (64%)\n> was 6 new governance sections**, each behavioral and salience-passing (two — Voice\u002FTone, Envelope-Boundary —\n> had been *promoted* to always-loaded precisely because memory-only placement made them miss), and actually\n> running the splitter on 4 sections yielded **−27 lines \u002F −3.2k chars (−3.7%)** — confirming salience-splitter's\n> own Target Selection rule (\"splitting a file with only behavioral content adds structure without governance\n> value\"). The **footprint** row meanwhile fired M-tier correctly and had been M since 06-15. Two rows measured\n> the same property; the worse instrument drove the verdict. The line-count rows are now field-scoped.\n\nAlways-loaded + pointer-illusion checks are mechanical (found 2026-07-12 — FH itself shipped ~50k chars of rules\u002F behind \"detail pointers\" that saved nothing; the meta-harness blind spot this row closes):\n\n```bash\n# always-loaded footprint (chars). Counts every file the session loads before turn 1:\n#   CLAUDE.md + CLAUDE.local.md + rules files lacking paths: frontmatter + their DIRECT @-imports.\n# EVERY path is rooted at $TARGET — the same root the scope test used. Reading from cwd instead\n# measures whichever harness you happen to be standing in (usually the hub, while diagnosing a\n# field target) — a wrong-target measurement that reports the hub's number as the target's.\nTARGET=\"${1:?pass the target root explicitly — cwd is not the target}\"\n# MEMORY-INDEX (reported SEPARATELY — see the memory-index row above; do NOT add it to T).\n# It is auto-loaded every session but lives outside $TARGET, so the $TARGET-rooted sum below is\n# structurally blind to it. Measured 2026-07-20: it was 55% the size of CLAUDE.md and invisible here.\nMEMSLUG=$(printf '%s' \"$TARGET\" | sed 's|^\u002F||; s|\u002F|-|g')\nMEMIDX=\"$HOME\u002F.claude\u002Fprojects\u002F-$MEMSLUG\u002Fmemory\u002FMEMORY.md\"\nif [ -f \"$MEMIDX\" ]; then\n  echo \"memory-index: $(wc -c \u003C \"$MEMIDX\") chars — $MEMIDX  (lever: \u002Fmemory-hygiene, NOT salience-splitter)\"\nelse\n  echo \"memory-index: not found at $MEMIDX — report as UNMEASURED, not as 0 (a missing file is not an empty one)\"\nfi\nT=0\nfor f in \"$TARGET\u002FCLAUDE.md\" \"$TARGET\u002FCLAUDE.local.md\"; do\n  [ -f \"$f\" ] && T=$((T + $(wc -c \u003C \"$f\")))\ndone\n# find | while, not a glob: an unmatched glob aborts under zsh, and a here-string of \"\" still yields\n# one empty line -> head -5 \"\" errors and the sum breaks. A scan that dies mid-run reports a LOW\n# number (= toward PASS), so guard the empty case explicitly.\nwhile IFS= read -r f; do\n  [ -n \"$f\" ] || continue\n  head -5 \"$f\" | grep -q '^paths:' || T=$((T + $(wc -c \u003C \"$f\")))\ndone \u003C \u003C(find \"$TARGET\u002F.claude\u002Frules\" -name '*.md' 2>\u002Fdev\u002Fnull)\n# DIRECT @-imports only (not transitive — a nested import chain is a named residual below).\n# Resolve against the IMPORTING FILE's own dir first, then ~\u002F.claude\u002F. SUM into T — never\n# print-and-ask-the-reader-to-add: a scan that delegates arithmetic re-introduces the judgment\n# it exists to remove, and the omission points toward PASS.\nfor f in \"$TARGET\u002FCLAUDE.md\" \"$TARGET\u002FCLAUDE.local.md\"; do\n  [ -f \"$f\" ] || continue\n  d=$(dirname \"$f\")\n  for i in $(grep -oE '^@[A-Za-z0-9_.\u002F-]+' \"$f\" 2>\u002Fdev\u002Fnull | sed 's\u002F^@\u002F\u002F'); do\n    for c in \"$d\u002F$i\" \"$HOME\u002F.claude\u002F$i\"; do\n      [ -f \"$c\" ] && { T=$((T + $(wc -c \u003C \"$c\"))); echo \"  +import $c: $(wc -c \u003C \"$c\") chars\"; break; }\n    done\n  done\ndone\necho \"always-loaded TOTAL ($TARGET): $T chars\"\n# Verdict: the HIGHEST tripped threshold wins — 80k supersedes 40k. Reporting only the\n# S-tier row while >80k is a silent FAIL->CONDITIONAL_PASS downgrade.\n[ \"$T\" -gt 80000 ] && echo \"  => M-tier (>80k)\" || { [ \"$T\" -gt 40000 ] && echo \"  => S-tier (>40k)\" || echo \"  => footprint ok\"; }\n# pointer-illusion: CLAUDE.md pointers targeting still-auto-loaded rules files (any filename shape)\ngrep -oE '\\.claude\u002Frules\u002F[A-Za-z0-9_.\u002F-]+\\.md' \"$TARGET\u002FCLAUDE.md\" 2>\u002Fdev\u002Fnull | sort -u | while read -r p; do\n  [ -f \"$TARGET\u002F$p\" ] && echo \"ILLUSION: $p (pointed-to AND always-loaded)\"\ndone\n```\n\n**Named residuals of this scan** (all documented, none silent): **transitive imports are not followed** —\nan import chain `CLAUDE.md → A.md → B.md` counts A but not B, so a deep chain under-counts *toward PASS*;\n**`head -5 … grep '^paths:'`** is a proxy, not a frontmatter parser — an incidental early `paths:` line\nfalsely excludes an always-loaded rule (toward PASS), while a `paths:` below line 5 over-counts (toward\nFAIL, the safe direction); and the scope test reads directory *existence*, so three empty dirs flip\nfield→meta (acceptable: the operator names the target, and the footprint rows apply to **both** scopes\nregardless — but it does skip the field-only line rows).\n\n\u003C!-- Context-File Taxonomy check removed 2026-07-22\u002F23 (#153 → weekly-audit #6 decision): consumer\n     re-measure = 0 skills read role:\u002Ftype: from these files; measured FP 99\u002F161 (61%) un-narrowed,\n     19\u002F26 (73%) after narrowing; origin citation was mis-attributed (SPECULATIVE, no primary source).\n     Decorative unit per doctrine — FP figures preserved in the removal commit message as the\n     regression anchor. Re-adding requires a named consumer first. -->\n\n### Step 3-L. Language Lint (`--lint` mode only)\n\n> Activate with `\u002Fharness-doctor --lint` or when harvest-loop surfaces a P10-series signal. Skipped in standard runs.\n\nGrep-based scan of SKILL.md, agent `.md`, and doc files for self-marketing language patterns. Outputs replacement suggestions — no automatic edits.\n\n**Detection patterns**:\n\n| Pattern | Examples | Replacement direction |\n|---|---|---|\n| Self-declarations of quality | \"industry-leading\", \"the world's first\", \"core skill\", \"best\" | Delete — no external evidence |\n| Version \u002F iteration labels | \"v0.3\", \"22nd naming round\", \"26th iteration\", \"(added 2026-05-24)\" | Remove (git history manages versioning) |\n| Cushion language | \"easily\", \"instantly\", \"seamlessly\", \"without burden\", \"fully automated\" | Replace with behavior-based description |\n| Owner self-reference loops | \"validated by our team\", \"proven internally\" | Delete or replace with external evidence |\n| Marketing word stacking | 3+ adjectives in one sentence | Reduce to functional description |\n| Spec-only artifacts | SKILL.md or agent file missing `Done When` section | Add observable output criteria |\n\n**Scan targets**:\n```bash\nfind {FH_ROOT}\u002Fplugins -name \"SKILL.md\" | sort\nfind {FH_ROOT}\u002F.claude\u002Fagents -name \"*.md\" | sort\nfind {FH_ROOT}\u002Fdocs -name \"*.md\" 2>\u002Fdev\u002Fnull | sort\n```\n\n**Detection commands**:\n```bash\n# version \u002F iteration labels\ngrep -n \"v[0-9]\\+\\.[0-9]\\|[0-9]\\+th\\|[0-9]\\+th iteration\\|prototype [0-9]\\+\" {file}\n# cushion language\ngrep -n \"fully\\|instantly\\|full coverage\\|automatically\\|conveniently\\|easily\\|without burden\\|seamlessly\" {file}\n# self-declaration patterns\ngrep -n \"core skill\\|world's first\\|best\\|most\\|top\\|industry-leading\" {file}\n```\n\n**Output format** (per file):\n```\nFile: {path}\n  L{N}: \"{original text}\"\n  → Suggested: \"{replacement}\" (reason: {pattern type})\n  → Or: remove (reason: {pattern type})\n```\n\n**Lint findings** feed into Step 7 report as a separate \"Language Quality\" section — not mixed into structural M\u002FS\u002FR tiers. Lint findings are advisory: HIGH (spec-only = missing Done When, treat as S-tier) \u002F LOW (language patterns, R-tier).\n\n---\n\n### Step 4. L3 — Drift Diagnosis\n\n| Check | Tier |\n|---|---|\n| Broken local file references in CLAUDE.md | M-tier |\n| .claude\u002Frules files unmodified 90+ days | R-tier |\n| settings.json JSON syntax error | M-tier |\n| Hooks in settings.json (PostToolUse\u002FStop) that don't fire in Agent View | S-tier or M-tier |\n| Public-surface FH recommendation or default changed — no N-shot measurement evidence traceable in session records or PR body | S-tier |\n| Pre-commit-adjacent gate reads the working tree (cat\u002Fglob of a *tracked* path) with no `--staged`\u002F`--cached`\u002F`git show :` on that path, when its verdict is about *what's committed* | S-tier |\n\nHook divergence verdict: 0 hooks = Normal · 1+ hooks (session-end\u002FStop) = S-tier · 1+ hooks (PostToolUse file writes or external API) = M-tier (data loss risk in Agent View).\n\n**Index-vs-worktree gate lint** (2026-06-21, gate-locality corollary — `[[feedback_gate_locality_principle]]`):\na gate whose verdict is about *what is being committed* must read the **staged index**\n(`git ls-files --cached` \u002F `git show :path`), not the working tree (`cat`\u002Fglob of a tracked file) —\nelse it false-PASSes a commit whose staged content ≠ disk (origin: `count_check.sh` read the worktree\nwhile the pre-commit hook fired on the index; the sibling `regression_guard` already used `--staged`,\nso the lesson existed but was non-local). Mechanical scan — in the pre-commit hook + the scripts it\ninvokes (+ `scripts\u002F*-check.sh`): flag a `cat`\u002F`\u003C`\u002Fglob read of a tracked path with no\n`--staged`\u002F`--cached`\u002F`git show :` on that path. **Conditional (NOT universal)**: a gate whose verdict is\nabout what *runs\u002Fdeploys* (pre-push tests, build, an auto-fixer that rewrites the worktree) correctly\nreads the working tree — a line-level `# worktree-intentional:` comment suppresses the flag. FP surface\n(isolated-critic): display\u002Flog reads and untracked generated files are not violations → keep advisory\n(S-tier, never M).\n\n### Step 5. L4 — Connection Diagnosis *(FH only)*\n\n- Tracks with no sync in 30+ days → R-tier\n- CATALOG.md: 5+ open items in recent 5 sessions → S-tier\n- Field project CLAUDE.md missing → S-tier\n- **Knowledge cross-ref lint**: `knowledge\u002F**\u002F*.md` with no CATALOG.md entry → S-tier\n  (index orphan — unfindable via CATALOG-first search); with no inbound reference from\n  any CLAUDE.md \u002F rules \u002F SKILL.md \u002F knowledge doc → R-tier (orphan page).\n  Mechanical: `grep -L` filenames against CATALOG.md, then `grep -rl` for inbound refs.\n\n### Step 6. L5 — Pattern Analysis *(FH only)*\n\n**L5-A Skill Activity** (grep-based on session records):\n\n| State | Criteria | Tier |\n|---|---|---|\n| ACTIVE | 2+ times in 30 days | Normal |\n| LOW_ACTIVE | 1 time in 30 days | R-tier |\n| INACTIVE_30D | 0 times in 30 days | S-tier |\n| INACTIVE_90D | 0 times in 90 days | M-tier |\n\n**L5-B Call Context Appropriateness**: Keyword grep for known misuse patterns (hub-persona-auditor in code PR context · sim-conductor without onboarding · harness-doctor self-loop). Report as \"suspected (false positive possible)\" — no LLM call.\n\n**L5-C Effect Metrics**:\n\n| Metric | OK condition | Tier if failing |\n|---|---|---|\n| E1 CLAUDE.md lines | Decrease or ±10 | E1_WARN if +50 lines |\n| E2 Complexity ratio | ≤100 lines\u002Fskill | E2_WARN (≤200) \u002F E2_FAIL (>200) |\n| E3 CATALOG open consumption | ≥50% in 30 days | — |\n| E4 harvest signals | ≥3 in 30 days | — |\n| E5 SKILL.md change | Within 14 days | — |\n| E6 Cold audit | Within 30 days | E6_WARN |\n| E7 Evolution-loop observability | Asset edits have edit_manifest predictions | E7_WARN = S-tier |\n\n**HHS** (Harness Health Score): Each OK condition = +1 point (7 max). HHS ≥ 4 = Healthy · 2~3 = Caution · ≤1 = Critical.\n\n> **Detail**: See `SKILL_detail.md §L5-Detail` — bash scripts for L5-A, L5-B, L5-C\u002FE metrics — read when running L5 pattern analysis.\n\n---\n\n## Harness-Defect Taxonomy (frontier cross-check)\n\n| Defect class | FH detectable signals | Tier |\n|---|---|:---:|\n| **Context Drift** | Stale paths in CLAUDE.md (L3) · rules unmodified 90+ days (L3) · CLAUDE.md over threshold (L2) | S |\n| **Schema Misalignment** | Plugin count drift · SKILL.md missing `Done When` (undocumented contract) | M |\n| **State Degradation** | tracks\u002F no sync 30+ days (L4) · INACTIVE_90D skills (L5-A) · orphaned memory entries | M |\n| **Agentic Laziness** *(runtime)* | Completion claims without per-item evidence — \"all N done\" with no enumerable list in session records \u002F PR bodies · Done When lacking any mandatory-pass condition | S |\n| **Self-Preferential Bias** *(runtime)* | judged-class check without a named adversarial pairing (gate-rejectable for new skills; scan existing for backfill) · a self-graded verdict cited as sole completion evidence | M |\n| **Goal Drift** *(runtime)* | Long session with S\u002FA-tier work but no pre-compaction completion log (`fh_completed_*` missing) · early-stated constraints absent from card\u002Fmanifest at close | S |\n| **Comprehension Debt** *(runtime\u002Foperator)* | Merged FH-asset change with no CATALOG entry · edit_manifest `validation_status: pending` backlog piling up unverified · session closed with work done but zero card delta | S |\n| **Evidence Gap** *(FH self-dev)* | Public-surface FH recommendation or default changed with no N-shot measurement evidence traceable in session records or PR history (L3 check) | S |\n\nSignal in 2+ classes → escalate one tier.\nRows 1–3 = structural (2026-06-02 frontier diagnosis). Rows 4–6 = runtime behavioral, agent-side —\nnamed from dynamic-workflows discourse (2026-06). Row 7 = runtime, operator-side — named from\nloop-engineering discourse (Osmani, 2026-06): loop output outpacing operator understanding. FH\ncountermeasures already exist and are what the signals check for: golden probes + multi-persona\ncoverage (laziness) · judged-pairing rule (bias) · pre-compaction completion log + card-last guard\n(drift) · CATALOG 3-line summaries + manifest predict-verify + card protocol (comprehension debt).\n\n---\n\n### Step 7. M\u002FS\u002FR Prescription Report Output\n\n```\n## harness-doctor Diagnostic Results\n\n### 🟥 M-tier (Immediate Action)\n### 🟧 S-tier (Strongly Recommended)\n### 🟩 R-tier (Recommended)\n\n---\n## ETCLOVG Layer Coverage (L1-E)\n- Covered: [layers with an asset, e.g. E·T·C·L·V·G]\n- Gaps (surfaced, never auto-tiered — each \"(human-confirm)\"): [e.g. \"O Observability (human-confirm) — retrospective audit only, no runtime layer\"] or \"full coverage\"\n\n---\n## L5 Pattern Analysis\n- Activity (L5-A): [list]\n- Context appropriateness (L5-B): [suspected misuse or \"no issues\"]\n- Effect metrics (L5-C): E1=[result] \u002F E3=[result] \u002F E5=[result]\n\n---\n## Language Quality (`--lint` mode only)\n- HIGH (spec-only — missing Done When): [list or \"none\"]\n- LOW (language patterns): [file: L{N}: \"{text}\" → {suggestion}]\n\nDiagnostic scope: L1 (+L1-E ETCLOVG coverage) ~L3 [· L4 · L5 (FH only)] [· --lint]\n```\n\nM-tier 0 → output \"Structure healthy. Maintaining simplification trend.\"\n\n**M-tier Immediate Human Gate**: If 1+ M-tier found → pause, surface options: (a) AI proceeds to Step 8 \u002F (b) human review first \u002F (c) abort. Do not auto-apply prescriptions that could close a self-referential loop.\n\n### Step 8. harvest-loop Integration *(when tracks\u002F_audit\u002F exists)*\n\nWhen 1+ M-tier found → propose adding `## Harness Structure Check (harness-doctor)` section to latest weekly_audit file.\n\n### Step 9. Eval-First Quantitative Gate *(v0.x → v1 promotion only)*\n\n**Thresholds** (measured over 5 sim-conductor runs): Tool Selection Accuracy > 0.90 · Multi-Step Coherence > 0.85 · Clarification Rate \u003C 0.30.\n\n### Step 10. Regression Guard *(when SKILL.md \u002F rules \u002F CLAUDE.md modified)*\n\nVerifies that prescription application didn't strip operational content. Run after prescription applied, at pre-merge gate, or when harvest-loop Step 4 detects file changes.\n\n| Check | Tier |\n|:---:|:---:|\n| F1 Frontmatter integrity | M |\n| F2 Critical section preservation (Execution Steps · Done When · Triggers) | M |\n| F3 Code block count not reduced by 4+ | S |\n| F4 Operational keyword preservation (M-tier\u002FS-tier\u002FWave\u002FStep\u002FDone When) | M if ≥50% drop · S if 20~49% |\n| F5 Cross-reference paths resolve | M |\n| F6 Line reduction ≥30% | S |\n| F7 Bash block syntax (bash -n parse) | M if net increase in bad blocks |\n\nVerdict: ✅ PASS (0M 0S) · ⚠️ REVIEW (0M 1+S) · ❌ BLOCK (1+M) · ⏭️ SKIP (검사 대상 0 — **PASS 가 아니다**).\n\nImplementation: `bash templates\u002Fregression_guard.sh` (compare vs main) or `bash templates\u002Fregression_guard.sh BASE HEAD`.\n**Verdict 는 종료코드가 아니라 typed 채널로 읽어라** — `exit 0` 은 pass 와 skip 둘 다다(2026-07-23):\n`REGRESSION_GUARD_RESULT_FILE=\u002Ftmp\u002Frg.$$ bash templates\u002Fregression_guard.sh …` 후 파일의\n`result=pass|review|block|skip` 를 판정에 쓴다. `skip` = 미검사 — PASS 로 보고하지 말고 \"Axis 1\n해당 없음(대상 파일 0)\" 으로 보고한다.\n\n> **Detail**: See `SKILL_detail.md §Step-1-3` — bash scripts for Steps 1~6 (L1~L4 diagnostics) — read when running the diagnostic commands.\n\n### Step 11. PR Change Consistency Check *(triggered on \"PR\" \u002F \"push\" \u002F branch with FH changes)*\n\nDetect changed files vs main → category-based consistency checks:\n\n| Category | What's checked |\n|---|---|\n| SKILL.md changes | Plugin description count drift · README skill table · CATALOG entry |\n| Agent file changes | README agent count · agent_cards.json count sync |\n| knowledge\u002Fshared\u002F changes | CATALOG coverage |\n| README.md changed | Stale org\u002Fversion references |\n| AGENTS.md \u002F CLAUDE.md changed | Agent count cross-reference sanity |\n\nVerdict: ✅ CONSISTENT · 🟧 INCONSISTENT (fix before push) · 🟩 REVIEW (intent check).\n\n**Auto-propose** (non-blocking) when \"PR\", \"push\", \"merge\" detected in session.\n\n> **Detail**: See `SKILL_detail.md §Step11` — bash scripts for each consistency check category — read when running PR change verification.\n\n---\n\n## Done When\n\n| Stage | Completion |\n|---|---|\n| Step 7 M\u002FS\u002FR prescription report output | ✅ Diagnosis complete |\n| Step 2-E ETCLOVG coverage line in report (covered layers + gaps, or \"full coverage\") | ✅ Layer-coverage lens applied |\n| M-tier 0 + \"Structure healthy\" output | ✅ Diagnosis complete (no prescription needed) |\n| Step 8 weekly_audit section proposed | ✅ Integration proposal complete |\n| Step 9 Eval-First verdict output (when requested) | ✅ Promotion verdict complete |\n| Step 10 Regression Guard verdict (PASS\u002FREVIEW\u002FBLOCK) | ✅ Post-fix verification complete |\n| Step 11 PR consistency check verdict | ✅ PR pre-push verification complete |\n\n**This skill Done When = \"prescription report output complete\".** Actual resolution of M\u002FS\u002FR items belongs to user or follow-up work.\n\n**Check classes** (`harness_6axis_framework.md` §Axis 5): report-output completions above = mandatory-pass (report exists or not). M\u002FS\u002FR tier *assignments* = judged — paired with verify-bidirectional when the user challenges a tier.\n\nVerdict: PASS (M-tier 0, \"Structure healthy\") | CONDITIONAL_PASS (S\u002FR remain, no M) | FAIL (1+ M-tier found) | ESCALATE (structural ambiguity before prescription can be issued)\n\n**Three-Doctor Loop chain** (auto-propose after prescription report):\n- M-tier + context\u002Ftoken waste → propose `\u002Fcontext-doctor`\n- M-tier + user-facing behavior changes → propose `\u002Fsim-conductor Area A`\n- SKILL.md S-tier (> 300 lines, no SKILL_detail.md) → auto-propose `\u002Fsalience-splitter`: `\"I see [skill] SKILL.md is [N] lines with no SKILL_detail.md. Want me to run \u002Fsalience-splitter?\"`\n- Both → propose full Three-Doctor Loop: context-doctor → sim-conductor Area A\n\n---\n\n## Trigger Phrases\n\n- `\u002Fharness-doctor` · \"harness diagnosis\" · \"harness structure check\" · \"CLAUDE.md audit\"\n- `\u002Fharness-doctor --lint` · \"check FH files for marketing language\" · \"description diet\" · \"remove marketing language\" (→ Step 3-L)\n- \"my Claude settings seem off\" · \"something that used to work doesn't anymore\" · \"skill isn't triggering\"\n- \"PR 올려줘\" · \"PR check\" · \"변경사항 영향 범위\" (→ Step 11)\n\nNo auto-firing — only executes when user explicitly invokes. Step 11 exception: propose as one-liner when \"PR\"\u002F\"push\"\u002F\"merge\" detected.\n\n## Failure Fallback\n\nOn Claude API \u002F MCP failure → refer to [`references\u002Ffallback-guide.md`](..\u002F..\u002Freferences\u002Ffallback-guide.md).\n\n---\n\n## Three-Doctor Loop Integration\n\nharness-doctor = **current structure diagnostician**. context-doctor = context collapse. sim-conductor = future behavior prediction. Together: diagnose → prescribe → re-diagnose closed loop.\n",{"name":5,"model":23,"description":7,"allowed-tools":24,"user-invocable":29,"complexity_routing":30},"sonnet",[25,26,27,28],"Read","Bash","Glob","Grep",true,{"base":23,"high":31,"escalate_when":32},"opus",[33,34],"cold_start","cross_project","main","899495d17a23f30ca149d4ac29a137a8fa7864e3","plugins\u002Ffh-meta\u002Fskills\u002Fharness-doctor",1,"https:\u002F\u002Fgithub.com\u002Fchrono-meta\u002Fforge-harness","https:\u002F\u002Fchrono-meta.github.io\u002Fforge-harness\u002F","https:\u002F\u002Fgithub.com\u002Fchrono-meta","2026-11-15 02:42:21",{"source":8,"skillName":5,"commands":44,"prompt":54,"zipAvailable":29},[45,48,51],{"tool":46,"command":47},"npx","npx skills add chrono-meta\u002Fforge-harness --skill harness-doctor",{"tool":49,"command":50},"bunx","bunx skills add chrono-meta\u002Fforge-harness --skill harness-doctor",{"tool":52,"command":53},"pnpm","pnpm dlx skills add chrono-meta\u002Fforge-harness --skill harness-doctor","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fchrono-meta\u002Fforge-harness\u002Fblob\u002Fmain\u002Fplugins\u002Ffh-meta\u002Fskills\u002Fharness-doctor\u002FSKILL.md",[56],{"path":57,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":60,"sourceHtmlUrl":61},"SKILL_detail.md","REFERENCE","参考文档",22784,"https:\u002F\u002Fgithub.com\u002Fchrono-meta\u002Fforge-harness\u002Fblob\u002Fmain\u002Fplugins\u002Ffh-meta\u002Fskills\u002Fharness-doctor\u002FSKILL_detail.md",[63,70,77,84,90,97],{"skillNo":64,"name":65,"nameZh":6,"description":66,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":67,"categories":68,"keywords":69,"publishedAt":18},"01M74ZPW36H1HVE0R61QZ5ZND0","todo-orchestrator","TODO CLI 프로젝트의 기능 추가·버그 수정·리팩터링·테스트 보강을 개발자와 QA 에이전트로 조율한다. todo 앱 관련 코드 작업 요청에 사용한다. 다시 실행, 재실행, 수정, 보완, 이전 결과 개선, QA만 다시 같은 후속 요청에도 사용한다. 단순 질문에는 사용하지 않는다.","https:\u002F\u002Fgithub.com\u002Fchrono-meta\u002Fforge-harness\u002Fblob\u002Fmain\u002Fscripts\u002Ffixtures\u002Fgenerated_harness\u002FP4_r2\u002F.claude\u002Fskills\u002Ftodo-orchestrator\u002FSKILL.md",[],[],{"skillNo":71,"name":72,"nameZh":6,"description":73,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":74,"categories":75,"keywords":76,"publishedAt":18},"01M74ZPS4EP2349B346R5JQEYE","todo-dev","TODO CLI(todo\u002Fcli.py)에 명령을 추가하거나 버그를 고치고 테스트를 작성하는 방법. todo 앱 코드 수정·기능 추가·테스트 작성·리팩터링 작업에 사용한다. 수정, 보완, 다시 구현 요청에도 사용한다.","https:\u002F\u002Fgithub.com\u002Fchrono-meta\u002Fforge-harness\u002Fblob\u002Fmain\u002Fscripts\u002Ffixtures\u002Fgenerated_harness\u002FP4_r2\u002F.claude\u002Fskills\u002Ftodo-dev\u002FSKILL.md",[],[],{"skillNo":78,"name":79,"nameZh":6,"description":80,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":81,"categories":82,"keywords":83,"publishedAt":18},"01M74ZPPX2743J6FPT8N2ZT0D5","todo-dev-team","TODO CLI(todo\u002Fcli.py) 개발 작업을 개발자·테스터·리뷰어 팀으로 진행하는 오케스트레이터. 명령 추가, 버그 수정, 테스트 작성, 리팩터링, 커밋·푸시 요청에 사용한다. 다시 실행, 재실행, 수정, 보완, 리뷰 반영, 테스트만 다시 같은 후속 요청에도 사용한다. 단순 질문에는 쓰지 않는다.","https:\u002F\u002Fgithub.com\u002Fchrono-meta\u002Fforge-harness\u002Fblob\u002Fmain\u002Fscripts\u002Ffixtures\u002Fgenerated_harness\u002FP3_r2\u002F.claude\u002Fskills\u002Ftodo-dev-team\u002FSKILL.md",[],[],{"skillNo":85,"name":72,"nameZh":6,"description":86,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":87,"categories":88,"keywords":89,"publishedAt":18},"01M74ZPKWST7DF24H0EN9RCEME","TODO CLI 개발 작업(명령·기능 추가, 버그 수정, 테스트 작성, 리뷰, 커밋·push)을 개발자·테스터·리뷰어 에이전트 팀으로 진행하는 오케스트레이터. todo CLI, todo.json, todo\u002Fcli.py 관련 구현·수정·테스트 요청에 사용한다. 재실행, 수정, 보완, 이전 결과 개선, 테스트만 다시, 리뷰만 다시 요청에도 사용한다. 단순 질문에는 쓰지 않는다.","https:\u002F\u002Fgithub.com\u002Fchrono-meta\u002Fforge-harness\u002Fblob\u002Fmain\u002Fscripts\u002Ffixtures\u002Fgenerated_harness\u002FP3_r1\u002F.claude\u002Fskills\u002Ftodo-dev\u002FSKILL.md",[],[],{"skillNo":91,"name":92,"nameZh":6,"description":93,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":94,"categories":95,"keywords":96,"publishedAt":18},"01M74ZPHBP62X3KKSV2RVKSBKT","weekly-summary-write","정리된 회의록으로 주간 회의 요약 문서를 작성하는 형식과 문체 규칙. 주간 요약 작성, 요약 문서 수정·보완, 검토 의견 반영 시 사용한다.","https:\u002F\u002Fgithub.com\u002Fchrono-meta\u002Fforge-harness\u002Fblob\u002Fmain\u002Fscripts\u002Ffixtures\u002Fgenerated_harness\u002FP2_r2\u002F.claude\u002Fskills\u002Fweekly-summary-write\u002FSKILL.md",[],[],{"skillNo":98,"name":99,"nameZh":6,"description":100,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":101,"categories":102,"keywords":103,"publishedAt":18},"01M74ZPECSXY4C0QNHAD96Z88H","weekly-meeting-summary","주간 회의록을 정리하고 요약 문서를 만드는 전체 작업을 조율하는 오케스트레이터. 회의록 요약, 주간 회의 정리, 주간 보고용 요약 요청 시 사용한다. 다시 실행, 재실행, 요약 수정·보완, 이전 결과를 바탕으로 한 개선, 정리만\u002F검토만 다시 같은 후속 요청에도 사용한다.","https:\u002F\u002Fgithub.com\u002Fchrono-meta\u002Fforge-harness\u002Fblob\u002Fmain\u002Fscripts\u002Ffixtures\u002Fgenerated_harness\u002FP2_r2\u002F.claude\u002Fskills\u002Fweekly-meeting-summary\u002FSKILL.md",[],[]]