@chrono-meta/fh-gate 1.4.74 → 1.4.76
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/AGENTS.md +18 -0
- package/CHEATSHEET.md +1 -1
- package/CLAUDE.md +14 -1
- 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/harness-core/multi_model_sidecar_strategy.md +6 -0
- package/knowledge/shared/learnings/subagent_invocations_log.yaml +29 -1
- package/package.json +7 -1
- package/plugins/fh-commons/.claude-plugin/plugin.json +1 -1
- package/plugins/fh-meta/.claude-plugin/plugin.json +1 -1
- package/plugins/fh-meta/skills/auto-decorrelation/SKILL.md +38 -3
- package/plugins/fh-meta/skills/sim-conductor/SKILL_detail.md +6 -0
- package/plugins/fh-meta/skills/steel-quench/SKILL_detail.md +6 -0
- package/scripts/degrade_direction_scan.sh +17 -2
- package/scripts/memory_link_check.py +237 -0
- package/scripts/memory_nearcheck.py +131 -0
- package/scripts/package_coverage_check.sh +25 -4
- package/scripts/selfcheck.sh +35 -0
- package/scripts/session_close_check.sh +31 -1
- package/scripts/sidecar_wait.sh +76 -0
- package/scripts/test_card_drift_probe.sh +77 -0
- package/scripts/test_degrade_scan_shell_probes.sh +26 -0
- package/scripts/test_memory_link_check.sh +134 -0
- package/scripts/test_session_close_lanes.sh +99 -0
- package/templates/degrade_direction_scan.sh +17 -2
- 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,99 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# test_session_close_lanes.sh — known-pair anchor for session_close_check.sh ② (harvest-loop
|
|
3
|
+
# obligation) and ⑤ (card-last invariant).
|
|
4
|
+
#
|
|
5
|
+
# WHY (2026-07-28): ② used to be an UNSATISFIABLE warning — it fired whenever an FH asset was
|
|
6
|
+
# touched today and the script had no way to observe whether harvest-loop ran, so no session could
|
|
7
|
+
# ever discharge it. A line that fires on every healthy close is noise, and noise trains the runner
|
|
8
|
+
# to skim past the ❌ lines that matter. The repair gave it a mechanical discharge (a harvest-loop
|
|
9
|
+
# decision recorded in TODAY's fh_completed file). This file is that repair's regression anchor:
|
|
10
|
+
# the fix is only real if the ⚠️ still fires when NOTHING is recorded, and stops firing when it is.
|
|
11
|
+
#
|
|
12
|
+
# Lanes (each is a decision the gate must get right, not a smoke test):
|
|
13
|
+
# ②-N FH asset touched today, no harvest-loop line anywhere → ⚠️ MUST fire
|
|
14
|
+
# ②-P1 same, plus "harvest-loop 실행 완료" → ✅ must NOT fire
|
|
15
|
+
# ②-P2 same, plus an explicit SKIP note → ✅ must NOT fire
|
|
16
|
+
# (CLAUDE.md ② accepts "harvest-loop (or an explicit skip note)" — a recorded skip is
|
|
17
|
+
# a discharged obligation, not an evaded one)
|
|
18
|
+
# ②-C no FH asset touched today → neither line appears at all
|
|
19
|
+
# (over-firing is a defect in its own right — the whole reason this repair exists)
|
|
20
|
+
# ⑤-N a close artifact newer than the card → ❌ card-last MUST fire (exit 1)
|
|
21
|
+
# ⑤-P card is the newest artifact → ✅ card-last holds
|
|
22
|
+
#
|
|
23
|
+
# Exit 0 = 7/7 lanes calibrated · exit 1 = the gate's instrument is wrong (do not trust its verdict)
|
|
24
|
+
|
|
25
|
+
set -uo pipefail
|
|
26
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
27
|
+
CHECK="$SCRIPT_DIR/session_close_check.sh"
|
|
28
|
+
TODAY=$(date +%Y-%m-%d)
|
|
29
|
+
FAILED=0
|
|
30
|
+
|
|
31
|
+
if [ ! -f "$CHECK" ]; then
|
|
32
|
+
echo "FAIL session-close lanes: subject $CHECK missing"
|
|
33
|
+
exit 1
|
|
34
|
+
fi
|
|
35
|
+
|
|
36
|
+
# Builds a throwaway repo whose HEAD commit touches (or does not touch) an FH asset path.
|
|
37
|
+
_fixture() { # $1=touch_fh_asset(0/1) $2=completed-file body (empty = no file)
|
|
38
|
+
local touch_fh="$1" body="$2" T
|
|
39
|
+
T=$(mktemp -d)
|
|
40
|
+
( cd "$T" \
|
|
41
|
+
&& git init -q . \
|
|
42
|
+
&& git config user.email anchor@local && git config user.name anchor \
|
|
43
|
+
&& if [ "$touch_fh" = 1 ]; then echo x > CLAUDE.md; else echo x > unrelated.txt; fi \
|
|
44
|
+
&& git add -A && git commit -qm "fixture" ) >/dev/null 2>&1
|
|
45
|
+
mkdir -p "$T/tracks/_meta"
|
|
46
|
+
[ -n "$body" ] && printf '%s\n' "$body" > "$T/tracks/_meta/fh_completed_${TODAY}.md"
|
|
47
|
+
printf '# card\n' > "$T/tracks/_meta/reference_next_session_starter.md"
|
|
48
|
+
printf '%s' "$T"
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
_lane() { # $1=name $2=grep-pattern $3=expect(0/1) $4=fixture dir
|
|
52
|
+
local name="$1" pat="$2" expect="$3" T="$4" out hit
|
|
53
|
+
out=$(bash "$CHECK" "$T" 2>/dev/null)
|
|
54
|
+
hit=0
|
|
55
|
+
printf '%s\n' "$out" | grep -q "$pat" && hit=1
|
|
56
|
+
rm -rf "$T"
|
|
57
|
+
if [ "$hit" = "$expect" ]; then
|
|
58
|
+
echo "✅ $name (hit=$hit, expected=$expect)"
|
|
59
|
+
else
|
|
60
|
+
echo "❌ $name — hit=$hit, expected=$expect"
|
|
61
|
+
printf '%s\n' "$out" | sed 's/^/ /'
|
|
62
|
+
FAILED=1
|
|
63
|
+
fi
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
WARN2='⚠️ ② FH assets changed today'
|
|
67
|
+
OK2='✅ ② FH assets changed today'
|
|
68
|
+
|
|
69
|
+
_lane "②-N no harvest-loop decision recorded → warns" "$WARN2" 1 "$(_fixture 1 '- 항목 하나')"
|
|
70
|
+
_lane "②-P1 harvest-loop run recorded → silent" "$WARN2" 0 "$(_fixture 1 '- harvest-loop 실행 완료')"
|
|
71
|
+
_lane "②-P2 explicit skip note → silent" "$WARN2" 0 "$(_fixture 1 '- harvest-loop: skipped — 3-repo session, deferred')"
|
|
72
|
+
_lane "②-P1 run recorded → prints the ✅ form" "$OK2" 1 "$(_fixture 1 '- harvest-loop 실행 완료')"
|
|
73
|
+
_lane "②-C no FH asset touched → no ② line at all" ' ② ' 0 "$(_fixture 0 '- 항목 하나')"
|
|
74
|
+
|
|
75
|
+
# ⑤ card-last: an artifact newer than the card is the bug class the invariant exists to catch.
|
|
76
|
+
T=$(_fixture 1 '- harvest-loop 실행 완료')
|
|
77
|
+
touch "$T/tracks/_meta/fh_completed_${TODAY}.md" # make it strictly newer than the card
|
|
78
|
+
if bash "$CHECK" "$T" >/dev/null 2>&1; then
|
|
79
|
+
echo "❌ ⑤-N artifact newer than card → expected exit 1, got 0 (card-last not enforced)"
|
|
80
|
+
FAILED=1
|
|
81
|
+
else
|
|
82
|
+
echo "✅ ⑤-N artifact newer than card → exit 1 (card-last enforced)"
|
|
83
|
+
fi
|
|
84
|
+
touch "$T/tracks/_meta/reference_next_session_starter.md" # card becomes newest
|
|
85
|
+
if bash "$CHECK" "$T" >/dev/null 2>&1; then
|
|
86
|
+
echo "✅ ⑤-P card newest → exit 0"
|
|
87
|
+
else
|
|
88
|
+
echo "❌ ⑤-P card newest → expected exit 0, got 1 (over-blocking: trains --no-verify)"
|
|
89
|
+
bash "$CHECK" "$T" 2>&1 | sed 's/^/ /'
|
|
90
|
+
FAILED=1
|
|
91
|
+
fi
|
|
92
|
+
rm -rf "$T"
|
|
93
|
+
|
|
94
|
+
if [ "$FAILED" -ne 0 ]; then
|
|
95
|
+
echo "SESSION-CLOSE LANES: FAIL — the gate's instrument is miscalibrated"
|
|
96
|
+
exit 1
|
|
97
|
+
fi
|
|
98
|
+
echo "SESSION-CLOSE LANES: PASS (7/7)"
|
|
99
|
+
exit 0
|
|
@@ -150,9 +150,24 @@ for f in "${FILES[@]}"; do
|
|
|
150
150
|
# S5 — the pipefail-fallback disarm: `... | grep -c ... || echo 0` appends a SECOND line under
|
|
151
151
|
# `set -o pipefail`, so the later `-gt` integer test becomes a bash error (= false) and the guard
|
|
152
152
|
# passes silently, with the error going only to stderr. Measured class, 2026-07-26.
|
|
153
|
+
#
|
|
154
|
+
# NARROWED 2026-07-28 after hand-verifying all 9 hits this repo produced: 9/9 were false
|
|
155
|
+
# positives, i.e. the probe was pure noise for its own class, and 100% FP trains dismissal of
|
|
156
|
+
# the one hit that will matter. Two distinct causes, both mechanically reproduced:
|
|
157
|
+
# (a) `a || b || echo 0` was read as a pipeline — the old regex could anchor its `\|` on the
|
|
158
|
+
# SECOND bar of the first `||`. No pipe exists, so no second line can ever be produced.
|
|
159
|
+
# (Every `_mtime() { stat -c %Y … || stat -f %m … || echo 0; }` in the tree was flagged.)
|
|
160
|
+
# (b) a real pipeline whose failing stage emits NOTHING (`… | jq -r … || echo 0`) — the
|
|
161
|
+
# fallback then supplies the only line, which is exactly the intended behavior.
|
|
162
|
+
# The disarm needs BOTH a real pipe AND a final stage that emits regardless of upstream failure
|
|
163
|
+
# — a counter (`grep -c`, `wc`). That is the measured shape: `find … | grep -c . || echo 0`
|
|
164
|
+
# yields "9\n0" and the `-gt` guard goes silent. Verified as a known pair (both directions) in
|
|
165
|
+
# scripts/test_degrade_scan_shell_probes.sh; narrowing without that anchor would just trade a
|
|
166
|
+
# noisy probe for a blind one.
|
|
153
167
|
while IFS= read -r m; do
|
|
154
|
-
emit "$f" "${m%%:*}" "S5:pipefail-fallback(sh)" "\`|| echo 0\` fallback on a pipeline — under \`set -o pipefail\`
|
|
155
|
-
done < <(grep -nE '\|[^|]
|
|
168
|
+
emit "$f" "${m%%:*}" "S5:pipefail-fallback(sh)" "\`|| echo 0\` fallback on a pipeline ending in a counter (grep -c/wc) — that stage emits even when an upstream stage fails, so under \`set -o pipefail\` the value gains a SECOND line, the integer comparison errors out, and the guard passes silently; split the pipeline and sanitize to an integer"
|
|
169
|
+
done < <(grep -nE '[^|]\|[[:space:]]*([a-z]+[[:space:]]+)*(grep[^|]*-c|wc)[^|]*\|\|[[:space:]]*echo[[:space:]]+[\"'"'"']?0' "$f" 2>/dev/null \
|
|
170
|
+
| grep -vE '^[0-9]+:[[:space:]]*#' \
|
|
156
171
|
| grep -vE '#[[:space:]]*noqa[:[:space:]]*degrade')
|
|
157
172
|
fi
|
|
158
173
|
|
|
@@ -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.
|