@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
|
@@ -1470,6 +1470,18 @@ validate_soul_present_leg() { # $1 = marker path
|
|
|
1470
1470
|
echo " «이 기록이 템플릿 자신인가»만 본다 — 채널 검사다."
|
|
1471
1471
|
return 1
|
|
1472
1472
|
fi
|
|
1473
|
+
# ── ①영혼 2칸 존재 검사 (advisory only, 2026-09-04 — six_axis_review 판정안 4) ─────
|
|
1474
|
+
# «성공 정의»와 «절대 안 함» 두 낱말(변형 포함)이 둘 다 있는지만 본다. Mechanization
|
|
1475
|
+
# Boundary: 존재만 — 두 칸이 다 있어도 내용이 옳다는 보장은 없고, 하나가 없어도 커밋을
|
|
1476
|
+
# 막지 않는다(위 non-vacuity 검사가 이미 최소 6낱말을 요구·차단한다 — 이건 그 위에 얹는
|
|
1477
|
+
# 별도 관측이지 새 차단이 아니다). 「없음」 선언 분기는 위에서 이미 return 했으므로 여기
|
|
1478
|
+
# 도달하지 않는다.
|
|
1479
|
+
_soul_missing=""
|
|
1480
|
+
printf '%s' "$body" | grep -qE '성공 ?정의' || _soul_missing="성공 정의"
|
|
1481
|
+
printf '%s' "$body" | grep -qE '절대 ?안 ?함' || _soul_missing="${_soul_missing:+$_soul_missing · }절대 안 함"
|
|
1482
|
+
if [ -n "$_soul_missing" ]; then
|
|
1483
|
+
echo " ⚠️ ①영혼 2칸 미달 — 빠진 낱말: $_soul_missing (advisory, 커밋은 안 막는다)"
|
|
1484
|
+
fi
|
|
1473
1485
|
echo " ✅ ①영혼 present: $words word(s)"
|
|
1474
1486
|
return 0
|
|
1475
1487
|
}
|
|
@@ -2658,14 +2670,25 @@ if [ -n "$MD_STAGED" ]; then
|
|
|
2658
2670
|
echo "[Pointers] Detail-pointer resolution (staged markdown)..."
|
|
2659
2671
|
PTR_FAIL=0; PTR_CHECKED=0
|
|
2660
2672
|
for f in $MD_STAGED; do
|
|
2661
|
-
|
|
2662
|
-
|
|
2663
|
-
|
|
2673
|
+
# Read the STAGED blob, not the working-tree file. diff-filter=ACMR already guarantees $f
|
|
2674
|
+
# exists in the index, but a file can be staged and then deleted or further-edited on disk
|
|
2675
|
+
# before commit — `git commit` commits the INDEX, so `[ -f "$REPO_ROOT/$f" ] || continue`
|
|
2676
|
+
# here silently dropped the check on a committed broken pointer (deleted-on-disk case) and,
|
|
2677
|
+
# for a further-edited case, would have checked the wrong bytes entirely. Reproduced 2026-09-03:
|
|
2678
|
+
# stage a .md with a broken `**Detail**: See §X` pointer, `rm` it from disk (index untouched),
|
|
2679
|
+
# commit — PTR_CHECKED stayed 0 and the broken pointer landed silently.
|
|
2680
|
+
_md_blob="$(git -C "$REPO_ROOT" show ":$f" 2>/dev/null)" || {
|
|
2681
|
+
echo " ❌ $f: staged (diff-filter=ACMR) but unreadable from the index — cannot verify its Detail pointers"
|
|
2682
|
+
PTR_FAIL=1; continue
|
|
2683
|
+
}
|
|
2684
|
+
fdir="$(cd "$REPO_ROOT/$(dirname "$f")" 2>/dev/null && pwd)"
|
|
2685
|
+
[ -n "$fdir" ] || fdir="$REPO_ROOT/$(dirname "$f")"
|
|
2686
|
+
blocks="$(printf '%s\n' "$_md_blob" | awk '
|
|
2664
2687
|
inblk && /^>/ { blk=blk" "$0; next }
|
|
2665
2688
|
inblk { print blk; inblk=0; blk="" }
|
|
2666
2689
|
/\*\*Detail\*\*: See/ { blk=$0; inblk=1; next }
|
|
2667
2690
|
END { if(inblk) print blk }
|
|
2668
|
-
'
|
|
2691
|
+
')"
|
|
2669
2692
|
[ -z "$blocks" ] && continue
|
|
2670
2693
|
while IFS= read -r block; do
|
|
2671
2694
|
[ -z "$block" ] && continue
|
|
@@ -50,7 +50,28 @@
|
|
|
50
50
|
"built on a 46-PR-behind clone and manufactured a duplicate of an upstream lane. found→extend",
|
|
51
51
|
"applies at repo level; this is its mechanical layer. Same advisory contract; fail-open on",
|
|
52
52
|
"every uncertainty (non-repo, no upstream, fetch failure).",
|
|
53
|
-
" bash scripts/test_stale_clone_guard_lanes.sh # expect: all known pairs hold (count self-reported)"
|
|
53
|
+
" bash scripts/test_stale_clone_guard_lanes.sh # expect: all known pairs hold (count self-reported)",
|
|
54
|
+
"",
|
|
55
|
+
"FOURTH GUARD, Bash matcher — backtick_guard.sh (added 2026-09-03, weekly_audit_2026-09-02 HIGH #1):",
|
|
56
|
+
"advisory when a Bash call carries a backtick inside a shell DOUBLE-QUOTING context — an unquoted",
|
|
57
|
+
"heredoc body (<<EOF) or a \"double-quoted string\". There a backtick is command substitution: the text",
|
|
58
|
+
"between the backticks is REPLACED by the command's output — empty when it names no command, so the",
|
|
59
|
+
"text is silently DELETED and the record commits with a hole (every record hook checks presence, not",
|
|
60
|
+
"completeness). Measured 7x 2026-08-10..09-02 with a resident memory rule that failed each time because",
|
|
61
|
+
"the actor's task had a different name than the rule's title. Quote-aware state machine, not a regex:",
|
|
62
|
+
"single-quoted text, quoted heredocs (<<'EOF'), and escaped backticks are CLEAN. Same advisory contract;",
|
|
63
|
+
"escalate with FH_BACKTICK_BLOCK=1; opt out with `# noqa: backtick` (whole payload).",
|
|
64
|
+
" bash scripts/test_backtick_guard_lanes.sh # expect: all known pairs hold (count self-reported)",
|
|
65
|
+
"",
|
|
66
|
+
"FIFTH GUARD, Edit|Write|Bash matcher — proposal_hook.sh (added 2026-09-03, identity ⑤ r4):",
|
|
67
|
+
"advisory when a verdict/guard line in scripts/**/*.sh or templates/*.sh is about to change: puts ONE",
|
|
68
|
+
"instruction into the model context — offer the user a known-pair control + degrade_direction_scan.sh in",
|
|
69
|
+
"one line. Measured: the same rule as a CLAUDE.md table row fired 1/15 at floor tier (r3); as this hook",
|
|
70
|
+
"9/9 relay on editing reps and 0/5 on a usage-string edit (r4). Quote-aware: an edit confined to quoted",
|
|
71
|
+
"strings does not fire. Bash path (sed -i / > / tee into a .sh) covered with a weaker rule (named",
|
|
72
|
+
"residual in the script header). Evidence row in .claude/.proposal_hook_events.tsv. Relaying an",
|
|
73
|
+
"injected instruction is not initiative — see the r4 RESULT for what this does and does not claim.",
|
|
74
|
+
" bash scripts/test_proposal_hook_lanes.sh # expect: all known pairs hold (count self-reported)"
|
|
54
75
|
],
|
|
55
76
|
"project_settings_json": {
|
|
56
77
|
"hooks": {
|
|
@@ -67,6 +88,11 @@
|
|
|
67
88
|
"type": "command",
|
|
68
89
|
"command": "bash \"$CLAUDE_PROJECT_DIR/scripts/destructive_pre_gate.sh\"",
|
|
69
90
|
"timeout": 5
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
"type": "command",
|
|
94
|
+
"command": "bash \"$CLAUDE_PROJECT_DIR/scripts/backtick_guard.sh\"",
|
|
95
|
+
"timeout": 5
|
|
70
96
|
}
|
|
71
97
|
]
|
|
72
98
|
},
|
|
@@ -79,6 +105,16 @@
|
|
|
79
105
|
"timeout": 20
|
|
80
106
|
}
|
|
81
107
|
]
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
"matcher": "Edit|Write|Bash",
|
|
111
|
+
"hooks": [
|
|
112
|
+
{
|
|
113
|
+
"type": "command",
|
|
114
|
+
"command": "bash \"$CLAUDE_PROJECT_DIR/scripts/proposal_hook.sh\"",
|
|
115
|
+
"timeout": 5
|
|
116
|
+
}
|
|
117
|
+
]
|
|
82
118
|
}
|
|
83
119
|
]
|
|
84
120
|
}
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
# fh-commons — Contention-Born Skill Habitat
|
|
2
|
-
|
|
3
|
-
**A different layer of plugin from fh-meta.**
|
|
4
|
-
|
|
5
|
-
fh-meta = meta-engineering skills for operating, diagnosing, and improving the harness itself
|
|
6
|
-
fh-commons = general-purpose utility skills born from the contention layer, transplantable to any project
|
|
7
|
-
|
|
8
|
-
## Placement Criteria
|
|
9
|
-
|
|
10
|
-
When the `contention-layer` skill harvests contentions and generates new skill candidates:
|
|
11
|
-
|
|
12
|
-
| Determination | Destination |
|
|
13
|
-
|---|---|
|
|
14
|
-
| Harness engineering in nature | `fh-meta` |
|
|
15
|
-
| Project-general · domain-agnostic | **`fh-commons`** (this plugin) |
|
|
16
|
-
| Domain/team specific | field harvest (decided by the field team) |
|
|
17
|
-
|
|
18
|
-
## Skill List
|
|
19
|
-
|
|
20
|
-
| Skill | Description | Contention Parent |
|
|
21
|
-
|---|---|---|
|
|
22
|
-
| `convergence-loop` | General-purpose gate reinforcement that replaces single-pass structures with a convergence loop of up to N rounds | harvest-loop (recurring single-pass-distrust pattern across hub gates) |
|
|
23
|
-
| `deliberation` | Innovator → Devil-Advocate → Mediator 3-layer multi-perspective synthesis. Generates conditional verdicts without binary win/loss | Migrated from fh-meta (2026-05-23 — domain-agnostic general decision structure) |
|
|
24
|
-
| `ko-tech-writer` | Korean technical-writing pipeline — register detection, venue calibration, translationese scan, honesty layering, number/claim gate, perceptual QA | Field-session harvest (2026-08-10 — conference tech-doc revision session, operator-driven shipping) |
|
|
25
|
-
|
|
26
|
-
## The `origin` Field
|
|
27
|
-
|
|
28
|
-
Commons skills include the following fields in their SKILL.md frontmatter:
|
|
29
|
-
|
|
30
|
-
```yaml
|
|
31
|
-
# Contention-born (extracted by contention-layer)
|
|
32
|
-
origin: contention-layer
|
|
33
|
-
contention-parents: [skill-A, skill-B]
|
|
34
|
-
|
|
35
|
-
# Migrated from fh-meta (reclassified as general-purpose)
|
|
36
|
-
origin: fh-meta
|
|
37
|
-
migration: "YYYY-MM-DD — reason for migration"
|
|
38
|
-
```
|