@chrono-meta/fh-gate 1.4.37 → 1.4.38
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.md +13 -3
- package/package.json +1 -1
- package/plugins/fh-meta/skills/harness-doctor/SKILL.md +14 -0
- package/scripts/selfcheck.sh +7 -29
package/CLAUDE.md
CHANGED
|
@@ -520,6 +520,15 @@ harvest-loop Step 0-b uses this file as its source — relying on LLM memory aft
|
|
|
520
520
|
```
|
|
521
521
|
Closing phrase detected ("wrap up", "done", "good work", "end session", etc.)
|
|
522
522
|
→ ① Check git diff + unpushed commits (status snapshot)
|
|
523
|
+
→ ①-b Open-PR sweep — `gh pr list --author @me --state open` (+ `gh search prs --author @me
|
|
524
|
+
--state open` for cross-repo). Classify, **surface-not-auto**: a **self-mergeable** PR
|
|
525
|
+
(operator's own repo, checks green) → *propose merge now* (never auto-merge — HITL); an
|
|
526
|
+
**awaiting-external** PR (other repos / corp review) → *surface for tracking only*. Why here:
|
|
527
|
+
the harness's "마감" ≠ the operator's "마감" — a self-authored PR (PR #111) sat open across
|
|
528
|
+
sessions with un-integrated skills + count drift because no close step surfaced it. Pairs with
|
|
529
|
+
the count-consistency check (which now runs at BOTH the local pre-commit hook AND the plugins/**
|
|
530
|
+
PR-CI merge boundary): the sweep surfaces the PR → merging it → the count-check catches any
|
|
531
|
+
drift at the merge (fh_signal_2026-06-21, gate-locality paired fix).
|
|
523
532
|
→ ② If FH assets changed: harvest-loop
|
|
524
533
|
→ ③ Sync local/gitignored session state to your durable companion store, if you keep one
|
|
525
534
|
→ ④ Memory hygiene — update stale entries + record new session findings
|
|
@@ -542,9 +551,10 @@ Closing phrase detected ("wrap up", "done", "good work", "end session", etc.)
|
|
|
542
551
|
→ ⑤ Card update ← ABSOLUTE LAST: must capture ①–④-b outcomes
|
|
543
552
|
→ ⑥ Commit card + push
|
|
544
553
|
```
|
|
545
|
-
**Card-last guard**: ①–④-b must ALL complete before ⑤ runs. Any new
|
|
546
|
-
during ①–④ (new commits, model changes, new findings)
|
|
547
|
-
written mid-sequence and then left open for more work to accumulate
|
|
554
|
+
**Card-last guard**: ①–④-b (incl. ①-b open-PR sweep) must ALL complete before ⑤ runs. Any new
|
|
555
|
+
information produced during ①–④ (new commits from a merged self-PR, model changes, new findings)
|
|
556
|
+
feeds INTO ⑤ — card is never written mid-sequence and then left open for more work to accumulate
|
|
557
|
+
after it.
|
|
548
558
|
|
|
549
559
|
**Mid-session card writes are drafts**: If a task (e.g., a calibration run) internally updates
|
|
550
560
|
the card, that is a draft. The close chain always re-runs ⑤ to capture post-draft activities.
|
package/package.json
CHANGED
|
@@ -136,9 +136,23 @@ File: {path}
|
|
|
136
136
|
| settings.json JSON syntax error | M-tier |
|
|
137
137
|
| Hooks in settings.json (PostToolUse/Stop) that don't fire in Agent View | S-tier or M-tier |
|
|
138
138
|
| Public-surface FH recommendation or default changed — no N-shot measurement evidence traceable in session records or PR body | S-tier |
|
|
139
|
+
| Pre-commit-adjacent gate reads the working tree (cat/glob of a *tracked* path) with no `--staged`/`--cached`/`git show :` on that path, when its verdict is about *what's committed* | S-tier |
|
|
139
140
|
|
|
140
141
|
Hook divergence verdict: 0 hooks = Normal · 1+ hooks (session-end/Stop) = S-tier · 1+ hooks (PostToolUse file writes or external API) = M-tier (data loss risk in Agent View).
|
|
141
142
|
|
|
143
|
+
**Index-vs-worktree gate lint** (2026-06-21, gate-locality corollary — `[[feedback_gate_locality_principle]]`):
|
|
144
|
+
a gate whose verdict is about *what is being committed* must read the **staged index**
|
|
145
|
+
(`git ls-files --cached` / `git show :path`), not the working tree (`cat`/glob of a tracked file) —
|
|
146
|
+
else it false-PASSes a commit whose staged content ≠ disk (origin: `count_check.sh` read the worktree
|
|
147
|
+
while the pre-commit hook fired on the index; the sibling `regression_guard` already used `--staged`,
|
|
148
|
+
so the lesson existed but was non-local). Mechanical scan — in the pre-commit hook + the scripts it
|
|
149
|
+
invokes (+ `scripts/*-check.sh`): flag a `cat`/`<`/glob read of a tracked path with no
|
|
150
|
+
`--staged`/`--cached`/`git show :` on that path. **Conditional (NOT universal)**: a gate whose verdict is
|
|
151
|
+
about what *runs/deploys* (pre-push tests, build, an auto-fixer that rewrites the worktree) correctly
|
|
152
|
+
reads the working tree — a line-level `# worktree-intentional:` comment suppresses the flag. FP surface
|
|
153
|
+
(isolated-critic): display/log reads and untracked generated files are not violations → keep advisory
|
|
154
|
+
(S-tier, never M).
|
|
155
|
+
|
|
142
156
|
### Step 5. L4 — Connection Diagnosis *(FH only)*
|
|
143
157
|
|
|
144
158
|
- Tracks with no sync in 30+ days → R-tier
|
package/scripts/selfcheck.sh
CHANGED
|
@@ -35,35 +35,13 @@ done
|
|
|
35
35
|
# Count consistency: stated skill/agent counts vs actual directories.
|
|
36
36
|
# Drift class recurred 4x on 2026-06-10 alone (local_fh_context 26, plugin.json "3 agents",
|
|
37
37
|
# README "5 agents", marketplace.json "3 agents") — this makes the check mechanical and permanent.
|
|
38
|
-
#
|
|
39
|
-
#
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
done
|
|
46
|
-
echo "$n"
|
|
47
|
-
}
|
|
48
|
-
count_agents() { ls plugins/"$1"/agents/*.md 2>/dev/null | wc -l | tr -d ' '; }
|
|
49
|
-
|
|
50
|
-
meta_sk=$(count_active fh-meta); meta_ag=$(count_agents fh-meta)
|
|
51
|
-
com_sk=$(count_active fh-commons); com_ag=$(count_agents fh-commons)
|
|
52
|
-
total_sk=$((meta_sk + com_sk)); total_ag=$((meta_ag + com_ag))
|
|
53
|
-
|
|
54
|
-
count_check() { # count_check <label> <file> <expected-string>
|
|
55
|
-
if grep -q "$3" "$2"; then
|
|
56
|
-
echo "PASS count: $1"
|
|
57
|
-
else
|
|
58
|
-
echo "FAIL count: $1 — expected \"$3\" in $2 (actual: fh-meta ${meta_sk}sk/${meta_ag}ag, fh-commons ${com_sk}sk/${com_ag}ag)"
|
|
59
|
-
fail=1
|
|
60
|
-
fi
|
|
61
|
-
}
|
|
62
|
-
count_check "fh-meta plugin.json" plugins/fh-meta/.claude-plugin/plugin.json "${meta_sk} skills + ${meta_ag} agents"
|
|
63
|
-
count_check "fh-commons plugin.json" plugins/fh-commons/.claude-plugin/plugin.json "${com_sk} skills"
|
|
64
|
-
count_check "marketplace.json fh-meta" .claude-plugin/marketplace.json "${meta_sk} skills + ${meta_ag} agents"
|
|
65
|
-
count_check "README header" README.md "${total_sk} skills · ${total_ag} agents"
|
|
66
|
-
count_check "local_fh_context fh-meta" templates/local_fh_context.md "(fh-meta, ${meta_sk})"
|
|
38
|
+
# Logic extracted to scripts/count_check.sh so the SAME check also runs at commit time in
|
|
39
|
+
# the pre-commit hook (shift-left, gated on a skills-dir add/remove — fh_signal_2026-06-21
|
|
40
|
+
# gate-locality gap: the check previously lived only here at the publish boundary, so a
|
|
41
|
+
# skill-adding PR could merge with stale counts undetected until the next publish).
|
|
42
|
+
if ! bash scripts/count_check.sh; then
|
|
43
|
+
fail=1
|
|
44
|
+
fi
|
|
67
45
|
|
|
68
46
|
# Referenced-path existence: backtick-quoted repo-relative file refs in the always-loaded
|
|
69
47
|
# governance surface (CLAUDE.md + .claude/rules/*.md) must exist. Phantom-reference class
|