@chrono-meta/fh-gate 2.6.0 → 2.8.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 (55) hide show
  1. package/.claude/rules/fh_4axis_gate.md +26 -3
  2. package/.claude-plugin/marketplace.json +2 -2
  3. package/AGENTS.md +28 -3
  4. package/CLAUDE.md +146 -168
  5. package/README.ja.md +144 -24
  6. package/README.ko.md +135 -22
  7. package/README.md +204 -27
  8. package/README.zh.md +126 -21
  9. package/docs/ETHOS.md +10 -3
  10. package/knowledge/shared/dialogue/ai_dialogue_playbook.md +131 -0
  11. package/knowledge/shared/harness-core/claude_md_gate_details.md +90 -0
  12. package/knowledge/shared/harness-core/dispatch_conditional_prohibition.md +75 -0
  13. package/knowledge/shared/harness-core/fh_three_layer_canon.md +77 -3
  14. package/knowledge/shared/harness-core/field_verdict_crossfamily_gate.md +92 -5
  15. package/knowledge/shared/harness-core/harness_incubator_doctrine.md +12 -2
  16. package/knowledge/shared/harness-core/multi_model_sidecar_strategy.md +32 -0
  17. package/knowledge/shared/harness-core/ship_readiness_gate.md +77 -8
  18. package/knowledge/shared/learnings/subagent_invocations_log.yaml +196 -0
  19. package/knowledge/shared/rules/knowledge_layer_seam.md +1 -1
  20. package/knowledge/shared/rules/multi_session_close_protocol.md +7 -3
  21. package/package.json +15 -2
  22. package/plugins/fh-commons/.claude-plugin/plugin.json +1 -1
  23. package/plugins/fh-meta/.claude-plugin/plugin.json +1 -1
  24. package/plugins/fh-meta/CHANGELOG.md +157 -0
  25. package/plugins/fh-meta/agents/persona-innovator.md +170 -0
  26. package/plugins/fh-meta/skills/cross-ecosystem-synergy-detection/SKILL.md +37 -0
  27. package/plugins/fh-meta/skills/public-surface-audit/SKILL_detail.md +16 -1
  28. package/plugins/fh-meta/skills/steel-quench/SKILL.md +97 -0
  29. package/scripts/adapters/peer_resolve.sh +58 -6
  30. package/scripts/branch_claim.sh +3 -1
  31. package/scripts/cluster_capability_scan.sh +42 -13
  32. package/scripts/digest_landing_check.sh +142 -2
  33. package/scripts/fh_hub_identity.sh +83 -0
  34. package/scripts/fh_session_load.sh +53 -5
  35. package/scripts/fh_track_resolve.sh +114 -0
  36. package/scripts/field_canon_preload.sh +50 -5
  37. package/scripts/listing_watch.sh +187 -0
  38. package/scripts/package_coverage_check.sh +8 -0
  39. package/scripts/prior_art_prompt.sh +168 -0
  40. package/scripts/psa_scan_lib.sh +201 -15
  41. package/scripts/residency_admission_check.sh +204 -0
  42. package/scripts/selfcheck.sh +103 -0
  43. package/scripts/test_adapter_lanes.sh +67 -2
  44. package/scripts/test_heavy_classifier_lanes.sh +144 -0
  45. package/scripts/test_listing_watch_lanes.sh +162 -0
  46. package/scripts/test_marker_defense_lanes.sh +152 -0
  47. package/scripts/test_marker_soul_check_lanes.sh +211 -0
  48. package/scripts/test_prior_art_prompt_lanes.sh +128 -0
  49. package/scripts/test_psa_singlefile_lanes.sh +351 -1
  50. package/scripts/test_residency_admission_lanes.sh +60 -0
  51. package/scripts/test_track_resolve_lanes.sh +158 -0
  52. package/scripts/test_wizard_snippet_merge_lanes.sh +40 -0
  53. package/templates/.git-hooks/pre-commit +400 -4
  54. package/templates/.git-hooks/pre-push +17 -2
  55. package/templates/settings.PriorArt.snippet.json +44 -0
