@chrono-meta/fh-gate 1.4.86 → 1.4.88
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/rules/fh_4axis_gate.md +1 -1
- package/.claude-plugin/marketplace.json +2 -2
- package/AGENTS.md +8 -0
- package/CLAUDE.md +30 -6
- package/knowledge/shared/harness-core/capability_composition_contract.md +416 -0
- package/knowledge/shared/harness-core/fh_detail_protocols.md +4 -0
- package/knowledge/shared/learnings/subagent_invocations_log.yaml +128 -0
- package/knowledge/shared/rules/auto_project_mapping.md +64 -1
- package/knowledge/shared/rules/operations.md +26 -0
- package/package.json +6 -2
- 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/prompt-regression/SKILL.md +1 -1
- package/scripts/degrade_direction_scan.sh +34 -2
- package/scripts/gate_pathspec_check.sh +91 -1
- package/scripts/package_coverage_check.sh +27 -0
- package/scripts/selfcheck.sh +112 -1
- package/scripts/session_close_check.sh +18 -4
- package/scripts/test_degrade_scan_shell_probes.sh +11 -2
- package/scripts/test_dispatch_log_lanes.sh +41 -1
- package/scripts/test_node_infra_delta_lanes.sh +211 -0
- package/scripts/test_session_close_chain_lanes.sh +349 -0
- package/scripts/test_wizard_snippet_merge_lanes.sh +202 -0
- package/templates/.claude/rules/session.md +28 -5
- package/templates/.git-hooks/pre-commit +9 -2
- package/templates/degrade_direction_scan.sh +34 -2
- package/templates/regression_guard.sh +25 -0
|
@@ -164,9 +164,41 @@ for f in "${FILES[@]}"; do
|
|
|
164
164
|
# yields "9\n0" and the `-gt` guard goes silent. Verified as a known pair (both directions) in
|
|
165
165
|
# scripts/test_degrade_scan_shell_probes.sh; narrowing without that anchor would just trade a
|
|
166
166
|
# noisy probe for a blind one.
|
|
167
|
+
#
|
|
168
|
+
# WIDENED 2026-08-04 — the narrowing had gone one step too far, and the proof is that this
|
|
169
|
+
# probe was BLIND to the live instance that bit us the day before. PR #251 fixed
|
|
170
|
+
# `grep -c … | tr -d ' ' || echo 0` in session_close_check.sh ④-e; running this scanner over
|
|
171
|
+
# the pre-#251 file produced ZERO hits (re-measured: fixed rule = 2, old rule = 0).
|
|
172
|
+
#
|
|
173
|
+
# THE ANCHOR WAS ON THE WRONG PROPERTY. The old regex asked "is there an upstream pipe" and
|
|
174
|
+
# required the counter to be the LAST stage. Neither is the discriminator. The discriminator
|
|
175
|
+
# is: **does the failing side still EMIT?** `grep -c` prints "0" and exits 1 on no-match, so it
|
|
176
|
+
# disarms with no upstream pipe at all, and any trailing stage that passes that "0" through
|
|
177
|
+
# keeps the "0\n0" intact.
|
|
178
|
+
#
|
|
179
|
+
# A first fix widened to a NAMED filter list (tr|head|sed|…). Cross-family review (gpt-5.5,
|
|
180
|
+
# 2026-08-04) refuted it with reproduced counter-examples, and the refutation held on
|
|
181
|
+
# measurement in BOTH directions:
|
|
182
|
+
# · still missed, all verified to yield "0\n0": `grep -Ec …`, `grep --count …`, `grep -Fcx …`
|
|
183
|
+
# (combined/long flag forms the `-c` literal never matched) and `| cat`.
|
|
184
|
+
# · newly over-matched: `| tail -n +2` after the counter yields ONE line — not a disarm.
|
|
185
|
+
# Name-based approximation produced under-match and over-match simultaneously. So the trailing
|
|
186
|
+
# chain is no longer enumerated: the rule keys on the COUNTER (grep with a `c` in any flag
|
|
187
|
+
# cluster or `--count`; or `wc` behind a real pipe) plus the `|| echo 0` fallback, and accepts
|
|
188
|
+
# any chain between them.
|
|
189
|
+
#
|
|
190
|
+
# PRESERVED from the 2026-07-28 narrowing, still pinned as known-negatives: (a) `a || b ||
|
|
191
|
+
# echo 0` has no pipeline, and (b) a stage that emits NOTHING on failure (`| jq -r … ||
|
|
192
|
+
# echo 0`) — there the fallback supplies the only line, as intended.
|
|
193
|
+
# KNOWN RESIDUAL, stated not hidden: a trailing stage that can swallow the counter's output
|
|
194
|
+
# (`| tail -n +2`, `| sed -n '/[1-9]/p'`) is now flagged though it is not a disarm. That is a
|
|
195
|
+
# deliberate recall-over-precision trade on an ADVISORY probe, taken because the measured cost
|
|
196
|
+
# of the other direction was a real defect shipping. Revisit if non-fixture FPs appear.
|
|
197
|
+
# Known pair: scripts/test_degrade_scan_shell_probes.sh (9 positives / negatives silent).
|
|
198
|
+
# Reverting this line turns the positive lane red — checked by applying the revert.
|
|
167
199
|
while IFS= read -r m; do
|
|
168
|
-
emit "$f" "${m%%:*}" "S5:pipefail-fallback(sh)" "\`|| echo 0\` fallback
|
|
169
|
-
done < <(grep -nE '[^|]\|[[:space:]]*([a-z]+[[:space:]]+)*(grep[
|
|
200
|
+
emit "$f" "${m%%:*}" "S5:pipefail-fallback(sh)" "\`|| echo 0\` fallback after a COUNTER (grep with -c / --count, or wc) — the counter PRINTS \"0\" and exits non-zero on no-match, so the fallback appends a SECOND line, the value becomes \"0\\n0\", the integer test dies with 'integer expression expected' (stderr only) and the guard goes silent; split it and sanitize: n=\$(...); n=\${n:-0}; case \$n in *[!0-9]*) n=0;; esac. VERIFY the trailing stage can actually emit — if it swallows the count (| tail -n +2), this is a known false positive"
|
|
201
|
+
done < <(grep -nE '(([^|]\|[[:space:]]*([a-z]+[[:space:]]+)*wc[^|]*)|(grep([[:space:]]+-[A-Za-z]*c[A-Za-z]*|[[:space:]]+--count)[^|]*))([^|]*\|[^|]*)*\|\|[[:space:]]*echo[[:space:]]+[\"'"'"']?0' "$f" 2>/dev/null \
|
|
170
202
|
| grep -vE '^[0-9]+:[[:space:]]*#' \
|
|
171
203
|
| grep -vE '#[[:space:]]*noqa[:[:space:]]*degrade')
|
|
172
204
|
fi
|
|
@@ -117,6 +117,31 @@ GUARD_PATHSPEC=(
|
|
|
117
117
|
'AGENTS.md'
|
|
118
118
|
'docs/*.md'
|
|
119
119
|
'templates/*.md'
|
|
120
|
+
# ── Added 2026-08-04 — the pathspec had drifted from the 4-axis ASSET LIST it exists to gate.
|
|
121
|
+
# Measured that day by mechanically walking every asset class in CLAUDE.md §FH Improvement
|
|
122
|
+
# 4-Axis against this array: four classes had NO covering pattern, and two of them are this
|
|
123
|
+
# repo's own mechanical floor — `templates/.git-hooks/*` (the hook that hard-blocks commits)
|
|
124
|
+
# and `templates/*.sh` (THIS FILE — the guard could not guard itself). The pre-commit HEAVY
|
|
125
|
+
# classifier already listed `^scripts/.*\.sh$`, so a scripts-only change entered the heavy
|
|
126
|
+
# path and then met Axis 1 returning `SKIP (not-checked, NOT a pass)`. Observed three times
|
|
127
|
+
# on 2026-08-04 alone, the third being the S5 fix (PR #253) — a change to a verdict-surface
|
|
128
|
+
# scanner that shipped with zero Axis-1 coverage.
|
|
129
|
+
#
|
|
130
|
+
# Calibrated before shipping, both directions (a widened copy, run against real history):
|
|
131
|
+
# · 12 consecutive historical commits touching scripts/*.sh → M=0 S=0 (no FP storm), and a
|
|
132
|
+
# control confirmed the files were actually SELECTED (4 files checked) rather than the
|
|
133
|
+
# zero coming from an inert pathspec — the unwired-instrument reading of a clean 0.
|
|
134
|
+
# · known-positive: truncating a shipped .sh by 60% → M-TIER BLOCK (`BLOCK` token dropped
|
|
135
|
+
# 100%, 60% line reduction). The md-shaped checks (F1 frontmatter, F2 sections, F3 fences)
|
|
136
|
+
# are inert on shell files; F4 keyword / F5 xref / F6 line-loss / F7 syntax are the ones
|
|
137
|
+
# that carry, and they are exactly the regressions that matter in a gate script.
|
|
138
|
+
# NOTE on globbing: git pathspec `*` crosses `/` (verified here — `templates/*.md` matches
|
|
139
|
+
# `templates/.claude/rules/session.md`), so these single-star forms are recursive.
|
|
140
|
+
'scripts/*.sh'
|
|
141
|
+
'templates/*.sh'
|
|
142
|
+
'templates/.git-hooks/*'
|
|
143
|
+
'plugins/*/agents/*.md'
|
|
144
|
+
'.claude/agents/*.md'
|
|
120
145
|
)
|
|
121
146
|
|
|
122
147
|
# 계기 무결: base ref 가 안 풀리면 diff 실패가 2>/dev/null 로 삼켜져 CHANGED 공백 →
|