@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.
Files changed (45) hide show
  1. package/.claude/rules/fh_4axis_gate.md +38 -0
  2. package/.claude-plugin/marketplace.json +2 -2
  3. package/CLAUDE.md +1 -1
  4. package/README.md +6 -1
  5. package/knowledge/shared/harness-core/fh_three_layer_canon.md +47 -0
  6. package/knowledge/shared/harness-core/field_verdict_crossfamily_gate.md +10 -0
  7. package/knowledge/shared/harness-core/measurement-integrity-checklist.md +15 -1
  8. package/knowledge/shared/harness-core/ship_readiness_gate.md +19 -2
  9. package/knowledge/shared/learnings/subagent_invocations_log.yaml +49 -0
  10. package/package.json +9 -1
  11. package/plugins/fh-commons/.claude-plugin/plugin.json +1 -1
  12. package/plugins/fh-meta/.claude-plugin/plugin.json +1 -1
  13. package/plugins/fh-meta/CHANGELOG.md +25 -0
  14. package/scripts/backtick_guard.sh +194 -0
  15. package/scripts/context_continuity_score.sh +49 -7
  16. package/scripts/fh-gate.sh +3 -3
  17. package/scripts/files_manifest_shipping_check.sh +19 -0
  18. package/scripts/gate_pathspec_check.sh +1 -1
  19. package/scripts/package_coverage_check.sh +24 -2
  20. package/scripts/proposal_hook.sh +89 -0
  21. package/scripts/public_surface_scan_files.sh +11 -2
  22. package/scripts/revert_probe.sh +250 -0
  23. package/scripts/selfcheck.sh +65 -2
  24. package/scripts/sim_isolated_run.sh +97 -7
  25. package/scripts/test_backtick_guard_lanes.sh +115 -0
  26. package/scripts/test_degrade_scan_shell_probes.sh +7 -7
  27. package/scripts/test_files_manifest_shipping_lanes.sh +5 -5
  28. package/scripts/test_heavy_classifier_lanes.sh +1 -1
  29. package/scripts/test_lane_runner_lanes.sh +59 -33
  30. package/scripts/test_mapped_tracks_lanes.sh +1 -1
  31. package/scripts/test_marker_soul_check_lanes.sh +24 -0
  32. package/scripts/test_node_check_lanes.sh +34 -34
  33. package/scripts/test_package_coverage_lanes.sh +53 -27
  34. package/scripts/test_pipe_verdict_guard_lanes.sh +5 -5
  35. package/scripts/test_precommit_pointer_index_lanes.sh +33 -0
  36. package/scripts/test_preprep_drift_anchor.sh +13 -4
  37. package/scripts/test_preprep_drift_anchor_lanes.sh +23 -0
  38. package/scripts/test_proposal_hook_lanes.sh +36 -0
  39. package/scripts/test_revert_probe_lanes.sh +146 -0
  40. package/scripts/test_session_close_lanes.sh +3 -5
  41. package/scripts/test_sim_isolated_run_lanes.sh +17 -0
  42. package/scripts/utterance_landing_check.sh +2 -2
  43. package/templates/.git-hooks/pre-commit +27 -4
  44. package/templates/settings.PreToolUse.snippet.json +37 -1
  45. 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
- [ -f "$REPO_ROOT/$f" ] || continue
2662
- fdir="$(cd "$REPO_ROOT/$(dirname "$f")" && pwd)"
2663
- blocks="$(awk '
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
- ' "$REPO_ROOT/$f")"
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
- ```