@@ -8,8 +8,164 @@ Format: [Keep a Changelog](https://keepachangelog.com/en/1.1.0/)
8
8
 
9
9
  ---
10
10
 
11
+ ### [2.8.0] — 2026-08-22
12
+
13
+ **자릿수 근거 (minor)**: 새 게이트 레인 · 행동을 바꾸는 교리 · 소비자 install 동작 변경.
14
+ major 아님(정체성 다섯이 전부 🟢 도, capability class 신설도 아니다).
15
+ **`BREAKING (gate)` 없음** — 새로 등록되는 훅은 `exit 0` 로 끝나는 표면화 훅이고 아무것도 차단하지 않는다.
16
+
17
+ #### 🟥 install-wizard 가 PriorArt 스니펫을 «항상 조용히 SKIP» 하고 있었다
18
+
19
+ `templates/settings.PriorArt.snippet.json` 이 형제 스니펫 넷과 달리 `project_settings_json`
20
+ 래퍼 없이 출하되고 있었고, install-wizard 머지 코드는 그 키가 없으면
21
+ `SKIP (no project_settings_json) … continue` 로 건너뛴다.
22
+ ⇒ **이 훅은 install-wizard 를 돌려도 한 번도 등록된 적이 없었다.**
23
+ 전수 실측: Compaction·FieldCanon·PreToolUse·SessionStart 래퍼 O · PriorArt 혼자 부재.
24
+
25
+ **소비자 영향**: 이제 install-wizard 가 이 훅을 실제로 등록한다. 새 메커니즘을 짓기 직전에
26
+ 「책장 먼저, 없으면 도서관」을 표면화하는 PreToolUse 훅이고, **차단하지 않는다**.
27
+
28
+ 회귀 앵커: `scripts/test_wizard_snippet_merge_lanes.sh` 에 **SHIP-1**(출하 스니펫 전수 스키마,
29
+ 0개 스캔 시 FAIL — 부재를 통과로 안 렌더) + **SHIP-2**(판별력 컨트롤) 신설. 되돌림 3단 검증됨.
30
+
31
+ #### door ④ 가 하네스 레벨 이식쌍을 기본값으로 낸다 — Step 3-b
32
+
33
+ `cross-ecosystem-synergy-detection` 이 «설치된 플러그인/스킬» 층만 냈다. 매핑 트랙 2+ 환경에서
34
+ **매핑된 필드 하네스끼리의 거버넌스 이식쌍**을 조건부 기본값으로 낸다. 발화 트리거 4행(단독 호출)
35
+ + Done When 2행(`harness-error` 는 NON-PASS, 세 번째 허용 상태가 아니다).
36
+ ⚠️ 재발 N=2 로 **이 레포 임계(N≥3) 미달**이며 **운영자 지시로** 기계화했다. 본문에 명시.
37
+
38
+ #### 「워크트리에서 4축 증거가 구조적으로 부재」 철회
39
+
40
+ `pre-commit` 이 `--git-common-dir` 로 메인 트리 증거를 잡는다(2026-08-18 수리, 08-22 첫 실사용).
41
+ 🟥 **운영 규칙은 불변 — 워크트리에서 FH 자산을 커밋하지 않는다.** 남은 것은 성립한 근거가 아니라
42
+ 열린 위험 영역이고 이유로 열거하지 않는다(초판이 열거했다가 적대검증에서 추가 주장 대부분에 결함).
43
+
44
+ #### 정체성 ④ 트리거 재정의 (운영자)
45
+
46
+ 「의문 표명」 예시 넷 → **요청·질문·제안 ∧ «조금이라도» 불확실**의 곱. ①은 채널·②는 판정.
47
+ 결말 셋 신설: **숙고만으로 닫힘** / 책장 / 도서관.
48
+
49
+ #### 기타
50
+
51
+ 디스패치 원장 3엔트리(66건 무기록 해소) · README 4언어 · `listing_watch.sh` · 3층 정본 ·
52
+ `docs/ETHOS.md` (2.7.0 이후 누적).
53
+
54
+ ---
55
+
11
56
  ## Plugin Level
12
57
 
58
+ ### [2.7.0] — 2026-08-21
59
+
60
+ ### 🟥 BREAKING (gate): 2026-08-21 이후 날짜의 마커는 `①영혼` 줄이 없으면 커밋이 막힌다 — 없으면 `soul: 없음` 한 줄로 통과한다
61
+
62
+ 이 필드는 `CLAUDE.md §자기 대조` 가 **2026-08-09 부터 의무**로 정한 것이고, 이 릴리스는 그것을
63
+ 새로 요구하는 게 아니라 **처음으로 읽는다.** 소급 안 한다(그 날짜 이전 마커는 그대로).
64
+ **선언된 부재는 1급 값이다** — `없음`/`none`/`n/a` 는 통과하고, 통과가 아니라 **기록**으로 찍힌다
65
+ (`⚠️ ①영혼: 없음 — declared absent. Recorded, not silent.`). 빈 필드만 막힌다.
66
+
67
+ ---
68
+
69
+ **마커의 `①영혼` 은 6주째 의무였는데, 읽는 코드가 0줄이었다.**
70
+
71
+ 컨트롤 동반 실측: 훅에서 `crossfamily` 는 **21곳**에서 검사되는데 `①영혼`/`soul` 을 읽는 코드는
72
+ **0줄**이었고, 게이트 명세(`fh_4axis_gate.md`)는 그 필드 이름조차 안 적는다. 실물 코퍼스에서
73
+ **2026-08-10 이후 마커 98건 중 37건(37.8%)** 이 어떤 표기로도 그 줄을 안 갖고 있었다 — 그중
74
+ 손검증한 하나는 **codex+agy 패널 · 28레인 · controls alive · 나머지 필드 전부 채운** 마커다.
75
+ **시킨 축은 다 돌렸고, 아무 기계도 안 읽는 그 한 줄만 없었다.**
76
+
77
+ - **새 축이 아니다 — ⓒ 격리 그라운딩의 확장이다.** `fh_three_layer_canon.md §1-a-2` 의 판별자는
78
+ «무엇을 받았는가»이고, ⓒ 는 이미 «저자가 쓴 문장 + 지금의 트리» 를 받는다 — 사전 선언 검사의
79
+ 입력과 한 글자도 다르지 않다. 시제(사전 선언 ↔ 사후 주장)는 적대성과 같은 **자세**지 축이 아니다.
80
+ 🟥 초안은 ⓖ 로 뽑으려 했고 **운영자가 기존 카테고리 검토를 지시해 정정했다** — 그대로 갔으면
81
+ 정본 6축·`axes-run` enum·덱 표·마커 190건 재해석이 전부 따라왔을 것이고, 그건 정본 안에 이미
82
+ 기록된 오류(저자가 ⓓ에 귀속한 5건 중 3건이 다른 축으로 재분류)의 반복이었다.
83
+ - **검사하는 것은 채널뿐이다.** 선언이 있는가(줄머리 키) · 공허하지 않은가 · `soul-check:` 가 닫힌
84
+ enum 인가 · **같은 레코드 안에서 정합적인가**(`reflected` 를 적으려면 그 마커에 실제로 선언이
85
+ 있어야 한다). **검사하지 않는 것**: 사전에 썼는가(파일에서 안 갈린다) · 그 판단이 옳은가.
86
+ 날조된 `reflected` 는 통과한다 — §4-b(cross-family 가 마커를 읽는다)의 몫이고 여기서 안 닫혔다.
87
+ - **검증**: 레인 44개(BLOCK/PASS 양방향 · 실물 코퍼스 known-pair 2쌍) · 되돌림에서 **정확히 대응
88
+ 7레인만** 적색 · 격리 클론 실 커밋 2팔(선언 없음 `rc=1` / 있음 `rc=0 ALL AXES PASSED`).
89
+ - 🟥 **자력 적발 0 이 14건.** cross-family 2계열 분리 발주(codex=diff 축 / agy=주장 축) 10건 +
90
+ 첫실사용 4건, **겹친 지적 0**. 그중 하나는 **사이드카의 수리가 새 fail-open 을 만든 것**이다 —
91
+ 넓힌 탐지기가 `soul-check:` 줄 자신의 텍스트를 증거로 잡아 BLOCK 레인이 PASS 로 뒤집혔고
92
+ **레인 41개가 전부 초록이었다.** 잡은 것은 격리 클론 첫실사용이다.
93
+
94
+ **유출 스캐너가 zsh 에서 죽었고, 그 죽음이 「깨끗함」과 바이트 동일이었다.** (PR #480)
95
+
96
+ `psa_scan_tagged` 가 `local path` 를 선언하는데 **zsh 에서 `path` 는 `PATH` 와 tied 된 특수
97
+ 배열**이라 그 스코프의 `PATH` 가 비고 첫 실행문(`input=$(cat)`)부터 죽는다. 계약이
98
+ 「빈 입력 = `return 0`」이라 **출력이 깨끗한 스캔과 구별되지 않았다.** `/public-surface-audit` 가
99
+ 한 줄도 안 스캔하고 「유출 없음」을 냈고, 그 스킬은 **Pre-Publish Gate 가 publish 직전에 1번으로
100
+ 체이닝하는 렌즈**다.
101
+
102
+ - 훅 경로(`pre-commit`·`pre-push`)는 bash 로 `execve` 되어 **원래 안전했다.** 뚫린 것은
103
+ **에이전트가 Bash 툴로 치는 스킬 본문**이고, macOS 기본 셸이 zsh 라서 난다.
104
+ - 수리는 둘이다: **A** 식별자 개명 · **E** `psa_scan_tagged` 진입에 생존성 가드 배선
105
+ (실패 → `rc=3 NOT SCANNED`). 🟥 **A 만으로는 계열이 안 닫힌다** — 같은 형태가 7곳 더 있고 그중
106
+ 6곳은 «오늘 안전한데 그건 호출부가 bash 라서»지 코드가 이식성 있어서가 아니다.
107
+ **A 는 이 실례를, E 는 다음 실례를 막는다.**
108
+ - ⚠️ **소비자에게 보이는 변화**: 패턴 파일이 **부분만 로드되는** 설치본은 이제 `rc=3`
109
+ (NOT SCANNED)를 받는다 — 전에는 `rc=0`(깨끗)이었다. 방향은 옳지만 **막히는 경우가 늘었다**.
110
+ 잘못된 패턴 파일을 쓰던 소비자는 그 사실을 이제 통보받는다.
111
+ - **rc 계약 `0 깨끗 · 1 유출 · 3 미측정` 을 1과 3으로 접지 않는다** — 합치면 `PUBLIC_SURFACE_OK=1`
112
+ 이 **계기 사망까지 «승인된 유출»로 통과**시킨다. 비가역 표면에서 가장 나쁜 조합이다.
113
+ - **소비자 설치본 실측**(리뷰에서 추가): 깨끗한 클론 → `npm pack` → `node_modules` 경로 추출 →
114
+ **스킬 본문 호출 형태 그대로** known-pair. 수리 전 `zsh` 양성 **rc=0 무보고**(유일한 흔적은
115
+ stderr 한 줄) → 수리 후 **rc=1 보고**. bash 팔은 양쪽 불변(컨트롤).
116
+
117
+ **릴리스 표면 — 두 계보가 한 이름공간을 쓰고 있었다.**
118
+
119
+ GitHub Releases 가 **v0.3.0(8/16)을 「Latest」로** 보여주는 동안 배포물은 **2.6.0** 이었다. 둘 다
120
+ `vX.Y.Z` 를 쓰고 정체성 계보에만 Release 객체가 있었기 때문이다. 🟥 **이건 이 저장소가 자기
121
+ 게이트에서 반복해 찾아낸 그 결함(두 층·한 이름)이 자기 버전 번호에 난 것이다.**
122
+
123
+ - **통일하지 않는다** — 두 숫자가 다른 것을 잰다(무엇을 설치하는가 ↔ 얼마나 익었는가). 합치면
124
+ 성숙도 신호가 사라지고, **`identity-v1.0.0` = 전정체성 🟢** 라는 마일스톤이 죽는다.
125
+ - 이름공간만 가른다: 정체성 계보는 **`identity-v0.4.0` 부터** 접두어를 갖는다. 기존
126
+ `v0.1.0`·`v0.2.0`·`v0.3.0` 은 **개명하지 않는다** — 공개 ref 재작성은 비가역이라
127
+ Destructive-Op 게이트가 우리 자신의 태그에도 적용된다.
128
+ - `README §Two version numbers` 신설 ·
129
+ 🟥 `v2.6.0` Release 객체를 만들었다가 **같은 시각에 되돌렸다**(운영자 지적) — GitHub 의 «Latest»
130
+ 배지는 **슬롯이 하나**라 두 계보가 한 페이지에 있으면 경쟁하고, 배지를 쥔 쪽이 «이 저장소가
131
+ 뭐라고 말하는가»를 정한다. 패키지 번호가 표제를 가져가면서 **성숙도 주장이 그 아래로 밀렸다.**
132
+ 오독은 더 싼 절반(기존 본문 맨 위 한 줄)이 이미 닫았다. ⇒ **Releases 는 정체성 계보만** 나른다 ·
133
+ `v0.3.0` 본문 **맨 위**에 계보 한 줄(본문 4문단 아래엔 이미 있었다 — **gate-locality**: 읽는
134
+ 자리에 없으면 없는 것이다).
135
+ - ⚠️ 정본의 stale 하나 같이 정정: `ship_readiness_gate.md` 가 npm 을 *"`1.4.x` range"* 로 적고
136
+ 있었다(실제 2.6.0). **산문에 박힌 버전 숫자는 조용히 낡고 사실처럼 읽힌다.**
137
+
138
+ **사이드카는 감사하지 쓰지 않는다.** (`multi_model_sidecar_strategy.md §Runtime Authority`)
139
+
140
+ 기존 교리는 «사이드카 finding 은 증거 후보이지 판정이 아니다»를 **판정 축**에서만 말했고 **쓰기
141
+ 축이 비어 있었다.** 실측: 적대 감사자로 발주된 사이드카가 워킹트리를 **직접 편집**했고(`mtime`
142
+ 으로 적발 — 어떤 게이트도 못 잡았다), 그 수리가 **자기참조 fail-open** 을 새로 만들었다.
143
+ 🟥 **금지 근거는 「월권」이 아니라 「고친 쪽과 검사하는 쪽이 같아진다」다.**
144
+ 프로세스 판도 같이 적었다 — 폭주 사이드카를 죽일 때 **자기 프로세스 판별자**(모델 핀·PID·
145
+ `pgrep` 선열거)를 갖고 쓰고, **죽인 뒤 무엇이 죽었는지 확인한다**.
146
+
147
+ **규칙은 세 자리 중 하나에 산다.** (`README §Where a rule lives`)
148
+
149
+ 상주 층이 무한히 자라야만 하는가라는 질문에 대한 답이다. 🟥 **가운데 자리가 보통 비어 있고,
150
+ 그게 공짜다** — **게이트 자신의 오류 메시지**는 행위자가 **행동하는 순간에** 읽는 자리라 상주
151
+ 예산을 한 글자도 안 쓴다. 한계도 같이 적었다: **막힐 때만 읽힌다.** 그래서 대체가 아니라 3층이고,
152
+ 실측이 그 증거다 — 이번 게이트에서 **기계 +480줄, 상주 산문 ±0**.
153
+
154
+ ### 명시 잔여 — 안 닫은 것
155
+
156
+ - **날조된 `reflected(…)` 는 통과한다.** provenance 는 파일에서 안 갈린다. §4-b 의 몫이다.
157
+ - **`①영혼` 소급 안 함** — grace `2026-08-21`, 기존 37건 유지.
158
+ - **형제 축 문법 분열**: `standpoint:` 는 근거를 em-dash 로만 받고 `thirdparty:`·`soul-check:` 는
159
+ 괄호로 받는다. 같은 훅 안에서 갈리고, 괄호로 쓰면 *"is not a member of the enum"* 이라는
160
+ **오진**을 낸다(값은 멤버가 맞고 문법만 틀렸다).
161
+ - **psa 계열 7건이 호출부에 의존해 잠들어 있다** — 「남은 7건」이 아니라 **조건부 활성**이다.
162
+ - **`M-1`(상주) · `M-2`(memory) · `M-3`(스킬 활동도)은 안 건드렸다.** 🟥 셋 다 **계기가 미검증**
163
+ 이다: 임계 40k·80k·10k **어느 것도 절단점 근거가 없고**(도입 커밋이 축은 20줄 논증하고
164
+ 절단점은 한 줄도 안 함, 그리고 도입 당일 대상이 이미 초과였다) · 출하 스캔이 `wc -c`(바이트)를
165
+ **«chars» 라고 라벨**하며(163,456 vs 실제 문자 144,471) · 스킬 활동도 계기가 **언급을 사용으로**
166
+ 센다(실행 0인데 «활발» 로 오분류 27종). **재정초 전에 감량하면 근거 없는 목표를 향해 깎는 것**
167
+ 이고, 그 절약으로 fail-open 을 산다.
168
+
13
169
  ### [2.6.0] — 2026-08-20
14
170
 
15
171
  **배포본이 소비자 설치에서 `SELFCHECK: FAIL` 이었다 — 그리고 원인 넷이 전부 «계기가 저자의 머신에 결박» 이었다.** 이 릴리스의 중심은 새 기능이 아니라 그 복구다. 발견 경로는 재출하 준비 중의 손 실행이다: `npm pack` → 추출 → **`node_modules/@chrono-meta/fh-gate` 실경로에서 완주**. 레지스트리에서 받은 **실물 2.5.1** 로도 재현했다(컨트롤).
@@ -75,6 +231,7 @@ BREAKING (gate): edit_manifest.yaml 에 `date` 만 있는 엔트리가 있으면
75
231
  실측: 이 레포 매니페스트 411건 중 date-only **0건** — **건강한 매니페스트를 가진 소비자는 안 막힌다.** 막히는 것은 동시 append 로 손상된 경우이고, 그 손상은 종전에 **조용히 통과**했다.
76
232
 
77
233
  **동작 변경(차단 아님)**: 워크트리에서 FH 자산 커밋이 **가능해진다**(evidence-root 를 `--git-common-dir` 로 해석). 종전엔 `tracks/` 가 안 따라와 Axis 2+3·Axis 4 가 구조적으로 부재했다 — 즉 이 항목은 **완화**다.
234
+ > 🟥 **정정 (2026-08-22) — 위 줄을 「워크트리에서 커밋해도 된다」로 읽지 마라.** 기술적으로 *가능해진* 것은 맞으나, **운영 규칙은 여전히 «워크트리에서 FH 자산을 커밋하지 않는다»** 이다(`CLAUDE.md §Agent Dispatch Operation`). 이 항목이 없앤 것은 «증거에 도달 못 한다»는 **우연한 장벽** 하나뿐이고, 마커 provenance·동시 append 같은 남은 근거는 그대로다. 이 줄이 없으면 소비자는 출하 문서에서 내부 규칙과 반대되는 지시를 읽는다.
78
235
  ⚠️ **위 둘은 같은 사건의 앞뒤다.** 경로 변경으로 워크트리 소비자에게 게이트가 **처음 도달**하는데, 그 순간 `core.hooksPath` 가 **상대 경로**면 워크트리가 **자기 훅 사본**을 돌아 자기무력화가 가능하다.
79
236
  권고: `git config core.hooksPath "$(git rev-parse --show-toplevel)/templates/.git-hooks"`
80
237
 
@@ -20,6 +20,7 @@ The main agent passes you one of:
20
20
  - **Mode E (External scan)**: "scan frontier" / "what are people building" / specific topic
21
21
  - **Mode F (Full)**: both — default when no mode is specified
22
22
  - **Mode T (Technical bridge)**: "can't connect" / "not possible" / "blocked" / "no direct path" / technical constraint hit
23
+ - **Mode X (Intervention cross-check)**: "쎄한데 확인해줘" / "내가 뭘 놓쳤나" / "개입 대조" / a session asking whether it is about to be stopped. Runs Phase 3-b ONLY — no naming, no frontier scan.
23
24
 
24
25
  Optionally: a focus area (e.g., "token efficiency", "agent orchestration", "cascade patterns")
25
26
 
@@ -153,6 +154,175 @@ For each gap or absorbed signal:
153
154
  4. **Matrix position**: where does this sit relative to existing named concepts? (complement / extend / replace)
154
155
  5. **Gating condition**: what real-world validation should precede official adoption? (simplicity guard applied)
155
156
 
157
+
158
+ ## Phase 3-b — Intervention algorithm (Mode X, and MANDATORY inside Mode F)
159
+
160
+ Phase 3 above carries the owner's **naming** algorithm. This phase carries the owner's
161
+ **intervention** algorithm — *where the owner has historically stopped a session and turned it.*
162
+
163
+ **Provenance (measured, not asserted)** — census of the conversation corpus itself, not of what
164
+ sessions wrote down afterwards: `~/.claude/projects/…/*.jsonl`, **69 sessions / 2026-07-22–08-21**,
165
+ **433 operator utterances**, semantically classified. **54 interventions claimed · ~43 estimated
166
+ after a 5-sample hand-check (1 false positive) · full hand-verification NOT done.**
167
+ 🟥 **CORRECTED 2026-08-21 — that census read 21% of its own corpus and called it 전수.** A full
168
+ re-scan of the same directory with the same discriminator returns **168 sessions · 1,703 operator
169
+ utterances** (uuid-deduplicated; ~1% contamination hand-checked: `<bash-input>` / `<command-message>`,
170
+ 17 of 1,703). The census's own note recorded **169MB**, and `du -sh` on that directory is **817MB** —
171
+ the ratio was written down and never compared. **So «54» is a count over a fifth of the corpus, not a
172
+ census.** Do not cite it alone. If the 12% rate holds, the true intervention count is nearer **200**.
173
+ The shapes and the class distribution below are unaffected in *direction* (they were derived from a
174
+ random-in-practice fifth), but every absolute number on this page is a lower bound.
175
+ Detail + the seal comparison: `tracks/_meta/RESULT_2026-08-21_intervention-corpus.md`.
176
+
177
+ 🟥 **The dominant class is NOT "you didn't search the world."** Measured distribution:
178
+ `판단결함 32 (59%) · 내부미조회 9 · 외부미조회 6 (11%) · 범위겨냥 6`. A design that treats this
179
+ as a *search* trigger is aiming at an 11% slice — the first draft of this capability did exactly that.
180
+
181
+ **Prior art (2026-08-21) — this task has a published benchmark; price the capability against it.**
182
+ Wu et al., *"User Feedback in Human-LLM Dialogues: A Lens to Understand Users But Noisy as a Learning
183
+ Signal"*, EMNLP 2025 main (`arXiv:2507.23158`). Numbers read from the PDF text, not from a summary:
184
+ automatic feedback identification with a purpose-built GPT-4o-mini prompt scores **P 61.1 / R 35.9**
185
+ in the *dense* setting (label every turn — the realistic one) and **P 100.0 / R 69.2** in the *sparse*
186
+ setting (the feedback turn is pointed out in advance); inter-annotator agreement **Cohen κ = 0.70
187
+ (binary) / 0.74 (three-way) / 0.60 (fine-grained)** over 54 cross-annotated conversations.
188
+ ⇒ Two consequences. **(a)** A weak separation here is the task's difficulty, not this rule set being
189
+ unusually bad — quote precision against **P61/R36**, never against a vacuum. **(b)** Their conclusion
190
+ (*noisy as a learning signal*) converges independently with residual (0) below.
191
+ 🟥 **Do not collapse the two tasks.** They read the user's turn and judge post-hoc; this phase predicts
192
+ *before* the user speaks, from the session's own acts, with the next human turn structurally excluded.
193
+ Ours is strictly harder and that difference is the net-new angle — normalizing it away both overstates
194
+ the prior art and invalidates any direct number comparison.
195
+ 🟥 Provenance of this paragraph: the world was consulted **only after the operator asked whether it had
196
+ been**; zero external lookups preceded the design. That is identity ④'s measured gap, not a footnote.
197
+
198
+ ### The ten shapes — a session in this state is about to be stopped
199
+
200
+ | Shape | The session is… | n |
201
+ |---|---|---|
202
+ | 손안의 기록 미개봉 | reporting «missing / incomplete / impossible» about material it already holds but never opened | 9 |
203
+ | 막힘을 종점으로 접기 | folding at a blocker (hard / absent / over quota / someone else's job / next session) without trying one alternate route | 9 |
204
+ | 산출물 미대조 완료선언 | writing «applied it / fixed it» without re-opening or re-rendering the artifact | 7 |
205
+ | 세계 미조회 설계 | designing from repo-and-session material only, zero external prior art consulted | 6 |
206
+ | 단일 관측 전역 단언 | fixing a cause/state/number from one node or one observation, no second instrument | 6 |
207
+ | 과녁 치환 | working hard on a different target than the one named in the request | 5 |
208
+ | 정적 리뷰로 완료 | closing a wiring/rule change on a static read, never run from the target tier or target harness | 4 |
209
+ | 이상신호 흘려보내기 | passing over a tool error, odd latency, or overwrite side-effect without citing or acting | 4 |
210
+ | 기준 없는 등급 판정 | setting a version digit or identity grade without citing the document that defines it | 2 |
211
+ | 절차 규모 오조준 | defaulting to a heavier procedure than the change needs | 2 |
212
+
213
+ ### The self-check list — run these against **this turn's tool calls and output**
214
+
215
+ 🟥 **Every line is stated as an observable act, never as a feeling.** That is deliberate: the
216
+ adversarial review that killed the first draft found the fatal flaw was a trigger keyed on the
217
+ session's own sense of uncertainty — *a session that is confident does not report uncertainty, and
218
+ the measured failures were all confident.* These lines are checkable from what the session just did.
219
+
220
+ 1. Wrote a paragraph or more of design/definition/gap-diagnosis, and opened **zero** external sources this turn.
221
+ 2. About to write «없다 / 미등재 / 미완 / 불가», and never opened the file or history that would hold it.
222
+ 3. Wrote «반영 완료» about a document without counting the items in it.
223
+ 4. Wrote «applied / fixed / included it all» with **no tool call re-reading that artifact after the edit**.
224
+ 5. Was given N items and touched fewer than N, without putting both numbers side by side.
225
+ 6. About to write «next session / someone else / later» with **no tool call attempting an alternate route this turn**.
226
+ 7. Dropped a verification leg because a sidecar was blocked, with no record of trying another family / local LLM / subagent.
227
+ 8. Withdrew its own proposal citing only «hard / side effects», with not one line on how to make it work.
228
+ 9. Asked the operator about a peer session's state instead of asking that session via ListAgents/SendMessage.
229
+ 10. Routed a candidate to CURATED / drop / hand-off **without one line on how it could become our own capability**.
230
+ 11. The file / environment / axis being edited is not the noun the operator named.
231
+ 12. Filled a mapping or candidate list only from what exists locally on this machine.
232
+ 13. About to write PASS on a rule/wiring change and cannot quote a command run in the target tier or harness with its output.
233
+ 14. Ran a «standpoint review» from its own vantage, with no agent dispatched inside the target harness.
234
+ 15. Fixed a cause/state/number from one node or one observation, with no second instrument.
235
+ 16. Wrote an aggregate count without checking whether already-running or pre-existing items are inside it.
236
+ 17. Wrote a time/date/environment fact from memory or inference rather than from a command.
237
+ 18. Judged a tool error or warning «non-blocking» and moved on without citing it or acting.
238
+ 19. Created or changed a setting and wrote «done» without printing its expiry / default fields.
239
+ 20. Regenerated or overwrote a file without a diff showing which prior lines are gone.
240
+ 21. Waiting on a run that is taking longer than expected without checking its output or whether a session was created.
241
+ 22. Raised a version digit or grade without quoting the document that defines that digit.
242
+ 23. Proposed follow-up work larger than the original request without putting a minimal option beside it.
243
+
244
+ ### Output for Mode X
245
+
246
+ For each line that fires: quote the session's own act that trips it, and propose **one line** —
247
+ *"확인해볼까?"* — naming the cheapest check that would settle it. **Propose; never decide.**
248
+ Fires nothing → say «걸린 줄 없음» explicitly; silence is not a verdict.
249
+
250
+ ### Tier M — signals decidable from the session RECORD (calls + turns + diff), no judgment
251
+
252
+ 🟥 **The first draft of this heading said «from the tool-call record alone». That was false**
253
+ (cross-family, 2026-08-21): #9, #10, #12, #15 and #18 require reading the user's turn, the reply, or
254
+ the commit diff — not the call log. The tier's real claim is narrower and is what the heading now
255
+ says: **no judgment is needed**, but more than the call log is read. An evaluator for this tier needs
256
+ a defined input contract (calls · user turns · final reply · staged diff) that **does not exist yet**.
257
+
258
+ A **second census** (same question, different corpus: what sessions *recorded* about
259
+ interventions, `tracks/`+`knowledge/`+memory — 300 scanner hits → 199 claimed → **33 hand-verified,
260
+ 18% rejected**) produced signals of a different grade: each one is a **countable fact about this
261
+ session's own calls**, needing no judgment. Both censuses landed on the same class distribution
262
+ (판단결함 dominant · 외부미조회 a minority).
263
+ 🟥 **That agreement is CORROBORATING BUT CORRELATED — not independent** (cross-family caught the
264
+ overclaim). Same operator, same canon, same model family; and the `tracks/` records are *derivative
265
+ of the same events* the transcripts hold. Claiming independence would need event-linkage removal, a
266
+ different annotator/model, a pre-registered codebook and blind reclassification — **none were done.**
267
+
268
+ 1. An absence/blocked claim (`없다`·`0건`·`not found`·`unavailable`·`막혔`·`overdue`) appears, and the tool call against that subject happened **exactly once** — no second attempt.
269
+ 2. A tool output carries a truncation marker (`truncated`·`… N more`·a next/page cursor·line count exactly equal to the limit) and the tool was **never re-called with a different offset/page/cursor**.
270
+ 3. A call ended non-zero or errored, and the **same tool with the same arguments was not retried** — the session switched to a different tool instead.
271
+ 4. A background handle has produced **0 bytes of stdout for N seconds** and has not exited, and the call carried no timeout.
272
+ 5. A freshness/cadence verdict rests on a single glob whose match count is **0** (rendering `not found` as `overdue`).
273
+ 6. After session-start `pull`/`fetch`, the newest remote commit is **later than the date field of the card/INDEX that was read**, and **zero** of the files those commits touched were Read.
274
+ 7. A staged git-tracked added line contains an absolute home path, a companion-store name, a vendor/product proper noun, or an executable that only `command -v` resolves **on this machine**.
275
+ 8. A diff under `package.json files[]` · `templates/` · `plugins/` newly introduces a local-only path or local-only CLI name — an environment dependency entering the shipped set.
276
+ 9. A noun phrase or quoted string from the user's turn appears **0 times** in the session's whole commit diff (operator utterance ↔ canon landing).
277
+ 10. A quantity token (`N건`·`N자`·`N%`·`HH:MM`) appears in an artifact or final reply, and the session made **no call able to produce it** (`wc`·`grep -c`·`date`·arithmetic).
278
+ 11. A time/date predicate (`심야`·`오전`·`어제`·a weekday) was written to a record with **zero `date` calls**.
279
+ 12. The first user turn matches the greeting corpus and the first reply carries **neither the 🐿️ literal nor the fixed welcome line**.
280
+ 13. A section a rule marks «always include» greps **0 times** in the artifact that rule governs.
281
+ 14. A new file is about to be written with **zero** prior Read/Grep against `CATALOG.md` / the skill list / `plugins/**/SKILL.md`, while its name or keywords already match the index.
282
+ 15. A skill/agent proper noun the session named as the routing target appears **nowhere in the user's turn** — the session introduced that name.
283
+ 16. An external model's or sidecar's **self-report string** is cited as verdict evidence, with **0 calls** running the same probe against a known control.
284
+ 17. The diff changes an exit code, a default, or a fail-open/closed direction, and the commit message or 4-axis marker quotes the user's turn **0 times**.
285
+ 18. A recommendation to install or use a tool carries **no conditional marker** (`when`·`only if`·`unless`·`~일 때만`) anywhere.
286
+
287
+ ### How the two tiers are used
288
+
289
+ ```
290
+ Tier M (18) countable from this session's calls → a hook could evaluate these
291
+ Tier J (23) need reading the session's own output → invocation, judged
292
+ ```
293
+ **Noise cap (mandatory).** Rank by tier then by how cheap the check is, and surface **at most 2 per
294
+ turn**; hold the rest silently. 🟥 Without this, Mode F makes this phase mandatory and every firing
295
+ emits a proposal — up to **41 «확인해볼까?» in one turn**, which is the nag that trains dismissal and
296
+ kills the capability (cross-family MED). Repeat suggestions dedupe by shape, not by wording.
297
+
298
+ 🟥 **Neither tier decides.** Both produce the same one line — *"확인해볼까?"* — naming the cheapest
299
+ check. The operator's bar for this capability is exactly that: *"'쎄함'을 감지하고 사람에게
300
+ 「한번 확인해볼까?」 라고 제안하는 것만 가능해도 성공이다."*
301
+
302
+ ⚠️ **Named residuals.** (0) **MEASURED 2026-08-21 — and it did not pass its pre-registered bar.**
303
+ (The 18% figure below is the rejection rate of one census's *claims*; it never was these rules'
304
+ precision.) A sealed pre-registration (`sha256 8414a44d…`, re-verified at opening) ran the 41 rules
305
+ against **44 windows** — 22 immediately preceding an operator intervention, 22 preceding an approval —
306
+ with blinding enforced by file boundary (the rule-evaluator never receives the next human turn; the
307
+ labeler never receives the rules). Result: **12 of 41 rules ever fired · 2 discriminate**
308
+ (`J2` +4, `M10` +3) · **10 fired below the +3 line** (J1 · J17 · M2 · J4 · J12 · M1 · J6 · M4 · J18 ·
309
+ M3 — «did not clear the bar in this sample», **not** the same bucket as dead) · **29 never fired at
310
+ all**, 14 of them Tier M. The pre-registered stop condition **«no separation» HIT** (median difference
311
+ +0.5 vs a required +2.0).
312
+ 🟥 **The pre-registration itself was defective and that is recorded, not hidden**: a median is a poor
313
+ statistic on a 0–1 sparse count. A post-hoc binary comparison (any rule fires: POS 82% vs NEG 50%,
314
+ Fisher p=0.055) suggests signal — **it does not overturn the verdict**, and claiming it would require
315
+ replication under a *new* pre-registration naming that statistic in advance. Current status:
316
+ **signal possible, not established.**
317
+ ⚠️ Scope of that run: **in-sample** (no out-of-sample corpus exists — sessions in other repos are
318
+ one-shot dispatches with no preceding window), which makes it a *favourable* arm: failing it is
319
+ conclusive, passing it would not have been. Detail: `tracks/_meta/RESULT_2026-08-21_intervention-precision.md`. (0-b) Tier M has **no executable definitions** — «N seconds», «same subject»,
320
+ «alternate route», «conditional marker» are undefined; an evaluator schema, window and no-data
321
+ verdict must precede any wiring. (a) Tier M is written but **not wired** — no hook evaluates it yet; both
322
+ tiers currently run on invocation. (b) Neither census hand-verified in full: transcripts 5/54
323
+ checked, tracks 33 of 199 claims verified at an 18% rejection rate. (c) The transcript corpus is
324
+ **one month deep** (2026-07-22 onward); earlier interventions are structurally absent, not zero.
325
+
156
326
  ## Self-floor discipline (FH floors, applied to the innovator itself)
157
327
 
158
328
  These are FH's own governance floors turned reflexively on this agent's process — an ideation tool
@@ -39,6 +39,13 @@ Automatically discovers cross-invocable pairs in environments with multiple inst
39
39
  | "My tools feel disconnected and inconvenient" | Detect namespace/cwd fragmentation |
40
40
  | "Wouldn't combining these plugins be more powerful?" | Explore component combination synergies |
41
41
  | "I feel like there's synergy here — find it" | Automatic cross-invocation pair discovery |
42
+ | "Do my harnesses have synergy with each other?" | **Step 3-b standalone** — harness-level scan |
43
+ | "Can I transplant a governance pattern from another project?" | **Step 3-b standalone** |
44
+ | "Could I bring that project's gate over here?" | **Step 3-b standalone** |
45
+ | "하네스끼리 시너지" · "거버넌스 패턴 이식" · "다른 프로젝트 게이트 가져올 수 있나" | **Step 3-b standalone** |
46
+
47
+ > **Step 3-b fires standalone.** The last four rows call that step alone; they do not require the full
48
+ > door-④ pass. A request about *harnesses* is not a request about *installed plugins*.
42
49
 
43
50
  ## Processing Steps (7-step)
44
51
 
@@ -90,6 +97,34 @@ Call mechanism compatibility:
90
97
  - **Hook**: Auto-triggered (no direct cross-component calls)
91
98
  - **MCP**: Per-tool calls (namespace separated)
92
99
 
100
+ ### Step 3-b. Harness-level pattern-transplant scan (conditional default)
101
+
102
+ **Condition**: 2+ mapped field-harness tracks exist under `tracks/` (underscore-prefixed meta dirs
103
+ such as `_meta`/`_audit`/`_contrib`/`_chamber` do not count). Otherwise skip with one line.
104
+
105
+ Steps 1–3 look at **installed plugins/skills**. This step looks one layer up: the **governance
106
+ mechanisms of the mapped field harnesses themselves** — verification axes, verdict enums, gate exit
107
+ codes, persona systems — and finds pairs where one harness's mechanism is transplantable into another.
108
+
109
+ - Read each mapped track's **canon** (`CLAUDE.md` / `README.md`), not its code. Field-harness
110
+ vocabulary must not be normalized into general concepts — that is this repo's habitual failure.
111
+ - Emit **transplantable pairs only**: the two must share the *same problem shape*. Merely overlapping
112
+ subject matter is excluded.
113
+ - 🟥 Declare the read depth. "Read the top ~150 lines of CLAUDE.md" is a different claim from "read the
114
+ file"; say which, and mark anything not opened as **unverified**, never as absent.
115
+ - Store under its **own section** in the Step 6 result file, separate from the skill/agent pair table —
116
+ the two layers answer different questions and merging them hides which one produced a finding.
117
+
118
+ > **Boundary with Step 7**: Step 7 (proactive) may *trigger* Step 3-b; it does not replace its scan.
119
+ > Step 7 decides *when to offer*, Step 3-b decides *what to read and which transplant pairs come out*.
120
+ >
121
+ > **Why this is a default and not an extra**: door ④ was run live on 2026-08-21 and 2026-08-22 and both
122
+ > times produced only the skill/agent layer, while the operator was asking for this one. The wiring
123
+ > existed; its target was pinned to the old object. Provenance: `tracks/_meta/fh_signal_2026-08-21_unused-skills-are-unwired.md`
124
+ > (cause ⓓ) and `tracks/_meta/fh_signal_2026-08-22_operator.md`.
125
+ > ⚠️ **Mechanized at N=2 by explicit operator instruction; do not count as threshold-triggered
126
+ > mechanization** (`[[feedback_mechanize_at_repetition_prose_before]]`).
127
+
93
128
  ### Step 4. Synergy Grade Derivation (★~★★★)
94
129
 
95
130
  | Grade | Compatibility conditions |
@@ -245,6 +280,8 @@ External users automatically derive their own inventory via Step 1 `installed_pl
245
280
  | Condition | Check class |
246
281
  |---|---|
247
282
  | Steps 1~6 completed | **mandatory-pass** |
283
+ | **Step 3-b reported as `run(n pairs)` or `skipped(<2 mapped tracks)`** — never silently omitted; read depth declared per track | **mandatory-pass** |
284
+ | **`harness-error` is a NON-PASS, not a third accepted state.** Reporting the error satisfies the anti-silence rule and nothing else — it does not clear this row. Surface it and stop; do not let a status string stand in for a result | **mandatory-pass** |
248
285
  | Synergy ranking table (★~★★★) output | **mandatory-pass** |
249
286
  | **Step 7 state reported as one of `run` / `not-configured` / `harness-error`** — never silently omitted, and `harness-error` never reported as a skip | **mandatory-pass** |
250
287
  | Step 5 drift reported as `MATCH / DRIFTED / DRIFT-UNKNOWN(n=…)`, with `DRIFT-UNKNOWN` excluded from the match count; Step 2 `ABSENT` asset classes carried through as `ABSENT`, not `0` | **measured** (counts come from the Step 1/2 output, not from recall) |
@@ -25,9 +25,24 @@ if [ -r "scripts/psa_scan_lib.sh" ]; then
25
25
  # Feed every tracked file as path<TAB>line, the stream psa_scan_tagged consumes. Sourcing the lib
26
26
  # without these calls is a no-op scan — measured on this repo (PSA_STREAM stayed unset), so the
27
27
  # calls are spelled out here rather than pointed at.
28
+ # 🟥 rc 를 반드시 받아라 (2026-08-21 배선 리뷰 S-1). 이 파이프는 **원래 뚫렸던 바로 그 진입점**이고,
29
+ # 바로 아래 coverage 조건이 `$?` 를 덮으므로 여기서 안 받으면 계약이 소실된다.
30
+ # 계약: 0=신고할 것 없음 · 1=유출(이미 인쇄됨) · 3=NOT SCANNED(계기 사망)
31
+ # ⚠️ `_psa_rc=0` 은 반드시 `while` **밖**에 둔다 — 안에 두면 루프 본문이라 매 줄 초기화되고
32
+ # 파이프 서브셸에 갇힌다(초판이 그렇게 넣었고 `bash -n` 은 통과했다. 문법은 맞고 의미가 틀린다).
33
+ _psa_rc=0
28
34
  while IFS= read -r f; do
29
35
  awk -v p="$f" '{printf "%s\t%s\n", p, $0}' "$f" 2>/dev/null
30
- done < /tmp/_psa_tracked.txt | psa_scan_tagged
36
+ done < /tmp/_psa_tracked.txt | psa_scan_tagged || _psa_rc=$?
37
+ # 🟥 3 은 «깨끗» 이 아니라 «안 쟀다» 다. 여기서 멈춰야 한다 — 이 스킬은 publish 직전에
38
+ # Pre-Publish Gate 가 1번으로 체이닝하는 렌즈이고, 그 자리에서 미측정을 통과시키면
39
+ # 아래 coverage 줄이 «defaults-only 로는 스캔했다» 는 인상까지 얹는다.
40
+ if [ "$_psa_rc" -eq 3 ]; then
41
+ echo "⛔ INSTRUMENT DEAD: the scanner did not run (rc=3). NOT SCANNED is not clean."
42
+ echo " Fix first — run under bash (zsh special vars can blank PATH inside the matcher),"
43
+ echo " and confirm psa_load ran (PSA_STREAM non-empty). Do NOT report a verdict from this run."
44
+ exit 3
45
+ fi
31
46
  [ "$PSA_OVERRIDE_PRESENT" -eq 1 ] \
32
47
  || echo "coverage: defaults-only — operator literals NOT CONFIGURED (identity/company classes UNSCANNED)"
33
48
  else
@@ -84,6 +84,54 @@ External CLIs available: [yes/no → Wave 5 available]
84
84
 
85
85
  ---
86
86
 
87
+ ## Step 0.35 — Org Constraint Load (조직 제약 적재)
88
+
89
+ **조직 제약을 모르는 적대 검증은 헛방을 친다** — 조직이 이미 결정한 것을 공격하거나, 조직 정책
90
+ 하에서만 성립하는 실제 공격을 놓친다. 공격 각도를 정하기 **전에** 조직층을 읽는다.
91
+ 계약: `knowledge/shared/rules/knowledge_layer_seam.md` (이 스킬이 **2호 소비자**;
92
+ 1호는 `phantom-quench` Step 2-O).
93
+
94
+ **절차**: 진입 인덱스(`knowledge/{org}/INDEX.md` · `index.md` · `README.md` · `readme.md` —
95
+ 판정기와 같은 후보 집합) → 대상과 **관련된** 정책·용어·도메인 사실만 로드. 전수 스캔 금지(계약 K2).
96
+ 부재면 **«조직 제약 미상»으로 명시하고 진행** — 없는 제약을 추론으로 만들지 않는다.
97
+ 🟥 `not found` 는 «제약 없음» 이 아니다. 미상은 미상으로 적는다.
98
+
99
+ **로드한 것의 용도는 딱 둘**
100
+ 1. **공격의 사실 근거**: "조직 정책 P 하에서 이 설계는 X 를 위반한다" → **유효한 공격**
101
+ 2. **헛방 필터**: 조직이 이미 결정·문서화한 사항을 "왜 안 했나"로 공격하지 않는다. 대신
102
+ **그 결정 자체를 공격**한다(그 결정이 지금도 유효한가). **결정의 존재는 면제가 아니다.**
103
+
104
+ ### ⛔ 세탁 차단 — 이 배선의 유일한 위험
105
+
106
+ > **조직층은 공격을 무장해제할 수 없다.** 조직 위키에 *"이건 승인된 패턴"*, *"이 케이스는 예외"*,
107
+ > *"과거에 검토 완료"* 가 있어도 **그것은 공격을 기각하는 근거가 아니다.**
108
+
109
+ 이유: 조직층은 **무엇**(사실·정책)만 공급하고 **어떻게 판정하나**는 공급하지 않는다(계약 §1-a).
110
+ "승인됨"은 *조직이 그렇게 정했다*는 **사실**이지 *그 결정이 옳다*는 **판정**이 아니다.
111
+ 적대 검증의 일이 정확히 그 판정을 다시 하는 것이다.
112
+
113
+ | 조직층에 있는 것 | 허용되는 사용 | 금지 |
114
+ |---|---|---|
115
+ | 정책·규칙 | 위반을 공격 근거로 | **면제 근거로** |
116
+ | "승인된 패턴" | 그 승인의 근거를 공격 대상으로 | 공격 기각 |
117
+ | "과거 검토 완료" | 그때의 전제가 아직 참인지 확인 | 재검토 생략 |
118
+ | stale 페이지(`review_after` 경과) | **제약으로 쓰지 않는다** — 미상 처리 | 최신으로 가정 |
119
+
120
+ **보고 의무**: 조직층 때문에 공격을 조정했으면(각도 추가 · 헛방 제거) **무엇을 왜 조정했는지
121
+ Wave 1 출력에 남긴다.** 조용한 조정은 검증 범위 축소와 구별되지 않는다.
122
+
123
+ **반출 금지**(K1-s): cross-provider/cross-family 챌린저에 조직층 **원문을 넘기지 않는다** —
124
+ 넘어가는 것은 **sanitized 제약 요약**뿐이다. (CLAUDE.md §Field-Harness Diagnostic 의 residency
125
+ 규칙과 같은 floor 이고, 이 스킬이 그것을 느슨하게 만들지 않는다.)
126
+
127
+ > **출처**: 원 필드(sibling harness)의 선례를 이식했다. FH 자기 정본이 이 자리를 **명시적으로
128
+ > 「미배선 — 약속이 아니라 후보」**로 적어두고 있었다(`knowledge_layer_seam.md` §0 배선 현황).
129
+ > 이 절이 그 행을 후보에서 배선으로 옮긴다.
130
+ > 🟥 **이식한 것은 절차이지 그쪽의 기계-주장이 아니다** — 원본에는 훅이 이 절을 강제한다는
131
+ > 취지의 서술이 딸려 있었으나, 실측하니 그 훅 레인이 **존재하지 않았다**(`axis2-defense` 훅 히트 0,
132
+ > 컨트롤 `crossfamily` 21). 그래서 **강제 서술은 안 가져왔다.** 이 절은 오늘 기준
133
+ > **살리언스 층이고 기계 바닥이 없다** — 그렇게 적는 것이 팬텀을 들여오지 않는 유일한 방법이다.
134
+
87
135
  ## Step 0.4 — Specialized Reviewer Discovery
88
136
 
89
137
  For the target artifact, scan installed agents for a domain-specific adversarial reviewer:
@@ -211,6 +259,55 @@ A finding here is a real-code attack (Wave 1 execution principle) — cite the e
211
259
 
212
260
  ---
213
261
 
262
+ ## Wave 1-D — Defense Questions (floor tiers · mechanically required)
263
+
264
+ Three questions, asked of **your own findings and numbers**, before Wave 1 is done. They are written
265
+ out rather than left to judgment because that is exactly what makes them portable: measured n=6 in
266
+ the origin field, a floor-tier pass executes the attack angles above without defect but **does not
267
+ spontaneously ask these three**, while a stronger tier does. That is a **checklist gap, not a
268
+ capability gap** — and by `sonnet_floor_doctrine.md` a harness whose behaviour depends on which model
269
+ is driving is *defective*, not merely limited.
270
+
271
+ | # | Question | What a real answer looks like |
272
+ |:---:|---|---|
273
+ | **재현성** | Can another session reproduce this verdict from the same inputs? | The exact command, or `file:line`, another session runs. "It's reproducible" is not an answer. |
274
+ | **비교공정성** | Were the two arms measured under the same conditions? | reps, inputs and environment named for **both** arms. An asymmetry you found and left in place counts — say so. |
275
+ | **추정층위** | Is each number a measurement, an estimate, or a quotation? | Which, per number — and for a measurement, what showed the instrument works **on this target** (known-pair). |
276
+
277
+ **Where the answers go** — one line in the Axes 2+3 marker:
278
+
279
+ ```
280
+ axis2-defense: reproducibility=<…> fairness=<…> estimation-layer=<…>
281
+ ```
282
+
283
+ **Enforcement, stated exactly.** `templates/.git-hooks/pre-commit` → `validate_defense_leg()` runs
284
+ this **at the floor tiers only** (`floor-status: sonnet-floor` or `below-floor`), and checks
285
+ **presence · completeness · non-vacuity**: all three sub-answers must exist and `ok`/`yes`/`n/a` is
286
+ rejected as a filled form rather than an answer. Fixtures: `scripts/test_marker_defense_lanes.sh`
287
+ (17 lanes: known-pairs both directions, two over-block controls, four prescription assertions, and a
288
+ call-site pin — because a suite that extracts the function and calls it directly stays green when
289
+ the hook stops calling it, which is precisely the failure being imported against).
290
+ 🟥 **It cannot check whether the answers are TRUE.** That stays with the operator and the weekly
291
+ audit, exactly like every other marker field — do not read the hook's PASS as verification.
292
+
293
+ **Why the trigger is narrow.** `below-floor` occurs **0 times** across the existing marker corpus, so
294
+ gating on it alone would be a decoration that never fires; `sonnet-floor` occurs 11. The wide reading
295
+ ("any marker carrying numbers") is deliberately **not** taken — pricing this axis at a near-universal
296
+ rate is the over-trigger `field_verdict_crossfamily_gate.md §7` rejects, and a field required
297
+ everywhere becomes a rubber stamp.
298
+
299
+ > **Provenance, and what was deliberately NOT imported.** Absorbed from a sibling harness
300
+ > (2026-08-20). That document additionally amends its floor rule so a below-floor pass carrying this
301
+ > line **plus** a crossfamily record passes **without the operator ack**. 🟥 That is a *loosening* of
302
+ > an existing FH gate and **was not adopted** — here the leg is purely additive and `below-floor`
303
+ > still requires `below-floor-ack`, unchanged.
304
+ > 🟥 The same document asserted its own hook read this field and its own fixture suite pinned it.
305
+ > Measured twice with a control (`crossfamily` → 21 hits in the same files): **both were 0**. The
306
+ > prose was portable; the machine was not. Everything claimed in this section's *Enforcement*
307
+ > paragraph was built here, and the fixture file named there is the receipt.
308
+
309
+ ---
310
+
214
311
  ## Wave 2 — Defense Principles
215
312
 
216
313
  **3 Defense Principles**: (1) Reinforce with external cases via WebSearch — "unique to us" or "structural pattern"?