@chrono-meta/fh-gate 2.15.1 → 3.0.0
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 +38 -0
- package/.claude-plugin/marketplace.json +2 -2
- package/CLAUDE.md +1 -1
- package/README.md +6 -1
- package/knowledge/shared/harness-core/fh_three_layer_canon.md +47 -0
- package/knowledge/shared/harness-core/field_verdict_crossfamily_gate.md +10 -0
- package/knowledge/shared/harness-core/measurement-integrity-checklist.md +15 -1
- package/knowledge/shared/harness-core/ship_readiness_gate.md +19 -2
- package/knowledge/shared/learnings/subagent_invocations_log.yaml +49 -0
- package/package.json +9 -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/CHANGELOG.md +25 -0
- package/scripts/backtick_guard.sh +194 -0
- package/scripts/context_continuity_score.sh +49 -7
- package/scripts/fh-gate.sh +3 -3
- package/scripts/files_manifest_shipping_check.sh +19 -0
- package/scripts/gate_pathspec_check.sh +1 -1
- package/scripts/package_coverage_check.sh +24 -2
- package/scripts/proposal_hook.sh +89 -0
- package/scripts/public_surface_scan_files.sh +11 -2
- package/scripts/revert_probe.sh +250 -0
- package/scripts/selfcheck.sh +65 -2
- package/scripts/sim_isolated_run.sh +97 -7
- package/scripts/test_backtick_guard_lanes.sh +115 -0
- package/scripts/test_degrade_scan_shell_probes.sh +7 -7
- package/scripts/test_files_manifest_shipping_lanes.sh +5 -5
- package/scripts/test_heavy_classifier_lanes.sh +1 -1
- package/scripts/test_lane_runner_lanes.sh +59 -33
- package/scripts/test_mapped_tracks_lanes.sh +1 -1
- package/scripts/test_marker_soul_check_lanes.sh +24 -0
- package/scripts/test_node_check_lanes.sh +34 -34
- package/scripts/test_package_coverage_lanes.sh +53 -27
- package/scripts/test_pipe_verdict_guard_lanes.sh +5 -5
- package/scripts/test_precommit_pointer_index_lanes.sh +33 -0
- package/scripts/test_preprep_drift_anchor.sh +13 -4
- package/scripts/test_preprep_drift_anchor_lanes.sh +23 -0
- package/scripts/test_proposal_hook_lanes.sh +36 -0
- package/scripts/test_revert_probe_lanes.sh +146 -0
- package/scripts/test_session_close_lanes.sh +3 -5
- package/scripts/test_sim_isolated_run_lanes.sh +17 -0
- package/scripts/utterance_landing_check.sh +2 -2
- package/templates/.git-hooks/pre-commit +27 -4
- package/templates/settings.PreToolUse.snippet.json +37 -1
- package/plugins/fh-commons/README.md +0 -38
|
@@ -81,7 +81,7 @@ EOF
|
|
|
81
81
|
cat > "$TMP/non_detections.sh" <<'EOF'
|
|
82
82
|
#!/usr/bin/env bash
|
|
83
83
|
# (a) integer sanitization — the PRESCRIBED remedy for the pipefail-fallback class, not the defect.
|
|
84
|
-
count=$(grep -c pattern file)
|
|
84
|
+
count=$(grep -c pattern file) # portability-noqa: fixture text written by a quoted heredoc, never executed — statically grepped by degrade_direction_scan.sh only
|
|
85
85
|
if [ "${count:-0}" -gt 0 ]; then echo "found"; fi
|
|
86
86
|
# (b) SCOPE guards — "this run does not apply here" is not a claim that a check passed.
|
|
87
87
|
[ -d "$HOME/projects" ] || exit 0
|
|
@@ -165,11 +165,11 @@ N=$(find /nope . -maxdepth 1 2>/dev/null | grep -c . || echo 0)
|
|
|
165
165
|
M=$(git log --oneline 2>/dev/null | wc -l || echo 0)
|
|
166
166
|
# WIDENED 2026-08-04. Every line below was INVISIBLE to the narrowed rule, and each was verified to
|
|
167
167
|
# actually produce "0\n0" before being pinned here (line count measured, not assumed):
|
|
168
|
-
P=$(cat /etc/hosts | grep -c . | tr -d ' ' || echo 0) # transparent filter after the counter
|
|
169
|
-
Q=$(grep -c "^nosuchline$" /etc/hosts 2>/dev/null | tr -d ' ' || echo 0) # the PR #251 shape
|
|
170
|
-
R=$(grep -Ec "^nosuchline$" /etc/hosts || echo 0) # combined flag cluster -Ec
|
|
171
|
-
S=$(grep --count "^nosuchline$" /etc/hosts || echo 0) # long option
|
|
172
|
-
T=$(grep -Fcx "nosuchline" /etc/hosts || echo 0) # -Fcx
|
|
168
|
+
P=$(cat /etc/hosts | grep -c . | tr -d ' ' || echo 0) # transparent filter after the counter # portability-noqa: fixture text, never executed
|
|
169
|
+
Q=$(grep -c "^nosuchline$" /etc/hosts 2>/dev/null | tr -d ' ' || echo 0) # the PR #251 shape # portability-noqa: fixture text, never executed
|
|
170
|
+
R=$(grep -Ec "^nosuchline$" /etc/hosts || echo 0) # combined flag cluster -Ec # portability-noqa: fixture text, never executed
|
|
171
|
+
S=$(grep --count "^nosuchline$" /etc/hosts || echo 0) # long option # portability-noqa: fixture text, never executed
|
|
172
|
+
T=$(grep -Fcx "nosuchline" /etc/hosts || echo 0) # -Fcx # portability-noqa: fixture text, never executed
|
|
173
173
|
U=$(false | grep -c . | cat || echo 0) # trailing stage that always emits
|
|
174
174
|
V=$(false | grep -c . | grep -v nosuch || echo 0) # trailing grep whose pattern misses the "0"
|
|
175
175
|
EOF
|
|
@@ -688,7 +688,7 @@ fi
|
|
|
688
688
|
# flips to a hit — proves the exclusion is load-bearing for this specific fixture, not just
|
|
689
689
|
# present somewhere in the file.
|
|
690
690
|
_scan_reverted="$TMP/scan_reverted.sh"
|
|
691
|
-
_excl_line=$(grep -n "grep -vE 'in \[A-Z_\]" "$SCAN" | head -1 | cut -d: -f1)
|
|
691
|
+
_excl_line=$(grep -n "grep -vE 'in \[A-Z_\]" "$SCAN" | head -1 | cut -d: -f1) # portability-noqa: this file has no `set -e` (top line 22 is `set -uo pipefail` only) and the next line already guards empty via -z
|
|
692
692
|
if [ -z "$_excl_line" ]; then
|
|
693
693
|
bad "C2-REVERT could not locate the exclusion line by its known text — fixture cannot run"
|
|
694
694
|
else
|
|
@@ -46,9 +46,9 @@ trap 'rm -rf "$LANE2_DIR"' EXIT
|
|
|
46
46
|
cp package.json "$LANE2_DIR/package.json.orig"
|
|
47
47
|
node -e '
|
|
48
48
|
const fs = require("fs");
|
|
49
|
-
const pkg = JSON.parse(fs.readFileSync("package.json", "utf8"));
|
|
49
|
+
const pkg = JSON.parse(fs.readFileSync("package.json", "utf8")); // # portability-noqa: cwd is REPO_ROOT (line 18) -- this is the subject under tests own manifest, not a foreign fixture
|
|
50
50
|
pkg.files.push("scripts/__test_fixture_does_not_exist__.sh");
|
|
51
|
-
fs.writeFileSync("package.json", JSON.stringify(pkg, null, 2) + "\n");
|
|
51
|
+
fs.writeFileSync("package.json", JSON.stringify(pkg, null, 2) + "\n"); // # portability-noqa: same as above -- writes back to the same repo-relative manifest it read
|
|
52
52
|
'
|
|
53
53
|
restore_pkg() { cp "$LANE2_DIR/package.json.orig" package.json; }
|
|
54
54
|
|
|
@@ -132,7 +132,7 @@ D6="$(fixture_dir)"
|
|
|
132
132
|
mkdir -p "$D6/.git"
|
|
133
133
|
node -e '
|
|
134
134
|
const fs = require("fs");
|
|
135
|
-
const pkg = JSON.parse(fs.readFileSync("package.json", "utf8"));
|
|
135
|
+
const pkg = JSON.parse(fs.readFileSync("package.json", "utf8")); // # portability-noqa: cwd is REPO_ROOT -- seeds the fixture from the subject own real manifest, then mutates a copy
|
|
136
136
|
pkg.files = ".";
|
|
137
137
|
fs.writeFileSync(process.argv[1], JSON.stringify(pkg, null, 2) + "\n");
|
|
138
138
|
' "$D6/package.json"
|
|
@@ -152,7 +152,7 @@ D7="$(fixture_dir)"
|
|
|
152
152
|
mkdir -p "$D7/.git"
|
|
153
153
|
node -e '
|
|
154
154
|
const fs = require("fs");
|
|
155
|
-
const pkg = JSON.parse(fs.readFileSync("package.json", "utf8"));
|
|
155
|
+
const pkg = JSON.parse(fs.readFileSync("package.json", "utf8")); // # portability-noqa: cwd is REPO_ROOT -- seeds the fixture from the subject own real manifest, then mutates a copy
|
|
156
156
|
pkg.files.push("missing\nPASS\\t999 entries checked, 0 phantom, 0 unpacked");
|
|
157
157
|
fs.writeFileSync(process.argv[1], JSON.stringify(pkg, null, 2) + "\n");
|
|
158
158
|
' "$D7/package.json"
|
|
@@ -175,7 +175,7 @@ mkdir -p "$D8/.git" "$D8/scripts_dummy"
|
|
|
175
175
|
echo x > "$D8/scripts_dummy/foo.sh"
|
|
176
176
|
node -e '
|
|
177
177
|
const fs = require("fs");
|
|
178
|
-
const pkg = JSON.parse(fs.readFileSync("package.json", "utf8"));
|
|
178
|
+
const pkg = JSON.parse(fs.readFileSync("package.json", "utf8")); // # portability-noqa: cwd is REPO_ROOT -- seeds the fixture from the subject own real manifest, then mutates a copy
|
|
179
179
|
pkg.files = ["scripts_dummy"];
|
|
180
180
|
delete pkg.scripts.prepare;
|
|
181
181
|
delete pkg.scripts.prepublishOnly;
|
|
@@ -103,7 +103,7 @@ check carveout "README.md" "npm-shipped surface — first-scre
|
|
|
103
103
|
check carveout "README.ko.md" "language variants route the same way"
|
|
104
104
|
check carveout "README.zh-CN.md" "🟥 5-char locale forms too — cross-family caught [a-z]{2} missing these"
|
|
105
105
|
check uncovered ".claude/registry/README.md" "🟥 STILL UNCOVERED — in files[] but not root; named, not closed"
|
|
106
|
-
check uncovered "package.json" "files[] / version changes are unclassified"
|
|
106
|
+
check uncovered "package.json" "files[] / version changes are unclassified" # portability-noqa: "package.json" is a string literal fed to classify()'s regex test, never opened from disk — a ported repo without this exact file still exercises the same classifier logic
|
|
107
107
|
check uncovered ".github/workflows/validate.yml" "🟥 CI definition — changing what CI runs is unclassified"
|
|
108
108
|
check uncovered "scripts/memory_link_check.py" "🟥 .py is not .sh — shipped python is unclassified"
|
|
109
109
|
|
|
@@ -30,18 +30,32 @@ mkfixture() { # $1 = dir
|
|
|
30
30
|
printf '#!/usr/bin/env bash\nbash scripts/lane_runner_check.sh\n' > "$d/scripts/selfcheck.sh"
|
|
31
31
|
printf '#!/usr/bin/env bash\n: orphan lane suite\n' > "$d/scripts/test_orphan_lanes.sh"
|
|
32
32
|
}
|
|
33
|
-
|
|
34
|
-
|
|
33
|
+
# ONE execution per fixture, stdout AND rc from the SAME run — never two separate invocations.
|
|
34
|
+
# Until 2026-09-03 this was split into run()+rcof(), each running lane_runner_check.sh on its own.
|
|
35
|
+
# lane_runner_check.sh reads live filesystem/git state on every invocation (its own mktemp, a
|
|
36
|
+
# `.git` up-chain walk, `git ls-files -z`, a python3 subprocess) and is not guaranteed to answer
|
|
37
|
+
# identically twice in a row under CI resource pressure — so a call site combining `$(run "$D")`
|
|
38
|
+
# with a SEPARATE `$(rcof "$D")` could silently pair stdout from one run with the exit code of a
|
|
39
|
+
# DIFFERENT run. That produced an impossible-looking CI flake: rc=0 with the literal substring
|
|
40
|
+
# "declared debt" absent from $out, even though every rc=0 exit path in lane_runner_check.sh
|
|
41
|
+
# unconditionally prints that substring (traced exhaustively — see
|
|
42
|
+
# tracks/_meta/armC_armC-wt2_report2_2026-09-03.md). Sets LRC_OUT/LRC_RC as globals: this file is
|
|
43
|
+
# flat top-level (no `local` scoping across call sites), and bash functions cannot return two
|
|
44
|
+
# values through their exit status alone.
|
|
45
|
+
run_check() { # $1 = fixture dir
|
|
46
|
+
LRC_OUT="$(cd "$1" && bash scripts/lane_runner_check.sh 2>&1)"; LRC_RC=$?
|
|
47
|
+
}
|
|
35
48
|
|
|
36
49
|
# ── L1 known-POSITIVE: an undeclared orphan suite must FAIL ───────────────────────────────────
|
|
37
50
|
# Without this arm every lane below proves nothing: a checker that passed unconditionally would
|
|
38
51
|
# satisfy all the "declaration suppresses it" lanes.
|
|
39
52
|
D="$T/l1"; mkfixture "$D"
|
|
40
|
-
|
|
53
|
+
run_check "$D"; out="$LRC_OUT"; rc="$LRC_RC"
|
|
41
54
|
if [ "$rc" = "1" ] && printf '%s' "$out" | grep -q 'test_orphan_lanes.sh'; then
|
|
42
55
|
ok "L1 known-positive: undeclared orphan suite → rc=1 and it is named"
|
|
43
56
|
else
|
|
44
57
|
bad "L1 known-positive did not fire (rc=$rc) — every lane below is meaningless without it"
|
|
58
|
+
printf '%s\n' "$out" | sed 's/^/ │ /'
|
|
45
59
|
fi
|
|
46
60
|
|
|
47
61
|
# ── IDX7 the FAIL path must EXECUTE the provenance note, not merely contain a call to it ──────
|
|
@@ -55,7 +69,7 @@ fi
|
|
|
55
69
|
# It asserts the SHAPE of provenance, not the exact sentence: the fixture is a non-git dir, so the
|
|
56
70
|
# honest answer there is the DISK one, and pinning the index wording would make the lane wrong.
|
|
57
71
|
D="$T/idx7"; mkfixture "$D"
|
|
58
|
-
|
|
72
|
+
run_check "$D"; out="$LRC_OUT"
|
|
59
73
|
if printf '%s' "$out" | grep -qE 'unbound variable|command not found|syntax error'; then
|
|
60
74
|
bad "IDX7 the FAIL path errored: $(printf '%s' "$out" | grep -E 'unbound|not found|syntax' | head -1)"
|
|
61
75
|
elif printf '%s' "$out" | grep -qE 'ⓘ|🟥'; then
|
|
@@ -67,41 +81,45 @@ fi
|
|
|
67
81
|
# ── L2 NO-OP: no declaration file → behaviour is exactly the L1 behaviour ─────────────────────
|
|
68
82
|
# This is the arm that protects THIS repo, which ships no company/ directory.
|
|
69
83
|
D="$T/l2"; mkfixture "$D"
|
|
70
|
-
|
|
84
|
+
run_check "$D"; out="$LRC_OUT"
|
|
71
85
|
if ! printf '%s' "$out" | grep -q 'lane_declarations'; then
|
|
72
86
|
ok "L2 no-op: absent declaration file is silent (no mention in output)"
|
|
73
87
|
else
|
|
74
88
|
bad "L2 no-op: output mentions the declaration file when none exists"
|
|
89
|
+
printf '%s\n' "$out" | sed 's/^/ │ /'
|
|
75
90
|
fi
|
|
76
91
|
|
|
77
92
|
# ── L3 org EXEMPT suppresses the orphan ───────────────────────────────────────────────────────
|
|
78
93
|
D="$T/l3"; mkfixture "$D"; mkdir -p "$D/company"
|
|
79
94
|
printf 'exempt:\n - test_orphan_lanes.sh # org-owned, runs in the org CI only\n' > "$D/company/lane_declarations.yaml"
|
|
80
|
-
|
|
95
|
+
run_check "$D"; out="$LRC_OUT"; rc="$LRC_RC"
|
|
81
96
|
if [ "$rc" = "0" ] && printf '%s' "$out" | grep -q '1 exempt'; then
|
|
82
97
|
ok "L3 org exempt: declared suite no longer fails the check (rc=0, counted exempt)"
|
|
83
98
|
else
|
|
84
|
-
bad "L3 org exempt did not suppress (rc=$rc)
|
|
99
|
+
bad "L3 org exempt did not suppress (rc=$rc)"
|
|
100
|
+
printf '%s\n' "$out" | sed 's/^/ │ /'
|
|
85
101
|
fi
|
|
86
102
|
|
|
87
103
|
# ── L4 org DEBT suppresses AND is counted as debt ─────────────────────────────────────────────
|
|
88
104
|
D="$T/l4"; mkfixture "$D"; mkdir -p "$D/company"
|
|
89
105
|
printf 'debt:\n - test_orphan_lanes.sh\n' > "$D/company/lane_declarations.yaml"
|
|
90
|
-
|
|
106
|
+
run_check "$D"; out="$LRC_OUT"; rc="$LRC_RC"
|
|
91
107
|
if [ "$rc" = "0" ] && printf '%s' "$out" | grep -q 'declared debt'; then
|
|
92
108
|
ok "L4 org debt: declared suite suppressed and reported as debt"
|
|
93
109
|
else
|
|
94
110
|
bad "L4 org debt did not land (rc=$rc)"
|
|
111
|
+
printf '%s\n' "$out" | sed 's/^/ │ /'
|
|
95
112
|
fi
|
|
96
113
|
|
|
97
114
|
# ── L5 VISIBILITY: an org-declared list must never look like this repo's own zero ─────────────
|
|
98
115
|
D="$T/l5"; mkfixture "$D"; mkdir -p "$D/company"
|
|
99
116
|
printf 'debt:\n - test_orphan_lanes.sh\n' > "$D/company/lane_declarations.yaml"
|
|
100
|
-
|
|
117
|
+
run_check "$D"; out="$LRC_OUT"
|
|
101
118
|
if printf '%s' "$out" | grep -q 'org-declared'; then
|
|
102
119
|
ok "L5 visibility: output names the org file and its counts"
|
|
103
120
|
else
|
|
104
121
|
bad "L5 visibility: org declarations are invisible in the output"
|
|
122
|
+
printf '%s\n' "$out" | sed 's/^/ │ /'
|
|
105
123
|
fi
|
|
106
124
|
|
|
107
125
|
# ── L6 FAIL-CLOSED on an unparseable file ─────────────────────────────────────────────────────
|
|
@@ -109,41 +127,46 @@ fi
|
|
|
109
127
|
# render UNMEASURED as ZERO, and it would do so on the arm where a fork is relying on the file.
|
|
110
128
|
D="$T/l6"; mkfixture "$D"; mkdir -p "$D/company"
|
|
111
129
|
printf 'exempt:\n this line is not an entry\n' > "$D/company/lane_declarations.yaml"
|
|
112
|
-
|
|
130
|
+
run_check "$D"; out="$LRC_OUT"; rc="$LRC_RC"
|
|
113
131
|
if [ "$rc" = "2" ] && printf '%s' "$out" | grep -q 'UNMEASURED'; then
|
|
114
132
|
ok "L6 fail-closed: unparseable declaration file → rc=2 and says UNMEASURED"
|
|
115
133
|
else
|
|
116
134
|
bad "L6 fail-closed FAILED (rc=$rc) — a malformed file was read as 'no declarations'"
|
|
135
|
+
printf '%s\n' "$out" | sed 's/^/ │ /'
|
|
117
136
|
fi
|
|
118
137
|
|
|
119
138
|
# ── L6b control for L6: the SAME orphan tree with a WELL-FORMED file must not exit 2 ──────────
|
|
120
139
|
# Without this, L6 would also pass on a checker that exits 2 for any declaration file at all.
|
|
121
140
|
D="$T/l6b"; mkfixture "$D"; mkdir -p "$D/company"
|
|
122
141
|
printf 'exempt:\n - test_orphan_lanes.sh\n' > "$D/company/lane_declarations.yaml"
|
|
123
|
-
|
|
142
|
+
run_check "$D"; out="$LRC_OUT"; rc="$LRC_RC"
|
|
143
|
+
if [ "$rc" != "2" ]; then
|
|
124
144
|
ok "L6b control: a well-formed file does NOT trip the fail-closed arm"
|
|
125
145
|
else
|
|
126
146
|
bad "L6b control: every declaration file exits 2 — L6 proved nothing"
|
|
147
|
+
printf '%s\n' "$out" | sed 's/^/ │ /'
|
|
127
148
|
fi
|
|
128
149
|
|
|
129
150
|
# ── L7 unknown section is a parse failure, not a silent skip ──────────────────────────────────
|
|
130
151
|
D="$T/l7"; mkfixture "$D"; mkdir -p "$D/company"
|
|
131
152
|
printf 'allowed:\n - test_orphan_lanes.sh\n' > "$D/company/lane_declarations.yaml"
|
|
132
|
-
|
|
133
|
-
if [ "$
|
|
153
|
+
run_check "$D"; out="$LRC_OUT"; rc="$LRC_RC"
|
|
154
|
+
if [ "$rc" = "2" ] && printf '%s' "$out" | grep -q "unknown section"; then
|
|
134
155
|
ok "L7 unknown section → rc=2 and names the section"
|
|
135
156
|
else
|
|
136
|
-
bad "L7 unknown section was tolerated — a typo'd header would silently declare nothing"
|
|
157
|
+
bad "L7 unknown section was tolerated — a typo'd header would silently declare nothing (rc=$rc)"
|
|
158
|
+
printf '%s\n' "$out" | sed 's/^/ │ /'
|
|
137
159
|
fi
|
|
138
160
|
|
|
139
161
|
# ── L8 the same name in both sections is ambiguous, not last-wins ─────────────────────────────
|
|
140
162
|
D="$T/l8"; mkfixture "$D"; mkdir -p "$D/company"
|
|
141
163
|
printf 'exempt:\n - test_orphan_lanes.sh\ndebt:\n - test_orphan_lanes.sh\n' > "$D/company/lane_declarations.yaml"
|
|
142
|
-
|
|
143
|
-
if [ "$
|
|
164
|
+
run_check "$D"; out="$LRC_OUT"; rc="$LRC_RC"
|
|
165
|
+
if [ "$rc" = "2" ] && printf '%s' "$out" | grep -q "both exempt and debt"; then
|
|
144
166
|
ok "L8 same suite in both sections → rc=2 (ambiguous, not silently resolved)"
|
|
145
167
|
else
|
|
146
|
-
bad "L8 double declaration was silently resolved"
|
|
168
|
+
bad "L8 double declaration was silently resolved (rc=$rc)"
|
|
169
|
+
printf '%s\n' "$out" | sed 's/^/ │ /'
|
|
147
170
|
fi
|
|
148
171
|
|
|
149
172
|
# ── L9 a stale entry WARNS but does not block (same voice as upstream DEBT hygiene) ───────────
|
|
@@ -151,20 +174,23 @@ fi
|
|
|
151
174
|
# would train forks to delete the file, which costs more than a stale line.
|
|
152
175
|
D="$T/l9"; mkfixture "$D"; mkdir -p "$D/company"
|
|
153
176
|
printf 'exempt:\n - test_orphan_lanes.sh\n - test_deleted_lanes.sh\n' > "$D/company/lane_declarations.yaml"
|
|
154
|
-
|
|
177
|
+
run_check "$D"; out="$LRC_OUT"; rc="$LRC_RC"
|
|
155
178
|
if [ "$rc" = "0" ] && printf '%s' "$out" | grep -q 'test_deleted_lanes.sh'; then
|
|
156
179
|
ok "L9 stale entry: warns and names it, does not block (rc=0)"
|
|
157
180
|
else
|
|
158
181
|
bad "L9 stale entry handling wrong (rc=$rc)"
|
|
182
|
+
printf '%s\n' "$out" | sed 's/^/ │ /'
|
|
159
183
|
fi
|
|
160
184
|
|
|
161
185
|
# ── L10 comments and blank lines are not entries ──────────────────────────────────────────────
|
|
162
186
|
D="$T/l10"; mkfixture "$D"; mkdir -p "$D/company"
|
|
163
187
|
printf '# org lane declarations\n\nexempt:\n\n - test_orphan_lanes.sh # reason lives here\n' > "$D/company/lane_declarations.yaml"
|
|
164
|
-
|
|
188
|
+
run_check "$D"; out="$LRC_OUT"; rc="$LRC_RC"
|
|
189
|
+
if [ "$rc" = "0" ]; then
|
|
165
190
|
ok "L10 comments/blank lines tolerated (a file people can annotate)"
|
|
166
191
|
else
|
|
167
|
-
bad "L10 a commented, spaced file failed to parse"
|
|
192
|
+
bad "L10 a commented, spaced file failed to parse (rc=$rc)"
|
|
193
|
+
printf '%s\n' "$out" | sed 's/^/ │ /'
|
|
168
194
|
fi
|
|
169
195
|
|
|
170
196
|
# ── L11/L12 embedded --self-test subjects (found→extend, 2026-08-14) ──────────────────────────
|
|
@@ -186,7 +212,7 @@ mkfixture_clean() { # $1 = dir
|
|
|
186
212
|
# L11 known-POSITIVE: an unwired --self-test subject is reported, advisory (rc stays 0).
|
|
187
213
|
D="$T/l11"; mkfixture_clean "$D"
|
|
188
214
|
printf '#!/usr/bin/env bash\n[ "${1:-}" = "--self-test" ] && { echo ok; exit 0; }\n' > "$D/scripts/orphan_probe.sh"
|
|
189
|
-
|
|
215
|
+
run_check "$D"; out="$LRC_OUT"; rc="$LRC_RC"
|
|
190
216
|
if [ "$rc" = "0" ] && printf '%s' "$out" | grep -q 'orphan_probe'; then
|
|
191
217
|
ok "L11 known-positive: unwired --self-test subject named, advisory (rc=0)"
|
|
192
218
|
else
|
|
@@ -206,7 +232,7 @@ for _subj in orphan_probe; do
|
|
|
206
232
|
bash "scripts/$_subj.sh" --self-test
|
|
207
233
|
done
|
|
208
234
|
SC
|
|
209
|
-
|
|
235
|
+
run_check "$D"; out="$LRC_OUT"
|
|
210
236
|
if ! printf '%s' "$out" | grep -q 'orphan_probe'; then
|
|
211
237
|
ok "L12 known-negative: --self-test subject wired via _subj for-loop is not reported"
|
|
212
238
|
else
|
|
@@ -228,7 +254,7 @@ bash scripts/lane_runner_check.sh
|
|
|
228
254
|
bash scripts/test_ok_lanes.sh
|
|
229
255
|
bash scripts/orphan_probe.sh --self-test >/dev/null 2>&1
|
|
230
256
|
SC
|
|
231
|
-
|
|
257
|
+
run_check "$D"; out="$LRC_OUT"
|
|
232
258
|
if ! printf '%s' "$out" | grep -q 'orphan_probe'; then
|
|
233
259
|
ok "L13 known-negative: --self-test subject wired via direct dispatch is not reported"
|
|
234
260
|
else
|
|
@@ -262,7 +288,7 @@ cat > "$D/scripts/orphan_probe.sh" <<'SUBJ'
|
|
|
262
288
|
# bash scripts/orphan_probe.sh --self-test # known-pair calibration
|
|
263
289
|
[ "${1:-}" = "--self-test" ] && { echo ok; exit 0; }
|
|
264
290
|
SUBJ
|
|
265
|
-
|
|
291
|
+
run_check "$D"; out="$LRC_OUT"; rc="$LRC_RC"
|
|
266
292
|
if [ "$rc" = "0" ] && printf '%s' "$out" | grep -q 'orphan_probe'; then
|
|
267
293
|
ok "L14 known-positive: subject's own usage comment is not a caller — still reported unwired"
|
|
268
294
|
else
|
|
@@ -280,7 +306,7 @@ bash scripts/lane_runner_check.sh
|
|
|
280
306
|
bash scripts/test_ok_lanes.sh
|
|
281
307
|
# historical note: we used to run `bash scripts/orphan_probe.sh --self-test` here, removed 2026-01-01
|
|
282
308
|
SC
|
|
283
|
-
|
|
309
|
+
run_check "$D"; out="$LRC_OUT"; rc="$LRC_RC"
|
|
284
310
|
if [ "$rc" = "0" ] && printf '%s' "$out" | grep -q 'orphan_probe'; then
|
|
285
311
|
ok "L15 known-positive: a commented-out dispatch in another file is not a caller"
|
|
286
312
|
else
|
|
@@ -302,7 +328,7 @@ usage() { echo "run: bash scripts/orphan_probe.sh --self-test"; }
|
|
|
302
328
|
[ "${1:-}" = "--self-test" ] && { echo ok; exit 0; }
|
|
303
329
|
usage
|
|
304
330
|
SUBJ
|
|
305
|
-
|
|
331
|
+
run_check "$D"; out="$LRC_OUT"; rc="$LRC_RC"
|
|
306
332
|
if [ "$rc" = "0" ] && printf '%s' "$out" | grep -q 'orphan_probe'; then
|
|
307
333
|
ok "L16 known-positive: a subject's own NON-comment self-reference is not a caller"
|
|
308
334
|
else
|
|
@@ -323,36 +349,36 @@ fi
|
|
|
323
349
|
# ([[feedback_not_found_is_not_zero_family]]).
|
|
324
350
|
_ISN=$(mktemp); sed -n '/^index_source_note()/,/^}/p' "$CHECK" > "$_ISN"
|
|
325
351
|
if ! grep -q 'UNMEASURED' "$_ISN"; then
|
|
326
|
-
|
|
352
|
+
bad "IDX-harness — index_source_note did not extract from $CHECK (lanes would measure nothing)"
|
|
327
353
|
else
|
|
328
354
|
# shellcheck disable=SC1090
|
|
329
355
|
. "$_ISN"
|
|
330
356
|
o=$(index_source_note "index")
|
|
331
357
|
printf '%s' "$o" | grep -q "INDEX 기준" && printf '%s' "$o" | grep -q "스테이징" \
|
|
332
358
|
&& ok "IDX1 index mode names the index AND the staging remedy" \
|
|
333
|
-
||
|
|
359
|
+
|| bad "IDX1 index mode note missing/incomplete: $o"
|
|
334
360
|
|
|
335
361
|
o=$(index_source_note "nongit")
|
|
336
362
|
printf '%s' "$o" | grep -q "DISK" && ok "IDX2 nongit mode says DISK, not index" \
|
|
337
|
-
||
|
|
363
|
+
|| bad "IDX2 nongit: $o"
|
|
338
364
|
|
|
339
365
|
o=$(index_source_note "UNMEASURED")
|
|
340
366
|
printf '%s' "$o" | grep -q "못 셌다" && ok "IDX3 UNMEASURED says «could not count», not «none»" \
|
|
341
|
-
||
|
|
367
|
+
|| bad "IDX3 UNMEASURED: $o"
|
|
342
368
|
|
|
343
369
|
# 🟥 CONTROL — an unknown/empty mode must stay SILENT. Inventing a source line for a state the
|
|
344
370
|
# check does not recognise is worse than saying nothing, and without this lane the function
|
|
345
371
|
# could pass IDX1–IDX3 while emitting the index sentence for every input.
|
|
346
372
|
o=$(index_source_note "")
|
|
347
373
|
[ -z "$o" ] && ok "IDX4 control — empty mode is silent (no invented provenance)" \
|
|
348
|
-
||
|
|
374
|
+
|| bad "IDX4 control — empty mode spoke: $o"
|
|
349
375
|
|
|
350
376
|
# 🟥 CONTROL 2 — the three states must be DISTINGUISHABLE from each other, not merely non-empty.
|
|
351
377
|
a=$(index_source_note "index"); b=$(index_source_note "nongit"); c=$(index_source_note "UNMEASURED")
|
|
352
378
|
if [ "$a" != "$b" ] && [ "$b" != "$c" ] && [ "$a" != "$c" ]; then
|
|
353
379
|
ok "IDX5 control — the three states produce three different sentences"
|
|
354
380
|
else
|
|
355
|
-
|
|
381
|
+
bad "IDX5 control — states collapsed into the same sentence"
|
|
356
382
|
fi
|
|
357
383
|
fi
|
|
358
384
|
rm -f "$_ISN"
|
|
@@ -362,7 +388,7 @@ if sed -n '/lane suite(s) with no runner and no declaration/,/Fix by ONE of/p' "
|
|
|
362
388
|
| grep -q 'index_source_note'; then
|
|
363
389
|
ok "IDX6 the note is CALLED on the FAIL path (not just defined)"
|
|
364
390
|
else
|
|
365
|
-
|
|
391
|
+
bad "IDX6 index_source_note is defined but the FAIL path does not call it"
|
|
366
392
|
fi
|
|
367
393
|
|
|
368
394
|
echo "----"
|
|
@@ -53,7 +53,7 @@ EXPECT=3 # the_bible + pmh-dev + qasp ; _meta and _audit excluded
|
|
|
53
53
|
|
|
54
54
|
# PREMISE — if the worktree can already see the fixtures, every verdict below is meaningless.
|
|
55
55
|
NAIVE_WT=0
|
|
56
|
-
for d in "$TMP/wt"/tracks/*/; do [ -d "$d" ] || continue; case "$(basename "$d")" in _*) continue;; esac; NAIVE_WT=$((NAIVE_WT+1)); done
|
|
56
|
+
for d in "$TMP/wt"/tracks/*/; do [ -d "$d" ] || continue; case "$(basename "$d")" in _*) continue;; esac; NAIVE_WT=$((NAIVE_WT+1)); done # portability-noqa: the [ -d "$d" ] || continue guard is on this SAME line (right after 'do'), not the next 1-2 lines the P8 scanner checks
|
|
57
57
|
[ "$NAIVE_WT" -lt "$EXPECT" ] \
|
|
58
58
|
&& ok "premise: a naive cwd count from the worktree sees $NAIVE_WT of $EXPECT — the blindness is real here" \
|
|
59
59
|
|| ng "premise BROKEN: worktree already sees $NAIVE_WT — fixture does not reproduce the defect"
|
|
@@ -165,6 +165,30 @@ crossfamily: panel(codex,agy) — 겹친 지적 0'
|
|
|
165
165
|
planep P6-real-corpus-negative BLOCK "$GRACE" "$(cat "$REPO_ROOT/tracks/_meta/.axes_23_passed_feat_target-freeze-gate_2026-08-18.marker" 2>/dev/null || echo 'axes-run: x')"
|
|
166
166
|
planep P7-real-corpus-positive PASS "$GRACE" "$(cat "$REPO_ROOT/tracks/_meta/.axes_23_passed_fix_witness-two-commit-discipline_2026-08-17.marker" 2>/dev/null || echo '①영혼: 성공 정의 = 하나 둘 셋 넷 다섯 여섯')"
|
|
167
167
|
|
|
168
|
+
echo
|
|
169
|
+
echo "== ①영혼 2칸(성공정의/절대안함) advisory lanes (2026-09-04, six_axis_review 판정안 4) =="
|
|
170
|
+
# advisory only — 두 케이스 다 rc=0(PASS). 판별은 rc 가 아니라 stdout 의 ⚠️ 문자열이다
|
|
171
|
+
# (known-pair: 한 칸만 있는 마커는 경고가 «찍혀야» 하고, 두 칸 다 있는 마커는 «안 찍혀야» 한다).
|
|
172
|
+
planep_adv() { # $1=id $2=expect(WARN|QUIET) $3=filename-date $4=body
|
|
173
|
+
local id="$1" expect="$2" d="$3" body="$4" out f
|
|
174
|
+
f="$T/.axes_23_passed_fix_x_${d}.marker"
|
|
175
|
+
printf '%s\n' "$body" > "$f"
|
|
176
|
+
out=$( bash -c 'set -uo pipefail; SOUL_PRESENT_GRACE_DATE="$3"; . "$1"; validate_soul_present_leg "$2"' \
|
|
177
|
+
_ "$T/fnp.sh" "$f" "$GRACE" 2>&1 )
|
|
178
|
+
local got=QUIET; printf '%s' "$out" | grep -q '①영혼 2칸 미달' && got=WARN
|
|
179
|
+
if [ "$got" = "$expect" ]; then printf ' ✅ %-40s %s\n' "$id" "$got"
|
|
180
|
+
else printf ' ❌ %-40s expected %s, got %s\n %s\n' "$id" "$expect" "$got" "$(printf '%s' "$out"|head -2)"; FAIL=1; fi
|
|
181
|
+
}
|
|
182
|
+
# known-positive — 「성공 정의」만 있고 「절대 안 함」이 없다 → advisory 가 찍혀야 한다, 그래도 PASS(rc=0)
|
|
183
|
+
planep_adv Q1-one-slot-only-warns WARN "$GRACE" '①영혼: 성공 정의 = 소비자 경로에서 완주해 rc=0 을 낸다
|
|
184
|
+
axes-run: ⓐ=codex'
|
|
185
|
+
# known-negative — 두 칸 다 있다($SOUL 픽스처) → advisory 가 안 찍혀야 한다
|
|
186
|
+
planep_adv Q2-both-slots-quiet QUIET "$GRACE" "$SOUL
|
|
187
|
+
axes-run: ⓐ=codex"
|
|
188
|
+
# 둘 다 rc=0(PASS) 이어야 한다 — advisory 는 커밋을 막지 않는다(형식만 다르고 planep 로도 확인)
|
|
189
|
+
planep Q1b-one-slot-still-passes PASS "$GRACE" '①영혼: 성공 정의 = 소비자 경로에서 완주해 rc=0 을 낸다
|
|
190
|
+
axes-run: ⓐ=codex'
|
|
191
|
+
|
|
168
192
|
echo
|
|
169
193
|
echo "== cross-family findings — regression lanes (codex/gpt-5.5, diff 축, 2026-08-21) =="
|
|
170
194
|
# F1 self-referential FP: codex's own alignment fix flipped G8 to PASS because the
|
|
@@ -42,43 +42,43 @@ echo "── node-check lanes ──"
|
|
|
42
42
|
# LANE 1 (S3-1) — NOT a git repo. The git-hook floor cannot be installed here at all, so it is
|
|
43
43
|
# N/A, not missing. Reporting it would be an unfixable notice repeating every session forever.
|
|
44
44
|
mkdir -p "$TMP/nogit"
|
|
45
|
-
out="$(run "$TMP/nogit" "$TMP/s1" FH_MACHINE_ID=nogitbox)"
|
|
45
|
+
out="$(run "$TMP/nogit" "$TMP/s1" FH_MACHINE_ID=nogitbox)"; rc=$?
|
|
46
46
|
# POSITIVE CONTROL: assert what MUST appear alongside what must not. Absence-only lanes are
|
|
47
47
|
# satisfied by a script that prints nothing at all — an `exit 0` stub passed lanes 1, 4 and 7
|
|
48
48
|
# (cross-family mutation 2026-07-30), so each now pins an expected utterance too.
|
|
49
49
|
case "$out" in
|
|
50
|
-
*"Missing mechanical floor"*) bad "lane1 non-git: must NOT claim a missing floor (N/A, unfixable)" "$out" ;;
|
|
50
|
+
*"Missing mechanical floor"*) bad "lane1 non-git: must NOT claim a missing floor (N/A, unfixable)" "rc=$rc | $out" ;;
|
|
51
51
|
*"first session for this clone"*) ok "lane1 non-git: N/A on the git floor, but still reports the node event" ;;
|
|
52
|
-
*) bad "lane1 non-git: silent — a stub would pass this lane" "$out" ;;
|
|
52
|
+
*) bad "lane1 non-git: silent — a stub would pass this lane" "rc=$rc | $out" ;;
|
|
53
53
|
esac
|
|
54
54
|
|
|
55
55
|
# LANE 2 (S3-2) — hooks exist but belong to another framework (husky/pre-commit). Executable ≠ FH's
|
|
56
56
|
# gate. Silence here is the exact accident this check was built for: FH gates absent, machine quiet.
|
|
57
57
|
mk_git_hub "$TMP/husky" no
|
|
58
|
-
out="$(run "$TMP/husky" "$TMP/s2" FH_MACHINE_ID=huskybox)"
|
|
58
|
+
out="$(run "$TMP/husky" "$TMP/s2" FH_MACHINE_ID=huskybox)"; rc=$?
|
|
59
59
|
case "$out" in
|
|
60
60
|
*"Missing mechanical floor"*) ok "lane2 foreign hooks: FH gate absence reported" ;;
|
|
61
|
-
*) bad "lane2 foreign hooks: non-FH hooks were accepted as FH floors" "$out" ;;
|
|
61
|
+
*) bad "lane2 foreign hooks: non-FH hooks were accepted as FH floors" "rc=$rc | $out" ;;
|
|
62
62
|
esac
|
|
63
63
|
|
|
64
64
|
# LANE 3 (S3-3) — Mode D user on a FRESH clone: companion store present, settings.local.json absent
|
|
65
65
|
# (it is gitignored, so a clone never has it). This is the MEASURED 2026-07-30 incident. Must speak.
|
|
66
66
|
mk_git_hub "$TMP/moded" yes
|
|
67
67
|
mkdir -p "$TMP/companion/.git"
|
|
68
|
-
out="$(run "$TMP/moded" "$TMP/s3" FH_MACHINE_ID=modedbox BE_DIR="$TMP/companion")"
|
|
68
|
+
out="$(run "$TMP/moded" "$TMP/s3" FH_MACHINE_ID=modedbox BE_DIR="$TMP/companion")"; rc=$?
|
|
69
69
|
case "$out" in
|
|
70
70
|
*companion-load*) ok "lane3 fresh Mode D clone: companion-load absence surfaced" ;;
|
|
71
|
-
*) bad "lane3 fresh Mode D clone: SILENT — the measured incident would recur" "$out" ;;
|
|
71
|
+
*) bad "lane3 fresh Mode D clone: SILENT — the measured incident would recur" "rc=$rc | $out" ;;
|
|
72
72
|
esac
|
|
73
73
|
|
|
74
74
|
# LANE 4 (M2-4) — public non-Mode-D user: no companion store anywhere. The companion item must not
|
|
75
75
|
# appear, or the majority path gets a false positive for a feature it does not use.
|
|
76
76
|
mk_git_hub "$TMP/public" yes
|
|
77
|
-
out="$(run "$TMP/public" "$TMP/s4" FH_MACHINE_ID=publicbox)"
|
|
77
|
+
out="$(run "$TMP/public" "$TMP/s4" FH_MACHINE_ID=publicbox)"; rc=$?
|
|
78
78
|
case "$out" in
|
|
79
|
-
*companion-load*) bad "lane4a non-Mode-D: companion item shown to a user with no store" "$out" ;;
|
|
79
|
+
*companion-load*) bad "lane4a non-Mode-D: companion item shown to a user with no store" "rc=$rc | $out" ;;
|
|
80
80
|
*"first session for this clone"*) ok "lane4a non-Mode-D: companion absent, node event still reported" ;;
|
|
81
|
-
*) bad "lane4a non-Mode-D: silent — a stub would pass this lane" "$out" ;;
|
|
81
|
+
*) bad "lane4a non-Mode-D: silent — a stub would pass this lane" "rc=$rc | $out" ;;
|
|
82
82
|
esac
|
|
83
83
|
|
|
84
84
|
# LANE 4b (S4-1) — CLAUDE.local.md is Claude Code's STANDARD local-override file; anyone may keep
|
|
@@ -86,9 +86,9 @@ esac
|
|
|
86
86
|
# gets a companion notice every session forever (state-based emission makes it permanent, not
|
|
87
87
|
# one-shot). Only the binding INSIDE the file counts.
|
|
88
88
|
printf '# my local notes\nuse tabs not spaces\n' > "$TMP/public/CLAUDE.local.md"
|
|
89
|
-
out="$(run "$TMP/public" "$TMP/s4b" FH_MACHINE_ID=publicbox)"
|
|
89
|
+
out="$(run "$TMP/public" "$TMP/s4b" FH_MACHINE_ID=publicbox)"; rc=$?
|
|
90
90
|
case "$out" in
|
|
91
|
-
*companion-load*) bad "lane4b plain CLAUDE.local.md: existence alone classified the user as Mode D" "$out" ;;
|
|
91
|
+
*companion-load*) bad "lane4b plain CLAUDE.local.md: existence alone classified the user as Mode D" "rc=$rc | $out" ;;
|
|
92
92
|
*) ok "lane4b plain CLAUDE.local.md: not treated as a Mode D signal" ;;
|
|
93
93
|
esac
|
|
94
94
|
|
|
@@ -106,10 +106,10 @@ for binding in 'BE_DIR=/x/store' 'companion store: ~/notes' '컴패니언 스토
|
|
|
106
106
|
'vault: ~/vaults/notes' 'gbrain ingest target: ~/gbrain' 'backend: obsidian'; do
|
|
107
107
|
i=$((i+1))
|
|
108
108
|
printf '# local\n%s\n' "$binding" > "$TMP/public/CLAUDE.local.md"
|
|
109
|
-
out="$(run "$TMP/public" "$TMP/s4c$i" FH_MACHINE_ID=publicbox)"
|
|
109
|
+
out="$(run "$TMP/public" "$TMP/s4c$i" FH_MACHINE_ID=publicbox)"; rc=$?
|
|
110
110
|
case "$out" in
|
|
111
111
|
*companion-load*) ok "lane4c.$i Mode D detected via: $binding" ;;
|
|
112
|
-
*) bad "lane4c.$i binding present but Mode D not detected: $binding" "$out" ;;
|
|
112
|
+
*) bad "lane4c.$i binding present but Mode D not detected: $binding" "rc=$rc | $out" ;;
|
|
113
113
|
esac
|
|
114
114
|
done
|
|
115
115
|
rm -f "$TMP/public/CLAUDE.local.md"
|
|
@@ -136,24 +136,24 @@ done
|
|
|
136
136
|
# exist and working hooks read as missing.
|
|
137
137
|
mk_git_hub "$TMP/wt" yes
|
|
138
138
|
git -C "$TMP/wt" worktree add -q "$TMP/wt_linked" -b lane7 2>/dev/null
|
|
139
|
-
out="$(run "$TMP/wt_linked" "$TMP/s7" FH_MACHINE_ID=wtbox)"
|
|
139
|
+
out="$(run "$TMP/wt_linked" "$TMP/s7" FH_MACHINE_ID=wtbox)"; rc=$?
|
|
140
140
|
case "$out" in
|
|
141
|
-
*"Missing mechanical floor"*) bad "lane7 worktree: false missing-floor (hooks resolve to the main gitdir)" "$out" ;;
|
|
141
|
+
*"Missing mechanical floor"*) bad "lane7 worktree: false missing-floor (hooks resolve to the main gitdir)" "rc=$rc | $out" ;;
|
|
142
142
|
*"first session for this clone"*) ok "lane7 worktree: hooks resolved correctly, node event reported" ;;
|
|
143
|
-
*) bad "lane7 worktree: silent — a stub would pass this lane" "$out" ;;
|
|
143
|
+
*) bad "lane7 worktree: silent — a stub would pass this lane" "rc=$rc | $out" ;;
|
|
144
144
|
esac
|
|
145
145
|
|
|
146
146
|
# LANE 8 (M3-3) — python3 unavailable: the companion verdict is UNMEASURED, never silently "fine".
|
|
147
147
|
# Simulated by a PATH with no python3, for a Mode D hub (so the check is applicable).
|
|
148
148
|
mk_git_hub "$TMP/nopy" yes
|
|
149
149
|
mkdir -p "$TMP/emptybin" "$TMP/companion2/.git"
|
|
150
|
-
out="$(PATH="$TMP/emptybin:/usr/bin:/bin" run "$TMP/nopy" "$TMP/s8" FH_MACHINE_ID=nopybox BE_DIR="$TMP/companion2")"
|
|
150
|
+
out="$(PATH="$TMP/emptybin:/usr/bin:/bin" run "$TMP/nopy" "$TMP/s8" FH_MACHINE_ID=nopybox BE_DIR="$TMP/companion2")"; rc=$?
|
|
151
151
|
if command -v python3 >/dev/null 2>&1 && [ -x /usr/bin/python3 ]; then
|
|
152
152
|
ok "lane8 skipped: /usr/bin/python3 exists so absence cannot be simulated via PATH"
|
|
153
153
|
else
|
|
154
154
|
case "$out" in
|
|
155
155
|
*UNMEASURED*|*unmeasured*) ok "lane8 no python3: reported UNMEASURED, not silence" ;;
|
|
156
|
-
*) bad "lane8 no python3: absence read as pass" "$out" ;;
|
|
156
|
+
*) bad "lane8 no python3: absence read as pass" "rc=$rc | $out" ;;
|
|
157
157
|
esac
|
|
158
158
|
fi
|
|
159
159
|
|
|
@@ -249,11 +249,11 @@ else
|
|
|
249
249
|
fi
|
|
250
250
|
git -C "$_dn" fetch -q origin >/dev/null 2>&1
|
|
251
251
|
_h0="$(git -C "$_dn" rev-parse HEAD)"
|
|
252
|
-
run "$_dn" "$_ap_root/s_a"
|
|
252
|
+
_out_a="$(run "$_dn" "$_ap_root/s_a" 2>&1)"; _rc_a=$?
|
|
253
253
|
if [ "$(git -C "$_dn" rev-parse HEAD)" != "$_h0" ]; then
|
|
254
254
|
ok "lane10-a APPLY: consented + on default branch → fast-forwarded"
|
|
255
255
|
else
|
|
256
|
-
bad "lane10-a APPLY: consented + on default branch did NOT fast-forward (feature inert — every refuse lane below is then vacuous)" "
|
|
256
|
+
bad "lane10-a APPLY: consented + on default branch did NOT fast-forward (feature inert — every refuse lane below is then vacuous)" "before=$_h0 rc=$_rc_a out=$_out_a"
|
|
257
257
|
fi
|
|
258
258
|
|
|
259
259
|
# b — the envelope. Never applies off the default branch, and NEVER switches branches.
|
|
@@ -267,13 +267,13 @@ else
|
|
|
267
267
|
# version of this lane asserted only those two and stayed green against a defeated envelope —
|
|
268
268
|
# decorative. The tip that must not move is the CURRENT branch's own.
|
|
269
269
|
_f0="$(git -C "$_dn" rev-parse feat-x)"
|
|
270
|
-
run "$_dn" "$_ap_root/s_b"
|
|
270
|
+
_out_b="$(run "$_dn" "$_ap_root/s_b" 2>&1)"; _rc_b=$?
|
|
271
271
|
if [ "$(git -C "$_dn" rev-parse "$_DEF")" = "$_m0" ] \
|
|
272
272
|
&& [ "$(git -C "$_dn" rev-parse feat-x)" = "$_f0" ] \
|
|
273
273
|
&& [ "$(git -C "$_dn" branch --show-current)" = "feat-x" ]; then
|
|
274
274
|
ok "lane10-b ENVELOPE: off default branch → no apply on EITHER branch, no switch"
|
|
275
275
|
else
|
|
276
|
-
bad "lane10-b ENVELOPE: a branch tip moved off the default branch — the shared-checkout hazard" "main=$_m0->$(git -C "$_dn" rev-parse "$_DEF") feat-x=$_f0->$(git -C "$_dn" rev-parse feat-x) branch=$(git -C "$_dn" branch --show-current)"
|
|
276
|
+
bad "lane10-b ENVELOPE: a branch tip moved off the default branch — the shared-checkout hazard" "main=$_m0->$(git -C "$_dn" rev-parse "$_DEF") feat-x=$_f0->$(git -C "$_dn" rev-parse feat-x) branch=$(git -C "$_dn" branch --show-current) rc=$_rc_b out=$_out_b"
|
|
277
277
|
fi
|
|
278
278
|
git -C "$_dn" switch -q "$_DEF" >/dev/null 2>&1
|
|
279
279
|
|
|
@@ -285,29 +285,29 @@ p=sys.argv[1]; s=open(p,encoding='utf-8').read()
|
|
|
285
285
|
open(p,'w',encoding='utf-8').write(re.sub(r'\nstanding_consent:\n(?: .*\n| .*\n)*', '\n', s, count=1))
|
|
286
286
|
PYX
|
|
287
287
|
_h1="$(git -C "$_dn" rev-parse HEAD)"
|
|
288
|
-
run "$_dn" "$_ap_root/s_c"
|
|
288
|
+
_out_c="$(run "$_dn" "$_ap_root/s_c" 2>&1)"; _rc_c=$?
|
|
289
289
|
[ "$(git -C "$_dn" rev-parse HEAD)" = "$_h1" ] \
|
|
290
290
|
&& ok "lane10-c NO-GRANT: absent standing_consent → no apply" \
|
|
291
|
-
|| bad "lane10-c NO-GRANT: applied without a grant" "
|
|
291
|
+
|| bad "lane10-c NO-GRANT: applied without a grant" "before=$_h1 rc=$_rc_c out=$_out_c"
|
|
292
292
|
|
|
293
293
|
# d — expired lease. A lease nobody enforces is not a lease.
|
|
294
294
|
cp "$_ap_root/uap.bak" "$_dn/tracks/_meta/user_adaptation_profile.md"
|
|
295
295
|
sed -i.bak2 's/expires: [0-9-]*/expires: 2020-01-01/' "$_dn/tracks/_meta/user_adaptation_profile.md"
|
|
296
296
|
_h2="$(git -C "$_dn" rev-parse HEAD)"
|
|
297
|
-
run "$_dn" "$_ap_root/s_d"
|
|
297
|
+
_out_d="$(run "$_dn" "$_ap_root/s_d" 2>&1)"; _rc_d=$?
|
|
298
298
|
[ "$(git -C "$_dn" rev-parse HEAD)" = "$_h2" ] \
|
|
299
299
|
&& ok "lane10-d EXPIRED: past-dated lease → no apply" \
|
|
300
|
-
|| bad "lane10-d EXPIRED: applied under an expired lease" "
|
|
300
|
+
|| bad "lane10-d EXPIRED: applied under an expired lease" "before=$_h2 rc=$_rc_d out=$_out_d"
|
|
301
301
|
cp "$_ap_root/uap.bak" "$_dn/tracks/_meta/user_adaptation_profile.md"
|
|
302
302
|
|
|
303
303
|
# e — divergence. --ff-only must refuse rather than absorb, and local work must survive.
|
|
304
304
|
(cd "$_dn" && echo local-only > mine.txt && git add -A && git commit -qm diverge) >/dev/null 2>&1
|
|
305
305
|
_h3="$(git -C "$_dn" rev-parse HEAD)"
|
|
306
|
-
run "$_dn" "$_ap_root/s_e"
|
|
306
|
+
_out_e="$(run "$_dn" "$_ap_root/s_e" 2>&1)"; _rc_e=$?
|
|
307
307
|
if [ "$(git -C "$_dn" rev-parse HEAD)" = "$_h3" ] && [ -f "$_dn/mine.txt" ]; then
|
|
308
308
|
ok "lane10-e DIVERGED: ff refused, local commit survives"
|
|
309
309
|
else
|
|
310
|
-
bad "lane10-e DIVERGED: local history was moved or lost" "$_h3 -> $(git -C "$_dn" rev-parse HEAD)"
|
|
310
|
+
bad "lane10-e DIVERGED: local history was moved or lost" "$_h3 -> $(git -C "$_dn" rev-parse HEAD) rc=$_rc_e out=$_out_e"
|
|
311
311
|
fi
|
|
312
312
|
|
|
313
313
|
# f — WRONG CLASS. The refusal that the other three arms structurally cannot produce.
|
|
@@ -367,7 +367,7 @@ PYX
|
|
|
367
367
|
if [ "$_h5" = "$(git -C "$_dn" rev-parse "origin/$_DEF")" ]; then
|
|
368
368
|
bad "lane10-f VACUOUS: clone is not behind origin, so 'no apply' proves nothing" "$_h5"
|
|
369
369
|
fi
|
|
370
|
-
run "$_dn" "$_ap_root/s_f"
|
|
370
|
+
_out_f="$(run "$_dn" "$_ap_root/s_f" 2>&1)"; _rc_f=$?
|
|
371
371
|
_filewide=0
|
|
372
372
|
bash "$FH_REPO/scripts/consent_registry_check.sh" \
|
|
373
373
|
"$_dn/tracks/_meta/consent_classes.yaml" \
|
|
@@ -375,9 +375,9 @@ PYX
|
|
|
375
375
|
if [ "$(git -C "$_dn" rev-parse HEAD)" = "$_h5" ] && [ "$_filewide" = "0" ]; then
|
|
376
376
|
ok "lane10-f WRONG-CLASS: another class granted, this one only in prose → no apply (file-wide check still 0)"
|
|
377
377
|
elif [ "$_filewide" != "0" ]; then
|
|
378
|
-
bad "lane10-f VACUOUS: the fixture broke the file-wide verdict (rc=$_filewide), so it re-tests lane10-c's axis, not the class join" "rebuild the fixture so the bare check returns 0"
|
|
378
|
+
bad "lane10-f VACUOUS: the fixture broke the file-wide verdict (rc=$_filewide), so it re-tests lane10-c's axis, not the class join" "rebuild the fixture so the bare check returns 0 | run_rc=$_rc_f run_out=$_out_f"
|
|
379
379
|
else
|
|
380
|
-
bad "lane10-f WRONG-CLASS: applied on a class that was never granted" "$_h5 -> $(git -C "$_dn" rev-parse HEAD)"
|
|
380
|
+
bad "lane10-f WRONG-CLASS: applied on a class that was never granted" "$_h5 -> $(git -C "$_dn" rev-parse HEAD) run_rc=$_rc_f run_out=$_out_f"
|
|
381
381
|
fi
|
|
382
382
|
cp "$_ap_root/uap.bak" "$_dn/tracks/_meta/user_adaptation_profile.md"
|
|
383
383
|
|
|
@@ -387,10 +387,10 @@ PYX
|
|
|
387
387
|
(cd "$_ap_root/up" && echo newer3 > f.txt && git commit -qam ahead3) >/dev/null 2>&1
|
|
388
388
|
git -C "$_dn" fetch -q origin >/dev/null 2>&1
|
|
389
389
|
_h4="$(git -C "$_dn" rev-parse HEAD)"
|
|
390
|
-
run "$_dn" "$_ap_root/s_f"
|
|
390
|
+
_out_ctrl="$(run "$_dn" "$_ap_root/s_f" 2>&1)"; _rc_ctrl=$?
|
|
391
391
|
[ "$(git -C "$_dn" rev-parse HEAD)" != "$_h4" ] \
|
|
392
392
|
&& ok "lane10-CONTROL: apply arm still fires after the refuse arms (instrument alive)" \
|
|
393
|
-
|| bad "lane10-CONTROL: apply arm went inert — the refuse lanes above prove nothing" "
|
|
393
|
+
|| bad "lane10-CONTROL: apply arm went inert — the refuse lanes above prove nothing" "before=$_h4 rc=$_rc_ctrl out=$_out_ctrl"
|
|
394
394
|
fi
|
|
395
395
|
rm -rf "$_ap_root"
|
|
396
396
|
|