@chrono-meta/fh-gate 1.4.73 → 1.4.75
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +2 -2
- package/CHEATSHEET.md +1 -1
- package/CLAUDE.md +14 -1
- package/docs/ETHOS.md +106 -0
- package/docs/OUTPUT_EVIDENCE.md +118 -0
- package/docs/WHY.md +42 -0
- package/knowledge/patterns/ensemble_union_detection_task_pattern.md +125 -0
- package/knowledge/shared/GLOSSARY.md +77 -0
- package/knowledge/shared/harness-core/harness_frontier_diagnosis_2026-06-02.md +1 -1
- package/knowledge/shared/harness-core/meta_harness_engineering_definition.md +1 -1
- package/knowledge/shared/learnings/subagent_invocations_log.yaml +9 -0
- package/knowledge/shared/patterns/multi-persona-review.md +88 -0
- package/knowledge/shared/plugin-catalog/recommended_plugins.md +117 -0
- package/package.json +28 -1
- package/plugins/fh-commons/.claude-plugin/plugin.json +1 -1
- package/plugins/fh-meta/.claude-plugin/plugin.json +2 -2
- package/plugins/fh-meta/CHANGELOG.md +617 -0
- package/scripts/below_floor_scan.sh +91 -0
- package/scripts/chamber_run.sh +184 -0
- package/scripts/degrade_direction_scan.sh +17 -2
- package/scripts/fh_env_delta_scan.sh +108 -0
- package/scripts/memory_link_check.py +237 -0
- package/scripts/memory_nearcheck.py +131 -0
- package/scripts/package_coverage_check.sh +140 -0
- package/scripts/selfcheck.sh +47 -0
- package/scripts/session_close_check.sh +31 -1
- package/scripts/sidecar_wait.sh +76 -0
- package/scripts/substrate_jump_detector.sh +60 -0
- package/scripts/test_card_drift_probe.sh +77 -0
- package/scripts/test_degrade_scan_shell_probes.sh +26 -0
- package/scripts/test_marker_floor_lanes.sh +45 -0
- package/scripts/test_memory_link_check.sh +134 -0
- package/scripts/test_session_close_lanes.sh +99 -0
- package/scripts/tier_census_grep.sh +54 -0
- package/templates/.claude/rules/session.md +153 -0
- package/templates/contrib_session.md +34 -0
- package/templates/degrade_direction_scan.sh +17 -2
- package/templates/goal-quench-hook-setup.md +152 -0
- package/templates/starter_profile.md +83 -0
- package/templates/temper_check.sh +46 -0
- package/plugins/fh-meta/skills/context-bridge-dispatch/SKILL.md +0 -32
- package/plugins/fh-meta/skills/self-marketing-lint/SKILL.md +0 -30
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
# goal-quench Stop Hook Setup
|
|
2
|
+
|
|
3
|
+
Add the following to your project's `.claude/settings.json` to enable the goal-quench Stop hook:
|
|
4
|
+
|
|
5
|
+
```json
|
|
6
|
+
{
|
|
7
|
+
"hooks": {
|
|
8
|
+
"Stop": [
|
|
9
|
+
{
|
|
10
|
+
"matcher": "",
|
|
11
|
+
"hooks": [
|
|
12
|
+
{
|
|
13
|
+
"type": "command",
|
|
14
|
+
"command": "bash -c 'f=\".claude/goal-quench.active\"; [ -f \"$f\" ] && echo \"\\n[goal-quench] /goal finished. Running quality verification...\" && cp \"$f\" \".claude/goal-quench.pending\" && rm -f \"$f\" || true'"
|
|
15
|
+
}
|
|
16
|
+
]
|
|
17
|
+
}
|
|
18
|
+
]
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Add to your project's `.gitignore`:
|
|
24
|
+
|
|
25
|
+
```
|
|
26
|
+
.claude/goal-quench.active
|
|
27
|
+
.claude/goal-quench.pending
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## How it works
|
|
31
|
+
|
|
32
|
+
1. `/goal-quench` (Phase 1) writes `.claude/goal-quench.active` with scope + budget info
|
|
33
|
+
2. User runs `/goal [condition]`
|
|
34
|
+
3. When `/goal` finishes → Stop hook fires → detects `.active` → copies to `.pending` → removes `.active`
|
|
35
|
+
4. Next Claude response: detects `.pending` → auto-runs `pipeline-conductor --quick` → cleans up
|
|
36
|
+
|
|
37
|
+
## Merge with existing settings.json
|
|
38
|
+
|
|
39
|
+
If you already have a `settings.json`, merge the `hooks.Stop` array:
|
|
40
|
+
|
|
41
|
+
```json
|
|
42
|
+
{
|
|
43
|
+
"permissions": { ... your existing permissions ... },
|
|
44
|
+
"hooks": {
|
|
45
|
+
"Stop": [
|
|
46
|
+
{
|
|
47
|
+
"matcher": "",
|
|
48
|
+
"hooks": [
|
|
49
|
+
{ "type": "command", "command": "... your existing stop hook command if any ..." }
|
|
50
|
+
]
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
"matcher": "",
|
|
54
|
+
"hooks": [
|
|
55
|
+
{
|
|
56
|
+
"type": "command",
|
|
57
|
+
"command": "bash -c 'f=\".claude/goal-quench.active\"; [ -f \"$f\" ] && echo \"\\n[goal-quench] /goal finished. Running quality verification...\" && cp \"$f\" \".claude/goal-quench.pending\" && rm -f \"$f\" || true'"
|
|
58
|
+
}
|
|
59
|
+
]
|
|
60
|
+
}
|
|
61
|
+
]
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## Manual Apply (forge-harness)
|
|
67
|
+
|
|
68
|
+
A pre-merged `settings.json` for the forge-harness repo is available at:
|
|
69
|
+
|
|
70
|
+
```
|
|
71
|
+
templates/goal-quench-settings-merged.json
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
To apply it manually (one command, run from the forge-harness repo root):
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
cp templates/goal-quench-settings-merged.json .claude/settings.json
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
This file preserves all existing `permissions` and `enabledPlugins` from the current `.claude/settings.json` and adds the `hooks.Stop` section.
|
|
81
|
+
|
|
82
|
+
Note: `.claude/settings.json` is gitignored (local-only file), so this copy must be done manually on each machine.
|
|
83
|
+
|
|
84
|
+
## Verification Steps
|
|
85
|
+
|
|
86
|
+
After applying the hook, verify the full pipeline with these steps:
|
|
87
|
+
|
|
88
|
+
### Step 1 — Start a goal-quench session
|
|
89
|
+
|
|
90
|
+
Run the goal-quench skill to write the `.active` file:
|
|
91
|
+
|
|
92
|
+
```
|
|
93
|
+
/goal-quench
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
This should create `.claude/goal-quench.active` with scope + budget metadata.
|
|
97
|
+
|
|
98
|
+
Confirm:
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
ls -la .claude/goal-quench.active
|
|
102
|
+
cat .claude/goal-quench.active
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### Step 2 — Run a goal
|
|
106
|
+
|
|
107
|
+
```
|
|
108
|
+
/goal <your completion condition here>
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
Example: `/goal all acceptance tests pass`
|
|
112
|
+
|
|
113
|
+
### Step 3 — Verify Stop hook fired
|
|
114
|
+
|
|
115
|
+
When the `/goal` task finishes (Claude stops responding), check that:
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
# .active should be gone
|
|
119
|
+
ls .claude/goal-quench.active 2>/dev/null && echo "ERROR: .active still exists" || echo "OK: .active removed"
|
|
120
|
+
|
|
121
|
+
# .pending should exist
|
|
122
|
+
ls .claude/goal-quench.pending && echo "OK: .pending created" || echo "ERROR: .pending missing"
|
|
123
|
+
|
|
124
|
+
# .pending content
|
|
125
|
+
cat .claude/goal-quench.pending
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### Step 4 — Verify auto-trigger in next response
|
|
129
|
+
|
|
130
|
+
Send any message to Claude in the same session. The next response should:
|
|
131
|
+
1. Detect `.claude/goal-quench.pending`
|
|
132
|
+
2. Auto-run `pipeline-conductor --quick` (or equivalent quality verification)
|
|
133
|
+
3. Remove `.pending` after completion
|
|
134
|
+
|
|
135
|
+
If the skill is not installed, Claude will report the pending file and ask how to proceed.
|
|
136
|
+
|
|
137
|
+
### Step 5 — Cleanup check
|
|
138
|
+
|
|
139
|
+
After the verification round completes:
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
ls .claude/goal-quench.* 2>/dev/null || echo "OK: all state files cleaned up"
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
## Troubleshooting
|
|
146
|
+
|
|
147
|
+
| Symptom | Likely cause | Fix |
|
|
148
|
+
|---|---|---|
|
|
149
|
+
| `.active` not created after `/goal-quench` | Skill not writing the file | Check SKILL.md `goal-quench` for file write step |
|
|
150
|
+
| `.active` still present after session stop | Hook not installed / not firing | Re-run `cp templates/goal-quench-settings-merged.json .claude/settings.json`, restart Claude Code |
|
|
151
|
+
| `.pending` created but no auto-trigger | pipeline-conductor not installed | Install or implement the skill; Claude will report the pending state |
|
|
152
|
+
| Hook fires on every stop (not just goal-quench) | Expected — `[ -f "$f" ]` guard prevents false triggers when `.active` absent |
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# FH Starter Profile — Mode C (plugin only, no clone)
|
|
2
|
+
|
|
3
|
+
> **The one opinionated front door.** FH has 33 skills and a full hub you can clone — but you
|
|
4
|
+
> don't need any of that to get value today. This profile is the *single strong default*: one
|
|
5
|
+
> install command, a curated first-five skills, and a zero-install governance gate. Pick up the
|
|
6
|
+
> rest later if you want it.
|
|
7
|
+
>
|
|
8
|
+
> This is **Mode C** (see `knowledge/shared/rules/modes_and_value.md`): you install the plugin/skills only,
|
|
9
|
+
> you do **not** clone the hub. That trade-off is spelled out under *What Mode C does not include*.
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## 1. Install — one command
|
|
14
|
+
|
|
15
|
+
**Prerequisite**: Claude Code CLI (`claude --version`).
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
claude plugin marketplace add https://github.com/chrono-meta/forge-harness.git
|
|
19
|
+
claude plugin install -s user fh-meta@forge-harness
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
That's it — no clone, no shell hooks, no machine setup. Open Claude Code in *your own* project and
|
|
23
|
+
the skills are available as slash commands.
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
cd ~/your-project && claude
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## 2. Governance gate — zero install (no plugin needed either)
|
|
30
|
+
|
|
31
|
+
The core FH value — **"pass → accelerate"**: code that clears the gate ships faster. You can run it
|
|
32
|
+
on any file with nothing installed but `npx`:
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
npx --package @chrono-meta/fh-gate fh-gate # default: Claude backend
|
|
36
|
+
FH_BACKEND=codex npx --package @chrono-meta/fh-gate fh-gate # Codex backend
|
|
37
|
+
# → FH_GATE_VERDICT: PASS | PENDING | BLOCKED | ESCALATE
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
This wraps any coding agent (Claude, Codex) as a post-generation governance gate. It is the single
|
|
41
|
+
highest-leverage thing to try first if you only do one thing.
|
|
42
|
+
|
|
43
|
+
## 3. The opinionated first five (start here, ignore the other 28)
|
|
44
|
+
|
|
45
|
+
A new user dropped into 33 skills stalls. These five cover the common path; reach for the rest only
|
|
46
|
+
when a real need shows up.
|
|
47
|
+
|
|
48
|
+
| Skill | Run it when | One line |
|
|
49
|
+
|---|---|---|
|
|
50
|
+
| `/plugin-recommender` | "what tools should I even use?" | Discovery — classifies tools, checks token cost |
|
|
51
|
+
| `/context-doctor` | session feels slow / token-heavy | Generates `.claudeignore`, flags large files, `/clear` timing |
|
|
52
|
+
| `/harness-doctor` | "is my setup sane?" | L1–L4 structure diagnosis + prescription |
|
|
53
|
+
| `/goal-quench` | before executing a risky/long task | Gated execution — the acceleration gate in skill form |
|
|
54
|
+
| `/frontier-digest` | "what's new out there?" | External/frontier trend cross-reference |
|
|
55
|
+
|
|
56
|
+
Natural language works too — you don't need to memorize slash commands. "manage my context",
|
|
57
|
+
"recommend a plugin", "check my harness structure" route to the same skills.
|
|
58
|
+
|
|
59
|
+
## 4. What Mode C does *not* include (honest boundary)
|
|
60
|
+
|
|
61
|
+
Plugin-only install gives you **Layer 2 (the skills)**. It does **not** give you **Layer 1**, which
|
|
62
|
+
only activates when you clone the hub (Mode A/B):
|
|
63
|
+
|
|
64
|
+
- **No active onboarding cascade** — no greeting-triggered 5-skill auto-run. You invoke skills yourself.
|
|
65
|
+
- **No acceleration baseline** — no zshrc notification hook, no sentinels, no weekly-audit schedule,
|
|
66
|
+
no 4-axis pre-commit gate. Those are hub-internal infra and are deliberately not shipped to Mode C.
|
|
67
|
+
- **No automatic harness signals** — history accumulation happens on *your* project side; FH won't
|
|
68
|
+
prompt you. (FH absorbs Mode-C contributions through issue monitoring + PR cadence, not a daemon.)
|
|
69
|
+
|
|
70
|
+
If you later want Layer 1, clone the hub and run `/install-wizard` — the full path. The README's
|
|
71
|
+
"Get started in 2 minutes" covers it.
|
|
72
|
+
|
|
73
|
+
## 5. Want to go further?
|
|
74
|
+
|
|
75
|
+
- **Clone the hub** (Mode A/B) → persistent cross-project knowledge, `tracks/`, the compounding loop.
|
|
76
|
+
- **Contribute back** → a Mode-C PR is exactly the external validation FH is looking for. Open an
|
|
77
|
+
issue or PR on `chrono-meta/forge-harness`.
|
|
78
|
+
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
*Design note: this profile follows the frictionless-distribution + opinionated-front-door pattern
|
|
82
|
+
seen in field harnesses like [gstack](https://github.com/garrytan/gstack) — a single strong default
|
|
83
|
+
as the public entry point, full meta-flexibility kept behind it.*
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# temper_check.sh — Wave-T (Temper) step T-1: complexity delta of a quench.
|
|
3
|
+
# Measures how much complexity a steel-quench ADDED to a markdown asset
|
|
4
|
+
# (pre-quench baseline → post-convergence). It is a MEASUREMENT, not a detector
|
|
5
|
+
# (don't-overbuild guard: no judgment engine here — T-3 verdict is human/LLM).
|
|
6
|
+
#
|
|
7
|
+
# Usage: temper_check.sh <repo> <file-rel-path> <pre-quench-ref> [<post-ref>]
|
|
8
|
+
# <post-ref> default = working tree.
|
|
9
|
+
# See plugins/fh-meta/skills/steel-quench/SKILL.md §Wave-T.
|
|
10
|
+
set -euo pipefail
|
|
11
|
+
|
|
12
|
+
repo="${1:?repo path}"; file="${2:?file rel path}"; pre="${3:?pre-quench ref}"; post="${4:-}"
|
|
13
|
+
|
|
14
|
+
metrics() { # reads text on stdin → "lines sections steps tables fences crossrefs"
|
|
15
|
+
local t prose; t="$(cat)"
|
|
16
|
+
# sections/steps/tables count PROSE only — lines inside ``` fences are code
|
|
17
|
+
# (bash comments `# ...` would otherwise inflate Δsections; found run #4, install-wizard)
|
|
18
|
+
prose="$(printf '%s\n' "$t" | awk '/^[[:space:]]*```/{f=!f;next} !f')"
|
|
19
|
+
local lines sections steps tables fences crossrefs
|
|
20
|
+
lines=$(printf '%s\n' "$t" | wc -l | tr -d ' ')
|
|
21
|
+
sections=$(printf '%s\n' "$prose" | grep -cE '^#{1,6} ' || true)
|
|
22
|
+
steps=$(printf '%s\n' "$prose" | grep -cE '^[[:space:]]*([0-9]+\.|[-*] )' || true)
|
|
23
|
+
tables=$(printf '%s\n' "$prose" | grep -cE '^\|' || true)
|
|
24
|
+
fences=$(( $(printf '%s\n' "$t" | grep -c '```' || true) / 2 ))
|
|
25
|
+
crossrefs=$(printf '%s\n' "$t" | grep -oE '\]\(|\[\[' | wc -l | tr -d ' ')
|
|
26
|
+
echo "$lines $sections $steps $tables $fences $crossrefs"
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
pre_txt=$(git -C "$repo" show "$pre:$file")
|
|
30
|
+
if [ -n "$post" ]; then post_txt=$(git -C "$repo" show "$post:$file"); else post_txt=$(cat "$repo/$file"); fi
|
|
31
|
+
|
|
32
|
+
read -r l0 s0 p0 t0 f0 x0 <<<"$(printf '%s' "$pre_txt" | metrics)"
|
|
33
|
+
read -r l1 s1 p1 t1 f1 x1 <<<"$(printf '%s' "$post_txt" | metrics)"
|
|
34
|
+
|
|
35
|
+
printf '\n=== Wave-T complexity delta — %s ===\n' "$file"
|
|
36
|
+
printf 'baseline: %s post: %s\n\n' "$pre" "${post:-<working>}"
|
|
37
|
+
printf '%-12s %6s %6s %8s\n' metric pre post Δ
|
|
38
|
+
for row in "lines $l0 $l1" "sections $s0 $s1" "steps $p0 $p1" "tables $t0 $t1" "fences $f0 $f1" "cross-refs $x0 $x1"; do
|
|
39
|
+
set -- $row; printf '%-12s %6s %6s %+8d\n' "$1" "$2" "$3" "$(( $3 - $2 ))"
|
|
40
|
+
done
|
|
41
|
+
|
|
42
|
+
dx=$(( x1 - x0 )); dp=$(( p1 - p0 ))
|
|
43
|
+
printf '\n-- T-3 heuristic flags (review, not auto-reject) --\n'
|
|
44
|
+
[ "$dx" -gt "$dp" ] && printf ' ⚠ Δcross-refs(%+d) > Δsteps(%+d): quench added wiring, not function?\n' "$dx" "$dp" || true
|
|
45
|
+
[ "$(( s1 - s0 ))" -gt 0 ] && printf ' ⚠ %+d new section(s): confirm each fixes a flaw, not just defends a Wave finding\n' "$(( s1 - s0 ))" || true
|
|
46
|
+
printf '\nNext: run harness-doctor on post asset for absolute tier (T-2), then record τ verdict (PASS / FAIL + named construct)\n'
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: context-bridge-dispatch
|
|
3
|
-
description: >-
|
|
4
|
-
DEPRECATED — merged into agent-composer Step 3-a (2026-06-02).
|
|
5
|
-
Context Card injection (N≤2 standard / N≥3 Registry mode) + coordination-overhead budget + Focus Mode
|
|
6
|
-
are now part of agent-composer Step 3. Invoke /agent-composer for parallel dispatch.
|
|
7
|
-
user-invocable: false
|
|
8
|
-
allowed-tools: []
|
|
9
|
-
model: sonnet
|
|
10
|
-
deprecated: true
|
|
11
|
-
deprecated_reason: absorbed into agent-composer Step 3-a
|
|
12
|
-
deprecated_date: 2026-06-02
|
|
13
|
-
successor: agent-composer
|
|
14
|
-
---
|
|
15
|
-
|
|
16
|
-
# context-bridge-dispatch — DEPRECATED
|
|
17
|
-
|
|
18
|
-
> **Merged into `agent-composer` Step 3-a (2026-06-02).**
|
|
19
|
-
> Context Card injection, Registry mode, coordination-overhead budget, and Focus Mode are now part of agent-composer Step 3.
|
|
20
|
-
> Use `/agent-composer` for all parallel dispatch with context injection.
|
|
21
|
-
|
|
22
|
-
## Content preserved at
|
|
23
|
-
|
|
24
|
-
`plugins/fh-meta/skills/agent-composer/SKILL.md §Step 3-a` — the live successor.
|
|
25
|
-
|
|
26
|
-
> The original pre-merge content is preserved in git history (this stub's earlier revisions); the
|
|
27
|
-
> shipped `SKILL_detail.md` archive was removed in the curator shrink (2026-06-16) as redundant with
|
|
28
|
-
> git history. No live content lost — the functional content lives in agent-composer Step 3-a.
|
|
29
|
-
|
|
30
|
-
## Done When
|
|
31
|
-
|
|
32
|
-
Deprecated — no active execution path. Done When: skill is never directly invoked; all dispatch routes through `/agent-composer` Step 3-a (the successor). This entry satisfies the harness-doctor L2 M-tier requirement for missing Done When (CLAUDE.md §New Skill Creation Pre-Commit Gate).
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: self-marketing-lint
|
|
3
|
-
description: >-
|
|
4
|
-
DEPRECATED — merged into harness-doctor --lint mode (2026-06-02).
|
|
5
|
-
Language pattern detection (self-marketing, cushion words, version labels) is now Step 3-L of harness-doctor.
|
|
6
|
-
Use /harness-doctor --lint instead.
|
|
7
|
-
user-invocable: false
|
|
8
|
-
allowed-tools: []
|
|
9
|
-
model: sonnet
|
|
10
|
-
deprecated: true
|
|
11
|
-
deprecated_reason: absorbed into harness-doctor Step 3-L (--lint mode)
|
|
12
|
-
deprecated_date: 2026-06-02
|
|
13
|
-
successor: harness-doctor
|
|
14
|
-
---
|
|
15
|
-
|
|
16
|
-
# self-marketing-lint — DEPRECATED
|
|
17
|
-
|
|
18
|
-
This skill was absorbed into **harness-doctor** on 2026-06-02. Its self-marketing /
|
|
19
|
-
cushion-word / version-brag detection patterns now live in **harness-doctor Step 3-L
|
|
20
|
-
(`--lint` mode)**, which carries the canonical baseline.
|
|
21
|
-
|
|
22
|
-
**Use instead:**
|
|
23
|
-
|
|
24
|
-
```
|
|
25
|
-
/harness-doctor --lint
|
|
26
|
-
```
|
|
27
|
-
|
|
28
|
-
Triggers that previously reached this skill (`check FH files`, `remove marketing
|
|
29
|
-
language`, `description diet`) now route to harness-doctor Step 3-L. This stub remains
|
|
30
|
-
only so old references resolve.
|