@chrono-meta/fh-gate 1.4.98 → 2.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-plugin/marketplace.json +2 -2
- package/README.ja.md +219 -42
- package/README.ko.md +231 -45
- package/README.md +157 -31
- package/README.zh.md +209 -40
- package/docs/OUTPUT_EVIDENCE.md +21 -12
- package/knowledge/shared/harness-core/field_verdict_crossfamily_gate.md +36 -0
- package/knowledge/shared/learnings/subagent_invocations_log.yaml +21 -0
- package/package.json +4 -2
- package/plugins/fh-commons/.claude-plugin/plugin.json +1 -1
- package/plugins/fh-meta/.claude-plugin/plugin.json +1 -1
- package/plugins/fh-meta/CHANGELOG.md +129 -0
- package/scripts/capability_effect_probe.sh +381 -0
- package/scripts/capability_registry_check.sh +115 -6
- package/scripts/consent_registry_check.sh +124 -1
- package/scripts/fh_node_check.sh +69 -1
- package/scripts/lane_runner_check.sh +70 -14
- package/scripts/publish_freshness_check.sh +204 -0
- package/scripts/selfcheck.sh +101 -1
- package/scripts/test_capability_entrypoint_shipping.sh +75 -5
- package/scripts/test_consent_registry.sh +99 -0
- package/scripts/test_lane_runner_lanes.sh +74 -0
- package/scripts/test_node_check_lanes.sh +217 -0
- package/scripts/test_selfcheck_state_lanes.sh +61 -0
- package/templates/consent_classes.yaml.example +30 -0
|
@@ -357,6 +357,67 @@ CTLPY
|
|
|
357
357
|
[ "$_BARE_CTL" = FIRED ]
|
|
358
358
|
chk $? "CONTROL: that detector fires on a planted declared-shipped subject (got $_BARE_CTL)"
|
|
359
359
|
|
|
360
|
+
echo ""
|
|
361
|
+
echo "── directional_diff_gate verdict arm: exit 0 is not a pass ──"
|
|
362
|
+
# WHY THIS LANE EXISTS (2026-08-15): the block wiring directional_diff_gate.sh --self-test gates on
|
|
363
|
+
# the subject's terminal verdict, not on rc=0 alone, and both halves of that were put there by a
|
|
364
|
+
# cross-family round rather than by the author. Its first draft gated on rc=0 plus a SUBSTRING of
|
|
365
|
+
# the verdict, and two reachable inputs satisfied it while nothing ran:
|
|
366
|
+
# · `✅ calibration passed (0 pairs)` — the subject's own verdict line is
|
|
367
|
+
# `[ "$f" -eq 0 ] && echo "✅ calibration passed ($n pairs)"`, so deleting every lane prints a
|
|
368
|
+
# PASS with n=0. Deletion read as a pass is the quietest face of the not-found-is-not-zero class.
|
|
369
|
+
# · `usage: calibration passed (28 pairs)` — a prose/usage line carrying the words.
|
|
370
|
+
# Without this lane both repairs are reversible to green, which is anchor-is-decorative.
|
|
371
|
+
# LIFTED from selfcheck.sh, not re-spelled — a lane that restates the condition stops seeing edits
|
|
372
|
+
# to it, which is the failure the two lanes above were written to avoid.
|
|
373
|
+
DD_ARM=$(sed -n '/^ _dd_verdict=\$(printf/,/^ fi ;;$/p' "$SELFCHECK" | sed 's/ ;;$//')
|
|
374
|
+
if [ -z "$DD_ARM" ]; then
|
|
375
|
+
echo "FAIL the directional_diff_gate verdict arm is no longer where this lane lifts it from."
|
|
376
|
+
echo " If the block was moved or renamed, update the lane WITH the subject."
|
|
377
|
+
exit 1
|
|
378
|
+
fi
|
|
379
|
+
# An empty lift is not the only bad lift. If the END anchor stops matching — re-indent the arm, or
|
|
380
|
+
# move it out of the `case` — the START anchor still matches and the range runs to EOF, which is
|
|
381
|
+
# non-empty and therefore passes the guard above. What saves it today is luck, not design: the
|
|
382
|
+
# `;;`-stripping applies to every line in the range, so downstream case arms lose their terminators
|
|
383
|
+
# and `eval` dies of a syntax error. A downstream span that happened to be self-contained would
|
|
384
|
+
# instead `eval` several hundred lines of selfcheck.sh, once per fixture, at the repo root. Bound
|
|
385
|
+
# the lift by size so the failure is a lane message rather than an accident. Cross-family, 2026-08-15.
|
|
386
|
+
if [ "$(printf '%s\n' "$DD_ARM" | wc -l)" -gt 15 ]; then
|
|
387
|
+
echo "FAIL the lifted verdict arm is $(printf '%s\n' "$DD_ARM" | wc -l) lines — the sed END anchor"
|
|
388
|
+
echo " stopped matching and the range ran past the block. Fix the anchor, do not widen this bound."
|
|
389
|
+
exit 1
|
|
390
|
+
fi
|
|
391
|
+
dd_arm_says() { # $1 = the subject's stdout; echoes PASS or FAIL
|
|
392
|
+
( _out="$1"; fail=0; _show_failure() { :; }
|
|
393
|
+
eval "$DD_ARM" ) | grep -oE '^(PASS|FAIL)' | head -1
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
[ "$(dd_arm_says '✅ calibration passed (28 pairs)')" = PASS ]
|
|
397
|
+
chk $? "a real verdict with a non-zero pair count passes"
|
|
398
|
+
|
|
399
|
+
[ "$(dd_arm_says '✅ calibration passed (0 pairs)')" = FAIL ]
|
|
400
|
+
chk $? "every lane deleted (0 pairs, exit 0) is caught, not certified"
|
|
401
|
+
|
|
402
|
+
[ "$(dd_arm_says 'usage: calibration passed (28 pairs)')" = FAIL ]
|
|
403
|
+
chk $? "a usage/prose line carrying the words does not satisfy the gate"
|
|
404
|
+
|
|
405
|
+
# CONTROL — the pre-repair form (bare substring, no pair-count floor) must ACCEPT both bad
|
|
406
|
+
# fixtures. Without it these lanes could pass because the fixtures are wrong rather than because
|
|
407
|
+
# the repair works.
|
|
408
|
+
_pre() { printf '%s\n' "$1" | grep -oE 'calibration passed \([0-9]+ pairs\)' | tail -1; }
|
|
409
|
+
[ -n "$(_pre '✅ calibration passed (0 pairs)')" ] && [ -n "$(_pre 'usage: calibration passed (28 pairs)')" ]
|
|
410
|
+
chk $? "CONTROL: the pre-repair substring form accepts both — the fixtures discriminate"
|
|
411
|
+
|
|
412
|
+
# SCOPE of these four lanes, stated because the inherited §SCOPE block below is about a different
|
|
413
|
+
# anchor and does not cover them. The lift is the `0)` arm's BODY only, so these lanes see a change
|
|
414
|
+
# to the verdict predicate and are blind to the routing around it: widening `case ... in 0)` to
|
|
415
|
+
# `0|1)`, dropping `< /dev/null`, dropping the `$_LANE_TO` wrapper, or deleting the rc=124
|
|
416
|
+
# HARNESS-ERROR arm all leave every lane here green. Those are guarded by review, not by this file.
|
|
417
|
+
# The `_pre` control is also a RE-SPELLING of the pre-repair form rather than a lift of it — it has
|
|
418
|
+
# to be, since that form no longer exists in the subject to lift, but it means the control asserts
|
|
419
|
+
# what the old code did from memory. Both limits found by cross-family review, 2026-08-15.
|
|
420
|
+
|
|
360
421
|
# ── SCOPE OF THIS ANCHOR — stated so it is not over-trusted ───────────────────
|
|
361
422
|
# These lanes catch REVERSION (the run-twice form coming back, the helper being gutted, the
|
|
362
423
|
# call-site redirect returning). They do NOT catch deliberate EVASION: a cross-family round
|
|
@@ -44,6 +44,36 @@
|
|
|
44
44
|
# Re-point the class's `owner` or `mode` after the grant and the join fails: that is the point.
|
|
45
45
|
|
|
46
46
|
classes:
|
|
47
|
+
# ---- REAL, ADOPTABLE class (not illustrative) -------------------------------------
|
|
48
|
+
# Ships with fh_node_check.sh's consent-gated auto-pull. Copy this block verbatim into your
|
|
49
|
+
# own tracks/_meta/consent_classes.yaml, then grant it in your UAP frontmatter to enable the
|
|
50
|
+
# apply arm. Without both, the check surfaces "N commits behind" and never touches the repo —
|
|
51
|
+
# absent is not granted.
|
|
52
|
+
#
|
|
53
|
+
# Read the reason before adopting: this class takes a DIFFERENT verdict from the `local-commit`
|
|
54
|
+
# example further down, on a deliberately narrow ground. If your integration branch is not
|
|
55
|
+
# PR-only/protected, that ground does not hold for you and you should not adopt it.
|
|
56
|
+
- name: repo-freshness-autopull
|
|
57
|
+
owner: scripts/fh_node_check.sh
|
|
58
|
+
mode: ff-only-merge-on-default-branch
|
|
59
|
+
target: this repo's own default branch, in the local clone, when it is already checked out
|
|
60
|
+
capabilities: [network, repo-mutation]
|
|
61
|
+
sinks: []
|
|
62
|
+
feeds: []
|
|
63
|
+
promotion_eligible: true
|
|
64
|
+
lease_days: 92
|
|
65
|
+
reason: >
|
|
66
|
+
A fast-forward pull introduces nothing new: every commit it brings down is already on the
|
|
67
|
+
integration branch, which is PR-only and server-side protected, so all of it has passed the
|
|
68
|
+
gates. `local-commit` below is classified feeds:[go-public] because it CREATES ungated
|
|
69
|
+
content that publish can then ship; this makes the tree MATCH canon instead. Publish packs
|
|
70
|
+
the working tree, so a tree matching origin is strictly safer to publish from than a stale
|
|
71
|
+
one. Blast radius also excludes personal state by construction — a pull touches tracked
|
|
72
|
+
files only, and session/memory/companion state is gitignored or outside the repo.
|
|
73
|
+
Envelope (enforced in code, not prose): applies ONLY when the default branch is already
|
|
74
|
+
checked out, never switches branches, and --ff-only refuses a divergence rather than
|
|
75
|
+
absorbing it. Lanes: scripts/test_node_check_lanes.sh lane10-a..e + CONTROL.
|
|
76
|
+
|
|
47
77
|
# ---- promotion-eligible example -------------------------------------------------
|
|
48
78
|
- name: dispatch-readonly-sim-local-artifact
|
|
49
79
|
owner: fh-meta:sim-conductor # the gate/skill that does the asking
|