@chrono-meta/fh-gate 1.4.92 → 1.4.93
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +3 -3
- package/AGENTS.md +1 -1
- package/CHEATSHEET.md +1 -0
- package/CLAUDE.md +9 -1
- package/README.md +9 -4
- package/docs/codex-compat.md +1 -1
- package/knowledge/shared/harness-core/fh_detail_protocols.md +11 -0
- package/knowledge/shared/harness-core/gate_locality_principle.md +10 -0
- package/knowledge/shared/harness-core/return_path_gate.md +15 -0
- package/knowledge/shared/learnings/subagent_invocations_log.yaml +72 -0
- package/knowledge/shared/rules/knowledge_layer_seam.md +165 -0
- package/package.json +11 -2
- package/plugins/fh-commons/.claude-plugin/plugin.json +2 -2
- package/plugins/fh-commons/README.md +1 -0
- package/plugins/fh-commons/skills/ko-tech-writer/SKILL.md +157 -0
- package/plugins/fh-meta/.claude-plugin/plugin.json +1 -1
- package/plugins/fh-meta/skills/agent-composer/SKILL.md +3 -1
- package/plugins/fh-meta/skills/context-doctor/SKILL.md +4 -0
- package/plugins/fh-meta/skills/edit-manifest/SKILL.md +4 -0
- package/plugins/fh-meta/skills/harvest-loop/SKILL.md +19 -1
- package/plugins/fh-meta/skills/install-wizard/SKILL.md +26 -1
- package/plugins/fh-meta/skills/install-wizard/SKILL_detail.md +25 -4
- package/plugins/fh-meta/skills/phantom-quench/SKILL.md +44 -0
- package/plugins/fh-meta/skills/pipeline-conductor/SKILL.md +11 -3
- package/plugins/fh-meta/skills/steel-quench/SKILL.md +1 -1
- package/scripts/.env_purity_tokens.defaults +8 -0
- package/scripts/env_purity_scan.sh +50 -0
- package/scripts/fh_env_delta_scan.sh +16 -1
- package/scripts/gate_anchor_check.sh +344 -0
- package/scripts/knowledge_seam_check.sh +171 -0
- package/scripts/rtk_gross_ablation.sh +64 -0
- package/scripts/selfcheck.sh +15 -0
- package/scripts/session_close_check.sh +3 -0
- package/scripts/sidecar_calibrate.sh +32 -1
- package/scripts/test_env_purity_lanes.sh +30 -0
- package/scripts/test_knowledge_seam_lanes.sh +142 -0
- package/scripts/test_marker_axes_run_lanes.sh +115 -0
- package/scripts/test_sidecar_calibrate_lanes.sh +15 -1
- package/templates/.git-hooks/pre-commit +63 -2
- package/templates/CLAUDE.md +7 -0
- package/templates/starter_profile.md +2 -2
- package/tests/seam_absence_probes.md +31 -0
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ko-tech-writer
|
|
3
|
+
description: 'Writes or revises Korean technical prose across three registers — reader-facing documents (tech-blog posts, technical docs), spoken scripts, and derived compressed assets (teasers, summaries) — through a fixed pipeline: register detection, real-sample calibration of the target venue, a translationese-removal pass, honesty-level layering (reader information vs internal audit vocabulary), a number/claim gate, and a rendition + perceptual QA pass. Triggers: "기술문서 써줘", "테크블로그 초안 잡아줘", "이 문서 번역투 고쳐줘", "블로그체로 다듬어줘", "이 글 회사 기술블로그에 올릴 수 있게 다듬어줘".'
|
|
4
|
+
user-invocable: true
|
|
5
|
+
allowed-tools: ["Read", "Write", "Edit", "Bash", "Grep", "Glob", "WebFetch"]
|
|
6
|
+
model: sonnet
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# ko-tech-writer — 한국어 기술문서 집필·개고 파이프라인
|
|
10
|
+
|
|
11
|
+
독자 대면 한국어 기술 산출물(테크블로그 글 · 기술문서 · 발표 파생 자산)을 쓰거나 개고한다.
|
|
12
|
+
핵심 전제: **좋은 문장은 취향이 아니라 절차다** — 실물 표본으로 톤을 캘리브레이션하고,
|
|
13
|
+
번역투를 패턴 목록으로 제거하고, 수치는 근거와 창을 달고, 렌더 결과를 눈으로 확인한다.
|
|
14
|
+
|
|
15
|
+
> 출처: 2026-08-10 발표 기술문서 세션에서 실측으로 벼려진 규율의 자산화. 이 문서의 규칙
|
|
16
|
+
> 클래스는 그 세션의 개고에서 실제로 검출·수리된 것들이다 — 근거 원장은 그 세션 기록
|
|
17
|
+
> (`fh_completed_2026-08-10` 및 해당 개고 커밋 이력. 비공개 세션 기록이라 외부 배포본
|
|
18
|
+
> 독자에게는 도달하지 않는 내부 포인터다). **실측 근거가 없는 클래스를 추가하지 않는 것**이
|
|
19
|
+
> 이 문서의 유지 규칙이다. 이 SKILL.md 자체는 독자 대면 문서가 아니라 하네스 자산이므로
|
|
20
|
+
> 이 파이프라인의 적용 대상이 아니다(FH 하우스 스타일을 따른다).
|
|
21
|
+
|
|
22
|
+
## Step 0 — 대상 판별 (레지스터 분기)
|
|
23
|
+
|
|
24
|
+
같은 내용도 매체에 따라 규율이 다르다. 먼저 셋 중 무엇인지 정한다:
|
|
25
|
+
|
|
26
|
+
| 대상 | 레지스터 | 이 스킬의 적용 |
|
|
27
|
+
|---|---|---|
|
|
28
|
+
| **독자용 문서** (블로그 글·기술문서) | 문어 존댓말 (습니다체) | Step 1~5 전체 |
|
|
29
|
+
| **낭독 대본** (발표 스크립트) | 구어 발표체 | Step 2~4 만 — 구어 리듬 유지, 줄표는 «쉼»으로만 실현되므로 소리로 안 들리는 동격·재진술 줄표 제거 |
|
|
30
|
+
| **파생 압축 자산** (티저·요약 이미지·1장 슬라이드) | 자립형 평문 | Step 2~**5** + **자립성 검사**: 화면·본문 맥락 없이 서야 하므로 정본 어휘·주장 범위·은어를 따로 대조. 렌더 산출물을 만들면 Step 5 지각 QA 필수 |
|
|
31
|
+
|
|
32
|
+
검증된 원문에서 파생 자산을 만들 때도 재검사한다 — 압축은 주장 범위를 움직일 수 있다
|
|
33
|
+
(예: «지점 앞에서 벼려졌다» → «도메인에서 확인해 온»으로 줄면 담당 범위가 넓어져 읽힌다).
|
|
34
|
+
|
|
35
|
+
## Step 1 — 실물 캘리브레이션 (표본 없이 톤 단정 금지)
|
|
36
|
+
|
|
37
|
+
게재 매체가 지정되지 않았으면 **먼저 묻는다**(한 줄). 답을 받을 수 없는 환경이면 일반
|
|
38
|
+
규율로 진행하고 그 사실을 이력에 명기한다.
|
|
39
|
+
|
|
40
|
+
게재 목표 매체의 **실제 표본을 1편 이상** 확인(WebFetch)하고 세 가지를 기록한다:
|
|
41
|
+
|
|
42
|
+
1. **문체**: 존댓말 변형(습니다/해요), 도입 형식(질문형/선언형)
|
|
43
|
+
2. **구성**: 소제목 밀도, 마무리 관행(일반화 + 트레이드오프 + 실무 조언 등)
|
|
44
|
+
3. **시각물**: 다이어그램/그래프/표를 어느 밀도로 쓰는가
|
|
45
|
+
|
|
46
|
+
캘리브레이션 기록은 **산출물 이력**(작업 로그·PR 본문·문서 frontmatter)에 남긴다 — 게재
|
|
47
|
+
본문에는 노출하지 않는다. 표본을 확인할 수 없으면 **무엇을 시도했고 왜 안 됐는지**(호출
|
|
48
|
+
실패·매체 미상 등)를 같은 이력에 명기하고 일반 규율(습니다체·소제목 세분화)로 진행한다 —
|
|
49
|
+
확인 안 된 톤을 확정처럼 쓰지 않는다. **시도 기록 없는 «확인 불가»는 Done When 1조를
|
|
50
|
+
충족하지 않는다.**
|
|
51
|
+
|
|
52
|
+
## Step 2 — 문체 규율 (번역투 클래스 목록)
|
|
53
|
+
|
|
54
|
+
아래는 실측으로 검출된 클래스다. **기계 스캔 + 눈 판정**으로 제거한다
|
|
55
|
+
(grep은 후보를 표시할 뿐, 남길지 판정은 문맥으로):
|
|
56
|
+
|
|
57
|
+
| 클래스 | 검출 힌트 | 수리 |
|
|
58
|
+
|---|---|---|
|
|
59
|
+
| 줄표 이어붙임 「~다 — ~고,」 | `grep "다 — \|것 — \|음 — "` | 문장 분리. 줄표는 **일을 하는 곳만** 남긴다(열거 매달기·리듬 결속 — 남긴 이유를 적는다) |
|
|
60
|
+
| 용어-머리 «**X** — 설명» | 글머리 기호 뒤 `** — ` | «**X**: 설명» 콜론형 |
|
|
61
|
+
| 콜론 나열투 («관측된 분업은: …») | 서술어 없는 `:` 도입 | 완결 문장으로 («…분업은 ~라는 것입니다») |
|
|
62
|
+
| 조각문 («걸리는 층.») | 서술어 없는 마침 | 서술어 복원 («걸리는 층입니다») |
|
|
63
|
+
| 내부 조어·은어 | 팀 밖에서 안 쓰는 단어 (예: 렌더하다, 초록/빨강을 CI 결과 뜻으로) | 청중 어휘로 평문화. 단, **화면이 어휘를 받치면**(실제 빨간 화면을 가리키는 발화) 유지 가능 — 근거를 적는다 |
|
|
64
|
+
| 레지스터 드리프트 | 습니다↔해요↔평어 혼재 | 표본 기준 단일화 |
|
|
65
|
+
|
|
66
|
+
클래스의 성격이 갈린다: 앞 네 줄(줄표·용어-머리·콜론·조각문)은 **기계 검출 가능**(grep
|
|
67
|
+
후보 + 눈 판정)이고, 뒤 두 줄(내부 조어·레지스터)은 **판정 클래스**다 — Done When에서
|
|
68
|
+
서로 다른 check-class로 채점된다. 의도 보존으로 제외하는 항목은 **명명된 사유**(열거
|
|
69
|
+
매달기·리듬 결속·화면 받침)에 한하며, 제외 목록은 Step 5 콜드리드 짝에게 **통독이 끝난
|
|
70
|
+
뒤** 별도 패스로 전달해 대조받는다 — 사전 전달은 첫-읽기 눈을 오염시키고, 자기가 쓴
|
|
71
|
+
사유만으로 무제한 제외하지 않는다.
|
|
72
|
+
|
|
73
|
+
## Step 3 — 정직 수위 층 분리
|
|
74
|
+
|
|
75
|
+
정직함에는 두 층이 있고, 독자 문서에는 한 층만 싣는다:
|
|
76
|
+
|
|
77
|
+
- **싣는다 — 논지를 받치는 정직**: 한계 절, 소표본 명시, 자기 철회 사례, "측정 중".
|
|
78
|
+
이걸 빼면 글의 등뼈가 빠진다.
|
|
79
|
+
- **뺀다 — 내부 감사 어휘**: 검증 원장의 자기감사 디테일("실적은 X만 주장한다",
|
|
80
|
+
"도달만·채택 아님" 같은 규율-말투), 내부 등급/게이트 상태 세부. 내부 기록에는 남기고
|
|
81
|
+
독자 본문에서는 뺀다.
|
|
82
|
+
|
|
83
|
+
판단 기준 한 줄: **"이 문장이 독자의 다음 행동이나 판단을 바꾸는가?"** — 바꾸면 정보,
|
|
84
|
+
안 바꾸면 자기감사다. **문장 단위로 적용**하고, 한 절의 문장 대부분이 걸리면 절 단위로
|
|
85
|
+
제거를 검토한다. 경계 예시: «실패 3건은 내부 전용 API 의존이라 외부 재현이 안 된다»는
|
|
86
|
+
독자의 재현 판단을 바꾸므로 **정보**다. «실적은 머지된 것만 주장한다»는 저자의 집계 규율
|
|
87
|
+
서술이라 **자기감사**다.
|
|
88
|
+
|
|
89
|
+
## Step 4 — 수치·주장 게이트 (기존 검증 자산으로 라우팅 — 재발명 금지)
|
|
90
|
+
|
|
91
|
+
**분모는 기계로 연다**: 본문의 **아라비아 숫자 전수**를 grep으로 추출해 목록을 만들고,
|
|
92
|
+
수치 주장이 아닌 항목(버전 표기·목차 번호·연도 등)을 **사유와 함께 제외**한 뒤, 남은 각
|
|
93
|
+
행에 아래 라벨 중 하나를 단다. 단위 목록으로 좁혀 시작하지 않는다 — 영문 단위(ms·GB)가
|
|
94
|
+
새기 때문이다. 한글 수사("세 배")는 아라비아 전수로도 못 잡으므로 **눈 판정 잔여**로
|
|
95
|
+
명기하고 통독에서 본다. 자기 눈으로 고른 수치만 채점하는 것은 measured가 아니다.
|
|
96
|
+
|
|
97
|
+
수치·주장에는 **두 가지 라벨**이 있고 서로 다른 상태다 — 섞지 않는다:
|
|
98
|
+
|
|
99
|
+
- **«발행 직전 재측정 대상»** — 근거는 확인됐으나 **시간이 지나면 값이 변하는** 것
|
|
100
|
+
(다운로드·별 수·테스트 수). 측정 시점·조건(창)을 병기하고 이 라벨을 단다.
|
|
101
|
+
- **«미확인»** — **근거 실물을 아직 확인하지 못한** 주장. 창을 지어 붙이지 않는다(조작된
|
|
102
|
+
정밀도). 라벨과 확인 경로(어느 저장소·로그를 보면 닫히는지)를 적고, 발행 전 해소를
|
|
103
|
+
필수로 남긴다. 미발견은 "미확인"이지 "없음"이 아니다.
|
|
104
|
+
|
|
105
|
+
기록에 없는 실적·사례는 1차 출처(저장소·PR·로그)를 직접 조회해 확인하고 나서 싣는다.
|
|
106
|
+
- **출처 역추적이 필요하면** `/phantom-quench` 로, **차트를 그리게 되면** 차트 작성 전에
|
|
107
|
+
dataviz 스킬을 먼저 로드한다. 프로젝트에 금지·조건 수치 목록(원장)이 있으면 발행 전
|
|
108
|
+
1패스 대조한다. 이 스킬은 **외부 검증 도구를 재발명하지 않는다**(출처 검증·차트 검증은
|
|
109
|
+
위 라우팅으로) — 스킬 안의 grep 열거·스캔은 절차의 일부이지 검증기 신설이 아니다.
|
|
110
|
+
|
|
111
|
+
## Step 5 — 렌디션 + 지각 QA
|
|
112
|
+
|
|
113
|
+
- **md 정본은 항상** 만든다. 다이어그램은 mermaid(GitHub·주요 뷰어 네이티브 렌더).
|
|
114
|
+
- **HTML/PDF 렌디션은 조건부** — 요청이 명시했거나 게재 채널이 요구할 때만 만든다(판단
|
|
115
|
+
주체는 요청/채널이지 저자의 재량이 아니다): 자체완결 HTML(외부 의존 없는 인라인 SVG
|
|
116
|
+
다이어그램, 시스템 한글 폰트 스택, `@page` 인쇄 규칙) → headless Chrome `--print-to-pdf`.
|
|
117
|
+
- **지각 QA(필수 — 렌더 산출물이 있을 때)**: 렌더 결과를 **전 페이지 눈으로** 확인한다 —
|
|
118
|
+
라벨 잘림(한글 받침), 페이지 나눔, 표/그림 겹침, 다이어그램 텍스트 가림. 도구 exit 0은
|
|
119
|
+
렌더 성공이지 가독성 판정이 아니다. 판정 짝은 **독립 2차 지각 패스**(다른 눈이 같은
|
|
120
|
+
렌더를 봄)다 — 콜드리드는 내용을 읽지 렌더 결함을 보지 않으므로 짝이 될 수 없다.
|
|
121
|
+
- **발행 전 콜드리드 1패스**: 격리된 검토가 처음 읽는 눈으로 통독한다. 저자는 자기 글의
|
|
122
|
+
전제 결손을 못 본다. **격리의 정의**: 저작 맥락을 상속하지 않는 실행이다. 같은 레포에서
|
|
123
|
+
띄운 서브에이전트는 프로젝트 지침·메모리를 상속하므로 **완전 블라인드가 아니다** — 저작
|
|
124
|
+
맥락 차단이 필요한 판정(전제 결손·자기 어휘 검사)은 레포 밖 cwd의 headless 실행 +
|
|
125
|
+
컨트롤(알려진 결함 1건 동반)로 하고, 통독 수준 검토는 다른 에이전트로도 되지만 **어느
|
|
126
|
+
격리 수준이었는지 이력에 적는다.** 에이전트 디스패치는 호출 세션의 권한·도구를 따른다
|
|
127
|
+
(이 스킬의 allowed-tools 밖의 일이다). 강격리도 비저자 짝도 구할 수 없으면 해당 judged
|
|
128
|
+
조건을 **미충족으로 명시**하고 발행 판단자에게 넘긴다 — 자기 검토로 대체하지 않는다.
|
|
129
|
+
|
|
130
|
+
## Done When
|
|
131
|
+
|
|
132
|
+
| 조건 | check-class |
|
|
133
|
+
|---|---|
|
|
134
|
+
| 대상 매체 실물 표본 확인 기록이 산출물 이력에 존재 — 불가 시 **시도 내용·사유 포함** 명기(시도 기록 없는 «불가»는 불충족) | mandatory-pass |
|
|
135
|
+
| Step 2 **기계 클래스**(줄표·용어-머리·콜론·조각문) 스캔 잔여 0 — 컨트롤(알려진 양성 1건) 동반, 제외는 명명 사유와 함께 목록화 | measured |
|
|
136
|
+
| Step 2 **판정 클래스**(내부 조어·레지스터) 통과 | judged — 짝: 콜드리드 통독(통독 후 제외 목록 대조) |
|
|
137
|
+
| 본문 수치 전건(기계 추출 분모 기준)이 라벨(창 병기/재측정 대상/미확인) 동반 | measured |
|
|
138
|
+
| 렌더 산출물(HTML/PDF/이미지 — 파생 압축 자산 포함)이 존재하는 경우 전 페이지 지각 확인 — md-only 산출이면 N/A 명기 | judged — 짝: **독립 2차 지각 패스**(다른 눈이 같은 렌더를 봄) |
|
|
139
|
+
| 발행 전 콜드리드 통독 완료 — 격리 수준(강/약) 이력 기록. Step 5 미적용 레지스터(낭독 대본)는 N/A 명기 | judged — 짝: 격리 검토(Step 5 정의) |
|
|
140
|
+
| 정직 수위 분리(Step 3)가 적용됨 | judged — 짝: 발행 승인자 확인 또는 격리 적대 검토. 둘 다 불가하면 **미충족으로 명시 보고**(자기 검토로 대체 금지) |
|
|
141
|
+
|
|
142
|
+
## 역할 경계 (중복 아님을 명시)
|
|
143
|
+
|
|
144
|
+
- `hub-persona-auditor` **에이전트** — 완성된 대외 초안의 **페르소나 감사**(검토). 이 스킬은
|
|
145
|
+
**저작·개고 절차**다. Step 5 콜드리드에서 그 에이전트를 짝으로 쓸 수 있다(라우팅 관계).
|
|
146
|
+
- `harness-doctor --lint` — **하네스 자산**의 언어 패턴(자기마케팅) 검출. 이 스킬은 독자
|
|
147
|
+
대면 문서가 대상이고 번역투·레지스터·정직 수위까지 다룬다.
|
|
148
|
+
- 플랫폼 내장 문서 기능 — 특정 문체 캘리브레이션·정직 수위 층 분리·지각 QA 파이프라인은
|
|
149
|
+
내장에 없다(이 스킬이 더하는 것은 거버넌스다).
|
|
150
|
+
|
|
151
|
+
독립 실행 및 degrade 경로: phantom-quench·dataviz 미설치 → 해당 라우팅을 수동 대조로 ·
|
|
152
|
+
WebFetch 불가 → Step 1 «확인 불가» 경로(시도 기록 의무) · headless Chrome 부재 →
|
|
153
|
+
HTML/PDF 렌디션을 «미생성»으로 명기하고 md 정본만 산출. 각 degrade는 산출물 이력에 적는다.
|
|
154
|
+
|
|
155
|
+
**언어 범위**: 이름 그대로 **한국어 전용**이다. Step 0·1·3·4·5의 구조는 언어 무관이지만
|
|
156
|
+
Step 2 문체 클래스가 전부 한국어 실측이라, 영어 지원은 영어 실측 클래스가 쌓인 뒤 별도
|
|
157
|
+
확장(`en-` 자매 또는 일반화)으로 간다 — 실측 없는 클래스를 미리 짓지 않는다(유지 규칙).
|
|
@@ -478,7 +478,9 @@ All stages Step 0~6 complete
|
|
|
478
478
|
or user has confirmed Wave end
|
|
479
479
|
+ When deliberation was invoked: wait for verdict before closing Wave N+1;
|
|
480
480
|
verdict folds back into Step 4-b fan-in result set
|
|
481
|
-
+ Auto-recording gate (Step 4-c) complete (
|
|
481
|
+
+ Auto-recording gate (Step 4-c) complete — confirmed by the RECORD ARTIFACT (harvest output
|
|
482
|
+
file exists on disk + harvest-loop typed `Verdict:` line read), never by a completion notice
|
|
483
|
+
alone (completed-notice ≠ completion — return-path audit 2026-08-10)
|
|
482
484
|
```
|
|
483
485
|
|
|
484
486
|
> **Sprint Contract**: Done When must be in an externally verifiable contract format — "criteria a third party can confirm," not "when it feels done." (Anthropic official validation 2025)
|
|
@@ -212,6 +212,10 @@ The reductions above all act on the **context-footprint** axis (files, history r
|
|
|
212
212
|
**Two ways to reduce, safest first:**
|
|
213
213
|
1. **Per-call narrow flags (default — non-lossy, no install).** Prefer narrow commands: `git log --oneline -N` over bare `git log`, `--quiet` on noisy tools, `head`/`tail` on long output. The agent chooses what to drop, per call — no blind heuristic. This suffices for almost every session.
|
|
214
214
|
2. **A command-output proxy/hook (only under token scarcity).** A **Claude Code hook that rewrites verbose commands through a token-reducing proxy**, transparent (0 prompt-side overhead). Recommended tool: **`rtk` (Rust Token Killer)**, a CLI proxy that filters dev-command output (the tool reports ~60–90% savings on dev operations), wired so `git status` → `rtk git status` happens automatically.
|
|
215
|
+
- **Measure, don't quote**: `bash scripts/rtk_gross_ablation.sh [repo]` measures the actual gross
|
|
216
|
+
cut on YOUR env's command-output slice (instrument-check first — a dead filter emits stubs that
|
|
217
|
+
fake 82–100% cuts). The vendor band above is a claim; the script returns a local measurement — a char/4 approximation whose error direction is toward OVER-stating the cut
|
|
218
|
+
(e.g. 68.3% on the FH repo slice, 2026-08-10 — your number will differ; measure yours). NET (context-loss) stays unmeasured either way.
|
|
215
219
|
- ⚠️ **Name collision**: there is an unrelated `reachingforthejack/rtk` (Rust Type Kit). Verify the Token-Killer build — `rtk gain` (savings analytics) should work; "command not found" means the wrong binary.
|
|
216
220
|
- **No-reinvention**: FH **routes to** this tool; it does not rebuild a token-killer. Install + hook wiring live in the user's own config (global `CLAUDE.md` / `settings.json`), never reimplemented here.
|
|
217
221
|
- ⚠️ **Never filter a command whose output a mechanical gate parses.** FH gates read raw command output (a pre-commit hook greps, `regression_guard` diffs). A filtered `git diff` / `git log` feeding a gate gives the gate wrong input — the same trap as grepping filtered prose for a verdict (typed-verdict-channel). Keep filtering off gate-input paths, and keep a raw escape hatch (`rtk proxy <cmd>`).
|
|
@@ -242,6 +242,10 @@ RECORD mode:
|
|
|
242
242
|
|
|
243
243
|
VERIFY mode:
|
|
244
244
|
All pending entries checked (canonical + legacy freeform reconciled to pending)
|
|
245
|
+
+ Final output line, EVERY exit path including no-pending: literal `Verdict: PASS` |
|
|
246
|
+
`Verdict: PASS (no pending entries)` | `Verdict: CONDITIONAL_PASS` (rejected buffer non-empty —
|
|
247
|
+
attach the list on the same line) | `Verdict: FAIL` — nothing after it; callers gate on this
|
|
248
|
+
line (return-path audit + codex S2 2026-08-10)
|
|
245
249
|
+ validation_type classified (mechanical / judged / untestable)
|
|
246
250
|
+ match_score recorded with cited evidence (mechanical: delta; judged: one cited observation)
|
|
247
251
|
+ Gate decisions applied (accepted / redefine / rejected / pending)
|
|
@@ -25,6 +25,8 @@ model-note: session-inherit — Sonnet base is first-class (sonnet_floor_doctrin
|
|
|
25
25
|
**Lightweight mode Done When**:
|
|
26
26
|
```
|
|
27
27
|
Step 0 (Regression Guard) + Step 1 (field-harvest) + Step 2 (contention-layer) + Step 5 (verify-bidirectional) complete
|
|
28
|
+
+ record artifact path printed + final `Verdict:` line emitted — lightweight mode promises the SAME
|
|
29
|
+
consumer contract as full mode (agent-composer Step 4-c gates on artifact + verdict; codex M1 2026-08-10)
|
|
28
30
|
+ harvested pattern summary 1~3 lines output
|
|
29
31
|
+ "run full harvest-loop?" proposed (if patterns found)
|
|
30
32
|
+ [Card update prohibited] Do NOT update reference_next_session_starter.md in lightweight mode alone
|
|
@@ -216,8 +218,15 @@ Read reference_next_session_starter.md → apply Step 0-b removal list → add n
|
|
|
216
218
|
|
|
217
219
|
```
|
|
218
220
|
All stages Step 0-c → 0 → 1 → 2 → 3 (parallel) → 3.5 → 3.75 → 4 → 5 complete
|
|
219
|
-
+ Step 0-c: edit-manifest
|
|
221
|
+
+ Step 0-c: edit-manifest verdict received (rejected buffer non-empty → surfaced as an
|
|
222
|
+
Observability flag in the final list, never silently passed) + memory-hygiene scan run
|
|
223
|
+
(scheduling-only — callee self-contained via its own HITL; no verdict folds back BY DESIGN,
|
|
224
|
+
declared here so the absence reads as intent, not omission)
|
|
220
225
|
+ Step 3.75 Critic verdict received (PASS/CONDITIONAL PASS/FAIL stated) before Step 4
|
|
226
|
+
+ Step 4 harness-doctor verdict received — M-tier findings demote/separate the affected
|
|
227
|
+
candidates (same routing as Critic FAIL), never proceed unread
|
|
228
|
+
+ Step 5 verify-bidirectional verdict received — FAIL (= baseline requires redesign) routes the
|
|
229
|
+
affected baseline to redesign, never into the proposal list
|
|
221
230
|
+ synthesizer grade readjustment complete (rejected candidates separated)
|
|
222
231
|
+ Final proposal list output (sorted by HIGH/MED)
|
|
223
232
|
+ User Y/N approval gate complete
|
|
@@ -225,6 +234,15 @@ All stages Step 0-c → 0 → 1 → 2 → 3 (parallel) → 3.5 → 3.75 → 4
|
|
|
225
234
|
→ 6-1: STALE candidate list + merge candidates
|
|
226
235
|
→ 6-2: INDEX-ORPHAN/FILE-ORPHAN/MEM-STALE detection results
|
|
227
236
|
+ [Required] reference_next_session_starter.md delta update complete
|
|
237
|
+
|
|
238
|
+
**Typed verdict — the last output line, consumed by callers (pipeline-conductor Step 1 ·
|
|
239
|
+
agent-composer Step 4-c):**
|
|
240
|
+
`Verdict: PASS` (all steps green) | `CONDITIONAL_PASS` (sub-threshold skips/held patterns — list
|
|
241
|
+
them on the same line) | `FAIL` (Critic FAIL unresolved after one re-synthesis · drift detected) |
|
|
242
|
+
`ESCALATE` (operator decision required). Callers gate on this line, not on prose — harvest-loop
|
|
243
|
+
was the only core pipeline skill without a typed verdict and made 5 chains fire-and-forget
|
|
244
|
+
(return-path audit 2026-08-10). **The `Verdict:` line is the FINAL output line — emit nothing
|
|
245
|
+
after it; consumers read a missing/malformed final `Verdict:` line as `ESCALATE`, never as pass.**
|
|
228
246
|
→ BEFORE N items → AFTER M items diff output required (proof gate)
|
|
229
247
|
→ No diff (N=M) = warning + Step 0-b re-check
|
|
230
248
|
→ Completed items remaining = bug (Done When not met)
|
|
@@ -205,7 +205,19 @@ recording it rather than implying an expiry alarm exists.
|
|
|
205
205
|
|
|
206
206
|
### Step 4. Acceleration Baseline Setup
|
|
207
207
|
|
|
208
|
-
After executing approved items,
|
|
208
|
+
After executing approved items, offer the automatic maintenance structure — **each piece is its own
|
|
209
|
+
Y/N, none is folded into an unconditional batch** (decline-integrity sim 2026-08-10: the earlier
|
|
210
|
+
"batch" wording had the zshrc hook and the SessionStart registration running without a gate, which
|
|
211
|
+
contradicted this skill's own Per-item-approval principle): zshrc hook (idempotent, **preview the
|
|
212
|
+
exact block, then Y/N**) + SessionStart floor-check hook registration (**Y/N — it writes to
|
|
213
|
+
`.claude/settings.json`**) + sentinel initialization (per-project) + weekly-audit cadence (no cron —
|
|
214
|
+
zshrc hook + session-start detection are the durable mechanisms).
|
|
215
|
+
|
|
216
|
+
**Every N is recorded, not just skipped**: append the item key to
|
|
217
|
+
`~/.cc_sentinels/{project}_wizard_declined`. A declined item means the corresponding intended FH
|
|
218
|
+
feature does not run (declined zshrc = no shell-side audit nag · declined SessionStart hooks = no
|
|
219
|
+
turn-0 floor/env-delta/companion signal — those fall back to session prose, which is
|
|
220
|
+
salience-dependent). State this at decline time in one line.
|
|
209
221
|
|
|
210
222
|
**4-axis pre-commit gate (behavioral — OPT-IN, double-confirm)**: Mode D / FH-self-development only. It gates commits **in the user's FH clone** and is **never installed into field projects** (FH-internal infra — see `auto_project_mapping.md §6`). Not auto-run: a separate explicit Y/N, never folded into the baseline-setup batch.
|
|
211
223
|
|
|
@@ -215,6 +227,19 @@ After executing approved items, install the automatic maintenance structure: zsh
|
|
|
215
227
|
|
|
216
228
|
Output the completion summary (executed/skipped/later counts + what runs automatically from now on) followed by next-step skill suggestions, FH contribution guidance, Mode D companion-store pointer, and the fork-your-own-hub option.
|
|
217
229
|
|
|
230
|
+
**If any item was declined or deferred, the summary MUST also carry a consequences block**
|
|
231
|
+
(operator requirement 2026-08-10 — a decline is respected, never silent):
|
|
232
|
+
- the declined items by name, and the plain statement that **the corresponding intended FH features
|
|
233
|
+
will not run in this state** (which gates/hooks/automation are off);
|
|
234
|
+
- how to change your mind: re-run `/install-wizard` (declined items are re-proposed, approved ones
|
|
235
|
+
are not re-asked);
|
|
236
|
+
- that a **one-line per-session reminder** will note the not-installed state until resolved —
|
|
237
|
+
mechanical via the env-delta SessionStart hook where hooks were accepted, session prose where they
|
|
238
|
+
were declined (an unwired node has no hook to remind with — named residual: a task-first entry on
|
|
239
|
+
a fully-unwired node has no reminder surface at all);
|
|
240
|
+
- how to silence the reminder deliberately: `touch ~/.cc_sentinels/{project}_wizard_reminder_muted`
|
|
241
|
+
(recorded as its own decision, not a default).
|
|
242
|
+
|
|
218
243
|
> **Detail**: See `SKILL_detail.md §Step5-Completion-Report` — full completion report template — read when executing Step 5.
|
|
219
244
|
|
|
220
245
|
## Re-run (Inspection Mode)
|
|
@@ -506,8 +506,13 @@ Output preview before execution:
|
|
|
506
506
|
## §Step4-Baseline-Bash
|
|
507
507
|
|
|
508
508
|
```bash
|
|
509
|
-
# zshrc hook
|
|
509
|
+
# zshrc hook — preview then confirm. The wizard is AI-mediated: SHOW the user the exact block
|
|
510
|
+
# below and ask in-chat "Append this to ~/.zshrc? (Y/N)" BEFORE running the append. An earlier
|
|
511
|
+
# revision's comment promised preview-then-confirm while the bash appended unconditionally —
|
|
512
|
+
# the decline-integrity sim (2026-08-10) caught the mismatch; the gate is the instruction, the
|
|
513
|
+
# bash below runs ONLY on Y.
|
|
510
514
|
if ! grep -q "fh_audit_check.zsh" ~/.zshrc 2>/dev/null; then
|
|
515
|
+
# (run only after an explicit in-chat Y)
|
|
511
516
|
cat >> ~/.zshrc << 'EOF'
|
|
512
517
|
export FH_DIR="{FH_DIR}"
|
|
513
518
|
export CC_HUB_DIR="{CC_HUB_DIR}"
|
|
@@ -515,12 +520,28 @@ export CC_SENTINELS_DIR="$HOME/.cc_sentinels"
|
|
|
515
520
|
source "$FH_DIR/templates/fh_audit_check.zsh"
|
|
516
521
|
EOF
|
|
517
522
|
fi
|
|
523
|
+
# On N: do NOT append; record the decline and state its consequence in one line —
|
|
524
|
+
# echo "zshrc_hook" >> "$HOME/.cc_sentinels/{project}_wizard_declined"
|
|
525
|
+
# "declined — shell-side audit nag off; only session-start prose detection remains."
|
|
518
526
|
|
|
519
527
|
# Node floor check hook — ALL users, not Mode D only. Source of truth = the tracked snippet
|
|
520
528
|
# templates/settings.SessionStart.snippet.json (`project_settings_json` key). Registration itself
|
|
521
|
-
# cannot be tracked (every .claude/settings*.json path is gitignored), so the wizard is what wires it
|
|
522
|
-
#
|
|
523
|
-
#
|
|
529
|
+
# cannot be tracked (every .claude/settings*.json path is gitignored), so the wizard is what wires it.
|
|
530
|
+
#
|
|
531
|
+
# ⚠️ Y/N GATE (added 2026-08-10 — decline-integrity sim finding D): this block WRITES to
|
|
532
|
+
# .claude/settings.json, so it gets the same explicit in-chat gate as the 4-axis block below —
|
|
533
|
+
# it was the only settings-writing step without one (structural asymmetry, and a violation of this
|
|
534
|
+
# skill's own Per-item-approval principle). Ask BEFORE running the python:
|
|
535
|
+
# "Register the SessionStart hooks (floor check · env-delta · companion load) into
|
|
536
|
+
# .claude/settings.json? (Y/N)
|
|
537
|
+
# On N: you get no turn-0 mechanical signal — floor gaps, env changes and companion freshness
|
|
538
|
+
# fall back to session prose, and some of FH's intended features will not run as designed.
|
|
539
|
+
# The decline is recorded and a one-line per-session reminder will note the state
|
|
540
|
+
# (re-run /install-wizard to change it; mute deliberately via
|
|
541
|
+
# ~/.cc_sentinels/{project}_wizard_reminder_muted)."
|
|
542
|
+
# On N: echo "sessionstart_hooks" >> "$HOME/.cc_sentinels/{project}_wizard_declined" and SKIP the
|
|
543
|
+
# python below entirely. "Must not be skipped" in the earlier wording meant the wizard must not
|
|
544
|
+
# FORGET this step — it never licensed skipping the user's consent.
|
|
524
545
|
# NPM-INSTALL PRECONDITION: this block reads the snippet from disk, so both it and
|
|
525
546
|
# scripts/fh_node_check.sh must be in package.json `files[]`. They are (added 2026-07-30 after
|
|
526
547
|
# scripts/package_coverage_check.sh caught the omission — without it an npm-installed wizard hit
|
|
@@ -246,6 +246,50 @@ paper citation that is Unsupported is **at least A** — a published wrong citat
|
|
|
246
246
|
|
|
247
247
|
---
|
|
248
248
|
|
|
249
|
+
### Step 2-O. Org Knowledge Layer — the third grounding surface for domain claims
|
|
250
|
+
|
|
251
|
+
Step 2 grounds claims against **locally declared files**; Step 2-E grounds **externally cited
|
|
252
|
+
sources**. **Domain claims** — org-specific facts, terminology, policy ("this service's policy is X",
|
|
253
|
+
"here Y means Z") — hit neither surface and all fall to 🔴 Source-Missing, even though the org
|
|
254
|
+
knowledge layer is exactly their ground. It was simply not on the search path. This step is that
|
|
255
|
+
wiring. Contract: `knowledge/shared/rules/knowledge_layer_seam.md` (this skill is its first FH
|
|
256
|
+
consumer; machine check = `scripts/knowledge_seam_check.sh`).
|
|
257
|
+
|
|
258
|
+
**When it fires**: the claim is (a) an org-specific fact/term/policy and (b) **undeclared** in
|
|
259
|
+
Step 2 (a 🔴 candidate). A declared source always wins — this step is an **additional surface,
|
|
260
|
+
never a replacement**.
|
|
261
|
+
|
|
262
|
+
**Procedure** (reuses Step 2's typed-anchor rule — no new adjudication method):
|
|
263
|
+
1. Read the org entry index first — `knowledge/{org}/INDEX.md` or `index.md`/`README.md`
|
|
264
|
+
(the checker accepts all; case matters on Linux). **Never full-scan** (contract K2).
|
|
265
|
+
2. Apply the same typed anchor as Step 2 to candidate pages — the grep hit must be in the
|
|
266
|
+
**claiming slot** and quoted literally as `file:line: matched text`. A token existing somewhere
|
|
267
|
+
is not grounding.
|
|
268
|
+
3. Check the hit page's frontmatter `review_after` (contract K3-f).
|
|
269
|
+
|
|
270
|
+
**Classification**
|
|
271
|
+
|
|
272
|
+
| Situation | Verdict | Why |
|
|
273
|
+
|---|---|:---:|
|
|
274
|
+
| Slot hit + `review_after` not elapsed | **Grounded** | ✅ |
|
|
275
|
+
| Slot hit + **`review_after` elapsed** | **Partial** | ⚠️ **stale ground is not ground** — do not pretend freshness |
|
|
276
|
+
| Slot hit + no date | **Partial** | ⚠️ freshness **unknown** — do not assume current |
|
|
277
|
+
| No hit | keep 🔴 | state explicitly that the org layer lacks it too |
|
|
278
|
+
| `knowledge/{org}/` **absent** | keep 🔴 + mark **UNMEASURED** | ⚠️ **absence is not zero** — "no context" ≠ "confirmed groundless"; never fill by inference |
|
|
279
|
+
|
|
280
|
+
**Two boundaries that are never crossed** (contract §1-a · K1-s):
|
|
281
|
+
|
|
282
|
+
- **The org layer supplies *what*, never *how to judge*.** An org wiki rule like "this case passes
|
|
283
|
+
as an exception" cannot override this skill's verdict criteria. On conflict the skill wins **and
|
|
284
|
+
the conflict is reported** — otherwise org custom silently bypasses the gate.
|
|
285
|
+
- **Org-layer content never leaves.** Even when Step 2-E fetches or dispatches externally, raw
|
|
286
|
+
`knowledge/{org}/` content does not go out — only sanitized summaries do.
|
|
287
|
+
|
|
288
|
+
*(Adversarial pair for the contract's absence-declaration clause: `tests/seam_absence_probes.md` —
|
|
289
|
+
5 fixed prompts, pass = 5/5 explicit absence declarations.)*
|
|
290
|
+
|
|
291
|
+
---
|
|
292
|
+
|
|
249
293
|
### Step 2.7. Split-Pair Bidirectional Integrity (SKILL.md ↔ SKILL_detail.md)
|
|
250
294
|
|
|
251
295
|
**Runs only when the artifact is a split pair** — a `SKILL.md` (or any doc) that carries
|
|
@@ -114,11 +114,19 @@ Run `/return-path-gate --skill [scope]`.
|
|
|
114
114
|
|
|
115
115
|
Check for harvest-loop signals in the current session — read session context rather than invoking harvest-loop directly (a mid-sweep invocation would conflict with the sweep's own pattern collection).
|
|
116
116
|
|
|
117
|
+
**Typed-first parsing (codex M3 2026-08-10)**: if a harvest-loop output block exists, classify
|
|
118
|
+
ONLY from its final non-empty `Verdict:` line; absent/malformed → `ESCALATE`. The prose rows below
|
|
119
|
+
apply ONLY to pre-contract historical runs (no typed line anywhere in the output).
|
|
120
|
+
|
|
117
121
|
| harvest-loop result | pipeline-conductor verdict |
|
|
118
122
|
|---|---|
|
|
119
|
-
|
|
|
120
|
-
|
|
|
121
|
-
|
|
|
123
|
+
| Typed `Verdict: PASS` | `PASS` |
|
|
124
|
+
| Typed `Verdict: CONDITIONAL_PASS` | `CONDITIONAL_PASS` (carry the attached skip-list into the report) |
|
|
125
|
+
| Typed `Verdict: FAIL` | `FAIL` |
|
|
126
|
+
| Typed `Verdict: ESCALATE` | `ESCALATE` (own handling — never collapsed into FAIL) |
|
|
127
|
+
| (legacy, no typed line) all steps pass prose | `PASS` |
|
|
128
|
+
| (legacy, no typed line) patterns found but no blockers | `CONDITIONAL_PASS` — capture pattern list |
|
|
129
|
+
| (legacy, no typed line) drift/failure prose | `FAIL` |
|
|
122
130
|
| Did not run this session | `CONDITIONAL_PASS` — note: knowledge loop not validated |
|
|
123
131
|
| Auto-skipped (< 3 patterns) | `CONDITIONAL_PASS` — note: sub-threshold, not validated |
|
|
124
132
|
|
|
@@ -475,7 +475,7 @@ over **unchanged** code:
|
|
|
475
475
|
| Attack angle is a harness structure problem | `/harness-doctor` | optional |
|
|
476
476
|
| After Wave convergence, propose new pattern rules | `fh-meta:persona-innovator` | optional |
|
|
477
477
|
| Wave 1 structure-specific attack (6-axis) | `fh-commons:quench-challenger` | priority |
|
|
478
|
-
| Back-trace whether claims exist in source files | `/phantom-quench` | **mandatory** when `phantom_risk=true` OR `scope=external` (
|
|
478
|
+
| Back-trace whether claims exist in source files | `/phantom-quench` | **mandatory** when `phantom_risk=true` OR `scope=external` — **its verdict folds back: a load-bearing Phantom = a new S-grade finding, convergence blocked until closed** (routing defined in tpa_schema.md §Gate Routing Table — read it when this fires) |
|
|
479
479
|
|
|
480
480
|
**steel-quench → sim-conductor gate**: After Wave convergence in external-publish context, `/sim-conductor Area A` is the mandatory next step.
|
|
481
481
|
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# env_purity_scan.sh — 공유층 환경-순도 계기 (2026-08-10, 운영자 제안 «자체점검기 모듈화»)
|
|
3
|
+
#
|
|
4
|
+
# 무엇을 재나: 공유층(scripts/ knowledge/shared/ templates/ plugins/ CLAUDE.md AGENTS.md)에
|
|
5
|
+
# **특정 환경에만 뜻이 있는 산문**(공개-환경: npm publish·레지스트리·launchd… / 조직-환경:
|
|
6
|
+
# 로컬 목록)이 몇 파일에 실려 있는지. 이 산문은 다른 환경에서 «깨지는» 게 아니라 **적용 불능인
|
|
7
|
+
# 죽은 텍스트**가 된다 — 동기화 때마다, 그리고 FH 큰 업그레이드 때 돌아볼 대상 목록이다.
|
|
8
|
+
#
|
|
9
|
+
# ADVISORY BY DESIGN: 목록을 내지 차단하지 않는다 (환경 서술이 본문에 있는 것 자체는 결함이
|
|
10
|
+
# 아니고, 포인터화 여부는 판단이다). exit 0 = 보고 완료 · exit 10 = 계기 오류(판정 불가).
|
|
11
|
+
#
|
|
12
|
+
# 토큰 2층 (public-surface-patterns 와 같은 패턴):
|
|
13
|
+
# scripts/.env_purity_tokens.defaults tracked — 공개-환경 토큰 (공개 사실만)
|
|
14
|
+
# .claude/rules/.env-purity-tokens gitignored — 환경별 추가 토큰 (조직 식별자는 여기만)
|
|
15
|
+
#
|
|
16
|
+
# Usage: scripts/env_purity_scan.sh [REPO_DIR]
|
|
17
|
+
set -uo pipefail
|
|
18
|
+
REPO="${1:-$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)}"
|
|
19
|
+
DEF="$REPO/scripts/.env_purity_tokens.defaults"
|
|
20
|
+
LOCAL="$REPO/.claude/rules/.env-purity-tokens"
|
|
21
|
+
|
|
22
|
+
[ -f "$DEF" ] || { echo "⛔ env-purity: 기본 토큰 목록 부재($DEF) — 판정 불가"; exit 10; }
|
|
23
|
+
TOKENS=$(grep -v '^\s*#' "$DEF" | grep -v '^\s*$')
|
|
24
|
+
[ -f "$LOCAL" ] && TOKENS="$TOKENS
|
|
25
|
+
$(grep -v '^\s*#' "$LOCAL" | grep -v '^\s*$')"
|
|
26
|
+
[ -n "$TOKENS" ] || { echo "⛔ env-purity: 토큰 0개 — 판정 불가"; exit 10; }
|
|
27
|
+
|
|
28
|
+
LAYERS="CLAUDE.md AGENTS.md scripts knowledge/shared templates plugins"
|
|
29
|
+
total=0
|
|
30
|
+
echo "── env-purity: 공유층의 환경-전용 산문 (advisory — 포인터화/독해규칙 후보 목록) ──"
|
|
31
|
+
while IFS= read -r tok; do
|
|
32
|
+
[ -z "$tok" ] && continue
|
|
33
|
+
n=$(cd "$REPO" && git grep -l -F "$tok" -- $LAYERS 2>/dev/null | grep -cv "env_purity" ) || n=0
|
|
34
|
+
case "$n" in (*[!0-9]*|'') n=0 ;; esac
|
|
35
|
+
if [ "$n" -gt 0 ]; then
|
|
36
|
+
echo " '$tok': $n 파일"
|
|
37
|
+
total=$((total+n))
|
|
38
|
+
fi
|
|
39
|
+
done <<< "$TOKENS"
|
|
40
|
+
# 계기 생존 컨트롤: 공유 방법론 토큰은 반드시 잡혀야 한다 (0 이면 grep 자체가 죽은 것)
|
|
41
|
+
ctl=$(cd "$REPO" && git grep -l -F "steel-quench" -- knowledge/shared plugins 2>/dev/null | wc -l | tr -d ' ')
|
|
42
|
+
case "$ctl" in (*[!0-9]*|'') ctl=0 ;; esac
|
|
43
|
+
[ "$ctl" -gt 0 ] || { echo "⛔ env-purity: 컨트롤 사망(steel-quench 0히트) — 위 수치 무효"; exit 10; }
|
|
44
|
+
if [ "$total" -eq 0 ]; then
|
|
45
|
+
echo " ✅ 환경-전용 토큰 0 (컨트롤 생존 $ctl)"
|
|
46
|
+
else
|
|
47
|
+
echo " 요약: 히트 합 $total (파일 단위, 토큰별 중복 포함) · 컨트롤 생존 $ctl"
|
|
48
|
+
echo " 처방 방향: 본문 포인터화(큰 업그레이드 시) 또는 상대 환경의 독해규칙 1줄(company/env 블록)"
|
|
49
|
+
fi
|
|
50
|
+
exit 0
|
|
@@ -98,7 +98,19 @@ CWD_UNMAPPED="$(_candidate "${CLAUDE_PROJECT_DIR:-$PWD}")" || CWD_UNMAPPED=""
|
|
|
98
98
|
# «변화 감지» 헤더가 찍히고 그 아래가 비는 알림이 나간다(=내용 없는 경보).
|
|
99
99
|
fh_cadence_due "$_FH_HOOK_SRC" || COUNT=0
|
|
100
100
|
|
|
101
|
-
|
|
101
|
+
# Wizard-declined reminder (2026-08-10, operator-requested): declined wizard items = intended
|
|
102
|
+
# features off — surface ONE line per session until resolved or deliberately muted. This is the
|
|
103
|
+
# mechanical half; a fully-unwired node (hooks declined) cannot run this and falls back to the
|
|
104
|
+
# CLAUDE.md prose layer (named residual there).
|
|
105
|
+
DECLINED_LINE=""
|
|
106
|
+
for _df in "$SENT"/*_wizard_declined; do
|
|
107
|
+
[ -f "$_df" ] || continue
|
|
108
|
+
[ -f "${_df%_wizard_declined}_wizard_reminder_muted" ] && continue
|
|
109
|
+
_dn=$(grep -c . "$_df" 2>/dev/null); case "$_dn" in (*[!0-9]*|'') _dn=0 ;; esac
|
|
110
|
+
[ "$_dn" -gt 0 ] && DECLINED_LINE="${DECLINED_LINE}$(basename "${_df%_wizard_declined}")(${_dn}) "
|
|
111
|
+
done
|
|
112
|
+
|
|
113
|
+
[ "$COUNT" -eq 0 ] && [ -z "$CWD_UNMAPPED" ] && [ -z "$DECLINED_LINE" ] && exit 0
|
|
102
114
|
|
|
103
115
|
# Emit the delta proposal (one block, imperative). Trim trailing ", ".
|
|
104
116
|
LIST="${CANDIDATES%, }"
|
|
@@ -114,6 +126,9 @@ LIST="${CANDIDATES%, }"
|
|
|
114
126
|
if [ "$COUNT" -gt 0 ]; then
|
|
115
127
|
echo " • $COUNT unmapped sibling repo(s) under $ROOT — run \`/install-wizard --dry-run\` to review + map (HITL); skip via touch \"$SENT/<name>_mapping_skipped\" (mechanical, no re-nag)."
|
|
116
128
|
fi
|
|
129
|
+
if [ -n "$DECLINED_LINE" ]; then
|
|
130
|
+
echo " • install-wizard declined/deferred items remain — ${DECLINED_LINE}— the matching intended FH features are OFF in this state. Re-run \`/install-wizard\` to revisit; silence deliberately: touch \"$SENT/<project>_wizard_reminder_muted\"."
|
|
131
|
+
fi
|
|
117
132
|
# Honest scope (target-tier sim [surfacing residual]): this hook mechanizes the CONTEXT-INJECTION
|
|
118
133
|
# half of claim ② — the env-change now reliably REACHES turn-0 context. It does NOT mechanize the
|
|
119
134
|
# SURFACING half (whether the model mentions it to the operator), which stays salience-dependent —
|