@chrono-meta/fh-gate 3.2.0 → 3.5.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/registry/agent_cards.json +1 -1
- package/.claude/rules/fh_4axis_gate.md +25 -0
- package/.claude-plugin/marketplace.json +9 -3
- package/AGENTS.md +2 -2
- package/CATALOG.md +4 -4
- package/CHEATSHEET.md +1 -1
- package/CLAUDE.md +4 -4
- package/README.md +2 -2
- package/docs/OUTPUT_EVIDENCE.md +1 -1
- package/docs/STANDARDS_ALIGNMENT.md +1 -1
- package/docs/codex-compat.md +2 -2
- package/knowledge/shared/harness-core/agents_md_runtime_details.md +2 -2
- package/knowledge/shared/harness-core/field_verdict_crossfamily_gate.md +30 -3
- package/knowledge/shared/harness-core/iso_ai_standards_crosswalk.md +1 -1
- package/knowledge/shared/harness-core/skill_quality_rubric.md +1 -1
- package/knowledge/shared/learnings/subagent_invocations_log.yaml +120 -4
- package/knowledge/shared/rules/modes_and_value.md +2 -2
- package/package.json +9 -1
- package/plugins/fh-commons/.claude-plugin/plugin.json +2 -2
- package/plugins/fh-commons/README.md +38 -0
- package/plugins/fh-meta/.claude-plugin/plugin.json +1 -1
- package/plugins/fh-meta/CHANGELOG.md +117 -0
- package/plugins/fh-meta/skills/agent-composer/SKILL.md +2 -2
- package/plugins/fh-meta/skills/auto-decorrelation/SKILL.md +40 -0
- package/plugins/fh-meta/skills/frontier-digest/SKILL.md +1 -1
- package/plugins/fh-meta/skills/frontier-digest/SKILL_detail.md +43 -5
- package/plugins/fh-meta/skills/{hub-cc-pr-reviewer → harness-pr-reviewer}/SKILL.md +75 -3
- package/plugins/fh-meta/skills/{hub-cc-pr-reviewer → harness-pr-reviewer}/SKILL_detail.md +2 -2
- package/plugins/fh-meta/skills/harvest-loop/SKILL_detail.md +2 -2
- package/plugins/fh-meta/skills/install-doctor/SKILL.md +1 -1
- package/plugins/fh-meta/skills/install-wizard/SKILL.md +1 -1
- package/plugins/fh-meta/skills/meta-prompt-builder/SKILL.md +1 -1
- package/plugins/fh-meta/skills/pipeline-conductor/SKILL.md +1 -1
- package/plugins/fh-meta/skills/plugin-recommender/SKILL.md +1 -1
- package/plugins/fh-meta/skills/sim-conductor/SKILL.md +1 -1
- package/plugins/fh-preprep/.claude-plugin/plugin.json +22 -0
- package/plugins/fh-preprep/README.md +24 -0
- package/plugins/{fh-commons → fh-preprep}/skills/preprep/SKILL.md +75 -3
- package/plugins/{fh-commons → fh-preprep}/skills/preprep/fixtures/mk_slide_fixtures.py +152 -1
- package/plugins/fh-preprep/skills/preprep/lane_attr_consistency.py +370 -0
- package/plugins/fh-preprep/skills/preprep/lane_geometry.py +339 -0
- package/plugins/fh-preprep/skills/preprep/lane_screen_parity.py +232 -0
- package/plugins/fh-preprep/skills/preprep/oox.py +305 -0
- package/plugins/{fh-commons → fh-preprep}/skills/preprep/preprep.py +52 -4
- package/plugins/fh-preprep/skills/preprep/safe_install.py +369 -0
- package/plugins/{fh-commons → fh-preprep}/skills/preprep/surfaces.example.yaml +29 -0
- package/plugins/fh-preprep/skills/preprep/test_preprep_lanes_rp.py +1417 -0
- package/plugins/fh-preprep/skills/preprep/usage_ledger.py +191 -0
- package/plugins/fh-qp/.claude-plugin/plugin.json +1 -1
- package/scripts/fh-run.sh +13 -0
- package/scripts/field_canon_preload.sh +1 -1
- package/scripts/finding_fleet.sh +391 -13
- package/scripts/finding_pipeline.sh +370 -11
- package/scripts/finding_verifier.sh +31 -2
- package/scripts/finding_verify.py +198 -13
- package/scripts/frontier_digest_autopilot.sh +3 -3
- package/scripts/gate_shape_scan.sh +16 -2
- package/scripts/selfcheck.sh +12 -8
- package/scripts/test_fh_run_resolver_lanes.sh +116 -0
- package/scripts/test_files_manifest_shipping_lanes.sh +31 -0
- package/scripts/test_finding_pipeline_lanes.sh +1556 -4
- package/scripts/test_gate_shape_scan_lanes.sh +11 -0
- package/scripts/test_marker_crossfamily_lanes.sh +75 -3
- package/scripts/test_marker_standpoint_lanes.sh +31 -6
- package/scripts/test_preprep_adjacent_dup_lanes.sh +1 -1
- package/scripts/test_preprep_diagram_lanes.sh +1 -1
- package/scripts/test_preprep_drift_anchor.sh +27 -12
- package/scripts/test_preprep_drift_anchor_lanes.sh +4 -2
- package/scripts/test_preprep_font_lanes.sh +7 -7
- package/scripts/test_preprep_progression_lanes.sh +1 -1
- package/scripts/test_preprep_promise_lanes.sh +1 -1
- package/scripts/test_preprep_retired_lanes.sh +45 -2
- package/scripts/test_preprep_slide_refs_lanes.sh +5 -5
- package/scripts/test_usage_ledger_lanes.sh +243 -0
- package/scripts/usage_report.py +211 -0
- package/templates/.git-hooks/pre-commit +152 -6
- package/templates/local_fh_context.md +1 -1
- package/templates/regression_guard.sh +1 -1
- package/plugins/fh-commons/skills/preprep/lane_geometry.py +0 -181
- package/plugins/fh-commons/skills/preprep/test_preprep_lanes_rp.py +0 -184
- /package/plugins/{fh-commons → fh-preprep}/skills/preprep/README.md +0 -0
- /package/plugins/{fh-commons → fh-preprep}/skills/preprep/canon_terms.example.yaml +0 -0
- /package/plugins/{fh-commons → fh-preprep}/skills/preprep/diagram_from_json.py +0 -0
- /package/plugins/{fh-commons → fh-preprep}/skills/preprep/fixtures/adjdup_known_negative.md +0 -0
- /package/plugins/{fh-commons → fh-preprep}/skills/preprep/fixtures/adjdup_known_positive.md +0 -0
- /package/plugins/{fh-commons → fh-preprep}/skills/preprep/fixtures/fixture_R3_negative.pptx +0 -0
- /package/plugins/{fh-commons → fh-preprep}/skills/preprep/fixtures/fixture_R3_positive.pptx +0 -0
- /package/plugins/{fh-commons → fh-preprep}/skills/preprep/fixtures/font_revert_probe.py +0 -0
- /package/plugins/{fh-commons → fh-preprep}/skills/preprep/fixtures/progression_known_negative.md +0 -0
- /package/plugins/{fh-commons → fh-preprep}/skills/preprep/fixtures/progression_known_positive.md +0 -0
- /package/plugins/{fh-commons → fh-preprep}/skills/preprep/fixtures/promise_known_negative.md +0 -0
- /package/plugins/{fh-commons → fh-preprep}/skills/preprep/fixtures/promise_known_positive.md +0 -0
- /package/plugins/{fh-commons → fh-preprep}/skills/preprep/interslide_deps.py +0 -0
- /package/plugins/{fh-commons → fh-preprep}/skills/preprep/jargon_terms.example.yaml +0 -0
- /package/plugins/{fh-commons → fh-preprep}/skills/preprep/lane_adjacent_dup.py +0 -0
- /package/plugins/{fh-commons → fh-preprep}/skills/preprep/lane_diagram.py +0 -0
- /package/plugins/{fh-commons → fh-preprep}/skills/preprep/lane_font.py +0 -0
- /package/plugins/{fh-commons → fh-preprep}/skills/preprep/lane_progression.py +0 -0
- /package/plugins/{fh-commons → fh-preprep}/skills/preprep/lane_promise.py +0 -0
- /package/plugins/{fh-commons → fh-preprep}/skills/preprep/lane_slide_refs.py +0 -0
- /package/plugins/{fh-commons → fh-preprep}/skills/preprep/lane_slide_relations.py +0 -0
- /package/plugins/{fh-commons → fh-preprep}/skills/preprep/ooxml/c1_baseline.txt +0 -0
- /package/plugins/{fh-commons → fh-preprep}/skills/preprep/ooxml/gate.py +0 -0
- /package/plugins/{fh-commons → fh-preprep}/skills/preprep/preprep_wire.py +0 -0
- /package/plugins/{fh-commons → fh-preprep}/skills/preprep/presentation_checklist.md +0 -0
- /package/plugins/{fh-commons → fh-preprep}/skills/preprep/test_lane_font.py +0 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@chrono-meta/fh-gate",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.5.0",
|
|
4
4
|
"description": "FH runtime adapters — run FH governance, skills, and agents via Claude or Codex with machine-parseable gates.",
|
|
5
5
|
"homepage": "https://github.com/chrono-meta/forge-harness#readme",
|
|
6
6
|
"bugs": {
|
|
@@ -28,6 +28,7 @@
|
|
|
28
28
|
"fh-codex-doctor": "bin/fh-codex-doctor.js"
|
|
29
29
|
},
|
|
30
30
|
"scripts": {
|
|
31
|
+
"prepack": "find plugins -type d -name __pycache__ -prune -exec rm -rf {} + 2>/dev/null; true",
|
|
31
32
|
"prepare": "chmod +x bin/fh-gate.js bin/fh-run.js bin/fh-goal.js bin/fh-codex-doctor.js scripts/fh-gate.sh scripts/fh-run.sh scripts/fh-goal.sh",
|
|
32
33
|
"postinstall": "node scripts/postinstall_notice.js",
|
|
33
34
|
"test": "bash scripts/selfcheck.sh",
|
|
@@ -75,6 +76,9 @@
|
|
|
75
76
|
"scripts/version_lockstep_check.sh",
|
|
76
77
|
"scripts/test_selfcheck_state_lanes.sh",
|
|
77
78
|
"scripts/test_lane_runner_lanes.sh",
|
|
79
|
+
"scripts/usage_report.py",
|
|
80
|
+
"scripts/test_usage_ledger_lanes.sh",
|
|
81
|
+
"scripts/test_fh_run_resolver_lanes.sh",
|
|
78
82
|
"scripts/test_version_lockstep_lanes.sh",
|
|
79
83
|
"scripts/package_coverage_check.sh",
|
|
80
84
|
"scripts/files_manifest_shipping_check.sh",
|
|
@@ -227,6 +231,7 @@
|
|
|
227
231
|
"plugins/fh-meta/skills",
|
|
228
232
|
"plugins/fh-meta/agents",
|
|
229
233
|
"plugins/fh-commons/.claude-plugin/plugin.json",
|
|
234
|
+
"plugins/fh-commons/README.md",
|
|
230
235
|
"plugins/fh-commons/skills",
|
|
231
236
|
"plugins/fh-commons/agents",
|
|
232
237
|
"knowledge/shared/harness-core",
|
|
@@ -322,6 +327,9 @@
|
|
|
322
327
|
"scripts/test_utterance_intake_lanes.sh",
|
|
323
328
|
"scripts/worktree_reclaim.sh",
|
|
324
329
|
"scripts/test_worktree_reclaim_lanes.sh",
|
|
330
|
+
"plugins/fh-preprep/.claude-plugin/plugin.json",
|
|
331
|
+
"plugins/fh-preprep/README.md",
|
|
332
|
+
"plugins/fh-preprep/skills",
|
|
325
333
|
"plugins/fh-qp/.claude-plugin/plugin.json",
|
|
326
334
|
"plugins/fh-qp/README.md",
|
|
327
335
|
"plugins/fh-qp/qp_profile.example.yaml",
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fh-commons",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.5.0",
|
|
4
4
|
"engines": {
|
|
5
5
|
"claudeCode": ">=1.0.0"
|
|
6
6
|
},
|
|
7
|
-
"description": "Cross-project utility skill bundle —
|
|
7
|
+
"description": "Cross-project utility skill bundle — 5 skills + 1 agent. Domain-agnostic and portable: convergence-loop, deliberation, mcp-circuit-breaker, token-budget-gate, ko-tech-writer, preprep + quench-challenger agent.",
|
|
8
8
|
"author": {
|
|
9
9
|
"name": "chrono-meta",
|
|
10
10
|
"email": "chrono-meta@users.noreply.github.com"
|
|
@@ -0,0 +1,38 @@
|
|
|
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
|
+
```
|
|
@@ -1,5 +1,122 @@
|
|
|
1
1
|
# forge-harness (fh-meta) Changelog
|
|
2
2
|
|
|
3
|
+
### [3.5.0] — 2026-09-13 — preprep 를 자기 플러그인으로 승격 (`fh-preprep`)
|
|
4
|
+
|
|
5
|
+
**BREAKING (gate):** 스킬 경로가 **이동한다**.
|
|
6
|
+
`plugins/fh-commons/skills/preprep/` → `plugins/fh-preprep/skills/preprep/`
|
|
7
|
+
🟥 **그 경로를 직접 부르던 스크립트·문서·설정은 깨진다.** 처방 = 경로 한 곳 치환:
|
|
8
|
+
`sed -i '' 's|fh-commons/skills/preprep|fh-preprep/skills/preprep|g' <파일>`
|
|
9
|
+
플러그인으로 설치해 쓰는 경우(스킬 이름으로 호출)는 영향이 없다 — 이름은 `preprep` 그대로다.
|
|
10
|
+
|
|
11
|
+
**왜 옮겼나**: 스킬 하나가 레인 17개(내장 7 + 모듈 10)·픽스처군·오라클을 들면서
|
|
12
|
+
**역할이 갈렸다**(라우팅 / 판정 / 오라클). 규모가 아니라 역할 분기가 근거다.
|
|
13
|
+
|
|
14
|
+
- 새 `plugins/fh-preprep/` — 자기 `plugin.json` · README(종료코드 계약 명시) · `skills/preprep/`
|
|
15
|
+
- marketplace 항목 3 → **4**. 버전 락스텝 8개 문자열 전부 3.5.0
|
|
16
|
+
- `files[]` 에 `plugins/fh-preprep/{plugin.json,README.md,skills}` 등재 — 빼먹으면 조용한 출하 누락
|
|
17
|
+
- 드리프트 앵커·레인 12개·`field_canon_preload.sh`·`selfcheck.sh` 의 경로 참조를 같이 옮겼다
|
|
18
|
+
|
|
19
|
+
**승격 전에 닫은 것**(순서가 근거다 — 앵커 수리와 이동이 한 diff 에 섞이면 귀속이 안 갈린다):
|
|
20
|
+
① #702 머지로 드리프트 앵커 초록 · ② 실물 14 표면 완주(rc=1 확정) 로 Done-When #1·#6 닫힘
|
|
21
|
+
(#705 에서 「설정을 못 읽음」이 `rc=1`(=발견 있음)으로 나가던 선재 결함을 `rc=2` 로 수리).
|
|
22
|
+
|
|
23
|
+
🟥 **승격이 닫지 않는 것**: preprep Done-When #5(죽은 선언 12개)는 여전히 미충족이고 다른 축이다.
|
|
24
|
+
|
|
25
|
+
### [3.4.0] — 2026-09-12 — 탈상관의 «강한 축» 을 기계로 옮긴다 (외부 실측 기인)
|
|
26
|
+
|
|
27
|
+
**BREAKING (gate):** 마커 두 자리가 조인다. 둘 다 **grace date 로 소급하지 않는다** — 그 날짜 이전
|
|
28
|
+
파일명의 마커는 종전대로다.
|
|
29
|
+
① `crossfamily: panel(<families>)` 는 이제 grounds 에 **`evidence=SHARED|INDEPENDENT|MIXED(...)`**
|
|
30
|
+
토큰을 요구한다(`EVIDENCE_TOKEN_GRACE_DATE=2026-09-12`). 처방 = 한 토큰 추가:
|
|
31
|
+
`crossfamily: panel(codex) — residency=CLEAN(files=3) · evidence=SHARED(same staged diff to both) · …`
|
|
32
|
+
② `standpoint:` 의 `tier2`/`tier2b`/`tier3` grounds 검사가 **advisory → 차단**
|
|
33
|
+
(`STANDPOINT_GROUNDS_GRACE_DATE=2026-09-12`). 처방 = 돌린 **명령과 본 출력을 명명**하거나,
|
|
34
|
+
실행을 안 했으면 정직하게 `tier1b`(grounds 미검사)로 내린다.
|
|
35
|
+
🟥 **소비자 install 도 같다** — 설치된 훅은 그 레포의 마커를 같은 기준으로 본다.
|
|
36
|
+
|
|
37
|
+
**왜 지금인가 — 근거가 내부 관찰에서 외부 실측으로 바뀌었다.** `arXiv:2609.10969`
|
|
38
|
+
(*Engineering Reliable Commit Gates for Agentic AI: Cost-Aware Verification Portfolios under
|
|
39
|
+
Common-Mode Data Failures*, 2026-09-10, cs.SE)이 탈상관 두 축을 **고정 호출예산 2×2**로 분리해
|
|
40
|
+
48 템플릿 · **2,880 시나리오**에서 쟀다: 「같은 증거를 읽는 교차-모델 투표」는 위험 제안의 **62.9 %**
|
|
41
|
+
를 승인하고 「독립 출처」는 **22.9 %** — 출처 효과 **40.9 %p** 대 모델 다양성 **11.3 %p**, **3.6 배**.
|
|
42
|
+
즉 FH 가 **하드 차단하던 축이 약한 쪽**이었고, 강한 쪽의 grounds 는 advisory 였다. 그 불균형을 뒤집는다.
|
|
43
|
+
|
|
44
|
+
**`SHARED` 는 합법이다.** 결함은 «같은 diff 를 읽은 패널» 이 틀렸다는 것이 아니라 그 사실이 **기록에
|
|
45
|
+
적힐 수 없었다**는 것 — 그런 런이 이 enum 의 가장 강한 값으로 남았다. 차단되는 것은: 어느 쪽인지 안
|
|
46
|
+
적은 `panel(...)` · 닫힌 셋 밖의 값 · 형식 위반/중복 토큰 · `SHARED`/`MIXED` 의 공허한 본문
|
|
47
|
+
(`INDEPENDENT` 는 자기서술적이라 본문 검사 없음 — 정직한 답을 과차단하면 override 를 훈련시킨다).
|
|
48
|
+
|
|
49
|
+
🟥 **막는 것은 «기록의 형태» 이고 «진위» 가 아니다.** 저자가 명령을 명명했는지는 기록의 속성이지만,
|
|
50
|
+
그 실행이 진짜였는지는 이 게이트가 보지 않는다 — §Mechanization Boundary 가 사람에게 남긴 의도된 잔여다.
|
|
51
|
+
|
|
52
|
+
**함께 — 도구 쪽 정직성 (`auto-decorrelation` Step 4.6 신설).** 🟥 **이 스킬의 기본형이 곧 약한 팔이다**:
|
|
53
|
+
Step 4 가 payload 하나를 만들어 팬아웃하므로 평범하게 돌린 패널은 구조적으로 62.9 % 팔이다. 그 사실을
|
|
54
|
+
스킬 본문에 적고, 토큰 값을 «의도가 아니라 실제 디스패치 형태로» 정하게 했다. **독립 출처 모드는 없다** —
|
|
55
|
+
비용 구조·residency 경계·«독립» 의 정의가 전부 미결이라 설계 문제로 이름만 남겼다
|
|
56
|
+
(`tracks/_meta/fh_signal_2026-09-12_independent-source-axis.md`, CHAMBER-CANDIDATE).
|
|
57
|
+
|
|
58
|
+
**frontier-digest — 목록 경로의 ID↔제목 짝짓기.** 429 폴백 경로에서 **위치로 짝지으면 안 된다**:
|
|
59
|
+
2026-09-12 실측에 목록이 **ID 51개 · 제목 50개**를 내서 두 병렬 추출이 중간부터 밀렸고, 그 뒤 짝은
|
|
60
|
+
**형식은 멀쩩한데 전부 틀렸다**(`2609.10550` 외 2건). 한 항목을 **한 단위로** 읽고, 그게 확인되기 전까지
|
|
61
|
+
**항목별 `abs/{id}` 재해소가 의무**이며 제목 불일치는 **버린다**. 훅은 없다(파싱이 세션 안에서 일어난다).
|
|
62
|
+
|
|
63
|
+
🟥 **이 게이트의 초판이 여섯 군데 틀렸고, 다른 계열이 그걸 찾았다 (자력 적발 0).**
|
|
64
|
+
같은 diff 를 `agy`(gemini-3.8-flash-high)에 보냈고 여섯 건 전부 **실행 프로브로 재현한 뒤** 고쳤다.
|
|
65
|
+
방향이 중요하다 — **넷은 과차단**이었다. 새 게이트가 advisory 가 아니라 차단이 된 순간, 과차단은
|
|
66
|
+
경고 한 줄이 아니라 `--no-verify` 를 훈련시키는 결함이 된다:
|
|
67
|
+
|
|
68
|
+
| # | 부류 | 초판 동작 | 수리 |
|
|
69
|
+
|:-:|---|---|---|
|
|
70
|
+
| ① | **과차단 S** | `evidence=MIXED(codex(diff), gemini(repo))` 의 본문이 안쪽 `)` 에서 잘려 «공허» 로 판정 → 정당한 기록 하드 차단 | 중첩 **한 겹** 허용(두 겹은 여전히 형식 위반) |
|
|
71
|
+
| ② | **fail-open S** | `evidence=INDEPENDENT()` 와 `INDEPENDENT(<what>)` 가 **통과** — «길이 미검사» 를 «본문 없어도 됨» 으로 접었다 | 빈 본문·자리표시자는 **세 값 모두** 차단, 길이 바만 SHARED/MIXED |
|
|
72
|
+
| ③ | **과차단 S** | `standpoint:` 키워드에 뒤따르는 공백이 박혀 `cargo check` · `python scripts/eval.py` · `ran: ./ci.sh` 가 전부 차단 | 경계를 비-알파벳으로 + 흔한 러너 추가 + `30/30`·`rc=`·`./path` 도 실행 증거로 |
|
|
73
|
+
| ④ | **fail-open S** | `EVIDENCE_TOKEN_GRACE_DATE` 미주입 시 grace 가 **조용히 꺼져** pre-grace 마커를 전부 차단 | 상수를 mdate 검사 **앞에서** `:?` 로 평가 → 크게 죽는다 |
|
|
74
|
+
| ⑤ | **fail-open A** | pre-grace 마커의 `evidence=PARTIAL(...)` 이 조용히 통과 | 부재는 면제, **오작성은 면제 아님**(residency 와 같은 약속) |
|
|
75
|
+
| ⑦ | **과차단 A** | `wc -w` 가 `same-diff` 도 `동일diff` 도 1 낱말로 세어 정당한 **한국어** 기록을 차단 | 길이 바를 **문자 수**로 |
|
|
76
|
+
|
|
77
|
+
⑥(가드 단축평가 — `[ -n "$mdate" ] && [ ... ${VAR:?} ]` 에서 mdate 가 비면 `:?` 가 **아예 안 돈다**)도
|
|
78
|
+
같이 고쳤다. 🟥 **가드가 있다고 적어두고 안 도는 것은 장식이다**(`[[feedback_anchor_can_be_decorative]]`).
|
|
79
|
+
|
|
80
|
+
**레인**: `test_marker_crossfamily_lanes.sh` **82 픽스처**(신규 `e1`–`e15`, 위 여섯 건이 각각 컨트롤과 짝) ·
|
|
81
|
+
`test_marker_standpoint_lanes.sh` `N8`~`N8i`. 되돌림 프로브 두 종 — evidence 요구를 떼면
|
|
82
|
+
**정확히 6개**(e1·e5·e6·e7·e8·e8c)만 적색, standpoint 차단을 떼면 **N8 하나만** 적색.
|
|
83
|
+
🟥 두 레인 러너가 새 grace 상수를 주입하지 않으면 기존 픽스처가 통째로 오판하는 자리였다(standpoint 쪽은
|
|
84
|
+
실제로 깨졌다) — 러너에 주입을 넣고, 훅에는 `:?` 가드를 박아 부분 추출이 **조용히 통과하지 않게** 했다.
|
|
85
|
+
|
|
86
|
+
### [3.3.0] — 2026-09-12 — 짝지음(paired) 측정: 한 round-1 을 두 분기가 나눠 먹는다
|
|
87
|
+
|
|
88
|
+
**① 새 자산 — `--r1-only` · `--reuse-r1 <dir>` (`finding_fleet.sh` · `finding_pipeline.sh`).**
|
|
89
|
+
round-1 을 **한 번** 돌려 두고, 그 **같은** round-1 에서 round-2 를 두 번 갈라 돌린다
|
|
90
|
+
(`--reuse-r1 <dir> --round2` / `--round2-blind`). 왜 필요했나: «round-2 에서 상대 계열의 목록을
|
|
91
|
+
보여주는가» 를 A/B 하려고 두 팔을 독립 실행했더니 **round-1 기저부터 달랐다**(146 vs 136, 7.4 %) —
|
|
92
|
+
즉 한 변수 비교가 아니었다. 이 플래그들은 그 교란을 설득이 아니라 **설계**로 없앤다.
|
|
93
|
+
부수 효과로 더 싸다 — round-1 을 두 번 돌리지 않는다(멤버콜 −25 %).
|
|
94
|
+
|
|
95
|
+
기계 보증(레인 `test_finding_pipeline_lanes.sh` L115~L124, 122 → **132**):
|
|
96
|
+
두 분기의 `findings_r1.jsonl` 이 공유 소스와 **바이트 동일** · 파이프라인이 r1 **sha256** 을 두 분기
|
|
97
|
+
로그에 찍어 사후 대조 가능 · **빈 r1 재사용 거부**(미측정을 0 으로 렌더하지 않는다) · 옛 round-2
|
|
98
|
+
잔재 제거 · 소스==out 거부 · `--reuse-r1` 단독 거부 · `--r1-only` 은 검증을 안 돌리므로 **씨앗 선언을
|
|
99
|
+
거부**한다(선언된 컨트롤이 돈 적 없이 «통과» 로 읽히는 것을 막는다).
|
|
100
|
+
|
|
101
|
+
**② fail-open 수리 (`--r1-only`, cross-family 적발).** `--r1-only` 이 **빈 round-1 을 «사용 가능»
|
|
102
|
+
으로 통과**시켰다. 기전: `grep -c . f || echo 0` 은 빈 파일에서 «`0` 을 찍고 rc=1» 이라 폴백이 줄을
|
|
103
|
+
하나 더 붙여 `_n1="0\n0"` 이 되고, `[ "$_n1" -eq 0 ]` 이 **구문오류로 거짓**이 되어 `R1_UNUSABLE`
|
|
104
|
+
분기를 건너뛴다. ⚠️ **새 경로라 종전 동작 변화는 없다** — 기존 팔(플래그 미사용)의 경로는 불변이고
|
|
105
|
+
레인 122개가 그대로 통과한다. 질문은 «폴백을 붙였나» 가 아니라 **«실패 시 stdout 이 비는가»** 다.
|
|
106
|
+
|
|
107
|
+
**③ 출하 누락 수리 — `plugins/fh-commons/README.md` 를 `files[]` 에 명시.** npm 11 은 중첩 README 를
|
|
108
|
+
암묵 포함했는데 **npm 12 는 뺀다**(실측: `npx npm@latest pack --dry-run` 에서 0건). 발행 경로가
|
|
109
|
+
npm@latest 이므로 그대로 두면 3.2.0 에서 이미 빠져 나갔을 파일이다.
|
|
110
|
+
|
|
111
|
+
**자릿수 근거**: 새 capability **instance** 가 아니라 새 플래그 둘 + 레인 10 + 출하 파일 1 —
|
|
112
|
+
§Version-Digit-Policy 의 minor(새 자산 · 새 게이트 레인)다. **`BREAKING (gate):` 없음** — 소비자의
|
|
113
|
+
게이트 수용을 깨지 않는다(새 플래그는 opt-in, 기존 호출 경로 불변).
|
|
114
|
+
|
|
115
|
+
**④ harness-pr-reviewer (개명 + Axis 2·3 의무 배선) — 이 릴리스가 싣는다.**
|
|
116
|
+
- **RENAME** `hub-cc-pr-reviewer` → `harness-pr-reviewer` (운영자 결정 2026-09-12): 실제 쓰임이 «현장 하네스가 자기 PR 을 FH 리뷰 능력으로 검증하는 standalone 창구» 라서. 옛 이름 발화·참조는 그대로 라우팅(별칭), 리다이렉트 스텁 없음(phantom-quench 선례).
|
|
117
|
+
- Step 3.5 «Axis 2·3 의무 디스패치 레인» — 트리거 3항(8-matrix ❌ · load-bearing 경로 grep · 머지 권고 요청)을 PR 에서 계산, Axis 2 = auto-decorrelation 재사용 + `crossfamily:` 닫힌 enum, Axis 3 = phantom-quench(N/A 는 `--name-only` 로), 판정형 질문 reps≥3. Self-Catch 는 «판정이 아니라 cue». 플로어 sim: 현행 0/3 → 수정 3/3 (pmh-dev #77).
|
|
118
|
+
|
|
119
|
+
**⑤ `gate_shape_scan.sh` 여러 줄 docstring 안쪽 오탐 수리 + 판정형 질문 reps≥3 교리** (pmh-dev #76 역수확, #699): `"""`/`'''` 짝 상태를 추적해 docstring 내부를 판정 어휘 스캔에서 뺀다(selftest 8 → 10, 레인 9 → 11, L8b 되돌림 프로브 포함).
|
|
3
120
|
### [3.2.0] — 2026-09-09 — 판정 파이프라인이 실제로 돌고, 축에 이름이 붙었다
|
|
4
121
|
|
|
5
122
|
**BREAKING (gate):** `scripts/**/*.py` 가 이제 HEAVY 다 — 마커 없는 파이썬 단독 커밋이 막힌다.
|
|
@@ -172,7 +172,7 @@ Default composition table by task type.
|
|
|
172
172
|
| Plugin recommendation | plugin-recommender (S) | — |
|
|
173
173
|
| Install conflict diagnosis | install-doctor (S) | — |
|
|
174
174
|
| Onboarding install | install-wizard (S) — ⚠️ interactive; `--dry-run` for bg parallel | — |
|
|
175
|
-
| Hub PR review |
|
|
175
|
+
| Hub PR review | harness-pr-reviewer (S) — requires PR number first | — |
|
|
176
176
|
| **Decision-maker approval review** | apex-review (S) — CTO/tech lead/QA lead personas + HTML deck | — |
|
|
177
177
|
| **Project local skills** | LOCAL_SKILL_REGISTRY lookup → relevant project skill (A/S) | Per project |
|
|
178
178
|
|
|
@@ -360,7 +360,7 @@ After fan-in report, evaluate conditions and auto-suggest the next Wave:
|
|
|
360
360
|
|
|
361
361
|
| Condition | Wave suggestion |
|
|
362
362
|
|---|---|
|
|
363
|
-
| ① M-tier > 0 | **Wave next-M**: fact-checker (A) →
|
|
363
|
+
| ① M-tier > 0 | **Wave next-M**: fact-checker (A) → harness-pr-reviewer (S) |
|
|
364
364
|
| ② persona-innovator naming candidates > 0 | **Wave next-I**: delegate to user + asset-placement-gate (S) |
|
|
365
365
|
| ③ External absorption signal High > 0 | **Wave next-E**: persona-innovator Mode E (A) + meta-prompt-builder (S) |
|
|
366
366
|
| ⑤ Design conflict / 2+ conflicting suggestions | **Wave next-D**: deliberation (S) — verdict folds back into Step 4-b |
|
|
@@ -229,6 +229,46 @@ format-checked `residency=(CLEAN|TAINTED|NOT_SCANNED)(...)` token on `DEGRADED_*
|
|
|
229
229
|
`declined`. Fixtures: `scripts/test_marker_crossfamily_lanes.sh` (`r1`–`r13`). This is the SAME
|
|
230
230
|
typed field Step 6 already emits into — one channel, not a second marker line.
|
|
231
231
|
|
|
232
|
+
## Step 4.6 — `evidence=` : say WHAT the panel received (mandatory with `panel(...)`, 2026-09-12)
|
|
233
|
+
|
|
234
|
+
`residency=` says the payload was safe to send. `evidence=` says **what was sent** — and that is the
|
|
235
|
+
axis the outside world just measured as the dominant one. `arXiv:2609.10969` (48 task templates →
|
|
236
|
+
2,880 scenarios, **fixed call budget** so the comparison is about the axis and not about spending
|
|
237
|
+
more): a cross-model vote over **shared** evidence approved **62.9 %** of unsafe proposals against
|
|
238
|
+
**22.9 %** with an **independent source** — source effect **40.9 pp** vs **11.3 pp** for model
|
|
239
|
+
diversity, i.e. **3.6×**.
|
|
240
|
+
|
|
241
|
+
Decide it from **how this run actually dispatched**, not from intent:
|
|
242
|
+
|
|
243
|
+
| What happened | Token |
|
|
244
|
+
|---|---|
|
|
245
|
+
| Every member got the **same** payload (one prompt file / one diff fanned out) | `evidence=SHARED(<name the artifact>)` |
|
|
246
|
+
| Each member produced its **own** evidence — own checkout, own run, own extraction | `evidence=INDEPENDENT(<what each got>)` |
|
|
247
|
+
| Some of each | `evidence=MIXED(<which member got which>)` |
|
|
248
|
+
|
|
249
|
+
🟥 **This skill's default flow is `SHARED`, by construction.** Step 4 builds **one** payload and fans
|
|
250
|
+
it out, so a panel dispatched the ordinary way through this skill is the **62.9 % arm** — the axis it
|
|
251
|
+
raises is model family, which the paper prices at 11.3 pp. That is not a reason to stop using it: a
|
|
252
|
+
finder is worth its recall, and this skill's value was never precision
|
|
253
|
+
(`[[feedback_decorrelation_is_a_cheap_finder]]`). It **is** a reason to stop recording that run as if
|
|
254
|
+
it carried the stronger axis. Write `SHARED` and mean it.
|
|
255
|
+
|
|
256
|
+
🟢 **`SHARED` is a legal, expected answer.** The hook does not block it; it blocks a `panel(...)` that
|
|
257
|
+
does not say which it was, a value outside the closed three, a malformed or duplicated token, and a
|
|
258
|
+
**vacuous body** on `SHARED`/`MIXED` (name the artifact — *"same staged diff"*, *"one findings.jsonl"*,
|
|
259
|
+
*"identical prompt file"*). `INDEPENDENT` is self-describing and is not body-checked, deliberately:
|
|
260
|
+
over-blocking the honest strong answer would train the override.
|
|
261
|
+
|
|
262
|
+
**Where it lands**: the same grounds line as `residency=`, in the same `crossfamily:` field —
|
|
263
|
+
`crossfamily: panel(codex) — residency=CLEAN(files=3) · evidence=SHARED(same staged diff to both) · R1, 3 findings`.
|
|
264
|
+
Hook: `validate_crossfamily_leg` (grace `EVIDENCE_TOKEN_GRACE_DATE`, no retroactivity).
|
|
265
|
+
Fixtures: `scripts/test_marker_crossfamily_lanes.sh` `e1`–`e10`.
|
|
266
|
+
|
|
267
|
+
⚠️ **Named gap, not built today**: this skill has **no independent-source mode**. Giving it one
|
|
268
|
+
(each member reconstructs the evidence itself rather than reading the author's payload) is the change
|
|
269
|
+
that would move it onto the 40.9 pp axis; it is a design question, not a wiring one, and it is
|
|
270
|
+
recorded as a signal rather than improvised here.
|
|
271
|
+
|
|
232
272
|
🟥 **A stripped file is invisible to the reviewer, and a reviewer's default read of invisible is
|
|
233
273
|
"absent," not "redacted"** (governor dogfood, 2026-09-05, same-day live use of this Step): two
|
|
234
274
|
TAINTED files were stripped from a real payload and the CLEAN remainder sent cross-family — the
|
|
@@ -215,7 +215,7 @@ Present Step 4 menu options [1]–[5]. Do not skip to [5] silently — surface t
|
|
|
215
215
|
## Simplification Guards
|
|
216
216
|
|
|
217
217
|
- Video Tier-3 probe fails (any of `yt-dlp` / `curl_cffi` / `ffmpeg` missing, or timedtext returns 429) → fall through to operator summary; never assume `yt-dlp` works
|
|
218
|
-
-
|
|
218
|
+
- 🟢 **arxiv transport, inverted 2026-09-12 (operator decision, condition met: 429 on 09-09·10·11·12)**: the **date-sorted `arxiv.org/list/cs.SE/recent` listing is PRIMARY**; the export API is the **fallback**; HN-only only if both fail. Same sort axis (submission date) is why the listing is promotable and WebSearch is not. 🟥 Cost of the promotion, not an oversight: the listing's ID↔title pairing is the weaker instrument, so **per-item `abs/{id}` re-resolution is now a PRIMARY-path requirement** and the progress line must name which transport produced the items. Never substitute WebSearch (recall channel, 5/5 REPEATs measured 2026-09-04); report `arxiv FAILED (429)`, never `0 items`. 🟥 **On the listing path, pair ID↔title INSIDE one list entry, never by zipping two ordered lists — measured 2026-09-12: 51 IDs vs 50 titles, so pairs drift partway down and mispair while looking well-formed (3 items caught, 0 shipped). Until that is what happened, per-item `abs/{id}` re-resolution is MANDATORY and a title mismatch DROPS the item.** Detail: `SKILL_detail.md §Execution form`
|
|
219
219
|
- On curl timeout, skip that item and continue with the rest
|
|
220
220
|
- If synthesis result exceeds 400 characters, retain top 3 items and truncate the rest
|
|
221
221
|
- Without `--save`, do not create files (conversation output only)
|
|
@@ -28,14 +28,52 @@ load: on-demand
|
|
|
28
28
|
> fell back to **WebSearch**, and the 09-04 run measured what that does: 5/5 papers it returned were
|
|
29
29
|
> REPEATs. Search sorts by *canonicity*, the export API by *submission date* — a search fallback is
|
|
30
30
|
> a **recall channel, not a discovery channel**, and swapping it in silently converts «unrun» into
|
|
31
|
-
> «nothing new» (`not found ≠ 0`).
|
|
32
|
-
>
|
|
33
|
-
>
|
|
31
|
+
> «nothing new» (`not found ≠ 0`).
|
|
32
|
+
>
|
|
33
|
+
> 🟢 **TRANSPORT ORDER INVERTED 2026-09-12 (operator decision) — the listing is now PRIMARY.**
|
|
34
|
+
> Condition stated by the operator was *«if the errors keep coming»*, and they did, measurably:
|
|
35
|
+
> `429` appears in the digest record on **09-09 · 09-10 · 09-11 · 09-12 — four consecutive days**,
|
|
36
|
+
> past the `N≥3` bar twice over. Paying two failed calls plus a backoff every single day to reach
|
|
37
|
+
> items that the listing reaches anyway is not a fallback, it is a toll. New order:
|
|
38
|
+
> 1. **PRIMARY — WebFetch the date-sorted HTML listing** `https://arxiv.org/list/cs.SE/recent`
|
|
34
39
|
> (and `https://arxiv.org/list/cs.AI/recent` if the first is empty of agent/harness items), keep
|
|
35
|
-
> items whose title/abstract match the three query phrases, cap 6
|
|
36
|
-
>
|
|
40
|
+
> items whose title/abstract match the three query phrases, cap 6. **Same sort axis as the API**
|
|
41
|
+
> (submission date) — that property is *why* this one is promotable and WebSearch is not.
|
|
42
|
+
> 2. **FALLBACK — the export API query** (back off ≥30s between attempts). Kept on the ladder on
|
|
43
|
+
> purpose: if arXiv redesigns the listing markup, the channel must not disappear with it.
|
|
44
|
+
> 3. only if both fail → HN-only, and the progress line says `arxiv FAILED (<which transports, why>)`,
|
|
45
|
+
> never `0 items`.
|
|
46
|
+
>
|
|
47
|
+
> 🟥 **What this costs, stated rather than discovered later.** The listing path has the **weaker
|
|
48
|
+
> instrument** — its ID↔title pairing is the defect documented immediately below, and promoting it
|
|
49
|
+
> moves that defect from the fallback onto the **main** path. Therefore the two rules below are no
|
|
50
|
+
> longer conditional-on-being-in-fallback: **per-item `abs/{id}` re-resolution is a PRIMARY-path
|
|
51
|
+
> requirement**, one fetch per shipped ID, and a title mismatch drops the item. That is a real
|
|
52
|
+
> per-run cost increase (≈N extra fetches for N shipped items) and it is the price of the promotion,
|
|
53
|
+
> not an oversight. The old order paid 2 failed calls + a backoff instead; this pays N verified reads.
|
|
54
|
+
> 🟥 The progress line must now name **which transport produced the items** (`arxiv via listing` /
|
|
55
|
+
> `arxiv via export-api`) — otherwise a reader cannot tell which instrument's limits apply to the run.
|
|
37
56
|
> 🟥 WebSearch is **not** on this ladder. If a run used it anyway, the arxiv leg is reported as
|
|
38
57
|
> `RECALL-ONLY (WebSearch)` and its items are excluded from the NEW/REPEAT count.
|
|
58
|
+
>
|
|
59
|
+
> 🟥 **On the listing path, do NOT pair ID and title by position — pair them inside one block
|
|
60
|
+
> (measured 2026-09-12, this runner, and it is the phantom class this skill already has on record).**
|
|
61
|
+
> The listing yielded **51 IDs and 50 titles**, so two parallel extractions drift partway down and
|
|
62
|
+
> every pair after the drift point is wrong *while looking well-formed*. Concretely measured that run:
|
|
63
|
+
> `2609.10550` was attached to *"When Passing Tests Hides Vulnerabilities"* by the positional parse,
|
|
64
|
+
> but its own `abs` page is *"Optimizing AI Inference Across the Deployment Stack"* (2026-07-01);
|
|
65
|
+
> `2609.11060` and `2609.11008` mispaired the same way. 3 items dropped, 7 verified, **0 shipped
|
|
66
|
+
> unverified** — it was caught only because every shipped ID was re-resolved.
|
|
67
|
+
> **Two rules, and the second is the floor:**
|
|
68
|
+
> ① read each entry as **one unit** (the ID and the title that sit in the *same* list item), never as
|
|
69
|
+
> two ordered lists zipped together. A count mismatch between the lists is not a warning to
|
|
70
|
+
> reconcile — it is proof the zip is already wrong.
|
|
71
|
+
> ② until ① is demonstrably what happened, **per-item `abs/{id}` re-resolution is MANDATORY on this
|
|
72
|
+
> path**, not optional — one fetch per shipped ID, confirming the title. Any ID whose `abs` title
|
|
73
|
+
> disagrees is **dropped**, never shipped with a note.
|
|
74
|
+
> ⚠️ There is no hook here and none is possible: the parse happens inside the session that read the
|
|
75
|
+
> page, so this is salience over a manual floor. The floor that actually held on 2026-09-12 was ② —
|
|
76
|
+
> keep it even after ① looks solved (`[[feedback_anchor_can_be_decorative]]`).
|
|
39
77
|
|
|
40
78
|
### HackerNews (Algolia API)
|
|
41
79
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
name:
|
|
2
|
+
name: harness-pr-reviewer
|
|
3
3
|
description: Checks a submitted PR against the environment's baseline assets (CLAUDE.md, memory, naming, asset classification) and attaches a review comment with a merge recommendation. 5 steps — diff read, 8-area consistency check, self-catch, comment, merge recommendation.
|
|
4
4
|
user-invocable: true
|
|
5
5
|
allowed-tools: ["Bash", "Read", "Grep", "Glob"]
|
|
@@ -15,13 +15,21 @@ complexity_routing:
|
|
|
15
15
|
|
|
16
16
|
> **Note:** The original developer is the forge-harness original developer (development source + meta-monitoring home). In external user install environments, the install environment user themselves is the baseline integrity gate operator (following path B generalization baseline / `SKILL_detail.md §External User Environment Adaptation Path` §).
|
|
17
17
|
|
|
18
|
-
#
|
|
18
|
+
# harness-pr-reviewer — Hub Gate Operation Rule Automation
|
|
19
19
|
|
|
20
20
|
When a PR is submitted, checks consistency against the user environment's baseline assets (CLAUDE.md · memory · naming · asset classification) and attaches a review comment. 5-step: diff read → 8-matrix check → self-catch → comment attachment → merge recommendation.
|
|
21
21
|
|
|
22
22
|
## Activation Triggers
|
|
23
23
|
|
|
24
|
-
|
|
24
|
+
> **Renamed from `hub-cc-pr-reviewer` (2026-09-12, operator decision).** The old name said where it
|
|
25
|
+
> was born (the hub's own cc reviewing its own PRs). What it actually is — measured on qasp/pmh PRs in
|
|
26
|
+
> 2026-09 — is the **standalone doorway through which a field harness verifies its own submitted PR
|
|
27
|
+
> with FH's review capability**. Old-name utterances ("hub-cc-pr-reviewer", "hub review", "hub cc
|
|
28
|
+
> review") still route here; downstream forks that carry the old directory name (PMH) keep working
|
|
29
|
+
> until they sync. No redirect stub directory is shipped (same policy as `phantom-quench`).
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
1. **PR #N input**: *"Review PR #N"* / *"Check PR #N"* / *"hub review"* (old-name alias) / *"harness PR review"* / *"baseline consistency check"*
|
|
25
33
|
2. **Action leader cc → hub sync point**: Large decision area PR catch (following Option C Hybrid policy — memory creation / CLAUDE.md change / CATALOG round / skill v0.x evolution / policy change / asset synergy branch judgment)
|
|
26
34
|
3. **Hub cc session entry**: Layer A auto-read recent external commit catch (auto-discover new PRs)
|
|
27
35
|
|
|
@@ -75,6 +83,54 @@ Self-precision catch areas after first cc review (following previous PR self-cat
|
|
|
75
83
|
|
|
76
84
|
Self-catch areas 0 items = skip this entire catch matrix — do not pad with token-filling to make the section look populated.
|
|
77
85
|
|
|
86
|
+
🟥 **Self-catch is a CUE, not a verdict.** Its output is the *input* to Step 3.5 below. A self-catch
|
|
87
|
+
that finds nothing does not clear Axis 2 or Axis 3 — measured 2026-09-08/11: a reviewer session with
|
|
88
|
+
no external cue ran the load-bearing gate **0/51**, and a PMH session reviewing qasp PR #13 dispatched
|
|
89
|
+
the cross-family panel only after the operator pushed (pmh-dev #77). The self-check *is* the reviewer;
|
|
90
|
+
it cannot be its own decorrelation.
|
|
91
|
+
|
|
92
|
+
### Step 3.5. Axis 2 · Axis 3 — mandatory dispatch lane (mechanical trigger, typed degrade)
|
|
93
|
+
|
|
94
|
+
Axis 1 above is wired at mandatory strength (`--pr` mode, typed verdict). Until 2026-09-12 Axis 2
|
|
95
|
+
(adversarial panel) and Axis 3 (phantom-quench) had **no dispatch block in this skill at all** — only
|
|
96
|
+
the self-catch matrix — so they fired only when someone said so. This step closes that with a trigger
|
|
97
|
+
that is decided from the PR, never from the reviewer's feel.
|
|
98
|
+
|
|
99
|
+
**Trigger — mandatory if ANY of these holds** (compute all three; record which fired):
|
|
100
|
+
|
|
101
|
+
```
|
|
102
|
+
(i) Step 2 matrix has ≥1 ❌ (Inconsistent)
|
|
103
|
+
(ii) the PR touches a load-bearing FH asset: SKILL.md · SKILL_detail.md · .claude/rules/*.md ·
|
|
104
|
+
knowledge/shared/rules/*.md · templates/** · scripts/**/*.sh · scripts/**/*.py ·
|
|
105
|
+
plugins/*/agents/** (same list as CLAUDE.md §FH Improvement 4-Axis Auto-Gate)
|
|
106
|
+
→ gh pr diff "$PR" --name-only | grep -E '(^|/)SKILL(_detail)?\.md$|^\.claude/rules/|^knowledge/shared/rules/|^templates/|^scripts/.*\.(sh|py)$|^plugins/[^/]+/agents/'
|
|
107
|
+
(iii) a merge recommendation (Step 5) will be issued for this PR
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
None of the three → record `axis2: not-triggered(reason)` · `axis3: not-triggered(reason)` in the
|
|
111
|
+
comment capsule and continue. This is the *only* non-run path, and it is stated, never silent.
|
|
112
|
+
|
|
113
|
+
**Axis 2 — cross-family adversarial panel.** Dispatch **`auto-decorrelation`** on the PR diff (reuse,
|
|
114
|
+
not a new engine — its Step 1 load-bearing predicate, Step 4.5 residency screen and Step 6 degrade
|
|
115
|
+
ladder all apply unchanged). What this step owns is only the *decision to dispatch*. The result lands
|
|
116
|
+
as the typed `crossfamily:` value: `panel(<families>)` with the source-grounded findings, or one of
|
|
117
|
+
`declined` · `DEGRADED_SINGLE_FAMILY` · `DEGRADED_PANEL_UNUSED` · `UNKNOWN` **with grounds** — e.g.
|
|
118
|
+
consent OFF, no different-family sidecar reachable, quota exhausted. A degrade value is allowed; an
|
|
119
|
+
*absent* value is not. 🟥 A judgment-type question put to the panel (by-design vs fail-open, is this
|
|
120
|
+
a regression) needs **reps ≥ 3**; a 1-of-3 split is recorded as *unresolved*, never as CONCUR
|
|
121
|
+
(`field_verdict_crossfamily_gate.md` §4-2).
|
|
122
|
+
|
|
123
|
+
**Axis 3 — phantom-quench.** Run `/phantom-quench` over the PR's changed documentation surfaces
|
|
124
|
+
(any `*.md` in the diff, plus every path/citation the PR body asserts). Mechanical N/A only when
|
|
125
|
+
`gh pr diff --name-only` has zero `*.md` files **and** the PR body cites no path — record
|
|
126
|
+
`axis3: N/A(no doc surface)`. A phantom finding is a ❌ in the comment capsule, and it flips the Step 5
|
|
127
|
+
recommendation the same way an Axis 1 M-tier block does.
|
|
128
|
+
|
|
129
|
+
**Degrade direction.** This is a review surface (reversible): tooling-down does not block the
|
|
130
|
+
*comment*, but the merge recommendation must carry the degrade value verbatim and read
|
|
131
|
+
**NOT-CONVERGED** while Axis 2 is a `DEGRADED_*`/`UNKNOWN` value on a load-bearing PR. Silent
|
|
132
|
+
same-family pass is the one outcome this step forbids.
|
|
133
|
+
|
|
78
134
|
### Step 4. Review Comment Attachment
|
|
79
135
|
|
|
80
136
|
**Mandatory before any `gh pr comment`: run `/public-surface-audit` over the composed comment text.**
|
|
@@ -176,6 +232,22 @@ All 5 Steps completed
|
|
|
176
232
|
passes; they mean Axis 1 did not examine this PR and the recommendation
|
|
177
233
|
may not cite it as green
|
|
178
234
|
|
|
235
|
+
+ Step 3.5 trigger computed from the PR (matrix ❌ count · load-bearing path
|
|
236
|
+
grep · merge-recommendation requested) and recorded with which clause fired
|
|
237
|
+
— measured: the three booleans appear in the comment capsule. Absent = the
|
|
238
|
+
step did not run, which is the pre-2026-09-12 defect (pmh-dev #77)
|
|
239
|
+
|
|
240
|
+
+ Axis 2 dispatched via auto-decorrelation when triggered, landing a typed
|
|
241
|
+
`crossfamily:` value (panel(...) or a DEGRADED_*/UNKNOWN value WITH grounds)
|
|
242
|
+
— mandatory-pass: the value exists and is one of the closed enum. A
|
|
243
|
+
load-bearing PR whose value is DEGRADED_*/UNKNOWN leaves the merge
|
|
244
|
+
recommendation NOT-CONVERGED; judgment-type panel questions carry reps ≥ 3
|
|
245
|
+
or are recorded unresolved
|
|
246
|
+
|
|
247
|
+
+ Axis 3 phantom-quench run over the PR's doc surfaces when triggered, or
|
|
248
|
+
N/A(no doc surface) decided by `--name-only` grep, never by feel
|
|
249
|
+
— mandatory-pass: a phantom finding is a ❌ that flips the recommendation
|
|
250
|
+
|
|
179
251
|
+ /public-surface-audit run over the composed comment text BEFORE any
|
|
180
252
|
gh pr comment
|
|
181
253
|
— mandatory-pass, fail-closed: CLEAN attaches; REVIEW/LEAK redact-and-rescan;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
|
-
name:
|
|
3
|
-
description: On-demand detail for
|
|
2
|
+
name: harness-pr-reviewer-detail
|
|
3
|
+
description: On-demand detail for harness-pr-reviewer — step bash commands, comment template, sister-asset utilization, external-environment adaptation, disable path, and persona synergy handling. Read when executing a step or operating in an external/own-PRS/deep-insight environment.
|
|
4
4
|
load: on-demand
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -35,7 +35,7 @@ Meaning of isolation: The Critic reads the synthesizer conclusion but does not i
|
|
|
35
35
|
- FAIL after re-synthesis → auto-persist as `fh_signal` on hold (no additional retries)
|
|
36
36
|
- Maximum retries: **1**
|
|
37
37
|
|
|
38
|
-
**Post-Core-Skill Critic Verdict Connection**: Following core skills can have Critic called inline after completion: harness-doctor · verify-bidirectional ·
|
|
38
|
+
**Post-Core-Skill Critic Verdict Connection**: Following core skills can have Critic called inline after completion: harness-doctor · verify-bidirectional · harness-pr-reviewer · context-doctor · sim-conductor. Trigger: immediately after completion announcement + "steel-quench" / "re-validate" / "run Critic" utterance.
|
|
39
39
|
|
|
40
40
|
---
|
|
41
41
|
|
|
@@ -150,7 +150,7 @@ grep -rl "complexity_routing" plugins/*/skills/*/SKILL.md
|
|
|
150
150
|
|
|
151
151
|
# 2. Aggregate escalation records from fh_signal files
|
|
152
152
|
grep -rh "" tracks/_meta/fh_signal_*.md 2>/dev/null | \
|
|
153
|
-
grep -oE "(harness-doctor|verify-bidirectional|
|
|
153
|
+
grep -oE "(harness-doctor|verify-bidirectional|harness-pr-reviewer|context-doctor|sim-conductor|agent-composer|harvest-loop|steel-quench)" | \
|
|
154
154
|
sort | uniq -c | sort -rn
|
|
155
155
|
```
|
|
156
156
|
|
|
@@ -169,7 +169,7 @@ grep -i -n "pr\|pull request\|audit\|review\|weekly" CLAUDE.md 2>/dev/null | hea
|
|
|
169
169
|
```
|
|
170
170
|
|
|
171
171
|
Judgment:
|
|
172
|
-
- Existing PR convention present → possible priority conflict with `
|
|
172
|
+
- Existing PR convention present → possible priority conflict with `harness-pr-reviewer` ⚠️
|
|
173
173
|
- Existing weekly audit present → possible format conflict with `harvest-loop` ⚠️
|
|
174
174
|
|
|
175
175
|
### 2-2. Skill Trigger Conflicts
|
|
@@ -322,7 +322,7 @@ Only activate the cluster matching the utterance — loading all skills degrades
|
|
|
322
322
|
| **A — Harvest/Evolution** | harvest · session wrap-up · pattern · reverse absorption · fh evolution | field-harvest · harvest-loop · contention-layer · verify-bidirectional |
|
|
323
323
|
| **B — Diagnosis (doctor)** | diagnose · health · check · inspect · token waste · install conflict · doctor | harness-doctor · context-doctor · sim-conductor · install-doctor · install-wizard |
|
|
324
324
|
| **C — Compose (composer)** | agent composition · parallel · compose prompt · context card | agent-composer · meta-prompt-builder |
|
|
325
|
-
| **D — Audit/Review** | review · audit · PR review · steel quench · adversarial · lint · placement |
|
|
325
|
+
| **D — Audit/Review** | review · audit · PR review · steel quench · adversarial · lint · placement | harness-pr-reviewer · steel-quench · apex-review · harness-doctor (--lint) · marketplace-gate · asset-placement-gate |
|
|
326
326
|
| **E — Explore/Frontier** | trends · plugin recommendation · synergy · frontier | frontier-digest · plugin-recommender · cross-ecosystem-synergy-detection |
|
|
327
327
|
| **F — Common (always-on)** | — | convergence-loop · deliberation (fh-commons) |
|
|
328
328
|
|
|
@@ -53,7 +53,7 @@ When Goal is provided in natural language (e.g., "I need to report to the team l
|
|
|
53
53
|
| "analyze", "diagnose", "something seems off" | harness-doctor → context-doctor | Structural + contextual diagnosis simultaneously |
|
|
54
54
|
| "simulate", "validate", "meta" | sim-conductor (D-code or Area B) | Multi-perspective validation |
|
|
55
55
|
| "install", "setup", "onboarding" | plugin-recommender → install-wizard | Recommend then install |
|
|
56
|
-
| "review", "code check" | sim-conductor D-code →
|
|
56
|
+
| "review", "code check" | sim-conductor D-code → harness-pr-reviewer | Code review chain |
|
|
57
57
|
|
|
58
58
|
Output format:
|
|
59
59
|
```
|
|
@@ -246,7 +246,7 @@ Resume is scope-bound — the scope from Step 0 is preserved across resume calls
|
|
|
246
246
|
After a `CLEAN (--full)` or `PENDING` sweep, the following are natural follow-ons:
|
|
247
247
|
|
|
248
248
|
- `field-harvest` — harvest patterns surfaced during the sweep
|
|
249
|
-
- `
|
|
249
|
+
- `harness-pr-reviewer` — if sweep was run pre-PR, feed results into PR review
|
|
250
250
|
- `agent-composer` — if multiple fix tasks are needed across the Pending list, compose agents to resolve them in parallel
|
|
251
251
|
- `return-path-gate --all` — if Step 0.5 surfaced OPEN chains, run a full chain closure audit
|
|
252
252
|
|
|
@@ -98,7 +98,7 @@ When queried for a specific capability (e.g., "adversarial reviewer for bash cod
|
|
|
98
98
|
⚠️ **A failed or empty discovery lane is NOT "no candidates".** Both CLIs above list only *configured* marketplaces, and a non-zero exit / empty array means the lane did not answer — not that nothing exists. Report each lane's state explicitly (`EXECUTED` / `EMPTY` / `FAILED: <stderr>`) and never render a `FAILED` lane as a zero result; a lane that could not run must be re-run or replaced by the web-search fallback (Priority 3) before you tell the user nothing was found.
|
|
99
99
|
|
|
100
100
|
**Discovery priority**: built-in (Tier 0) > installed > FH native > Tier 1 (any platform) > Tier 2 > Tier 3 > Tier 4
|
|
101
|
-
**Tier 0 guard**: FH native wins over a built-in only when the FH skill adds governance the built-in lacks (e.g. `/goal` → `goal-quench` adds budget+quality gates; code diff review stays with built-in `/code-review`, FH-asset coherence with `
|
|
101
|
+
**Tier 0 guard**: FH native wins over a built-in only when the FH skill adds governance the built-in lacks (e.g. `/goal` → `goal-quench` adds budget+quality gates; code diff review stays with built-in `/code-review`, FH-asset coherence with `harness-pr-reviewer`)
|
|
102
102
|
|
|
103
103
|
**When sim-conductor chains here for persona discovery**: apply the same platform-aware search scoped to persona/simulation/review capability tags. Return discovered agents with their Tier rating so sim-conductor can decide whether to install or use a built-in brief.
|
|
104
104
|
|
|
@@ -542,7 +542,7 @@ Verdicts: PASS · CONDITIONAL_PASS (S/R only, or Area B cadence skip) · FAIL (M
|
|
|
542
542
|
|
|
543
543
|
## Operations Notes
|
|
544
544
|
|
|
545
|
-
**AI-AI Loop Bias Defense**: sim-conductor →
|
|
545
|
+
**AI-AI Loop Bias Defense**: sim-conductor → harness-pr-reviewer → sim-conductor loop shares LLM cognitive blind spots. Internal convergence is "provisional convergence" — elevated only by external review or human gate. Area A/B convergence without human gate = incomplete.
|
|
546
546
|
|
|
547
547
|
---
|
|
548
548
|
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "fh-preprep",
|
|
3
|
+
"version": "3.5.0",
|
|
4
|
+
"engines": {
|
|
5
|
+
"claudeCode": ">=1.0.0"
|
|
6
|
+
},
|
|
7
|
+
"description": "preprep — a presentation-preparation harness. One CLI over 17 lanes (7 built-in + 10 module) that reads a declared surface manifest and checks a talk's assets against each other: canonical-term ledger, jargon glosses, retired vocabulary, inter-slide dependencies, pacing, get/put round-trips, adjacent duplication, slide relations, geometry, attribute consistency, fonts, diagrams, slide refs, and screen-parity between manuscript and deck. Verdict contract: exit 0 pass / 1 findings / 2 cannot-judge — a surface that could not be read is UNMEASURED, never 0. Every lane ships a known-pair fixture.",
|
|
8
|
+
"author": {
|
|
9
|
+
"name": "chrono-meta",
|
|
10
|
+
"email": "chrono-meta@users.noreply.github.com"
|
|
11
|
+
},
|
|
12
|
+
"keywords": [
|
|
13
|
+
"presentation",
|
|
14
|
+
"deck-review",
|
|
15
|
+
"ooxml",
|
|
16
|
+
"pptx",
|
|
17
|
+
"terminology",
|
|
18
|
+
"screen-parity",
|
|
19
|
+
"known-pair",
|
|
20
|
+
"verdict-contract"
|
|
21
|
+
]
|
|
22
|
+
}
|