@chrono-meta/fh-gate 1.4.96 → 1.4.98
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/CATALOG.md +19 -0
- package/CHEATSHEET.md +9 -1
- package/CLAUDE.md +39 -6
- package/README.ja.md +10 -0
- package/README.ko.md +10 -0
- package/README.md +30 -0
- package/README.zh.md +10 -0
- package/docs/pillars.svg +3 -7
- package/knowledge/shared/harness-core/fh_ecosystem_positioning.md +2 -0
- package/knowledge/shared/harness-core/fh_global_positioning_and_distribution_roadmap.md +136 -0
- package/knowledge/shared/harness-core/fh_three_layer_canon.md +20 -0
- package/knowledge/shared/harness-core/field_verdict_crossfamily_gate.md +215 -2
- package/knowledge/shared/harness-core/ship_readiness_gate.md +112 -0
- package/knowledge/shared/learnings/subagent_invocations_log.yaml +125 -0
- package/package.json +9 -2
- package/plugins/fh-commons/.claude-plugin/plugin.json +1 -1
- package/plugins/fh-commons/skills/ko-tech-writer/SKILL.md +63 -12
- package/plugins/fh-meta/.claude-plugin/plugin.json +1 -1
- package/plugins/fh-meta/CHANGELOG.md +65 -0
- package/plugins/fh-meta/skills/auto-decorrelation/SKILL.md +30 -0
- package/scripts/compaction_probe.sh +153 -10
- package/scripts/consent_registry_check.sh +63 -0
- package/scripts/degrade_direction_scan.sh +10 -1
- package/scripts/digest_landing_check.sh +20 -4
- package/scripts/fh_node_check.sh +60 -1
- package/scripts/fh_session_load.sh +22 -2
- package/scripts/frontier_digest_autopilot.sh +229 -0
- package/scripts/lane_runner_check.sh +637 -0
- package/scripts/package_coverage_check.sh +199 -35
- package/scripts/postinstall_notice.js +34 -0
- package/scripts/psa_scan_lib.sh +164 -0
- package/scripts/public_surface_scan_files.sh +30 -0
- package/scripts/selfcheck.sh +442 -33
- package/scripts/test_consent_registry.sh +54 -0
- package/scripts/test_degrade_scan_shell_probes.sh +75 -0
- package/scripts/test_field_canon_lanes.sh +29 -5
- package/scripts/test_lane_runner_lanes.sh +221 -0
- package/scripts/test_marker_crossfamily_lanes.sh +10 -1
- package/scripts/test_marker_floor_lanes.sh +25 -1
- package/scripts/test_psa_singlefile_lanes.sh +288 -0
- package/scripts/test_reviewer_capability_conformance.sh +10 -1
- package/scripts/test_selfcheck_state_lanes.sh +173 -0
- package/scripts/test_stale_clone_guard_lanes.sh +21 -7
- package/scripts/test_version_lockstep_lanes.sh +62 -0
- package/scripts/version_lockstep_check.sh +143 -1
- package/templates/.git-hooks/pre-commit +22 -1
- package/templates/degrade_direction_scan.sh +10 -1
- package/templates/goal-quench-settings-merged.json +30 -0
package/scripts/selfcheck.sh
CHANGED
|
@@ -15,6 +15,78 @@ set -u
|
|
|
15
15
|
cd "$(dirname "${BASH_SOURCE[0]}")/.."
|
|
16
16
|
fail=0
|
|
17
17
|
|
|
18
|
+
# Single source of "declared legitimately unshipped" — package_coverage_check.sh's ACCEPTED_ABSENT,
|
|
19
|
+
# read once via its --list-accepted flag. Two blocks below (ref-path, SessionStart anchor pairs) used
|
|
20
|
+
# to each re-derive "is this absence OK" from an environment predicate (`.git` presence) instead of
|
|
21
|
+
# consulting this declaration — which reproduces the exact bug the declaration exists to prevent in
|
|
22
|
+
# any git-TRACKED tree that vendors this package (a monorepo committing node_modules, or a consumer
|
|
23
|
+
# who runs `git init` after install): `.git` is present there, so the environment predicate answered
|
|
24
|
+
# "source checkout", ran the full check, and FAILed on paths the declaration had already said were
|
|
25
|
+
# fine to omit. Cross-family review, 2026-08-12 (reship axis, card §🔱⑮ G). `--list-accepted` has no
|
|
26
|
+
# git/package.json dependency itself, so this load is safe to attempt unconditionally.
|
|
27
|
+
_PKG_ACCEPTED_ABSENT=""
|
|
28
|
+
if [ -f scripts/package_coverage_check.sh ]; then
|
|
29
|
+
_PKG_ACCEPTED_ABSENT="$(bash scripts/package_coverage_check.sh --list-accepted 2>/dev/null)"
|
|
30
|
+
fi
|
|
31
|
+
_pkg_accepted_absent() { printf '%s\n' "$_PKG_ACCEPTED_ABSENT" | grep -qxF "$1"; }
|
|
32
|
+
|
|
33
|
+
# Is this path DECLARED shipped by package.json files[]? The companion question to the one above:
|
|
34
|
+
# ACCEPTED_ABSENT answers "is this absence legitimate", this answers "should this be here at all".
|
|
35
|
+
# Together they turn a bare "file missing" into a routed verdict instead of a blanket SKIP.
|
|
36
|
+
# Directory entries in files[] cover everything under them, which is how `templates/.git-hooks`
|
|
37
|
+
# covers `templates/.git-hooks/pre-push` — a prefix test, not equality (getting this wrong is what
|
|
38
|
+
# made a comment claim the hook does not ship while package.json:117 declared its whole directory).
|
|
39
|
+
# NOTE ON WHAT THIS DOES *NOT* PROVE: files[] membership is a DECLARATION, not the tarball. This repo
|
|
40
|
+
# has already measured the two diverging (card §🔱⑮ G/C: repo ✅ / files[] ❌). Here the direction is
|
|
41
|
+
# safe — an over-declaration makes this check stricter, never more lenient — but do not reuse this
|
|
42
|
+
# helper anywhere the answer needs to be "what the consumer actually received"; that needs
|
|
43
|
+
# `npm pack --dry-run --json`.
|
|
44
|
+
_ships_per_files() {
|
|
45
|
+
python3 - "$1" <<'SHIPPY' 2>/dev/null
|
|
46
|
+
import json, sys
|
|
47
|
+
p = sys.argv[1]
|
|
48
|
+
try:
|
|
49
|
+
files = json.load(open('package.json'))['files']
|
|
50
|
+
except Exception:
|
|
51
|
+
sys.exit(2) # unreadable manifest: UNKNOWN, and the caller must not read that as "no"
|
|
52
|
+
sys.exit(0 if any(p == f or p.startswith(f.rstrip('/') + '/') for f in files) else 1)
|
|
53
|
+
SHIPPY
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
# ── The single verdict for "my subject is not here" ───────────────────────────────────────────
|
|
57
|
+
# Measured 2026-08-12 (card §🔱⑮ A2): **18 blocks in this file** rendered a green SKIP when their
|
|
58
|
+
# subject was absent, and **all 18 subjects are declared in package.json files[] and present in the
|
|
59
|
+
# real tarball** (verified with `npm pack --dry-run --json`, 20/20 — so routing them to FAIL cannot
|
|
60
|
+
# over-block a legitimate consumer). For a subject that always ships, "absent" cannot mean "package
|
|
61
|
+
# mode"; the only ways to reach it are DELETION or a broken install, and both were reported green.
|
|
62
|
+
# That is the fourth face of the axis the card names three of: 미측정→clean · 미측정→findings ·
|
|
63
|
+
# 해당없음→FAIL · **삭제→SKIP** — and it is the quiet one, which is why it survived longest.
|
|
64
|
+
#
|
|
65
|
+
# Two of the eighteen are worth naming because they read as already-handled and were not:
|
|
66
|
+
# · the gate_pathspec block printed "— not-checked, NOT a pass" and then did not set fail. The
|
|
67
|
+
# LABEL was honest and the VERDICT was green; a reader greps the message and believes it.
|
|
68
|
+
# · the --self-test loop's comment says "never a silent pass" directly above the arm that was one.
|
|
69
|
+
# A comment asserting a property is not the property. Both were hand-verified by eye, not inferred.
|
|
70
|
+
#
|
|
71
|
+
# THE UNKNOWN ARM IS NOT A SKIP. `_ships_per_files` exits 2 when package.json is unreadable, and an
|
|
72
|
+
# unreadable manifest means we cannot tell deletion from package mode — `not found != 0`, so that
|
|
73
|
+
# case must not silently take the lenient branch (this repo's whole §Instrument-Calibration rule).
|
|
74
|
+
# Usage: [ -f "$subj" ] || { _absent_subject_verdict "<label>" "$subj" || fail=1; }
|
|
75
|
+
_absent_subject_verdict() {
|
|
76
|
+
local label="$1" subj="$2"
|
|
77
|
+
_ships_per_files "$subj"
|
|
78
|
+
case $? in
|
|
79
|
+
0) echo "FAIL $label: $subj is DECLARED SHIPPED (package.json files[]) but absent — that is a"
|
|
80
|
+
echo " deletion or a broken install, not package mode. The subject itself is missing."
|
|
81
|
+
return 1 ;;
|
|
82
|
+
1) echo "SKIP $label (subject $subj not in package.json files[], and absent)"
|
|
83
|
+
return 0 ;;
|
|
84
|
+
*) echo "FAIL $label: cannot read package.json, so '$subj absent' is UNDECIDABLE between a"
|
|
85
|
+
echo " deletion and package mode — unmeasured, not clean."
|
|
86
|
+
return 1 ;;
|
|
87
|
+
esac
|
|
88
|
+
}
|
|
89
|
+
|
|
18
90
|
check() { # check <label> <cmd...>
|
|
19
91
|
local label="$1"; shift
|
|
20
92
|
if "$@" 2>/dev/null; then
|
|
@@ -152,12 +224,32 @@ fi
|
|
|
152
224
|
# above the ref loop drains git's ref list → Destructive-Op gate silently allows a delete/force push).
|
|
153
225
|
# Wired here, not left standalone: an unwired checker is the exact defect this session found in
|
|
154
226
|
# session_close_check.sh — building the test and not running it repeats it one layer up.
|
|
155
|
-
#
|
|
156
|
-
#
|
|
157
|
-
#
|
|
158
|
-
#
|
|
227
|
+
# ⚠️ CORRECTED 2026-08-12 (innovator Mode F scan → resolved by measurement). This comment used to
|
|
228
|
+
# read: "neither the test nor its subject (templates/.git-hooks/pre-push) is in package.json files[]
|
|
229
|
+
# — both are source-tree-only infra." **That was false**, and it had been false long enough to be
|
|
230
|
+
# load-bearing. `npm pack --dry-run --json` on this tree returns 262 files including
|
|
231
|
+
# templates/.git-hooks/pre-push, templates/.git-hooks/pre-commit AND
|
|
232
|
+
# scripts/test_prepush_stdin_integrity.sh — subject and anchor both ship (package.json:117 declares
|
|
233
|
+
# the whole `templates/.git-hooks` directory).
|
|
234
|
+
# The consequence is what makes this worth fixing rather than just re-wording: if the subject always
|
|
235
|
+
# ships, then "subject absent" can no longer mean "package mode" — the only way to reach that arm is
|
|
236
|
+
# that **the hook was deleted**, and it was rendering that as a green SKIP. This is the fourth face
|
|
237
|
+
# of the axis the card names three of at §🔱⑮ (미측정→clean · 미측정→findings · 해당없음→FAIL):
|
|
238
|
+
# **삭제→SKIP**. A deleted Destructive-Op gate reporting green on every surface is the worst of the
|
|
239
|
+
# four, because the other three are loud.
|
|
240
|
+
# Kept as a three-valued check rather than a bare FAIL: a consumer's tree can legitimately lack the
|
|
241
|
+
# directory if they installed with --ignore-scripts and pruned, so the *declaration* is what decides,
|
|
242
|
+
# not the environment (same discipline as `_pkg_accepted_absent` above — consult what ships, do not
|
|
243
|
+
# re-derive it from what happens to be on disk).
|
|
159
244
|
if [ ! -f templates/.git-hooks/pre-push ]; then
|
|
160
|
-
|
|
245
|
+
if _ships_per_files "templates/.git-hooks/pre-push"; then
|
|
246
|
+
echo "FAIL pre-push stdin integrity: templates/.git-hooks/pre-push is DECLARED SHIPPED but absent"
|
|
247
|
+
echo " — that is a deletion or a broken install, not package mode. The Destructive-Op gate"
|
|
248
|
+
echo " this anchors is the thing that is missing."
|
|
249
|
+
fail=1
|
|
250
|
+
else
|
|
251
|
+
echo "SKIP pre-push stdin integrity (not shipped per package.json files[], and absent)"
|
|
252
|
+
fi
|
|
161
253
|
elif [ -f scripts/test_prepush_stdin_integrity.sh ]; then
|
|
162
254
|
if ! bash scripts/test_prepush_stdin_integrity.sh; then
|
|
163
255
|
fail=1
|
|
@@ -173,7 +265,7 @@ fi
|
|
|
173
265
|
# (scripts/degrade_direction_scan.sh) and the anchor both ship, so this runs in package mode too;
|
|
174
266
|
# only a missing SUBJECT is a legitimate skip.
|
|
175
267
|
if [ ! -f scripts/degrade_direction_scan.sh ]; then
|
|
176
|
-
|
|
268
|
+
_absent_subject_verdict "degrade-scan shell probes" "scripts/degrade_direction_scan.sh" || fail=1
|
|
177
269
|
elif [ -f scripts/test_degrade_scan_shell_probes.sh ]; then
|
|
178
270
|
if ! bash scripts/test_degrade_scan_shell_probes.sh; then
|
|
179
271
|
fail=1
|
|
@@ -189,7 +281,7 @@ fi
|
|
|
189
281
|
# pair, a template that defeats the gate (a rendered newline turns the pattern into an OR search)
|
|
190
282
|
# passes silently — measured 2026-08-12 on a stale README that the gate reported as PASS.
|
|
191
283
|
if [ ! -f scripts/count_check.sh ]; then
|
|
192
|
-
|
|
284
|
+
_absent_subject_verdict "count_check README-format lanes" "scripts/count_check.sh" || fail=1
|
|
193
285
|
elif [ -f scripts/test_count_check_readme_format_lanes.sh ]; then
|
|
194
286
|
if ! bash scripts/test_count_check_readme_format_lanes.sh; then
|
|
195
287
|
fail=1
|
|
@@ -199,6 +291,22 @@ else
|
|
|
199
291
|
fail=1
|
|
200
292
|
fi
|
|
201
293
|
|
|
294
|
+
# The public-surface scanner's SINGLE-FILE and MISUSE paths. Same subject-present/anchor-gone shape:
|
|
295
|
+
# the scanner is a fail-closed gate on an irreversible surface, and its failure mode is a green that
|
|
296
|
+
# was never earned — a misuse, an unloaded pattern set, or dead plumbing all used to render as clean.
|
|
297
|
+
# Wired here on purpose (cross-family round 2): the lane file existed and was syntax-checked only, so
|
|
298
|
+
# `npm test` and `prepublishOnly` never executed it. A checker nobody calls is prose.
|
|
299
|
+
if [ ! -f scripts/psa_scan_lib.sh ]; then
|
|
300
|
+
_absent_subject_verdict "psa single-file lanes" "scripts/psa_scan_lib.sh" || fail=1
|
|
301
|
+
elif [ -f scripts/test_psa_singlefile_lanes.sh ]; then
|
|
302
|
+
if ! bash scripts/test_psa_singlefile_lanes.sh; then
|
|
303
|
+
fail=1
|
|
304
|
+
fi
|
|
305
|
+
else
|
|
306
|
+
echo "FAIL psa single-file lanes: psa_scan_lib.sh present but its anchor is missing"
|
|
307
|
+
fail=1
|
|
308
|
+
fi
|
|
309
|
+
|
|
202
310
|
# package-coverage — a shipped doc must not point at a file the tarball omits. Distinct from the
|
|
203
311
|
# ref-path check below: that one asks "does this path exist at all", this one asks "does the
|
|
204
312
|
# CONSUMER get it". Measured 2026-07-28: 35 paths existed, were named by a shipped doc, and were
|
|
@@ -213,7 +321,7 @@ fi
|
|
|
213
321
|
# to reason about CI. scripts/test_package_coverage_lanes.sh pins the predicate across all four
|
|
214
322
|
# tree shapes plus a known pair.
|
|
215
323
|
if [ ! -f scripts/package_coverage_check.sh ]; then
|
|
216
|
-
|
|
324
|
+
_absent_subject_verdict "test_package_coverage_lanes.sh" "scripts/package_coverage_check.sh" || fail=1
|
|
217
325
|
elif [ -f scripts/test_package_coverage_lanes.sh ]; then
|
|
218
326
|
if ! bash scripts/test_package_coverage_lanes.sh; then
|
|
219
327
|
fail=1
|
|
@@ -226,16 +334,160 @@ else
|
|
|
226
334
|
fail=1
|
|
227
335
|
fi
|
|
228
336
|
|
|
229
|
-
#
|
|
230
|
-
#
|
|
231
|
-
#
|
|
337
|
+
# lane-runner — sibling of package-coverage one level up: that one asks "does the CONSUMER get the
|
|
338
|
+
# file a shipped doc names", this one asks "does ANYTHING execute the lane suite we wrote". Measured
|
|
339
|
+
# 2026-08-12 (reship axis, card §🔱⑮ A): 12 of 43 suites under scripts/ had no runner in selfcheck,
|
|
340
|
+
# the git hooks, or CI — including scripts/test_marker_crossfamily_lanes.sh, whose subject is a
|
|
341
|
+
# marker field that hard-blocks commits, and scripts/test_marker_floor_lanes.sh, whose subject is
|
|
342
|
+
# pre-commit's live validate_marker_floor(). Both gates ship; neither calibration had ever run.
|
|
343
|
+
# The card recorded this as three specific repairs needing "one anchor each"; wiring three anchors
|
|
344
|
+
# would have closed those three and stayed blind to the other nine and to the thirteenth. This runs
|
|
345
|
+
# unconditionally when present because its own absence is the defect class it exists to detect —
|
|
346
|
+
# there is no package-mode arm to skip into (a consumer running `npm test` should learn that a
|
|
347
|
+
# shipped suite of theirs is dead code just as much as we should).
|
|
348
|
+
# THREE-VALUED, and the third value exists because the two-valued version was this session's own
|
|
349
|
+
# instance of the defect it detects. The first draft was `if [ -f … ]; then run; fi` — an absent
|
|
350
|
+
# checker fell through to nothing, silently. That is "미측정을 0으로 렌더" reproduced by the commit
|
|
351
|
+
# that closed it: a 1.4.96 consumer has no lane_runner_check.sh (it was added to files[] AFTER that
|
|
352
|
+
# publish), so on their machine this block would have printed nothing at all and `npm test` would
|
|
353
|
+
# have reported a clean run of a check that never existed there.
|
|
354
|
+
# The three states are distinguished by the DECLARATION, not by the environment (same discipline as
|
|
355
|
+
# the pre-push block above): present → run · absent-but-declared-shipped → FAIL (deletion or broken
|
|
356
|
+
# install) · absent-and-not-declared → SKIP, saying so. For a 1.4.96 consumer the third arm is the
|
|
357
|
+
# correct and honest answer, and it names itself rather than being silent.
|
|
358
|
+
if [ -f scripts/lane_runner_check.sh ]; then
|
|
359
|
+
if ! bash scripts/lane_runner_check.sh; then
|
|
360
|
+
fail=1
|
|
361
|
+
fi
|
|
362
|
+
elif _ships_per_files "scripts/lane_runner_check.sh"; then
|
|
363
|
+
echo "FAIL lane-runner: scripts/lane_runner_check.sh is DECLARED SHIPPED but absent — deletion or"
|
|
364
|
+
echo " broken install. The check that detects unrun lane suites is itself missing."
|
|
365
|
+
fail=1
|
|
366
|
+
else
|
|
367
|
+
echo "SKIP lane-runner (not in this package's files[] — predates the version that ships it)"
|
|
368
|
+
fi
|
|
369
|
+
|
|
370
|
+
# ── the twelve suites lane_runner_check.sh measured as having NO runner (2026-08-12) ───────────
|
|
371
|
+
# The check directly above COUNTS them; this block is what makes the count go down. Until now the
|
|
372
|
+
# repo shipped a checker that reported its own todo list every run and nothing that discharged it,
|
|
373
|
+
# which is a decision surface only for as long as someone acts on it.
|
|
374
|
+
#
|
|
375
|
+
# What was actually measured before this wiring existed, because the size of the fact is the reason
|
|
376
|
+
# the block is here: all twelve pass when run by hand (rc=0, ~40s total), and NINE OF THE TWELVE
|
|
377
|
+
# ARE IN THE PUBLISHED TARBALL (`npm pack --dry-run --json`, 263 files). So a consumer running
|
|
378
|
+
# `npm test` was shipping-and-carrying nine test suites that nothing on their machine ever called.
|
|
379
|
+
# The two that hurt most: test_marker_crossfamily_lanes.sh calibrates the `crossfamily:` marker enum
|
|
380
|
+
# that hard-blocks commits, and test_marker_floor_lanes.sh calibrates pre-commit's live
|
|
381
|
+
# validate_marker_floor(). Both gates ship and block; neither calibration had ever executed.
|
|
382
|
+
#
|
|
383
|
+
# ONE loop, not twelve blocks, and that is deliberate: the four-value routing below would otherwise
|
|
384
|
+
# be hand-copied twelve times, and this repo has already measured what that produces — two copies of
|
|
385
|
+
# a normalizer drifting in leniency until one of them silently drops its input
|
|
386
|
+
# ([[feedback_divergent_leniency_duplicate_normalizers]]). The pair table is data; the verdict logic
|
|
387
|
+
# exists once. The existing SessionStart pair-loop below/above uses the same shape.
|
|
388
|
+
#
|
|
389
|
+
# FOUR values, and every arm is reachable on a real machine:
|
|
390
|
+
# subject absent → _absent_subject_verdict (deletion vs package mode, decided by files[])
|
|
391
|
+
# anchor present → run it. exit 10 is called out separately: several of these suites use it
|
|
392
|
+
# for "I could not set myself up" (mktemp failure), which is not a lane
|
|
393
|
+
# failure and must not be reported as one — it still sets fail, because a
|
|
394
|
+
# harness that could not measure did not pass ([[not_found_is_not_zero]]).
|
|
395
|
+
# anchor absent+shipped → FAIL. Deletion or broken install, exactly like the block above.
|
|
396
|
+
# anchor absent+unshipped → SKIP, naming itself. Three anchors genuinely do not ship
|
|
397
|
+
# (chamber_run · frontier_digest_retry · residency_closure), so for a
|
|
398
|
+
# consumer this arm is the honest answer, not a dodge.
|
|
399
|
+
#
|
|
400
|
+
# Subject choice is the file whose behaviour the suite pins, so that deleting the subject routes to
|
|
401
|
+
# "your install is broken" rather than to a green run of a test about nothing.
|
|
402
|
+
# test_capability_entrypoint_shipping.sh pins two (degrade_probe_capability.sh and
|
|
403
|
+
# psa_probe_capability.sh); degrade is named here as the sentinel — the suite itself checks both and
|
|
404
|
+
# fails if either is gone, so nothing is lost by not listing both in this table.
|
|
405
|
+
_LANE_TO=""; command -v timeout >/dev/null 2>&1 && _LANE_TO="timeout 300"
|
|
406
|
+
for _pair in \
|
|
407
|
+
"scripts/degrade_probe_capability.sh|scripts/test_capability_entrypoint_shipping.sh" \
|
|
408
|
+
"scripts/chamber_run.sh|scripts/test_chamber_run_lanes.sh" \
|
|
409
|
+
"scripts/destructive_pre_gate.sh|scripts/test_destructive_pre_gate_lanes.sh" \
|
|
410
|
+
"scripts/env_purity_scan.sh|scripts/test_env_purity_lanes.sh" \
|
|
411
|
+
"scripts/frontier_digest_daily.sh|scripts/test_frontier_digest_retry.sh" \
|
|
412
|
+
"scripts/knowledge_seam_check.sh|scripts/test_knowledge_seam_lanes.sh" \
|
|
413
|
+
"templates/.git-hooks/pre-commit|scripts/test_marker_crossfamily_lanes.sh" \
|
|
414
|
+
"templates/.git-hooks/pre-commit|scripts/test_marker_floor_lanes.sh" \
|
|
415
|
+
"scripts/residency_closure_scan.py|scripts/test_residency_closure_lanes.sh" \
|
|
416
|
+
"scripts/reviewer_capability_corpus.tsv|scripts/test_reviewer_capability_conformance.sh" \
|
|
417
|
+
"scripts/field_canon_preload.sh|scripts/test_field_canon_lanes.sh" \
|
|
418
|
+
"scripts/stale_clone_guard.sh|scripts/test_stale_clone_guard_lanes.sh"
|
|
419
|
+
do
|
|
420
|
+
_subj="${_pair%%|*}"; _anc="${_pair##*|}"; _lbl="${_anc##*/}"
|
|
421
|
+
if [ ! -f "$_subj" ]; then
|
|
422
|
+
_absent_subject_verdict "$_lbl" "$_subj" || fail=1
|
|
423
|
+
elif [ -f "$_anc" ]; then
|
|
424
|
+
# `< /dev/null` and the timeout are not decoration: test_frontier_digest_retry.sh deliberately
|
|
425
|
+
# plants a `sleep 300` stub and asserts a 3s watchdog kills it. If that watchdog ever regresses
|
|
426
|
+
# — which is the single defect this suite exists to catch — an unguarded call does not go RED,
|
|
427
|
+
# it HANGS, and CI dies on a job timeout with the cause unattributable. The suite that detects
|
|
428
|
+
# a broken watchdog must not be able to inherit the hang. Same `command -v timeout` guard as the
|
|
429
|
+
# --self-test loop below, because `timeout` is GNU coreutils and stock macOS has neither it nor
|
|
430
|
+
# a substitute; without it `< /dev/null` is the whole defence and a suite that reads stdin ends
|
|
431
|
+
# immediately instead of waiting forever.
|
|
432
|
+
$_LANE_TO bash "$_anc" < /dev/null; _rc=$?
|
|
433
|
+
case "$_rc" in
|
|
434
|
+
0) ;;
|
|
435
|
+
# The suite could not MEASURE. Distinguished from "the lane failed" because the two send a
|
|
436
|
+
# reader to different places, and a bare fail=1 sends them to the wrong one. 10 = the suite's
|
|
437
|
+
# own setup failed (mktemp, used by several of these); 2 = its subject was missing when it
|
|
438
|
+
# looked (test_knowledge_seam_lanes.sh:7 FATALs this way); 126/127 = the anchor is not
|
|
439
|
+
# executable or not found at all, i.e. a broken install that reached this arm anyway.
|
|
440
|
+
# Every one of them still sets fail — a harness that could not measure did not pass — but it
|
|
441
|
+
# is LABELLED, so the next reader debugs the instrument instead of the lane.
|
|
442
|
+
# The first draft of this loop routed only 10 and let everything else fall into an unlabelled
|
|
443
|
+
# fail=1. That is the same "assumed impossible rather than routed" shape that the sibling
|
|
444
|
+
# commit in lane_runner_check.sh had just written a paragraph against; adversarial review
|
|
445
|
+
# caught the inconsistency between the two files.
|
|
446
|
+
10|2|126|127)
|
|
447
|
+
echo "HARNESS ERROR $_lbl: the suite exited $_rc — it could not measure, so its verdicts"
|
|
448
|
+
echo " prove nothing about $_subj. Not a lane failure, and not a pass either."
|
|
449
|
+
fail=1 ;;
|
|
450
|
+
*) fail=1 ;;
|
|
451
|
+
esac
|
|
452
|
+
elif _pkg_accepted_absent "$_anc"; then
|
|
453
|
+
# DECLARED legitimately unshipped — the single source for that answer, not a guess from the
|
|
454
|
+
# environment. The first draft printed "this package predates it", which is a WRONG DIAGNOSIS
|
|
455
|
+
# printed forever on every consumer machine: these anchors do not lag the package, they are
|
|
456
|
+
# deliberately not in it (their subjects do not ship either). A confident wrong reason in a
|
|
457
|
+
# verdict line is worse than no reason, because it is the line the next person greps.
|
|
458
|
+
echo "SKIP $_lbl (declared legitimately unshipped — package_coverage_check.sh ACCEPTED_ABSENT)"
|
|
459
|
+
else
|
|
460
|
+
# Not present, and NOT declared absent — so either it should be here (deletion / broken
|
|
461
|
+
# install) or the declaration is stale. Routed through the same three-valued helper as the
|
|
462
|
+
# subject arm above, and for the identical reason: `elif _ships_per_files "$_anc"` was a
|
|
463
|
+
# BOOLEAN test over a THREE-valued function, so its exit 2 (package.json unreadable = UNKNOWN)
|
|
464
|
+
# fell through to a green SKIP. That is the lenient branch the helper's own comment forbids
|
|
465
|
+
# ("THE UNKNOWN ARM IS NOT A SKIP"), rebuilt twelve times in one loop, thirty lines under the
|
|
466
|
+
# helper that exists to prevent it. Found by adversarial review; I had written both.
|
|
467
|
+
_absent_subject_verdict "$_lbl (anchor)" "$_anc" || fail=1
|
|
468
|
+
fi
|
|
469
|
+
done
|
|
470
|
+
|
|
471
|
+
# embedded --self-test suites (compaction_probe · judgment_circuit_lint · novelty_claim_check ·
|
|
472
|
+
# chamber_witness · digest_landing_check).
|
|
473
|
+
# These carry their lanes INSIDE the script (`--self-test`) rather than in a sibling
|
|
474
|
+
# test_*_lanes.sh, so the name-list wiring above skipped them silently: lanes existed and ran
|
|
232
475
|
# only when a human typed the command. That is built-but-not-wired applied to the anchors themselves
|
|
233
476
|
# — a later edit that breaks a lane stays green everywhere the project actually checks
|
|
234
477
|
# (high re-review 2026-08-08). Same shape as the block above: subject absent → SKIP, subject present
|
|
235
478
|
# but self-test missing → FAIL, never a silent pass.
|
|
236
|
-
|
|
479
|
+
# chamber_witness/digest_landing_check joined 2026-08-15 (DEBT closed — lane_runner_check.sh
|
|
480
|
+
# flagged 4 undeclared self-test subjects; capability_registry_check and relay_channel are the
|
|
481
|
+
# other two and do NOT join this loop, each for its own reason, see their own blocks below).
|
|
482
|
+
# capability_registry_check was tried here first and reverted: its passing-run output never
|
|
483
|
+
# contains 캘리브레이션 as a VERDICT — the only occurrence is inside a Korean *test-case title*
|
|
484
|
+
# ("M4: 캘리브레이션 쌍 미선언", capability_registry_check.sh's own self-test), so a future rename
|
|
485
|
+
# or trim of that one test name would flip a real PASS into "dispatcher missing?" here (cross-family
|
|
486
|
+
# review caught this, 2026-08-15). chamber_witness/digest_landing_check both print a genuine
|
|
487
|
+
# terminal "캘리브레이션 통과/실패" line, so they stay.
|
|
488
|
+
for _subj in compaction_probe judgment_circuit_lint novelty_claim_check chamber_witness digest_landing_check; do
|
|
237
489
|
if [ ! -f "scripts/$_subj.sh" ]; then
|
|
238
|
-
|
|
490
|
+
_absent_subject_verdict "$_subj --self-test" "scripts/$_subj.sh" || fail=1
|
|
239
491
|
else
|
|
240
492
|
# ⚠️ **문자열 존재로 판정하지 마라.** 초판은 `grep -q -- '--self-test'` 였는데, 그 문자열은
|
|
241
493
|
# 헤더 주석과 usage echo 에도 있어서 **디스패처 한 줄만 지워도 여전히 매치**한다. 그리고
|
|
@@ -249,8 +501,29 @@ for _subj in compaction_probe judgment_circuit_lint novelty_claim_check; do
|
|
|
249
501
|
# 난다(실측: homebrew 없는 PATH 에서 3개 subject 전부). 소비자 머신에서 `npm test` 와
|
|
250
502
|
# `prepublishOnly` 를 깨뜨리는 경로다. 정답 폼은 이미 레포에 있다(sync-from-be.sh:134).
|
|
251
503
|
# 없으면 무한대기 방지를 잃는 대신 도는 쪽을 택한다 — `< /dev/null` 이 그 방어의 본체다.
|
|
252
|
-
local
|
|
504
|
+
# `local` OUTSIDE A FUNCTION, which this loop is. bash prints
|
|
505
|
+
# "selfcheck.sh: line N: local: can only be used in a function"
|
|
506
|
+
# on stderr, the assignment never happens, and `_to` stays empty — so the timeout this line
|
|
507
|
+
# exists to install was NEVER INSTALLED. The guard has been decoration since it was written;
|
|
508
|
+
# the comment above it describing what it protects against was true and unimplemented. Measured
|
|
509
|
+
# 2026-08-13: the error printed three times (once per subject) in a full run, and had been
|
|
510
|
+
# printing in every run before that, unread, because stderr scrolls past a 240-second check.
|
|
511
|
+
# ★ A guard that announces its own failure every single run is still a silent failure if
|
|
512
|
+
# nothing reads the announcement. Fixed by deleting one word.
|
|
513
|
+
_to=""; command -v timeout >/dev/null 2>&1 && _to="timeout 120"
|
|
253
514
|
_st_out="$($_to bash "scripts/$_subj.sh" --self-test < /dev/null 2>&1)"; _st_rc=$?
|
|
515
|
+
# rc=10 (or the sibling harness-error codes) means the subject could not even set up its own
|
|
516
|
+
# known-pair fixture (e.g. mktemp failed) — it never got to run a lane, so it never printed
|
|
517
|
+
# 캘리브레이션 either way. Falling through to the *) arm below would report the confident but
|
|
518
|
+
# WRONG cause "dispatcher missing?" for an instrument that was never reached. chamber_witness.sh
|
|
519
|
+
# and digest_landing_check.sh both have real mktemp-failure → return 10 paths (cross-family
|
|
520
|
+
# review 2026-08-15); the two original loop members never did, so this arm is a no-op for them.
|
|
521
|
+
case "$_st_rc" in
|
|
522
|
+
10|2|126|127)
|
|
523
|
+
echo "HARNESS ERROR $_subj --self-test: the suite exited $_st_rc — it could not measure,"
|
|
524
|
+
echo " so its verdicts prove nothing about $_subj. Not a lane failure, not a pass either."
|
|
525
|
+
fail=1; continue ;;
|
|
526
|
+
esac
|
|
254
527
|
case "$_st_out" in
|
|
255
528
|
*캘리브레이션*) : ;;
|
|
256
529
|
*) echo "FAIL $_subj: --self-test produced no calibration verdict (dispatcher missing?)"
|
|
@@ -265,6 +538,50 @@ for _subj in compaction_probe judgment_circuit_lint novelty_claim_check; do
|
|
|
265
538
|
fi
|
|
266
539
|
done
|
|
267
540
|
|
|
541
|
+
# capability_registry_check — one of the 4 embedded --self-test subjects lane_runner_check.sh
|
|
542
|
+
# flagged (2026-08-15), kept out of the loop above (see that loop's comment) because its own
|
|
543
|
+
# terminal line is `통과 N · 실패 N`, never 캘리브레이션 — gate on exit code instead, same shape
|
|
544
|
+
# as utterance_landing_check.sh below. Ships via package.json files[], so absence is FAIL, not SKIP.
|
|
545
|
+
if [ ! -f scripts/capability_registry_check.sh ]; then
|
|
546
|
+
echo "FAIL capability_registry_check.sh: missing — it ships via package.json files[], so absence is deletion, not package mode"
|
|
547
|
+
fail=1
|
|
548
|
+
elif _out=$(bash scripts/capability_registry_check.sh --self-test < /dev/null 2>&1); then
|
|
549
|
+
echo "PASS capability_registry_check.sh --self-test ($(printf '%s\n' "$_out" | grep -oE '통과 [0-9]+ · 실패 [0-9]+' | tail -1))"
|
|
550
|
+
else
|
|
551
|
+
echo "FAIL capability_registry_check.sh: --self-test failed"
|
|
552
|
+
_show_failure "$_out"
|
|
553
|
+
fail=1
|
|
554
|
+
fi
|
|
555
|
+
|
|
556
|
+
# relay_channel — the other embedded --self-test subject kept out of the loop above: its
|
|
557
|
+
# `--self-test` just `exec`s the sibling scripts/test_relay_channel_lanes.sh, whose own exit code
|
|
558
|
+
# is already disciplined (`[ "$fail" -eq 0 ] || exit 1`), so gating on exit code — same shape as
|
|
559
|
+
# utterance_landing_check.sh below — is both sufficient and correct here; a 캘리브레이션 substring
|
|
560
|
+
# check would be the wrong instrument for this subject's actual completion marker
|
|
561
|
+
# ("N PASS / M FAIL"). Ships via package.json files[] (no ACCEPTED_ABSENT declaration), so absence
|
|
562
|
+
# is FAIL, not SKIP — same reasoning as utterance_landing_check.sh's absence branch below.
|
|
563
|
+
# Existence check covers BOTH files: relay_channel.sh --self-test just execs the sibling lanes
|
|
564
|
+
# file, so a missing sibling alone produces an unrelated-looking `exec: No such file` (rc=127) that
|
|
565
|
+
# the generic FAIL branch would misreport as "the lane broke" rather than "the anchor is gone"
|
|
566
|
+
# (cross-family review 2026-08-15).
|
|
567
|
+
# `_LANE_TO` (defined above, the pair-suite loop's own guard) is reused rather than a fresh
|
|
568
|
+
# timeout var — this is, by lane count, the largest suite dispatched anywhere in this file
|
|
569
|
+
# (test_relay_channel_lanes.sh runs 45+ lanes, each spawning relay_channel.sh, each spawning its
|
|
570
|
+
# own node subprocess), and it was the one dispatch here with NO time bound at all; `< /dev/null`
|
|
571
|
+
# only stops a stdin-wait hang, not a runaway child (cross-family review 2026-08-15 — this file's
|
|
572
|
+
# own comment two loops up already names exactly this failure shape: an unguarded call does not go
|
|
573
|
+
# red, it hangs, and CI dies on a job timeout with the cause unattributable).
|
|
574
|
+
if [ ! -f scripts/relay_channel.sh ] || [ ! -f scripts/test_relay_channel_lanes.sh ]; then
|
|
575
|
+
echo "FAIL relay_channel.sh: missing (relay_channel.sh or its sibling test_relay_channel_lanes.sh) — ships via package.json files[], so absence is deletion, not package mode"
|
|
576
|
+
fail=1
|
|
577
|
+
elif _out=$($_LANE_TO bash scripts/relay_channel.sh --self-test < /dev/null 2>&1); then
|
|
578
|
+
echo "PASS relay_channel.sh --self-test ($(printf '%s\n' "$_out" | grep -oE 'relay_channel lanes: [0-9]+ PASS / [0-9]+ FAIL' | tail -1))"
|
|
579
|
+
else
|
|
580
|
+
echo "FAIL relay_channel.sh: --self-test failed"
|
|
581
|
+
_show_failure "$_out"
|
|
582
|
+
fail=1
|
|
583
|
+
fi
|
|
584
|
+
|
|
268
585
|
# memory-link-check — the memory store is a GRAPH (memory_intent_recall.md: nodes=files,
|
|
269
586
|
# edges=[[links]], recall walks one hop). Measured 2026-07-28: 50 of 872 edges pointed at a note
|
|
270
587
|
# that existed under a different separator and 22 at nothing — a dead edge returns nothing and is
|
|
@@ -291,7 +608,7 @@ fi
|
|
|
291
608
|
# anchor was written into tests/ with ZERO callers first — the same defect this file already
|
|
292
609
|
# records twice above; wiring it here is the fix, not a note about the fix.
|
|
293
610
|
if [ ! -f scripts/consent_registry_check.sh ]; then
|
|
294
|
-
|
|
611
|
+
_absent_subject_verdict "test_consent_registry.sh" "scripts/consent_registry_check.sh" || fail=1
|
|
295
612
|
elif [ -f scripts/test_consent_registry.sh ]; then
|
|
296
613
|
if ! bash scripts/test_consent_registry.sh; then
|
|
297
614
|
fail=1
|
|
@@ -306,7 +623,7 @@ fi
|
|
|
306
623
|
# cross-family verification. The anchor's first version shipped in tests/ with ZERO callers — the
|
|
307
624
|
# same defect the comment above records for test_card_drift_probe.sh, repeated one file later.
|
|
308
625
|
if [ ! -f scripts/sidecar_wait.sh ]; then
|
|
309
|
-
|
|
626
|
+
_absent_subject_verdict "test_sidecar_wait_stdin.sh" "scripts/sidecar_wait.sh" || fail=1
|
|
310
627
|
elif [ -f scripts/test_sidecar_wait_stdin.sh ]; then
|
|
311
628
|
if ! bash scripts/test_sidecar_wait_stdin.sh; then
|
|
312
629
|
fail=1
|
|
@@ -325,7 +642,7 @@ fi
|
|
|
325
642
|
# states that look identical from outside ("the sidecar ran" vs "the model I pinned answered",
|
|
326
643
|
# "absent" vs "unmeasured"), and its lanes are hermetic stubs, so running them costs nothing.
|
|
327
644
|
if [ ! -f scripts/sidecar_calibrate.sh ]; then
|
|
328
|
-
|
|
645
|
+
_absent_subject_verdict "test_sidecar_calibrate_lanes.sh" "scripts/sidecar_calibrate.sh" || fail=1
|
|
329
646
|
elif [ -f scripts/test_sidecar_calibrate_lanes.sh ]; then
|
|
330
647
|
if ! bash scripts/test_sidecar_calibrate_lanes.sh; then
|
|
331
648
|
fail=1
|
|
@@ -422,7 +739,7 @@ _gps_missing=""
|
|
|
422
739
|
[ -f templates/.git-hooks/pre-commit ] || _gps_missing="templates/.git-hooks/pre-commit"
|
|
423
740
|
[ -f templates/regression_guard.sh ] || _gps_missing="${_gps_missing:+$_gps_missing, }templates/regression_guard.sh"
|
|
424
741
|
if [ -n "$_gps_missing" ]; then
|
|
425
|
-
|
|
742
|
+
_absent_subject_verdict "gate_pathspec_check.sh" "$_gps_missing" || fail=1
|
|
426
743
|
elif [ -f scripts/gate_pathspec_check.sh ]; then
|
|
427
744
|
if ! bash scripts/gate_pathspec_check.sh; then
|
|
428
745
|
fail=1
|
|
@@ -444,7 +761,7 @@ else
|
|
|
444
761
|
fi
|
|
445
762
|
|
|
446
763
|
if [ ! -f scripts/fh_node_check.sh ]; then
|
|
447
|
-
|
|
764
|
+
_absent_subject_verdict "test_node_check_lanes.sh" "scripts/fh_node_check.sh" || fail=1
|
|
448
765
|
elif [ -f scripts/test_node_check_lanes.sh ]; then
|
|
449
766
|
if ! bash scripts/test_node_check_lanes.sh; then
|
|
450
767
|
fail=1
|
|
@@ -457,7 +774,7 @@ fi
|
|
|
457
774
|
# The infra-delta half of the same subject. Separate suite, same pairing rule: it exists only because
|
|
458
775
|
# fh_node_check.sh does, so its absence beside a present subject is a FAIL, not a skip.
|
|
459
776
|
if [ ! -f scripts/fh_node_check.sh ]; then
|
|
460
|
-
|
|
777
|
+
_absent_subject_verdict "test_node_infra_delta_lanes.sh" "scripts/fh_node_check.sh" || fail=1
|
|
461
778
|
elif [ -f scripts/test_node_infra_delta_lanes.sh ]; then
|
|
462
779
|
if ! bash scripts/test_node_infra_delta_lanes.sh; then
|
|
463
780
|
fail=1
|
|
@@ -468,14 +785,43 @@ else
|
|
|
468
785
|
fi
|
|
469
786
|
|
|
470
787
|
# SessionStart multi-hook + install-wizard snippet merge. Subject for both = the shipped settings
|
|
471
|
-
# snippets; a clone without them is a legitimate SKIP, a clone with them and no anchor is not
|
|
788
|
+
# snippets; a clone without them is a legitimate SKIP, a clone with them and no anchor is not —
|
|
789
|
+
# UNLESS the anchor itself is declared package-mode-optional. test_sessionstart_multihook_lanes.sh
|
|
790
|
+
# is exactly that. Its ACCEPTED_ABSENT entry (package_coverage_check.sh) covers a DIFFERENT case than
|
|
791
|
+
# this loop implements: that entry's "selfcheck reports it NOT EXERCISED (exit 2)" describes the
|
|
792
|
+
# anchor RUNNING and finding no CLI (handled a few lines below, rc==2). It never claimed anything
|
|
793
|
+
# about the anchor FILE being missing — a real consumer never gets to run it at all (the file is not
|
|
794
|
+
# in files[]), and this loop had no branch for that at all, so every installed package hit
|
|
795
|
+
# "FAIL … anchor is missing" (corrected 2026-08-12, cross-family review — an earlier revision of this
|
|
796
|
+
# comment miscited the ACCEPTED_ABSENT entry as already covering the missing-file case). Fixed by
|
|
797
|
+
# consulting the SAME declaration (`_pkg_accepted_absent`, loaded once near the top of this file) that
|
|
798
|
+
# the ref-path block above uses — not an environment predicate — because `.git` presence answers "is
|
|
799
|
+
# there a git repo here", not "was this anchor declared intentionally unshipped", and the two diverge
|
|
800
|
+
# in a git-tracked vendored tree (a monorepo committing node_modules, `git init` after install): `.git`
|
|
801
|
+
# exists there too, which would silently reproduce the original FAIL.
|
|
802
|
+
# test_wizard_snippet_merge_lanes.sh is NOT in ACCEPTED_ABSENT (it does ship, per files[]) — routing
|
|
803
|
+
# both anchors through the same declaration lookup, rather than hardcoding one as always-FAIL, means a
|
|
804
|
+
# future person who genuinely needs to exempt it does so by editing ONE list, not by finding this loop.
|
|
472
805
|
for _pair in \
|
|
473
|
-
"templates/settings.SessionStart.snippet.json|scripts/test_sessionstart_multihook_lanes.sh" \
|
|
474
|
-
"templates/settings.SessionStart.snippet.json|scripts/test_wizard_snippet_merge_lanes.sh"
|
|
806
|
+
"templates/settings.SessionStart.snippet.json|scripts/test_sessionstart_multihook_lanes.sh|package-optional" \
|
|
807
|
+
"templates/settings.SessionStart.snippet.json|scripts/test_wizard_snippet_merge_lanes.sh|always-shipped"
|
|
475
808
|
do
|
|
476
|
-
_subj="${_pair%%|*}";
|
|
809
|
+
_subj="${_pair%%|*}"; _rest="${_pair#*|}"; _anc="${_rest%%|*}"; _mode="${_rest#*|}"
|
|
810
|
+
# This mode field is a gate-verdict policy value (does a missing anchor FAIL or SKIP), not free
|
|
811
|
+
# text — an unrecognized value must not silently fall through to whichever branch string-matching
|
|
812
|
+
# happens to miss. Cross-family review, 2026-08-12: the two known values were previously the only
|
|
813
|
+
# ones exercised, so a typo (e.g. "alway-shipped") landed in the `else` FAIL branch by accident of
|
|
814
|
+
# string mismatch rather than by a checked policy — fail-closed in practice, but undeclared.
|
|
815
|
+
case "$_mode" in
|
|
816
|
+
package-optional|always-shipped) ;;
|
|
817
|
+
*)
|
|
818
|
+
echo "FAIL ${_anc##*/}: unrecognized pair mode '$_mode' (expected package-optional or always-shipped)"
|
|
819
|
+
fail=1
|
|
820
|
+
continue
|
|
821
|
+
;;
|
|
822
|
+
esac
|
|
477
823
|
if [ ! -f "$_subj" ]; then
|
|
478
|
-
|
|
824
|
+
_absent_subject_verdict "${_anc##*/}" "$_subj" || fail=1
|
|
479
825
|
elif [ -f "$_anc" ]; then
|
|
480
826
|
# THREE-valued, like the session-close anchors above — and for a third reason they do not have.
|
|
481
827
|
# test_sessionstart_multihook_lanes.sh measures what the LIVE `claude` CLI does with several
|
|
@@ -494,6 +840,8 @@ do
|
|
|
494
840
|
elif [ "$_rc" -ne 0 ]; then
|
|
495
841
|
fail=1
|
|
496
842
|
fi
|
|
843
|
+
elif [ "$_mode" = "package-optional" ] && _pkg_accepted_absent "$_anc"; then
|
|
844
|
+
echo "SKIP ${_anc##*/} (declared ACCEPTED_ABSENT — CLI/cost-gated, see package_coverage_check.sh)"
|
|
497
845
|
else
|
|
498
846
|
echo "FAIL ${_anc##*/}: $_subj present but its anchor is missing"
|
|
499
847
|
fail=1
|
|
@@ -504,7 +852,7 @@ done
|
|
|
504
852
|
# 2026-07-31; the pipe-verdict lane shipped in PR #209 WITHOUT this wiring, which is itself the
|
|
505
853
|
# half-fix class the second guard exists to catch — found by running that guard on this repo.
|
|
506
854
|
if [ ! -f scripts/sidecar_calibrate.sh ]; then
|
|
507
|
-
|
|
855
|
+
_absent_subject_verdict "test_ollama_panel_lanes.sh" "scripts/sidecar_calibrate.sh" || fail=1
|
|
508
856
|
elif [ -f scripts/test_ollama_panel_lanes.sh ]; then
|
|
509
857
|
if ! bash scripts/test_ollama_panel_lanes.sh; then
|
|
510
858
|
fail=1
|
|
@@ -515,7 +863,7 @@ else
|
|
|
515
863
|
fi
|
|
516
864
|
|
|
517
865
|
if [ ! -f scripts/pipe_verdict_guard.sh ]; then
|
|
518
|
-
|
|
866
|
+
_absent_subject_verdict "test_pipe_verdict_guard_lanes.sh" "scripts/pipe_verdict_guard.sh" || fail=1
|
|
519
867
|
elif [ -f scripts/test_pipe_verdict_guard_lanes.sh ]; then
|
|
520
868
|
if ! bash scripts/test_pipe_verdict_guard_lanes.sh; then
|
|
521
869
|
fail=1
|
|
@@ -526,7 +874,7 @@ else
|
|
|
526
874
|
fi
|
|
527
875
|
|
|
528
876
|
if [ ! -f scripts/halffix_propagation_scan.sh ]; then
|
|
529
|
-
|
|
877
|
+
_absent_subject_verdict "test_halffix_lanes.sh" "scripts/halffix_propagation_scan.sh" || fail=1
|
|
530
878
|
elif [ -f scripts/test_halffix_lanes.sh ]; then
|
|
531
879
|
if ! bash scripts/test_halffix_lanes.sh; then
|
|
532
880
|
fail=1
|
|
@@ -550,7 +898,7 @@ fi
|
|
|
550
898
|
|
|
551
899
|
for _anchor in scripts/test_session_close_lanes.sh scripts/test_card_drift_probe.sh scripts/test_session_close_chain_lanes.sh; do
|
|
552
900
|
if [ ! -f scripts/session_close_check.sh ]; then
|
|
553
|
-
|
|
901
|
+
_absent_subject_verdict "${_anchor##*/}" "scripts/session_close_check.sh" || fail=1
|
|
554
902
|
elif [ -f "$_anchor" ]; then
|
|
555
903
|
# Preserve the anchor's two failure CLASSES instead of flattening them into one `fail=1`.
|
|
556
904
|
# An anchor exits 3 when a fixture's premise never obtained — "this run's verdicts prove
|
|
@@ -660,7 +1008,7 @@ fi
|
|
|
660
1008
|
# tag reached the remote and a publish from the wrong tree was stopped only by npm's own collision
|
|
661
1009
|
# check, so an unrun anchor here would be the same luck-as-floor arrangement one layer up.
|
|
662
1010
|
if [ ! -f templates/.git-hooks/pre-push ]; then
|
|
663
|
-
|
|
1011
|
+
_absent_subject_verdict "test_tag_version_lanes.sh" "templates/.git-hooks/pre-push" || fail=1
|
|
664
1012
|
elif [ -f scripts/test_tag_version_lanes.sh ]; then
|
|
665
1013
|
# RUN-ONCE, CAPTURE (2026-08-05) — rationale in the sync_from_be_lanes block later in this file.
|
|
666
1014
|
if _out=$(bash scripts/test_tag_version_lanes.sh 2>&1); then
|
|
@@ -680,7 +1028,7 @@ fi
|
|
|
680
1028
|
# per-plugin entries inside marketplace.json, which the tag lane never opens. Measured 2026-08-06:
|
|
681
1029
|
# a bump left the second marketplace entry behind and the tag lane passed 8/8 straight through it.
|
|
682
1030
|
if [ ! -f scripts/version_lockstep_check.sh ]; then
|
|
683
|
-
|
|
1031
|
+
_absent_subject_verdict "test_version_lockstep_lanes.sh" "scripts/version_lockstep_check.sh" || fail=1
|
|
684
1032
|
elif [ -f scripts/test_version_lockstep_lanes.sh ]; then
|
|
685
1033
|
if _out=$(bash scripts/test_version_lockstep_lanes.sh 2>&1); then
|
|
686
1034
|
echo "PASS test_version_lockstep_lanes.sh (drift blocks · aligned silent · unreadable = exit 2, not pass)"
|
|
@@ -721,6 +1069,23 @@ if [ -f scripts/test_selfcheck_state_lanes.sh ]; then
|
|
|
721
1069
|
fi
|
|
722
1070
|
fi
|
|
723
1071
|
|
|
1072
|
+
# test_lane_runner_lanes.sh — the checker that finds unrun suites had no suite of its own until
|
|
1073
|
+
# 2026-08-13. It guarded its own WIRING (it fails when selfcheck stops calling it) and nothing
|
|
1074
|
+
# measured its BEHAVIOUR — the shape it exists to catch, one level up. Wired in the same change
|
|
1075
|
+
# that ships it, for the reason the block above states: a suite landed unwired is the defect.
|
|
1076
|
+
if [ -f scripts/test_lane_runner_lanes.sh ]; then
|
|
1077
|
+
if _out=$(bash scripts/test_lane_runner_lanes.sh 2>&1); then
|
|
1078
|
+
echo "PASS test_lane_runner_lanes.sh (org seam: no-op · suppression · fail-closed · controls)"
|
|
1079
|
+
else
|
|
1080
|
+
echo "FAIL test_lane_runner_lanes.sh: the unrun-suite detector's own verdicts have drifted"
|
|
1081
|
+
_show_failure "$_out"
|
|
1082
|
+
fail=1
|
|
1083
|
+
fi
|
|
1084
|
+
elif _ships_per_files "scripts/test_lane_runner_lanes.sh"; then
|
|
1085
|
+
echo "FAIL test_lane_runner_lanes.sh is DECLARED SHIPPED but absent — deletion or broken install"
|
|
1086
|
+
fail=1
|
|
1087
|
+
fi
|
|
1088
|
+
|
|
724
1089
|
# sync_from_be_lanes.sh — the RETURN path's anchor. Wired in the same change that ships it: the
|
|
725
1090
|
# script had an operator-side caller (a SessionStart hook outside this repo) while its 70 lanes had
|
|
726
1091
|
# NO caller anywhere, which is the shape this repo keeps re-finding — a transport that writes into
|
|
@@ -764,9 +1129,51 @@ else
|
|
|
764
1129
|
fail=1
|
|
765
1130
|
fi
|
|
766
1131
|
|
|
1132
|
+
# sync_to_be_lanes.sh — the FORWARD path's anchor (added 2026-08-14, pmh-dev#69). Same shape as the
|
|
1133
|
+
# return-path block above and wired in the same change that ships it, for the same reason: a
|
|
1134
|
+
# transport with real reported defects (a real add/add conflict, a real hard-abort risk) had no
|
|
1135
|
+
# suite exercising it at all before this. Same subject-presence idiom, same run-once-capture
|
|
1136
|
+
# discipline (a lane suite discarded to /dev/null on a non-deterministic run already burned two days
|
|
1137
|
+
# on this exact file's sibling).
|
|
1138
|
+
if [ ! -f scripts/sync-to-be.sh ]; then
|
|
1139
|
+
echo "SKIP sync_to_be_lanes.sh (subject scripts/sync-to-be.sh absent)"
|
|
1140
|
+
elif [ -f scripts/sync_to_be_lanes.sh ]; then
|
|
1141
|
+
if _out=$(bash scripts/sync_to_be_lanes.sh 2>&1); then
|
|
1142
|
+
echo "PASS sync_to_be_lanes.sh (forward-path lanes)"
|
|
1143
|
+
else
|
|
1144
|
+
echo "FAIL sync_to_be_lanes.sh: forward-path lanes failed"
|
|
1145
|
+
_show_failure "$_out"
|
|
1146
|
+
fail=1
|
|
1147
|
+
fi
|
|
1148
|
+
else
|
|
1149
|
+
echo "FAIL sync_to_be_lanes.sh: sync-to-be.sh present but its anchor is missing"
|
|
1150
|
+
fail=1
|
|
1151
|
+
fi
|
|
1152
|
+
|
|
767
1153
|
# Referenced-path existence is a source-tree check. The npm package intentionally
|
|
768
1154
|
# ships a narrower runtime surface, so package-mode selfcheck skips this section.
|
|
769
|
-
|
|
1155
|
+
# ⚠️ The skip predicate used to be `[ -d ".claude/rules" ]`. That broke the moment the tarball
|
|
1156
|
+
# started shipping PART of that directory (`.claude/rules/fh_4axis_gate.md` etc. are in files[]) —
|
|
1157
|
+
# the directory then exists in BOTH source and package mode, so the check never skipped in package
|
|
1158
|
+
# mode at all. It ran, extracted refs from the shipped CLAUDE.md/.claude/rules/*.md (which still
|
|
1159
|
+
# name `.claude/regression/ablation_verdicts.md` and `scripts/probe_scope_check.sh` — both
|
|
1160
|
+
# deliberately unshipped, per package_coverage_check.sh's own ACCEPTED_ABSENT list), then tried
|
|
1161
|
+
# `git check-ignore` against a tree with no `.git` at all (a real `npm pack` tarball is not a git
|
|
1162
|
+
# repo) — that call errors rather than confirming "ignored", so the fallback `[ -f "$p" ]` ran and
|
|
1163
|
+
# correctly found nothing, and the check reported FAIL on two paths it had already been told, one
|
|
1164
|
+
# check over, were fine to omit. First fix (2026-08-12, reship axis, card §🔱⑮ G/D) swapped the skip
|
|
1165
|
+
# predicate for `[ -e .git ]`. Cross-family review then caught that `[ -e .git ]` answers a different
|
|
1166
|
+
# question than the one this check needs: a git-TRACKED vendor of this package (a monorepo that
|
|
1167
|
+
# commits node_modules, or a consumer who runs `git init` after installing) has `.git` and IS a
|
|
1168
|
+
# legitimate package consumer, yet the predicate would route it into the full extraction and
|
|
1169
|
+
# reproduce the exact original FAIL on these same two paths — the fix would have closed the bug only
|
|
1170
|
+
# in the one shape it was tested against. The general fix is not a better environment predicate; it
|
|
1171
|
+
# is not re-deriving "is this legitimately absent" from the environment at all when a DECLARED answer
|
|
1172
|
+
# already exists — `_pkg_accepted_absent()`, loaded once near the top of this file — this block now
|
|
1173
|
+
# consults it before FAILing, so the two paths render SKIP regardless of how `.git` happens to be
|
|
1174
|
+
# shaped in the consumer's tree. `[ -e .git ]` still gates whether the SCAN runs at all (an installed
|
|
1175
|
+
# package with no tracked-refs source to lint), which is a real and unrelated question.
|
|
1176
|
+
if [ -e ".git" ]; then
|
|
770
1177
|
# Backtick-quoted repo-relative file refs in the always-loaded governance surface
|
|
771
1178
|
# (CLAUDE.md + .claude/rules/*.md) must exist. Phantom-reference class recurred
|
|
772
1179
|
# N>=3 in the 2026-06-11 audit window — instrument-not-habit.
|
|
@@ -811,6 +1218,8 @@ REFPY
|
|
|
811
1218
|
echo "SKIP ref-path (gitignored): $p"
|
|
812
1219
|
elif [ -f "$p" ]; then
|
|
813
1220
|
echo "PASS ref-path: $p"
|
|
1221
|
+
elif _pkg_accepted_absent "$p"; then
|
|
1222
|
+
echo "SKIP ref-path (declared ACCEPTED_ABSENT — see package_coverage_check.sh): $p"
|
|
814
1223
|
else
|
|
815
1224
|
echo "FAIL ref-path: $p — referenced in CLAUDE.md/.claude/rules but missing"
|
|
816
1225
|
fail=1
|
|
@@ -820,7 +1229,7 @@ $_refs
|
|
|
820
1229
|
REFS
|
|
821
1230
|
fi
|
|
822
1231
|
else
|
|
823
|
-
echo "SKIP ref-path (package mode: .
|
|
1232
|
+
echo "SKIP ref-path (package mode: no .git at package root — source-tree-only check)"
|
|
824
1233
|
fi
|
|
825
1234
|
|
|
826
1235
|
if [ "$fail" -ne 0 ]; then
|