@chrono-meta/fh-gate 1.4.63 → 1.4.64

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.
@@ -11,13 +11,13 @@
11
11
  "plugins": [
12
12
  {
13
13
  "name": "fh-meta",
14
- "version": "1.4.63",
14
+ "version": "1.4.64",
15
15
  "description": "Hub meta-operations toolkit — 34 skills + 7 agents. New in 1.4.53: `fh-codex-doctor` (npm bin) — Codex adapter drift scanner; reads the documented M1/M2/M3 skill tier map + skill/agent source and reports codex-native/adapter-required/claude-native/unclassified per unit, wired into `npm test`/`prepublishOnly` (fail-closed on unclassified Claude-native primitives). New in 1.4.49: steel-quench gains Step 0.6 Verdict-Invariance Probe (groundedness axis — a load-bearing judged gate's verdict must track behavior, not rubric phrasing; measured flip-count over cross-family paraphrases; arXiv:2605.06161 Policy Invariance anchor); multi_model_sidecar_strategy §Vendor-native harness (a model is strongest in its own vendor CLI — Claude/CC, GPT/codex, Gemini/Antigravity; a universal router degrades all of them, so it stays an autocomplete/QA sidecar, never orchestration); predelete_check.sh fail-closed rewrite; memory-hygiene A-TMA anchor. New in 1.4.48: phantom-quench + steel-quench gain external frontier anchors (arXiv:2607.02052 package-hallucination; arXiv:2607.02057 prompt-coverage-adequacy); README model-flat claim reframed from a per-release point-curve to structural invariants (operation flattens across tiers; depth tier-order fixed within a generation). New in 1.4.47: onboarding step ① surfaces the Mode D companion-store session-start load in the auto-read salience anchor (previously only in the local binding + rules, so a greeting could skip the load). New in 1.4.46: context-doctor command-output axis (route to rtk/proxy for verbose CLI stdout, complementing .claudeignore; risk-gated to token-scarce envs). New in 1.4.41: context-doctor 2026 trigger vocab (context engineering/rot/collapse) + phantom-citation hardening; hub measurement-integrity-checklist (cross-model measurement pre-flight: display-name pin/reps≥3/discriminating probe). New in 1.4.40: install-wizard queryable-wiki scaffold (INDEX + session-start read + R/W/C ingest). New in 1.4.39: auto-decorrelation (cross-family verifier sidecar recruitment) + video-ingest (capability-routed video ingestion). New in 1.4.x: verify-axis check-class taxonomy (mandatory-pass/measured/judged), no-reinvention Tier-0 inventory, 7-class failure taxonomy, Destructive-Op Gate, Wave-T (Temper), tier-floor governance, Mode D Model Notice, FC consent lane, default-Sonnet guidance. New in 1.3.0: public-surface-audit, field-harvest Mode B auto-trigger, 4-axis gate scope ext. Validated cross-CLI: Claude Code, Codex, Gemini.",
16
16
  "source": "./plugins/fh-meta"
17
17
  },
18
18
  {
19
19
  "name": "fh-commons",
20
- "version": "1.4.63",
20
+ "version": "1.4.64",
21
21
  "description": "Project-agnostic utility skills — 4 skills (convergence-loop · deliberation · mcp-circuit-breaker · token-budget-gate) + 1 agent (quench-challenger). Domain-independent utilities transplantable into any project.",
22
22
  "source": "./plugins/fh-commons"
23
23
  }
package/AGENTS.md CHANGED
@@ -104,6 +104,28 @@ For complex multi-step tasks, run `/agent-composer` first to plan which agents t
104
104
 
105
105
  The methodology layer (`tracks/`, `knowledge/`, `SKILL.md` docs) is Codex-compatible beta. Any AI model can follow skill workflows by reading SKILL.md files directly; the automation layer (hooks, plugin-channel agents under `plugins/*/agents/`, `/model`) is Claude Code-native and requires manual adaptation. FH's own agents are auto-loaded via the plugin channel when the plugin is enabled — `.claude/agents/` is the field-project override slot, not where FH ships its agents. Non-Claude runtimes use this `AGENTS.md`, `plugins/*/agents/*.md`, and `scripts/fh-run.sh` to apply the same methodology via adapter.
106
106
 
107
+ ### Non-Claude runtimes: two things CLAUDE.md holds that you will not auto-load
108
+
109
+ `.claude/rules/*.md` with `paths:` frontmatter is a **Claude Code platform feature** — those files are
110
+ auto-loaded into a Claude Code session when it reads a matching file, and **your runtime has no equivalent**.
111
+ So two things that govern behavior are not going to reach you on their own. Read them explicitly:
112
+
113
+ 1. **FH asset changes run a mandatory 4-axis verification chain before the session's first commit.**
114
+ Detail (axis definitions · marker required fields · lightweight exception · substantive carve-out):
115
+ `.claude/rules/fh_4axis_gate.md` — **open it directly**; nothing will load it for you. The commit is
116
+ hard-blocked by `templates/.git-hooks/pre-commit` regardless of runtime, so skipping the read does not
117
+ skip the gate — it just means you meet the block without knowing what it wants.
118
+ 2. **Company residency is absolute** (CLAUDE.md §Field-Harness Diagnostic): raw company source, secrets,
119
+ hostnames, internal repo/asset names, stack traces, and unredacted findings **never leave the local
120
+ machine** — not to an external *or same-family* cloud model, not through a browser/API tool, not into a
121
+ log, comment, or paste. Outbound gets a **sanitized summary only**; exceptions need explicit operator
122
+ approval plus a gitignored audit note. This binds every runtime, not just Claude Code — a leak does not
123
+ un-happen, and the guard is worth nothing if it only lives where one runtime reads.
124
+
125
+ The irreversible-surface gates (Pre-Publish · Destructive-Op) likewise live in CLAUDE.md and fire on
126
+ **intent**, not on a file — read them before any publish, delete, or history-rewrite. `pre-push` enforces
127
+ the git-side destructive surface mechanically for every runtime.
128
+
107
129
  ### Entry point for Codex users
108
130
 
109
131
  AGENTS.md is your starting point. Navigate from here to skill workflows:
package/CLAUDE.md CHANGED
@@ -37,7 +37,7 @@ core invariants never melt). Full doctrine: `knowledge/shared/harness-core/harne
37
37
  | **① Control Tower** | Coordinates all connected projects and **drives harness-ification across them** — decides *which* projects to harness and *when*, propagates harness assets to each, and feeds their synced learnings into the hub's compounding loop. The *how* (rules · gates · 6-axis) is executed via the Core Axis. Command HQ, not a passive registry. | `knowledge/shared/rules/auto_project_mapping.md` (mapping + **Full-Harness Mode**) · `harvest-loop` (compounding loop) · `templates/` (project-harness bundle) · `CATALOG.md` |
38
38
  | **② Frontier → Org Propagation** | Proactively applies global AI/harness frontier thinking and **translates it for your organization**. | `knowledge/shared/harness-core/harness_frontier_diagnosis_*.md` · `knowledge/{your-org}/` |
39
39
  | **③ AI Collaboration Guide** | Accumulates and distributes best practices for token efficiency and dialogue methodology — "how to ask, delegate, and record". | `CHEATSHEET.md` · `knowledge/shared/dialogue/ai_dialogue_playbook.md` · `MEMORY.md` intent-based + associative recall (`knowledge/shared/dialogue/memory_intent_recall.md`) |
40
- | **Core Axis** | **Harness Engineering (How)** — the methodology and practice axis that realizes the three layers above. The 6-axis framework is the operating unit. **A harness is a means, not an end** — Field harness: "simpler over time" (complexity = warning signal). Meta-harness: *optimize*, not necessarily simplify — complexity earns its scope; red flags are orphaned, redundant, and decorative units, not complexity itself. | `harness_6axis_framework.md` · `hub_compounding_loop.md` · `claude_code_runtime_flow.md` · `.claude/agents/` (sub-agents) |
40
+ | **Core Axis** | **Harness Engineering (How)** — the methodology and practice axis that realizes the three layers above. The 6-axis framework is the operating unit. **A harness is a means, not an end** — Field harness: "simpler over time" (complexity = warning signal). Meta-harness: *optimize*, not necessarily simplify — complexity earns its scope; red flags are orphaned, redundant, and decorative units, not complexity itself. | `harness_6axis_framework.md` · `hub_compounding_loop.md` · `claude_code_runtime_flow.md` · `plugins/*/agents/` (sub-agents) |
41
41
 
42
42
  ## Core Reference Documents (Consult First)
43
43
 
@@ -101,6 +101,41 @@ onto their single hardest sub-mechanism, and a failure from a **non-harness** ru
101
101
  metric — each read a live-but-incomplete thing as zero, each caught by the operator, not self-caught.
102
102
  Detail: `[[feedback_reinvention_reflex_normalization_counterweight]]`.)
103
103
 
104
+ ## Instrument Calibration — before you trust a number, prove the instrument works *here*
105
+
106
+ An instrument (a scan, a grep, a checker, a diagnostic row, a metric) is a claim about the world only
107
+ after it is shown to work **on this target**. The recurring defect is not "measured the wrong thing" —
108
+ it is **never asking whether this instrument is valid for this corpus at all**.
109
+
110
+ **Two mandatory steps — both cheap, neither skippable:**
111
+ 1. **Calibrate on a known pair** — run the instrument against **one known-positive and one
112
+ known-negative** before trusting any of its output. A scan that cannot separate a case you already
113
+ know the answer to is not measuring; it is generating.
114
+ 2. **Hand-verify one sample before publishing a number** — open the single case the instrument is most
115
+ confident about and confirm it by eye. Publishing first and correcting later is not symmetric: a
116
+ number, once written into a report, a card, and a signal, must then be corrected in **all three**.
117
+ **"Publish" = the first time the number is stated in ANY form — including saying it to the operator
118
+ in conversation** — not only writing it to a file. Saying "roughly 34 broken refs, I'll verify when
119
+ I write it up" is *not* compliance: the unverified figure is already anchored in the reader's head
120
+ and in the transcript, which is the propagation this rule exists to stop. (Closed 2026-07-20 by a
121
+ known-pair sim that found this loophole; the session that wrote the rule had itself leaked its bad
122
+ "70%" into conversation before any file.)
123
+
124
+ **Degrade direction**: calibration impossible → the output ships **labeled `UNCALIBRATED`**, never as a
125
+ bare number, and never as the basis of a tier/verdict. A missing measurement is not a zero
126
+ (`not found` ≠ `0` — a file that does not exist is not an empty file).
127
+
128
+ **Why resident**: the trigger is *intent* ("I am about to trust / publish this output"), not a file, and
129
+ **no hook can catch it** — there is no mechanical backstop by nature, so salience is the only layer.
130
+ (Measured 2026-07-20, one session, 3×: an always-loaded footprint scan that omitted 61% of the surface ·
131
+ an index/file **size ratio** used as a proxy for content coverage · an **ASCII-token scanner run over a
132
+ Korean corpus** → ~96% false positives, whose "77 items / 70%" was published into three records before a
133
+ single hand-check collapsed it to **3**. Each was caught by looking at one real case.)
134
+
135
+ > **Detail**: See `knowledge/shared/harness-core/measurement-integrity-checklist.md §Instrument-Calibration`
136
+ > — the known-pair procedure, the language/encoding mismatch class, and the publish-order rule — read
137
+ > before running a scan whose count will be reported.
138
+
104
139
  ## New Project Onboarding
105
140
 
106
141
  > Detailed procedure: `knowledge/shared/rules/auto_project_mapping.md` (5-step mapping + §6 Full-Harness Mode)
@@ -111,6 +146,8 @@ Detail: `[[feedback_reinvention_reflex_normalization_counterweight]]`.)
111
146
 
112
147
  **Light vs full**: steps 1–3 register lightly. For project-local harness assets (session rules + context filter + env card), run **Full-Harness Mode** (`auto_project_mapping.md §6`) — approval-gated, never overwrites. FH self-gate is **not** installed into projects.
113
148
 
149
+ **Trigger routing**: "connect a project" · "link to hub" · "map this project" · "scan parent directory and connect" → the mapping protocol above. "harness-ify this project" · "full harness setup" · "프로젝트 하네스화" (or accepting the post-mapping promotion prompt) → §6 Full-Harness Mode.
150
+
114
151
  ## Harness Drift Prevention Principles
115
152
 
116
153
  The forge-harness hub has a dual identity: **(a) a seed for others** + **(b) your own active work harness**. This is why clearly separating "team assets" from "personal assets" is essential to prevent drift.
@@ -165,7 +202,7 @@ Simplification guard: trivial denials with one obvious fix → state block + sin
165
202
 
166
203
  **4-step summary**: ① Auto-read CLAUDE.md + CATALOG + session card + registry scan + UAP (`tracks/_meta/user_adaptation_profile.md`, if present — apply user-tuned defaults: preferred tier, suppressed proposals, muted nags; see §Operational Adaptation Loop) **+ Mode D companion-store load — if a companion store is configured (your `CLAUDE.local.md` binding), pull it and read its index (its TOC) before its other files, then check freshness against the card (`modes_and_value.md §Session-start freshness`); this load is part of the auto-read, not a step the operator should have to request** → ② One-line proposal (new user / exploratory / returning branches) → ③ 5-skill cascade (plugin-recommender → synergy → .claudeignore → model → verify) → ④ Approval + setup
167
204
 
168
- **Greeting branch + door skeleton (summary-level — applies even if the detail file read is skipped)**: the branch test is **mechanical local state — session files under `tracks/`** — never git log / CATALOG residue (a fresh clone carries full history but zero session files: it is a NEW install — origin: a fresh-clone sonnet sim rendered the returning menu off commit messages, `fh_signal_2026-06-11` FP8). Every variant opens with **🐿️ then an identity-revealing welcome line on the SAME line** (🐿️ is no longer alone on its own line), followed by the menu — one salience unit, not a separate rule. (Put a space after 🐿️; the exact count is **not significant** — a markdown renderer collapses multiple mid-line spaces to one — so the verifiable invariant is *same-line*, NOT a space count.) Welcome line by branch: new / exploratory = "Welcome to FH." · returning = "Welcome back to FH." · operator (FH-dev state) = "The FH operator — good to see you." (rendered in the user's language **as a plain, natural translation of the pinned phrase not an invented coinage** (cf. the operator-caught `안 조종실…` mistranslation); the lid/onboarding-smoothness matters even though it is not the substance).
205
+ **Greeting branch + door skeleton (summary-level — applies even if the detail file read is skipped)**: the branch test is **mechanical local state — session files under `tracks/`** — never git log / CATALOG residue (a fresh clone carries full history but zero session files: it is a NEW install). Every variant opens with **🐿️ then an identity-revealing welcome line on the SAME line**, followed by the menu — one salience unit, not a separate rule. The verifiable invariant is *same-line*, **not** a space count. Welcome line by branch: new / exploratory = "Welcome to FH." · returning = "Welcome back to FH." · operator (FH-dev state) = "The FH operator — good to see you." rendered in the user's language as a **plain, natural translation of the pinned phrase, never an invented coinage**. (Why each of these reads as it does — the fresh-clone FP, the space-count retraction, the mistranslation: `fh_detail_protocols.md §Onboarding-Provenance`.)
169
206
 
170
207
  - **New user** (no session files AND no mapped project tracks under `tracks/` — fresh clone/install; **any underscore-prefixed dir** (`tracks/_*` — `_meta`/`_audit`/`_contrib`/`_chamber`…) doesn't count, general rule not a closed list — `_chamber` holds incubation chamber runs, never mapped projects): 2-door starter, never the returning menu —
171
208
 
@@ -185,150 +222,30 @@ Compose session-card candidates **into door ③ (field) and the 🔧 door (FH-de
185
222
 
186
223
  **Identity marker**: every greeting response (Step ②) opens with 🐿️ then an identity-revealing welcome line **on the same line** (a space after 🐿️; exact count not significant — the renderer collapses it — the invariant is *same-line*, not 🐿️ alone) — new / exploratory = "Welcome to FH." · returning = "Welcome back to FH." · operator (FH-dev state) = "The FH operator — good to see you." It is embedded in all skeletons above (do not strip it when composing doors); the exploratory branch template (`fh_detail_protocols.md` Step 2) uses the "Welcome to FH." line.
187
224
 
188
- **Guards**: explicit task-entry utterance → skip onboarding **menu** (the door skeleton / greeting) — but this **never skips the Mode D companion-store freshness load** (pull + INDEX read + card-vs-commit reconcile); that is a data-load, not the menu, and it fires even when the first message is a task (measured miss 2026-07-05: task-first entry skipped the companion-store pull → stale memory → wrong recommendations; now hook-backed via `scripts/fh_session_load.sh`, see `modes_and_value.md §Session-start freshness`) · once per session · code/debug requests → start working directly · project routing is a suggestion, mention at most once
225
+ **Guards**: explicit task-entry utterance → skip onboarding **menu** (the door skeleton / greeting) — but this **never skips the Mode D companion-store freshness load** (pull + INDEX read + card-vs-commit reconcile); that is a data-load, not the menu, and it fires even when the first message is a task hook-backed via `scripts/fh_session_load.sh` (measured miss + mechanics: `fh_detail_protocols.md §Onboarding-Provenance` · `modes_and_value.md §Session-start freshness`) · once per session · code/debug requests → start working directly · project routing is a suggestion, mention at most once
189
226
  **Metadata-is-not-intent guard**: the trigger is the user's **typed message only**. Session metadata — branch name (auto-derived from the first message, e.g. `claude/korean-greeting-*`), repo name, file paths — is **never** a task spec and never suppresses or redirects the greeting trigger. A bare greeting fires onboarding even when the branch name looks like a feature request; if the only "task" signal lives in metadata and not in what the user typed, treat the message as a greeting and run the greeting branch + door skeleton above.
190
227
 
191
228
  ## New Skill Creation Pre-Commit Gate
192
229
 
193
- All 6 items below must pass before committing a new SKILL.md. If any fails, fix and re-commit.
230
+ Every new `SKILL.md` must clear a **6-item bar** (role-duplication via `/asset-placement-gate` · description diet · **Done When** · check-class · natural-language triggers · independently executable) before commit. A **routing/gate skill** additionally owes a one-time `Step 0.5` trigger-probe, re-probed whenever its trigger phrases change.
194
231
 
195
- | Item | Criterion |
196
- |---|---|
197
- | **Role duplication check** | Pass `/asset-placement-gate` — no overlap with existing role clusters, **platform built-ins (Tier 0), or `claude-plugins-official` (Tier 1 official)**. Reinventing an official capability requires explicit justification in the SKILL.md (no-reinvention rule FH builds only what adds governance) |
198
- | **Description diet** | Plain text / 0 self-marketing expressions / 0 emphasis words (⭐, "critical", "groundbreaking") |
199
- | **Done When defined** | At least 1 explicit completion condition |
200
- | **Check-class declared** | Each Done When condition states its check class — mandatory-pass / measured / judged (`harness_6axis_framework.md` §Axis 5). Any judged condition names its adversarial pairing — no judge-only path |
201
- | **Natural language triggers** | At least 3 examples that work without internal vocabulary. This is a **form** check (judged — do the examples avoid internal jargon). For a load-bearing gate/router skill it can be upgraded **judged → measured** with steel-quench's `Step 0.5 — Trigger-Accuracy Probe` (a dispatched should-fire / near-miss-should-not-fire fire-count), turning "do these triggers collide?" from a guess into a number. Optional for ordinary skills; recommended when the skill is a routing/gate surface |
202
- | **Independently executable** | Confirmed to work without other FH skills (or dependencies are explicitly documented) |
203
-
204
- Skills without a Done When definition automatically qualify as harness-doctor L2 M-tier.
205
- Check-class declaration applies to **new** skills; existing skills backfill opportunistically
206
- (when next edited), not retroactively. **Obligation (always-loaded):** a **routing/gate skill** (primary
207
- output = a dispatch decision or pass/block verdict) owes a **one-time `Step 0.5` baseline trigger-probe**
208
- at the next `harness-doctor` run **and a re-probe whenever its trigger phrases change** — not optional for
209
- that skill class, and not a retroactive sweep of all routers.
210
-
211
- > **Detail**: See `knowledge/shared/harness-core/claude_md_gate_details.md §New-Skill-Backfill` — the
212
- > probe mechanics (fire-count procedure), the baseline-floor rationale, and the mechanical "routing/gate
213
- > skill" test — read when editing a router/gate skill.
232
+ **Consequence (kept resident on purpose)**: a skill shipped **without a `Done When` definition automatically qualifies as harness-doctor L2 M-tier** — the bar has teeth, and those teeth stay in the always-loaded layer even though the bar's detail does not. Each `Done When` condition must also declare its check class (mandatory-pass / measured / judged); a **judged** condition names its adversarial pairing — no judge-only path.
233
+
234
+ > **정본**: `.claude/rules/fh_4axis_gate.md §New Skill Creation Pre-Commit Gate` — the full 6-item table, the judged→measured upgrade path, and the routing/gate test. It is `paths:`-scoped to `plugins/**/SKILL.md`, so it **auto-loads when you read a SKILL.md**. **Creating a skill from scratch reads no SKILL.md — go read it explicitly.** Mechanical floor either way: `templates/.git-hooks/pre-commit` runs the full 4-axis gate on any `SKILL.md` path plus a new-skill count-consistency slice.
214
235
 
215
236
  ---
216
237
 
217
238
  ## FH Improvement 4-Axis Auto-Gate (Self-Verification Orchestrator)
218
239
 
219
- **Whenever the AI modifies FH assets** (SKILL.md · `.claude/rules/*.md` · `knowledge/shared/rules/*.md` (relocated protocol rules — always full-gate, NOT under the knowledge carve-out) · `templates/` · `CLAUDE.md` · substantive `knowledge/` docs · substantive `docs/*.md` · `AGENTS.md` — see Substantive carve-out below),
220
- the 4-axis verification chain runs **automatically before the first commit** of that session.
221
- No user request is needed — this is a mandatory autonomous step, not a proposal.
240
+ **FH 자산을 수정하면**(SKILL.md · `.claude/rules/*.md` · `knowledge/shared/rules/*.md` · `templates/` · `CLAUDE.md` · substantive `knowledge/`·`docs/*.md` · `AGENTS.md`) **4축 검증 체인이 그 세션 첫 커밋 전에 자동 실행된다.** 사용자 요청 불요 제안이 아니라 의무 단계다.
222
241
 
223
- **Commit gate**: `git commit` on FH asset changes is hard-blocked by `templates/.git-hooks/pre-commit` until all required axes PASS. Hook installation (one-time): `git config core.hooksPath templates/.git-hooks && chmod +x templates/.git-hooks/pre-commit templates/.git-hooks/pre-push` (the same `core.hooksPath` also activates the **pre-push** Destructive-Op gate see that section below).
242
+ **기계 floor**: `git commit` `templates/.git-hooks/pre-commit` **하드 차단**한다. 축이 전부 PASS 때까지 커밋 자체가 된다. 아래 상세가 로드되지 않아도 **훅이 막는다** 산문은 위의 살리언스 층이지 유일 floor 아니다.
224
243
 
225
- ```
226
- FH asset modifiedAxis 1 (templates/regression_guard.sh --pr {BRANCH})
227
- Axis 2 (/steel-quench) Axis 3 (/phantom-quench)
228
- marker: tracks/_meta/.axes_23_passed_{branch}_{date}.marker
229
- (required fields: axis2-engine / axis2-model / floor-status / axis2-evidence;
230
- hook validates mechanically: below-floor blocks without below-floor-ack, and axis2-evidence
231
- must be non-vacuous — a recorded verdict/count, not "it ran". Marker scope is form +
232
- non-vacuity + auditability, NOT provenance — a fabricated marker is the weekly-audit + operator
233
- residual by design, do NOT fake-close it.
234
- → **Detail**: See `knowledge/shared/harness-core/claude_md_gate_details.md §Marker-Irreducibility`
235
- — why the below-floor-ack is structurally irreducible for an autonomous runner + the
236
- operator-present GPG hard-close option — read when auditing or attempting to harden the marker.)
237
- → Axis 4 (/edit-manifest RECORD, today's entry in edit_manifest.yaml)
238
- → All 4 PASS → git commit allowed | Any FAIL → fix inline, re-run
239
- ```
244
+ > **상세 정본**: `.claude/rules/fh_4axis_gate.md` — 4축 정의·마커 필수 필드·경량 예외·substantive carve-out·target-tier sim 게이트·Mode D 모델 공지·cross-family 보완. **`paths:` 로 FH 자산 경로에 스코핑돼 있어 그 파일들을 *읽을 때* 자동 로드된다** (공식 트리거는 read — `code.claude.com/docs/en/memory.md` §Path-specific rules).
245
+ > (2026-07-20 분리. **파일 char 실측**: 이 절 자체가 76,706자 중 **10,331자(13.5%)**로 단일 최대였다. 그 분리 + 같은 세션의 중복 3건 제거 + New-Skill 게이트 편입까지 **합산**해 파일은 **76,706 67,611 (순감 9,095자, 11.9%)** — 합산치이지 이 절 하나의 성과가 아니다 — 이건 파일 크기지 `/context` 상주 실측이 아니다(계기≠대상, [[feedback_resident_memory_measured_fresh_toplevel]]: 상주는 톱레벨 새 세션 `/context` 로만 잰다 — 미측정). 트리거가 *파일*이고 *기계 백스톱*이 있어 1순위 후보였다. 같은 이유로 **비가역 게이트 3종은 이동 불가** — 의도 트리거라 경로 스코핑하면 fail-open 이 된다.)
246
+ > **의무**: 요약에는 **축 이름·마커 필수 필드·경량 예외 기준이 없다.** 4축을 실제로 실행하거나 마커를 쓰기 전에 위 파일을 **반드시 직접 읽어라** — 안 읽고 마커를 쓰면 필드를 지어내게 된다(2026-07-20 Sonnet sim 스스로 지목한 실패 모드).
247
+ > **잔여(살리언스 층에 한함, 훅은 무관)**: ⓐ 트리거가 read 라서 **신규 SKILL.md 를 Write 로 새로 만드는** 경로는 규칙이 안 실린다 ⓑ `CLAUDE.md` 는 glob 에서 의도적 제외라 CLAUDE.md-only 세션은 이 요약 + 훅만 본다. **두 경로에선 위 "반드시 읽어라"가 유일한 살리언스 층이다** — 단, 둘 다 pre-commit 훅이 여전히 커밋을 하드 차단한다.
240
248
 
241
- **Why automatic**: Each axis catches a different defect class; asking separately means slip-through. **Why hook**: CLAUDE.md rules are advisory — the hook physically blocks commit until marker + manifest exist. **Scope**: active from the moment any FH file is modified in the session.
242
-
243
- **Lightweight exception** (Axis 1 + 4 only, skip Axes 2–3): Sessions where **zero SKILL.md / rules / templates files changed** (e.g., CATALOG.md entry, tracks/ update). The hook detects this automatically — no Axes 2+3 marker required for light-only commits. Judgment is file-based, not subjective.
244
-
245
- **Substantive carve-out — `knowledge/` · `docs/*.md` · `AGENTS.md`** (Axes 2–3 DO run, despite these not being SKILL/rules/templates): a change to any of these is **not** light if its diff adds a fenced code block (```` ``` ````) or a citation/version claim (`arXiv:` / `DOI` / `http` / a versioned dependency like `x.y.z`). Executable patterns and factual claims need phantom-detection + adversarial review *wherever they live* — `knowledge/` Implementation-Patterns sections carry runnable commands, `docs/` holds published guides, and `AGENTS.md` is the Codex-user entry point, so a phantom skill name or wrong version there is an external-facing error the gate must catch. Prose-only edits (typos, rewording, link fixes) stay light. Detection is mechanical: `git diff` adds a ```` ``` ```` fence or a citation token → run Axes 2–3.
246
-
247
- **Unavailable axis**: If steel-quench or phantom-quench are not installed, note `Axis N: skipped (skill unavailable)` and proceed. Axis 1 PASS alone is sufficient to unblock a PR when Axes 2–3 are unavailable. Axis 4 (edit-manifest): if the skill is not installed, substitute a manual one-line prediction appended to `tracks/_meta/edit_manifest.yaml` — the record is what matters, not the skill.
248
-
249
- **Target-tier sim gate (Mode D supplement — all change classes: fix, improvement, new asset)**: the
250
- discriminator is not the change class but the **enforcement column**: does the asset's effect depend on
251
- a session *following prose instructions* (salience-dependent — rules, onboarding scaffolds, SKILL.md
252
- trigger behavior), or is it mechanically enforced (hooks, scripts — tier-independent, normal 4-axis
253
- path, exempt)? For salience-dependent changes, verify with a **blind simulation in an isolated Agent**
254
- (no main-session reasoning inherited — isolation is the FH mechanism that keeps the sim honest) with
255
- `model:` pinned to the tier the change must survive on — **default sim tier = Sonnet** (the base
256
- floor every FH behavior must survive on, `sonnet_floor_doctrine.md`). Application strength scales
257
- with context:
258
- - **Mode D (FH self-dev) — near-mandatory**: any salience-dependent FH asset change runs the sim
259
- before Done, at Sonnet by default. Mandatory without exception when the change fixes a behavioral
260
- miss *observed* on a specific tier — sim at that same tier, even below Sonnet (the verification
261
- tier must match the failure tier; fixing on a stronger model and verifying by review alone leaves
262
- "does it fire on the weaker tier?" unanswered).
263
- - **Field harness assets (templates/ propagated via Full-Harness Mode) — conditional**: sim at the
264
- default field tier (Sonnet) when the behavior is load-bearing (gates, onboarding, destructive/publish
265
- paths); skip with a one-line note for low-stakes prose.
266
- - **Light mapping (tracks/ registration, CATALOG entries) — exempt**, alongside mechanical changes
267
- (hook logic, scripts, file moves — tier-independent by construction).
268
-
269
- **Autonomy floor**: the skip/run *judgment* on conditional cases is itself depth-sensitive — trust it
270
- only at opus-tier or above. A below-floor orchestrator does not silently skip — and does not stall:
271
- its default is to RUN the sim (the conservative branch needs no trust); it asks the operator only when
272
- no runnable path exists (run-first, ask-last — sonnet_floor_doctrine.md §Autonomy at Sonnet).
273
-
274
- Record sim results in the Axes 2–3 marker + sub-agent invocation log.
275
-
276
- > **Detail**: See `knowledge/shared/harness-core/claude_md_gate_details.md §Sim-Dispatch-Fallback` — the
277
- > headless `claude -p --model` fallback when in-session model-pin is unavailable, the saturation-disguise
278
- > retry (compact-then-retry once), and the credit-pool caveat — read when a model-pinned dispatch fails.
279
-
280
- **Measurement-integrity pre-flight**: when the sim/dispatch is a *cross-model measurement* (pinned to a
281
- tier, comparing model behaviors, or feeding a published claim), **the instrument must be verified before
282
- the measurement is trusted**.
283
-
284
- > **Detail**: See `knowledge/shared/harness-core/measurement-integrity-checklist.md` — pin the display
285
- > name not a slug (silent fallback to a weaker model is a measured failure) · reps ≥ 3 on any
286
- > borderline/contested verdict (single draw = noise) · use a discriminating identity probe (a generic
287
- > "OK" proves nothing about which model answered) — read **before** running any cross-model measurement.
288
-
289
- **Floor-tier canary (optional pre-screen — token-free, *below* the Sonnet sim)**: a local model ≤ Sonnet
290
- can blind-pre-screen a salience-dependent edit before the Sonnet dispatch is spent. **Canary, NOT gate**:
291
- a PASS adds cheap floor confidence and you still run the Sonnet sim; a FAIL never blocks alone. The
292
- terminal verdict stays with the **Sonnet-or-higher governor bound to a mechanical anchor** — **no
293
- judge-only path**, no weak-local-judge regression of the judge-robustness principle.
294
-
295
- > **Detail**: See `knowledge/shared/harness-core/claude_md_gate_details.md §Floor-Tier-Canary` — the local
296
- > model/panel options, the blind-probe procedure, dogfood evidence, and the FAIL-triage (real salience gap
297
- > vs floor-model quirk) — read when running a floor canary.
298
-
299
- **Axis ownership** (each skill is already complete — orchestrator only coordinates):
300
-
301
- | Axis | Skill | What it catches |
302
- |---|---|---|
303
- | Backward | `templates/regression_guard.sh` | Critical section loss, broken refs, syntax errors, line reduction |
304
- | Adversarial | `steel-quench` | Trigger phrase collisions, design attack surface, over-engineered steps |
305
- | Forward | `phantom-quench` | Phantom references, paths that don't exist, stale external links |
306
- | Record | `edit-manifest` RECORD | Logs predicted impact — closes the predict-verify loop for future harvest-loop |
307
-
308
- **Cross-family complement (Axis 2, autonomous when consented)**: `steel-quench` dispatches in-session at the
309
- session tier — **same family** as the governor, so it shares the governor's blind spots. For a **load-bearing**
310
- change (gates · irreversible-surface code · doctrine), `auto-decorrelation` is the standing cross-family
311
- verifier: it recruits ≥1 **different-family** auditor when the sidecar panel is discoverable, and degrades
312
- honestly to single-session when none is. **Autonomous once the operator has consented** (one-time, in the
313
- UAP — `[[user_adaptation_profile]]`); the governor keeps the terminal verdict and **source-grounds** every
314
- sidecar finding before acting on it (`[[feedback_judge_robustness_mechanical_anchor]]`).
315
-
316
- > **Detail**: See `knowledge/shared/harness-core/claude_md_gate_details.md §Cross-Family-Complement` — the
317
- > UAP sidecar mapping (which family for which task class) and the 2026-06-27 dogfood evidence — read when
318
- > recruiting or configuring a cross-family auditor.
319
-
320
- ### Mode D Model Notice (fires once, at the same trigger as this gate)
321
-
322
- When FH self-dev begins (an FH asset is about to change), check the **session model** and surface **one
323
- line**, then proceed — never block, **never switch the model** (human override inviolable): opus-tier+ →
324
- no notice · below-opus → **dispatch-first recommend** (keep Sonnet + route depth turns to sidecar/opus
325
- dispatch; `/model opus` pin = secondary — `sonnet_floor_doctrine.md`) · unknown → static fallback recommend. Once per session;
326
- field-project (non-FH-asset) sessions never see it. Whether a session actually *escalates* (not just this
327
- advisory) is governed separately by `capability_escalation_consent.md`.
328
-
329
- > **Detail**: See `knowledge/shared/harness-core/claude_md_gate_details.md §Mode-D-Model-Notice` — the
330
- > exact 3-branch wording (한글), the full guards, and the capability-escalation-consent cross-ref — read
331
- > when surfacing the notice.
332
249
 
333
250
  ## Field-Harness Load-Bearing Change Gate (cross-family, pre-merge)
334
251
 
@@ -369,66 +286,53 @@ pipeline**, not an afterthought, and a below-floor orchestrator RUNS the review
369
286
 
370
287
  ## Field-Harness Diagnostic — "진단해줘 / 개선해줘" on a mapped project (compose → rank → HITL)
371
288
 
372
- The gate above fires on a **specific field code change**. This is its **on-demand pull sibling**: when
373
- the operator, working in a mapped project, asks to *diagnose* or *improve* the harness itself ("진단해줘",
374
- "개선해줘", "check this project"), don't hand-pick one skill **compose the checks FH already has**
375
- (no-reinvention: the diagnostic only *routes and ranks* existing checks) across **six lenses** —
376
- confidentiality/leak (`/public-surface-audit` incl. Step 3c ignore-verification) · split integrity (`/phantom-quench` Step 2.7) ·
377
- token/salience (`/context-doctor` · `/salience-splitter`) · structure (`/harness-doctor` L1–L4) ·
378
- verdict/gate degrade (`scripts/degrade_direction_scan.sh`) · loop-readiness (5-question lens
379
- `loop_engineering.md`) into **one ranked `M`/`S`/`R` list** (same tiering as harness-doctor; each
380
- item: *lens · file:line · one-line fix*). **Then HITL per item nothing is auto-fixed**: the diagnostic's job is the
381
- intelligent list, the human's job is the *go*; an approved fix routes to the owning skill's normal
382
- path (and, if load-bearing field code, through the Load-Bearing Change Gate above).
383
-
384
- **Guards**: (a) **project-level** "진단/개선" ask only (single-file asks go straight to the skill);
385
- (b) **once per ask**; (c) **company residency** leak lenses run locally, sanitize before
386
- cross-family dispatch, company-sensitive findings are *surfaced* for operator decision, never
387
- auto-fixed; (d) **autonomy floor** compose/rank trusted at opus-tier+; below-floor, run the
388
- individual checks and present raw rather than silently skipping a lens. Scale to the ask: a quick
389
- "뭐 고칠 있어?" = cheap mechanical lenses (leak · split · token); "제대로 진단해줘" = all six +
390
- harness-doctor depth.
391
-
392
- > **Detail**: See `knowledge/shared/harness-core/field_harness_diagnostic.md` — the full lens table
393
- > (incl. loop-readiness mechanics + its adversarial pairing), the 2026-07-08 dogfood examples, and
394
- > guard rationale — read when actually running the diagnostic.
289
+ The **on-demand pull sibling** of the gate above: a *project-level* "diagnose / improve this harness" ask
290
+ composes the checks FH **already has** across **six lenses** — leak (`/public-surface-audit`, incl. **Step 3c ignore-verification** — a file believed gitignored but actually tracked is the leak this sub-step exists to catch) · split
291
+ integrity (`/phantom-quench` **Step 2.7**) · token/salience (`/context-doctor` · `/salience-splitter`) · structure
292
+ (`/harness-doctor`) · verdict degrade (`scripts/degrade_direction_scan.sh`) · loop-readiness
293
+ (`loop_engineering.md`) into **one ranked `M`/`S`/`R` list**. No-reinvention: it only routes and ranks.
294
+
295
+ **Resident guards (do not defer these to the detail file)**: **nothing is auto-fixed** the list is the
296
+ skill's job, the *go* is the human's; and **company residency (absolute)** **raw company source, secrets,
297
+ hostnames, internal repo/asset names, stack traces, and unredacted findings never leave the local machine**:
298
+ not to an external **or same-family** cloud model, not through a browser/API tool, not into a log, comment,
299
+ or paste. Leak lenses run **locally**; anything dispatched outward is a **sanitized summary only**.
300
+ Company-sensitive findings are *surfaced* for operator decision, never auto-fixed. Any exception needs
301
+ **explicit operator approval + a gitignored audit note**. (A leak does not un-happen absolute, not
302
+ deferrable, and "is this sanitized enough?" is not a call the session makes alone.) **Autonomy floor**:
303
+ compose/rank is trusted at opus-tier+; below-floor, run the individual checks and present raw
304
+ **never silently skip a lens**.
305
+
306
+ > **Detail**: See `knowledge/shared/harness-core/field_harness_diagnostic.md` the full lens table (incl.
307
+ > loop-readiness mechanics + adversarial pairing), the remaining guards (project-level-only · once-per-ask ·
308
+ > autonomy floor · how to scale to the size of the ask), and the 2026-07-08 dogfood examples.
309
+ > **Read it before running the diagnostic** this summary names the lenses, not how to run them.
395
310
 
396
311
  ## Onboarding / Acceleration Autopilot — "새 프로젝트 · 하네스 작성 · 가속화" (discover → compose → rank → install-HITL)
397
312
 
398
- The **install-direction twin of the Field-Harness Diagnostic**: same `compose → rank → HITL` engine, but
399
- it decides *what to install/wire* instead of *what to fix*. When the operator enters an onboarding /
400
- acceleration door (returning-menu ①②③: "새 프로젝트", "하네스 작성/작성해줘", "이 프로젝트 가속화",
401
- "harness-ify", "accelerate this project"), don't hand-run one skill:
402
-
403
- 1. **Phase 0 — State Audit + branch**: auto-discover existing `.claude/`, `CLAUDE.md`, mapped
404
- `tracks/`, sibling repos, `LOCAL_SKILL_REGISTRY` branch *new-build* / *extend-existing*
405
- (found→extend, never fork) / *maintain* (→ Field-Harness Diagnostic instead). New-build that is
406
- uncertain · exploratory · failure-expensive **flag simulate-first**: a one-line HITL
407
- recommendation to run the chamber (`scripts/chamber_run.sh`), then Full-Harness Mode §6 for the
408
- actual onboarding **never presented as a push-button autonomous emit** (EMIT has never fired;
409
- the chamber to date *screens*, it has not *birthed*).
410
- 2. **Innovator-centered recommend**: `persona-innovator` (Mode I acceleration / Mode F FH-dev)
411
- composing `plugin-recommender` + `cross-ecosystem-synergy-detection` + inferred technical level.
412
- 3. **Ranked install plan**: one `M`/`S`/`R` list *what · why · source tier · exact install
413
- command*; an official/built-in that covers the need outranks a net-new scaffold.
414
- 4. **Install HITL, non-overwriting**: per-item approval; installed FH assets run the **4-axis
415
- gate**, field scaffolds run `asset-placement-gate` + `steel-quench`. **"끝까지 해줘 / 자율로
416
- 완주" → full-autonomy** under the `/goal-quench` budget+quality gate — autonomy removes the
417
- per-item *prompt*, never the *gate*.
418
-
419
- **Guards (inviolable)**: (a) **non-overwriting** propose merge, never clobber an existing
420
- `.claude/`; (b) **no-reinvention** Tier 0/1 first, scaffold only what adds governance; (c)
421
- **company residency** — a company sibling repo is surfaced, never auto-mapped/leaked; `residency` is
422
- a machine field on the skill registry (`fh_detail_protocols.md §1-c`), so recommendations naming a
423
- `company`/`operator-private` entry land only in gitignored `tracks/_meta/` or the private companion
424
- store; (d) **autonomy floor** — discover/rank trusted at opus-tier+; below-floor, present the raw
425
- recommend and ask; (e) **once per door-entry**. This is the door ③ engine made autonomous — the
426
- operator asks once and the harness discovers, ranks, and (on request) installs everything worth wiring.
427
-
428
- > **Detail**: See `knowledge/shared/harness-core/onboarding_acceleration_autopilot.md` — the full
429
- > Phase-0 branch logic (incl. the chamber/simulate-first honesty boundary + `chamber_run.sh` runner
430
- > scope), revfactory provenance, and guard evidence (chamber run #7) — read when executing this
431
- > autopilot.
313
+ The **install-direction twin** of the Diagnostic above — same `compose → rank → HITL` engine, deciding
314
+ what to *install/wire* rather than what to *fix*. Four phases: **Phase 0** state audit + branch
315
+ (*new-build* / *extend-existing* found→extend, never fork / *maintain* → use the Diagnostic instead) →
316
+ **innovator-centered recommend** **ranked `M`/`S`/`R` install plan** (an official/built-in that covers
317
+ the need outranks a net-new scaffold) → **install**.
318
+
319
+ **Resident guards (inviolable never deferred)**: **non-overwriting** propose a merge, never clobber an
320
+ existing `.claude/` · **company residency** a company sibling repo is **surfaced, never auto-mapped or leaked**; `residency` is a
321
+ machine field on the skill registry, so any recommendation naming a `company`/`operator-private` entry lands
322
+ **only** in gitignored `tracks/_meta/` or the private companion store never in a tracked file, and the
323
+ absolute no-raw-company-data rule in the Diagnostic above applies here unchanged · **per-item gate routing**
324
+ installed **FH assets** run the **4-axis gate**; **field scaffolds** run **`asset-placement-gate` +
325
+ `steel-quench`** (the FH pre-commit hook is repo-local and does **not** reach a scaffold installed into another
326
+ repo, so this routing is not redundant with it) · **autonomy floor** — discover/rank trusted at opus-tier+;
327
+ below-floor, present the raw recommend and ask · **HITL per item**, and `"끝까지 해줘 / 자율로 완주"` full-autonomy under the `/goal-quench`
328
+ gate: autonomy removes the per-item *prompt*, **never the gate**. Honesty boundary that must not soften in
329
+ summary: the chamber to date **screens**; it has not *birthed* simulate-first is a one-line HITL
330
+ recommendation, never a push-button autonomous emit.
331
+
332
+ > **Detail**: See `knowledge/shared/harness-core/onboarding_acceleration_autopilot.md` full Phase-0 branch
333
+ > logic + `chamber_run.sh` scope, the per-phase skill composition, the remaining guards (no-reinvention
334
+ > tiering · autonomy floor · once-per-door-entry), revfactory provenance, and chamber-run-#7 guard evidence.
335
+ > **Read it before running the autopilot.**
432
336
 
433
337
  ## Irreversibility Gates — Surface-Class Degrade Invariant (shared spine of the two gates below)
434
338
 
@@ -538,7 +442,7 @@ force-push, scrub of tracked history, bulk deletion of session records / tracks
538
442
  2. **Recover (judged — depth-sensitive)**: every CHECK/REVIEW item gets a content-direction look;
539
443
  live un-integrated state (cards · handoffs · signals · session records) is integrated to main
540
444
  **before** anything is deleted. This step exists because the loss class is silent — run it at the
541
- strongest available tier (floor semantics, §Tier-floor); a below-floor pass is provisional.
445
+ strongest available tier (floor semantics: `multi_model_sidecar_strategy.md §Tier-floor resolution`); a below-floor pass is provisional.
542
446
  3. **Destroy** only what passed — REVIEW blocks a scripted delete chain (script exits 1).
543
447
 
544
448
  **Mechanical floor (pre-push hook — git-side surfaces)**: at *push* time, **remote branch/ref deletion**
@@ -565,15 +469,7 @@ into "just delete it."
565
469
  At any point during a session, when the following signals are detected, propose the relevant skill in one line.
566
470
  Proposal format: `"I see [X]. Want me to run /[skill] to [one-line description]?"`
567
471
 
568
- > **Row diet (2026-07-17, Step 0.5 probe 13/18)**: rows whose skill frontmatter `description` already
569
- > catches the utterance at high confidence were removed — platform-native skill matching owns those
570
- > (plugin-recommender · harness-doctor · synergy · frontier-digest · sim-conductor · install-wizard ·
571
- > asset-placement-gate · marketplace-gate · public-surface-audit · verify-bidirectional ·
572
- > mcp-circuit-breaker · token-budget-gate · salience-splitter — the last one earned removal by a
573
- > description strengthening in the same change, not by its original description). This table keeps only: **proactive
574
- > safety gates** (publish · destructive · MCP-mount) · **non-skill protocol routes** (gates, doctrine
575
- > sections, deep-research ladder) · **disambiguators and weak-description rows**. Before adding a row
576
- > back, probe whether the description alone catches it.
472
+ > **Row diet (2026-07-17)**: rows already caught at high confidence by a skill's own frontmatter `description` were removed — platform-native skill matching owns those. The table keeps proactive safety gates · non-skill protocol routes · disambiguators and weak-description rows. **Before adding a row back, probe whether the description alone already catches it.** (Probe score, the full removed list, and the keep-criteria rationale: `fh_detail_protocols.md §Onboarding-Provenance`.)
577
473
 
578
474
  | Conversation Signal Keywords | Proposed Skill |
579
475
  |---|---|
@@ -593,7 +489,7 @@ Proposal format: `"I see [X]. Want me to run /[skill] to [one-line description]?
593
489
  | "publish", "make public", "make this repo public", "go public", "gh repo create --public", "flip to public", "first public push", "publish the package", "npm publish", "twine upload", **opening/updating a PR or pushing content to the public hub** (esp. company-origin) (publish intent — **proactive**, fire *before* the action; adding content to an already-public repo IS publishing that content) | **Pre-Publish Surface Gate** (see above → `/public-surface-audit` + `/marketplace-gate` Check 5 must PASS first). The commit-time half is now **hook-enforced** (mechanical confidentiality scan — see Pre-Publish Gate §Hook coverage (b)), so this proactive trigger is the salience layer over a mechanical floor. |
594
490
  | "delete the branch", "브랜치 삭제", "브랜치 정리", "clean up branches", "force-push", "rewrite history", "지워도 돼?" (destructive intent — **proactive**, fire *before* the action) | **Destructive-Op Gate** (see above → enumerate → recover → destroy; `templates/predelete_check.sh`) |
595
491
  | **"새 기능 검증해줘", "test this feature", "이 TC 확인해줘" — verifying the user's PRODUCT/feature (not FH itself)** | **Route to the mapped field harness first** (Cross-Project Skill Bus / registry) — the field harness owns product verification. The harness-verification rows in this table (`verify-bidirectional` · `prompt-regression` · `sim-conductor` · `pipeline-conductor`) verify the *harness*, and must not shadow a product-verification ask (a field project's *harness assets* — its skills/rules — still use those FH verification rows) |
596
- | "지난주에 뭐 했지", "what did we do last week", "예전에 이거 한 적 있나" (recall intent) | §Searching Past Work (CATALOG-first) — read CATALOG.md, then open only candidate files |
492
+ | "지난주에 뭐 했지", "what did we do last week", "예전에 이거 한 적 있나" (recall intent) | **CATALOG-first recall** — read `CATALOG.md`, identify candidates by tag/date, then open only those files. Never scan session files one by one |
597
493
  | "add this MCP server", "mount this MCP", "mcp.json에 추가", "connect this tool server" (external-MCP mount intent — **proactive**, fire *before* first tool call; mount intent only — a failing/erroring mounted server is `/mcp-circuit-breaker`'s row above) | `templates/.claude/rules/mcp_tool_gating.md` (name-keyed ask/allow table — never trust server annotations or names; fill §3 at mount time) |
598
494
  | "did my rule change break anything", "regression check", "test harness changes" | `/prompt-regression` |
599
495
  | "review for the team", "CTO review", "decision-maker", "share with leadership", "approval deck" | `/apex-review` |
@@ -604,8 +500,8 @@ Proposal format: `"I see [X]. Want me to run /[skill] to [one-line description]?
604
500
  | "memory feels bloated", "clean up memory", "memory too large", "memory hygiene" | `/memory-hygiene` |
605
501
  | "ready to PR", "about to push", "merge this", "PR 올려줘", FH asset changed in session | 4-axis auto-gate (see above — runs automatically, no proposal needed) |
606
502
  | **field verdict/gate/safety/irreversible code changed** in a mapped project (function returning a verdict enum / gate exit code / safety-invariant · publish/delete/history path) — **proactive, before merge** | **Field-Harness Load-Bearing Change Gate** (see above → degrade-lint → cross-family review → converge; same rigor as FH assets, applied to field code) |
607
- | **"진단해줘", "개선해줘", "diagnose this", "improve this harness", "check this project", "audit this project"** — said while working **in a mapped project** (not a single-file ask) | **Field-Harness Diagnostic** (see §Field-Harness Diagnostic below → compose existing checks into one ranked M/S/R list → HITL approval per item, nothing auto-fixed) |
608
- | **"새 프로젝트", "하네스 작성해줘", "이 프로젝트 가속화", "harness-ify this", "accelerate this project"** — an onboarding/acceleration door (returning-menu ①②③) | **Onboarding / Acceleration Autopilot** (see §Onboarding / Acceleration Autopilot below → Phase 0 auto-discover + branch → innovator-centered recommend → ranked install plan → HITL per item, non-overwriting; "끝까지 자율로" → full-autonomy under /goal-quench gate) |
503
+ | **"진단해줘", "개선해줘", "diagnose this", "improve this harness", "check this project", "audit this project"** — said while working **in a mapped project** (not a single-file ask) | **Field-Harness Diagnostic** (see §Field-Harness Diagnostic above → compose existing checks into one ranked M/S/R list → HITL approval per item, nothing auto-fixed) |
504
+ | **"새 프로젝트", "하네스 작성해줘", "이 프로젝트 가속화", "harness-ify this", "accelerate this project"** — an onboarding/acceleration door (returning-menu ①②③) | **Onboarding / Acceleration Autopilot** (see §Onboarding / Acceleration Autopilot above → Phase 0 auto-discover + branch → innovator-centered recommend → ranked install plan → HITL per item, non-overwriting; "끝까지 자율로" → full-autonomy under /goal-quench gate) |
609
505
 
610
506
  **Guard**: Do not propose a skill that is already running. One signal = one-line proposal (no pressure). Before proposing, consult the UAP (§Operational Adaptation Loop): a skill the user has rejected 3+ times is **suppressed**, not re-proposed.
611
507
  For per-skill utterance patterns, see the relevant `SKILL.md §Trigger Phrases` section.
@@ -707,28 +603,8 @@ Tiers: S=light(~5K) · M=standard(~15K, FH default) · L=full(~30K) · XL=max(~6
707
603
 
708
604
  ## Operational Status
709
605
 
710
- **Current: Beta → External Validation Achieved** — v1.0 formal release conditions: additional external install evidence + at least 1 external PR.
711
-
712
606
  > Usage modes (A/B/C) + what-you-get (Layer 1/2) + **ephemeral-session handoff rule** (leave a surfaced handoff in a durable location before an ephemeral/cloud session ends): `knowledge/shared/rules/modes_and_value.md`
713
607
 
714
- ## Auto Project Mapping Protocol
715
-
716
- > Detailed procedure: `knowledge/shared/rules/auto_project_mapping.md` (5-step mapping + §6 Full-Harness Mode)
717
-
718
- When the user requests **"connect a project"** · **"link to hub"** · **"map this project"** · **"scan parent directory and connect"**, follow the `auto_project_mapping.md` protocol. When they request **"harness-ify this project"** · **"full harness setup"** · **"프로젝트 하네스화"** (or accept the post-mapping promotion prompt), run **§6 Full-Harness Mode** — installs project-local harness assets (session rules · context filter · env card) from `templates/`, approval-gated and non-overwriting. (The FH self-gate is FH-internal and is not installed into projects.)
719
-
720
- ## Searching Past Work
721
-
722
- When searching for past work, **read CATALOG.md first**. Use tags and summaries to identify candidate files, then open only those files for detail.
723
-
724
- ```
725
- 1. Read CATALOG.md → identify candidate files by tag/date
726
- 2. Open candidate files directly → review details
727
- ```
728
-
729
- Do not scan session files one by one sequentially.
730
-
731
-
732
608
  ## Session Wrap-up — Card Update Protocol
733
609
 
734
610
  **Real-time completion tracking (card bug prevention)**: When any S-tier/A-tier/backlog item is completed during a session, **immediately** (before context compression) append to `tracks/_meta/fh_completed_{YYYY-MM-DD}.md`.
@@ -747,15 +623,18 @@ Closing phrase detected ("wrap up", "done", "good work", "end session", etc.)
747
623
  → ③ Sync local/gitignored session state to your durable companion store, if you keep one
748
624
  → ④ Memory hygiene — update stale entries + record new session findings
749
625
  → ④-b npm freshness — if any npm-shipped asset changed (`package.json` `files[]`: skills · agents ·
750
- knowledge/ · docs/ · README · AGENTS.md · CLAUDE.md · CHEATSHEET · CATALOG.md): **first a Codex-entrypoint
751
- drift check** — the script (`session_close_check.sh`) auto-*fires a candidate reminder* by cheap grep
752
- (file co-occurrence, not topical parity), then **you judge**: does the changed CLAUDE.md/knowledge topic
753
- actually mirror a section in `AGENTS.md` / `docs/codex-compat.md` (both files[]-shipped Codex entry
754
- points)? sync it, else record `drift:none`. The grep flags; it does not determine the parity call is
755
- judged. Version lockstep invalidates the plugin.json *cache* but is **orthogonal** to
626
+ knowledge/ · docs/ · README · AGENTS.md · CLAUDE.md · CHEATSHEET · CATALOG.md): **first an entry-point
627
+ drift check — BIDIRECTIONAL** — the script (`session_close_check.sh`) auto-*fires a candidate reminder*
628
+ by cheap grep (file co-occurrence, not topical parity), then **you judge** whether the changed topic
629
+ actually mirrors a section on the other side; sync it, else record `drift:none`. The grep flags; it does
630
+ not determine the parity call is judged. **Both directions fire, because the two entry points are read
631
+ by different runtimes and a rule living in only one is invisible to the other**:
632
+ ▸ *CC→Codex* — `CLAUDE.md`/`knowledge/` changed, `AGENTS.md`/`docs/codex-compat.md` did not
633
+ ▸ *Codex→CC* — `AGENTS.md`/`docs/codex-compat.md` changed, `CLAUDE.md`/`knowledge/` did not
634
+ Version lockstep invalidates the plugin.json *cache* but is **orthogonal** to
756
635
  entry-point *content* — a version-only bump can ship a stale Codex entry point (gate-locality,
757
636
  Codex side). Then **propose republish**: version bump **in lockstep**
758
- across `package.json` + every `.claude-plugin/plugin.json` + `marketplace.json` (single-source =
637
+ across `package.json` + every `.claude-plugin/plugin.json` + `.claude-plugin/marketplace.json` (single-source =
759
638
  `package.json`) → Pre-Publish gate → `npm publish` → `git tag vX.Y.Z` at publish. **Propose, don't
760
639
  auto-publish.** (Why lockstep — Codex caches on plugin.json version — + drift-check + tag-drift caveat → §detail below.)
761
640
  → ④-c Handoff lifecycle (cross-machine continuity) — when a durable **result artifact lands** this
@@ -775,8 +654,7 @@ Closing phrase detected ("wrap up", "done", "good work", "end session", etc.)
775
654
  > when executing that close step.
776
655
 
777
656
  **Card-last guard**: ①–④-c (incl. ①-b open-PR sweep, ④-c handoff lifecycle) must ALL complete before
778
- ⑤ runs. **Mechanical floor**: `bash scripts/session_close_check.sh` before ⑥ —
779
- exit 1 (card-last violated / required close artifact missing) blocks the push step until fixed. Any new information produced during ①–④ (new commits from a merged self-PR, model changes,
657
+ ⑤ runs. **Mechanical floor**: `scripts/session_close_check.sh` is **wired into `templates/.git-hooks/pre-push`** (2026-07-20) — it runs on *every* push, so it is no longer prose-invoked. Enforcement is surface-matched: an ordinary push **surfaces** ❌ violations (advisory — a branch push is reversible), and the **close push blocks** on them: run step as **`FH_SESSION_CLOSE=1 git push`** → exit 1 (card-last violated / required close artifact missing) stops the push until fixed. *Why not block always*: ⑤ card-last is a close-time invariant, while ④ mandates writing `fh_completed_*` **during** the session an unconditional block would pit the two rules against each other and train `--no-verify`, disarming the Destructive-Op gate in the same hook. Any new information produced during ①–④ (new commits from a merged self-PR, model changes,
780
658
  new findings, a carry item flipped to DONE) feeds INTO ⑤ — card is never written mid-sequence and
781
659
  then left open for more work to accumulate after it.
782
660
 
@@ -266,6 +266,20 @@ record `drift:none`) — the script flags, it does not *catch*. Origin: 2026-07-
266
266
  lockstep-bumped v1.4.56/57 but only an operator question ("코덱스 호환성도 자동?") confirmed AGENTS.md was
267
267
  clean — the chain never auto-checked it (`fh_signal_2026-07-13_self-dev` S3).
268
268
 
269
+ **Why the check is BIDIRECTIONAL (added 2026-07-19 — relocated here from always-loaded CLAUDE.md
270
+ 2026-07-20).** The drift check originally fired in one direction only: *CLAUDE.md/knowledge changed but
271
+ AGENTS.md did not*. That is half a check, and a real miss travelled **exactly the unwired way**: a field
272
+ harness's boundary-crossing behavior rules landed in `AGENTS.md` **only**, leaving Claude Code sessions
273
+ unaware of a rule whose violation destroys a downstream harness's identity. The asymmetry was invisible
274
+ precisely because the wired direction kept passing.
275
+
276
+ The root reason both directions are required: **the two entry points are read by different runtimes.**
277
+ `CLAUDE.md`/`knowledge/` → Claude Code; `AGENTS.md`/`docs/codex-compat` → Codex, OpenCode, and other
278
+ non-CC runtimes. A rule living in only one of them is **invisible to the other**, and which direction the
279
+ next miss travels is not predictable — so a one-directional check is not "most of the coverage", it is a
280
+ coin flip. `session_close_check.sh` now fires a candidate in both directions (`_ENTRY_CC` / `_ENTRY_CX`);
281
+ the honest-scope caveat above (mechanically *emitted*, judged-*determined*) applies unchanged to both.
282
+
269
283
  ---
270
284
 
271
285
  ## §Session-Close-Handoff-Lifecycle
@@ -200,3 +200,52 @@ EXECUTION_TIER: standard # light / standard / full / max
200
200
  ```
201
201
 
202
202
  Temporary session change: say "use light mode for this one" or "switch to max".
203
+
204
+ ---
205
+
206
+ ## §Onboarding-Provenance
207
+
208
+ > Relocated from always-loaded `CLAUDE.md` on 2026-07-20 (residency-ledger rank 3). The **rules** these
209
+ > stories justify stay resident in CLAUDE.md; only the archaeology moved. Read this when you are about to
210
+ > *change* one of those rules — the failure that produced each one is the reason it reads the way it does.
211
+
212
+ ### Why the greeting branch test is session files, never git history
213
+
214
+ A fresh-clone Sonnet simulation rendered the **returning-user menu** to a brand-new install, because it
215
+ inferred "returning" from commit messages and CATALOG residue. A fresh clone carries the full history and
216
+ **zero session files** — history is therefore evidence of the *project's* past, not *this user's*. Logged as
217
+ `fh_signal_2026-06-11` FP8. Hence the resident rule: the branch test is **mechanical local state — session
218
+ files under `tracks/`** — and underscore-prefixed dirs (`tracks/_*`) never count as mapped projects.
219
+
220
+ ### Why the 🐿️ invariant is "same line", not a space count
221
+
222
+ An earlier phrasing pinned the number of spaces after 🐿️. That is unverifiable: a markdown renderer
223
+ **collapses multiple mid-line spaces to one**, so any assertion about the count is untestable in the
224
+ rendered output the user actually sees. The verifiable invariant is that the emoji and the welcome line are
225
+ on the **same line** (🐿️ alone on its own line was the defect being corrected).
226
+
227
+ ### Why the welcome line must be a plain translation, not a coinage
228
+
229
+ Rendering the pinned welcome phrase in the user's language once produced an invented Korean coinage
230
+ (`안 조종실…`), caught by the operator. The line is a **plain, natural translation of the pinned phrase** —
231
+ onboarding smoothness is the lid, not the substance, but a wrong lid still reads as a broken product.
232
+
233
+ ### Why a task-first entry still runs the companion-store load
234
+
235
+ Measured miss **2026-07-05**: the first message was a task, the session skipped the onboarding menu
236
+ *and* the Mode D companion-store pull along with it, ran on stale memory, and produced wrong
237
+ recommendations. The menu is a *menu*; the companion load is a *data load*. They were separated, and the
238
+ data load is now hook-backed via `scripts/fh_session_load.sh` (see `modes_and_value.md
239
+ §Session-start freshness`).
240
+
241
+ ### Why the initiative table was diet-ed (2026-07-17)
242
+
243
+ A Step 0.5 trigger probe scored **13/18**. Rows whose skill-frontmatter `description` already caught the
244
+ utterance at high confidence were removed, because platform-native skill matching owns those: plugin-recommender ·
245
+ harness-doctor · synergy · frontier-digest · sim-conductor · install-wizard · asset-placement-gate ·
246
+ marketplace-gate · public-surface-audit · verify-bidirectional · mcp-circuit-breaker · token-budget-gate ·
247
+ salience-splitter (the last earned removal by a description strengthening made in the same change, not by
248
+ its original description). What the table deliberately KEEPS: proactive safety gates (publish · destructive ·
249
+ MCP-mount) · non-skill protocol routes (gates, doctrine sections, the deep-research ladder) · disambiguators
250
+ and weak-description rows. **Operative rule (resident):** before adding a row back, probe whether the
251
+ skill's description alone already catches it.
@@ -186,6 +186,39 @@ Honest boundaries: (a) core invariants (floors, gates, identity) are never melte
186
186
  overcome-and-adopt is curation with license/provenance respect, never wholesale copying; (c) the
187
187
  disruptive path *looks inferior early* — running it is a deliberate bet, named as such.
188
188
 
189
+ ### 4-b. Boundary crossing — what actually flows between harnesses
190
+
191
+ Compose and disrupt say *what FH does to* other harnesses. They do not say **what moves across the
192
+ boundary, or what must not**. That gap is where the value of a multi-harness cluster is won or lost, so
193
+ name it: a harness that only deepens its own well stays blind to what the neighbouring well knows —
194
+ one harness sees runtime behaviour and not source structure, another sees source structure and never
195
+ runtime. **The meta-harness's job is not to dig a deeper well; it is to make outputs flow across the
196
+ boundary between wells.**
197
+
198
+ Three rules, in falling order of how easily they are broken:
199
+
200
+ 1. **Crossing must not overwrite the receiving harness's identity.** If harness B is deliberately
201
+ black-box (it verifies only what a user could observe), pushing A's white-box artifacts into B does
202
+ not enrich B — it *destroys the property that made B worth having*. Route such insight to the
203
+ knowledge store instead, and let B keep its blindness on purpose. **Identity beats convenience**;
204
+ this is the rule that gets violated first, because injecting looks like helping.
205
+ 2. **What crosses is a transformed artifact, not a raw dump.** A finding is useful to the neighbour only
206
+ in the form that neighbour already consumes. The meta-harness owns the conversion — that conversion
207
+ *is* the pipe, and building it is the work.
208
+ 3. **Two-layer governance: the meta layer supplies, the field layer adjudicates.** FH (or any meta
209
+ harness) feeds the engine and the inputs; the field harness declares the verdict on its own surface.
210
+ A meta layer that issues field verdicts directly has collapsed the layers.
211
+
212
+ Honest boundary: crossing is only worth building where the wells are **genuinely different in kind**
213
+ (different observation modality, different failure classes). Between two harnesses that see the same
214
+ things, a pipe adds coordination cost and no information — that is composition, not crossing. And a pipe
215
+ being *connected* is not the same as it being *effective*: state infrastructure and measured effect
216
+ separately, never quote the former as the latter.
217
+
218
+ Origin: forged in a field environment (2026-07-19, operator) where a black-box regression harness and a
219
+ white-box static-review harness had to feed each other without either losing its character; generalized
220
+ here with the site-specific well names removed. The field-level instance keeps its own concrete form.
221
+
189
222
  ## 5. Sidecar corollary — ride the evolution, don't patch the weak spots
190
223
 
191
224
  Mechanically patching each frontier model's current weaknesses produces scaffolding that dies as models
@@ -57,9 +57,16 @@ Session learnings automatically absorbed back into FH ecosystem.
57
57
 
58
58
  ## Weekly Audit Cycle (Phase 1.5)
59
59
 
60
- 1. `./tracks/_audit/_scanner.sh "7 days ago"`aggregates: commits, tags, stale files, sub-agent invocation log, self-asset references
61
- 2. Copy `_template_weekly.md` `weekly_audit_YYYY-MM-DD.md`
62
- 3. Propose 3-tier improvements (🟥mandatory / 🟧strong / 🟩recommended)
60
+ 1. Gather window data by hand `git log --since="{window}" --oneline` (+ count), `git tag --sort=-creatordate`, tail of `knowledge/shared/learnings/subagent_invocations_log.yaml`, stale-file spot checks.
61
+ (**No `_scanner.sh` exists** — a prior reference here was a phantom; the automation path is Phase 2 harvest-loop, a standalone scanner script is deliberately not built.)
62
+ 2. `bash scripts/below_floor_scan.sh` — below-floor marker re-run queue (exit 1 = pending floor-tier re-validations, treat as S-tier)
63
+ 3. Write `tracks/_audit/weekly_audit_YYYY-MM-DD.md` mirroring the previous audit file's format — frontmatter + activity table + 🟥🟧🟩 + pattern table. (**No `_template_weekly.md` exists**; the previous audit file is the template.)
64
+ 4. Propose 3-tier improvements (🟥mandatory / 🟧strong / 🟩recommended)
65
+
66
+ > **Why this correction is here (2026-07-20)**: the same phantom pair (`_scanner.sh` · `_template_weekly.md`)
67
+ > was fixed in `knowledge/shared/rules/operations.md` on 2026-06-11, but **this file — its sibling
68
+ > describing the same Phase 1.5 — was not updated**, so the phantom survived in the document a reader
69
+ > is more likely to open for the loop itself. Half-applied fixes leave the weaker copy authoritative.
63
70
 
64
71
  **Phase 2 (skill-ized)**: `/harvest-loop` automates the above (manual ~10 min → auto ~3 min target).
65
72
 
@@ -84,3 +84,65 @@ practitioners conflate "running model X" with running a *pruned/quantized deriva
84
84
  low-bit quantization + expert pruning measurably degrade long-context quality while the model *name* is
85
85
  unchanged). This is a general measurement pitfall, not FH-specific: a leaderboard or replication that
86
86
  pins only the display name silently compares different instruments across serving paths.
87
+
88
+ ---
89
+
90
+ ## §Instrument-Calibration
91
+
92
+ > Scope note: the sections above govern **cross-model measurement** (pin the display name, reps ≥ 3,
93
+ > discriminating identity probe). This section is broader and upstream of them: it governs **any
94
+ > instrument whose output becomes a count, a tier, or a claim** — a scan, a grep, a checker script, a
95
+ > diagnostic row, a coverage ratio. Added 2026-07-20 after three instrument defects in one session.
96
+
97
+ ### The rule
98
+
99
+ **Before an instrument's output is trusted or published, it must be shown to work on *this* target.**
100
+
101
+ 1. **Known-pair calibration.** Run it against **one case you already know is positive** and **one you
102
+ know is negative**. If it cannot separate those, it is not measuring — it is generating. This costs
103
+ one run and catches the entire class below.
104
+ 2. **Hand-verify one sample before publishing.** Open the single case the instrument is *most* confident
105
+ about and confirm by eye. Do this **before** the number enters a report.
106
+
107
+ **Publish-order asymmetry (why step 2 is not optional):** verification is cheap *before* publication and
108
+ expensive *after*. A number written into a report, a session card, and a signal file must then be
109
+ corrected in **all three**, and every downstream reader who already consumed it is not recalled.
110
+ Measured 2026-07-20: a scanner's "77 items / 70% of the index" went into exactly those three records; a
111
+ single hand-check reduced the true figure to **3**.
112
+
113
+ ### The failure class this catches: *the instrument's assumptions don't hold for this target*
114
+
115
+ Not "measured the wrong property" — the subtler one: **never asked whether this instrument is valid
116
+ here.** Three shapes, all observed 2026-07-20 in a single session:
117
+
118
+ | # | Shape | Concrete instance | What the known-pair would have shown |
119
+ |---|---|---|---|
120
+ | n+7 | **Instrument sees only part of its own declared surface** | An "always-loaded footprint" scan summed files rooted at `$TARGET`, silently omitting the auto-loaded memory index living outside it — **61% of the real resident surface** | A known-positive (a file you *know* is resident) fails to appear in the sum |
121
+ | n+8 | **A cheap proxy substituted for the real property** | Index-line/topic-file **size ratio** used as a proxy for *content coverage*; minimum ratio 3.7× read as "safe" — while an entry whose file was 3.7× larger still lacked every fact the index carried | One known case checked by content, not size, inverts the verdict immediately |
122
+ | n+9 | **Language / encoding assumption mismatch** | An **ASCII-token scanner run over a Korean corpus**: the index wrote `catch`, `MERGED`, `expert-system`; the files wrote `잡았다`, `머지`, `케이스크래프트` → every token scored as missing. **~96% false positives** | One known-negative (an entry you know is fully covered) scores as "missing" → mismatch exposed |
123
+
124
+ Secondary false-positive sources in the same run, worth checking explicitly: **whitespace/hyphen
125
+ variants** (`3주새` vs `3주 새`), and treating a line's **navigational annotation** (`(detail …, archive)`)
126
+ as a factual claim.
127
+
128
+ ### Degrade direction
129
+
130
+ - Calibration impossible or inconclusive → ship the output **labeled `UNCALIBRATED`**. It may inform;
131
+ it may **not** ground a tier, a verdict, or a published figure.
132
+ - **`not found` ≠ `0`.** A file that does not exist is not an empty file; a scan that died mid-run
133
+ reports a low number, and low numbers read as PASS. Guard the empty case explicitly and say
134
+ `UNMEASURED`, never `0`.
135
+ - An instrument that produces an **impossible value** (all-pass, all-fail, or a self-scan in which the
136
+ running tool does not detect itself) is suspect **before** its target is. Suspect the instrument first.
137
+
138
+ ### Done When
139
+
140
+ - Known-positive and known-negative both run, and the instrument separated them
141
+ (check class: **mandatory-pass** — record both cases and their outcomes)
142
+ - At least one sample hand-verified before any count is written into a report
143
+ (check class: **mandatory-pass**)
144
+ - If either is absent, the output carries the literal token `UNCALIBRATED`
145
+ (check class: **mandatory-pass** — grep the report for the label)
146
+ - Adversarial pairing for the judged part ("is this instrument valid for this corpus?"): the
147
+ known-negative **is** the adversarial case — it is chosen to be one the instrument should *not* flag,
148
+ so a flag there is a refutation, not a finding.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@chrono-meta/fh-gate",
3
- "version": "1.4.63",
3
+ "version": "1.4.64",
4
4
  "description": "FH runtime adapters — run FH governance, skills, and agents via Claude or Codex with machine-parseable gates.",
5
5
  "license": "MIT",
6
6
  "keywords": [
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fh-commons",
3
- "version": "1.4.63",
3
+ "version": "1.4.64",
4
4
  "engines": {
5
5
  "claudeCode": ">=1.0.0"
6
6
  },
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fh-meta",
3
- "version": "1.4.63",
3
+ "version": "1.4.64",
4
4
  "engines": {
5
5
  "claudeCode": ">=1.0.0"
6
6
  },
@@ -50,13 +50,68 @@ single-session even when sidecars are available.
50
50
 
51
51
  ## Step 2 — Sidecar discovery (mechanical, the anti-power-waste core)
52
52
 
53
- Build the available panel at run time; absent tools drop off silently:
53
+ Build the available panel at run time; absent tools **and unreachable endpoints** drop off silently:
54
54
  ```bash
55
- command -v codex >/dev/null && echo "codex" # GPT family CLI
56
- command -v agy >/dev/null && echo "agy" # serves Gemini AND GPT-OSSprobe the model
55
+ # Sidecar-callable CLIs only. **Scope discipline**: the probe list is NOT "every agent CLI that exists".
56
+ # FH's main is Claude Code (vendor-native`[[feedback_vendor_native_harness]]`), and the recommended
57
+ # cross-family sidecars are **codex and gemini/agy**. Other agent CLIs on the machine (opencode, qwen,
58
+ # hermes, cursor-agent …) are **runtimes a user works INSIDE**, not verifiers FH calls out to — being
59
+ # installed is not a reason to probe them. Adding one costs a maintenance surface and dilutes the panel;
60
+ # add only when a concrete task needs that family. (2026-07-19: four were added off a general CLI
61
+ # catalog and removed the same session — installed ≠ belongs in the panel.)
62
+ command -v codex >/dev/null && echo "codex" # GPT family CLI
63
+ command -v agy >/dev/null && echo "agy" # serves Gemini AND GPT-OSS — probe the model
57
64
  command -v gemini>/dev/null && echo "gemini"
58
- curl -s -m6 http://<4090-tailscale>:11434/api/tags >/dev/null 2>&1 && echo "ollama-4090" # local
65
+ command -v gh >/dev/null && gh copilot --help >/dev/null 2>&1 && echo "copilot"
66
+ # ↑ gh EXTENSION, not a binary — `command -v copilot` misses it, and
67
+ # `gh copilot --help` shows only the LAUNCHER (its sole flag is
68
+ # --remove); the real flags live behind `--`.
69
+ # Call form (verified 2026-07-19 by live call — credits were consumed):
70
+ # gh copilot -- -p '<prompt>' --model <model> --allow-all-tools
71
+ # **Same class as codex/agy**: `--model` selects among several families
72
+ # behind ONE CLI ('auto' lets Copilot pick), so family MUST come from
73
+ # the pinned/probed model (Step 3), NEVER from the CLI name.
74
+ # ★ SEAT TIER CHANGES ITS VALUE ENTIRELY — probe, never assume:
75
+ # · free seat → narrow model choice; treat as ONE extra family
76
+ # · enterprise seat → serves GPT, Gemini AND Claude behind the single
77
+ # CLI: a THREE-FAMILY panel with no other CLI installed
78
+ # ([[reference_corp_env_decorrelation_panel]]).
79
+ # ⚠️ BUT each family runs on Copilot's harness, not its vendor-native
80
+ # one — Claude-via-copilot ≠ Claude Code, GPT-via-copilot ≠ codex,
81
+ # Gemini-via-copilot ≠ agy. Per `[[feedback_vendor_native_harness]]`
82
+ # a non-native harness costs depth. So copilot buys **breadth cheaply,
83
+ # not depth**: use it to widen the panel, and route the decisive
84
+ # check to the vendor-native CLI when one is reachable. Same shape as
85
+ # the local canary tier (breadth ≠ terminal depth, measured 2026-07-19).
86
+ # Because the panel it yields depends on the seat, Step 3's model probe
87
+ # is not optional here: enumerate what this seat actually serves before
88
+ # claiming family diversity.
89
+ # Cost shape: paid-seat credits. That makes it a strong *sidecar* but a
90
+ # poor main driver — seat quota is spent faster than it is worth when
91
+ # it drives the whole harness. Recruit it for decisive checks, not bulk.
92
+ # Residual: the launcher may fetch the CLI body on first call, so on a
93
+ # cold machine the first recruit pays a download.
94
+ # Local ollama serving-paths = canary tier (electricity-only). mac localhost is public → probed
95
+ # UNCONDITIONALLY. Any extra path (e.g. a Tailscale GPU box) is an operator-private token → read from a
96
+ # gitignored binding, NEVER hardcoded in this public file. Both mac-serving (H2) and 4090-serving (평시)
97
+ # are covered: whichever box is not serving simply fails the probe and drops off.
98
+ # probe() validates the /api/tags SCHEMA, not just a reachable port: -f rejects HTTP 4xx/5xx and the
99
+ # `"models"` grep rejects a non-ollama server or an empty/overloaded instance — else a dead box reports
100
+ # live (false-positive discovery). Endpoints are only ever curl-probed here, never eval'd.
101
+ probe() { curl -fsS -m"${2:-6}" "http://$1/api/tags" 2>/dev/null | grep -q '"models"'; }
102
+ probe localhost:11434 && echo "ollama-local(mac)"
103
+ EP="$FH_SIDECAR_EXTRA"
104
+ [ -z "$EP" ] && [ -f tracks/_meta/sidecar_endpoints.env ] && \
105
+ EP="$(grep '^OLLAMA_EXTRA=' tracks/_meta/sidecar_endpoints.env | cut -d= -f2- | tr -d '"')"
106
+ for e in $EP; do
107
+ case "$e" in *[!0-9a-zA-Z.:-]*|'') continue;; esac # host:port form only — reject glob/junk (no word-split hole)
108
+ probe "$e" 10 && echo "ollama-extra($e)" # -m10: a sleeping GPU box may wake slower than 6s
109
+ done
59
110
  ```
111
+ Endpoint resolution is a **mechanical env/file read** (not a prose instruction the runner must remember),
112
+ so this discovery is tier-independent — no target-tier sim owed. The extra-endpoint binding lives only in
113
+ the gitignored `tracks/_meta/sidecar_endpoints.env` (auto-synced to the companion store); the public skill
114
+ carries the probe logic, never the address.
60
115
 
61
116
  ## Step 3 — Family map by runtime model probe (NOT CLI name)
62
117
 
@@ -105,10 +105,12 @@ size instrument* is read. The footprint rows below apply to **both** scopes and
105
105
  | **Field/project** CLAUDE.md 200+ lines | M-tier — separation or reduction needed |
106
106
  | **Field/project** 15+ `##` sections in CLAUDE.md | S-tier warning |
107
107
  | **Meta-harness (FH hub)** CLAUDE.md — raw line / section count | **Not a verdict.** Judge by the always-loaded footprint rows below (char-based = actual token cost) + the doctrine's red flags (orphaned · redundant · decorative). Report the count as context only |
108
+ | **Meta-harness — residency ledger** (the positive instrument that replaces the disabled line-count rows) | For each `##` section record **trigger class** (intent / file / ambient) + **backstop** (a hook or script path that must be **grep-verified to exist AND to be wired**, or the literal `none-by-nature`). Tier ONLY these: **M** = a section claiming a mechanical floor whose script is referenced by no hook (a prose-invoked "floor" is not a floor) · **S** = `file`-triggered *with* a verified backstop but still resident (splittable — name the destination glob) · **S** = duplicated verbatim in another section · **R** = orphaned/decorative. A section that is intent- or ambient-triggered with `none-by-nature` is **PASS, not a finding** — moving it would be fail-open. Never tier a section on its size |
108
109
  | **Meta-harness** growth since last run: decompose into *new sections* vs *existing-section growth* (mechanical — diff `##` section names + line counts vs the prior run's commit; **first run / no prior commit → report both as n/a, no tier**) | **Tier is decided by the two counts alone**: **S-tier iff existing-section growth > new-section growth** (the file is thickening faster than it is gaining capability); otherwise advisory, no tier. Report both numbers **and** the new sections' names — the names are *reporting output for the human*, never an input to the tier. Do not judge "was this growth capability-bearing?" per line |
109
110
  | SKILL.md > 300 lines AND no `SKILL_detail.md` | S-tier — propose `/salience-splitter` (governance-semantic split, not compression) |
110
111
  | Rules files unreferenced in CLAUDE.md | R-tier |
111
112
  | Always-loaded footprint > 40k chars (see scan below for what counts) | S-tier — **lever depends on where the chars live**: rules/detail still auto-loading → relocate to a non-loaded dir (e.g. `knowledge/shared/rules/`), pointers stay in CLAUDE.md · narrative inside CLAUDE.md → `/salience-splitter` · **behavioral content only, nothing left to relocate** → capability-level (merge/retire a governance unit) |
113
+ | **Memory-index footprint** — the session's auto-loaded memory index (`~/.claude/projects/<slug>/memory/MEMORY.md`), reported as **its own line, never summed into the row above** | S-tier > 10k chars — **different residency, different lever**: this one is `/memory-hygiene` (archive closed items to `MEMORY_archive.md`, tighten hooks to one line), NOT `/salience-splitter`. Summing it into the CLAUDE.md row would mis-route the lever, which is exactly what the row above ties to "where the chars live". **Blind spot this closes (2026-07-20, measured)**: a fresh top-level `/context` showed **Memory files = 41.7k of 68.8k resident tokens (61%)**, of which `MEMORY.md` alone was **14.1k — 55% the size of CLAUDE.md (25.5k)** — and the footprint scan below counted **none of it**. The instrument was optimising the smaller half of the surface it claimed to measure |
112
114
  | Always-loaded footprint > 80k chars | M-tier — same lever selection, mandatory, **and never self-discharged** (see below) |
113
115
  | **Pointer-illusion**: a CLAUDE.md "detail/detailed procedure" pointer whose target is itself an always-loaded `.claude/rules/*.md` | S-tier — the split saves zero context (rules/ auto-loads regardless); move the target out of auto-load, keep the pointer |
114
116
  | weekly_audit 14~30 days elapsed | S-tier |
@@ -123,6 +125,31 @@ budget but every unit earns its scope, the remaining lever is **capability-level
123
125
  governance unit — **not** a salience split, which by construction only moves narrative and returns ~nothing
124
126
  when the content is behavioral.
125
127
 
128
+ **Any scan-derived count must be calibrated before it is reported.** Before a number from a scan
129
+ (broken refs, INACTIVE skills, footprint chars, orphan counts, coverage) enters the report, run it
130
+ against **one known-positive and one known-negative** and record both outcomes; then **hand-verify the
131
+ single case the scan is most confident about**. If either step is skipped the number ships labeled
132
+ `UNCALIBRATED` and may not ground a tier. `not found` is reported as `UNMEASURED`, never as `0` — a
133
+ scan that dies mid-run reports a low number, and low numbers read as PASS.
134
+ Origin (2026-07-20, three instrument defects in one session): a footprint scan omitted 61% of the
135
+ resident surface it claimed to measure · a size ratio was used as a proxy for content coverage · an
136
+ ASCII-token scanner run over a Korean corpus produced ~96% false positives and a "70%" figure that was
137
+ published to three records before one hand-check reduced it to 3 items. **Suspect the instrument before
138
+ the target whenever a value is impossible** (all-pass, all-fail, or a self-scan that fails to detect the
139
+ running tool itself). Full procedure: `knowledge/shared/harness-core/measurement-integrity-checklist.md
140
+ §Instrument-Calibration`.
141
+
142
+ **Every M/S-tier must cite the row it fired — verbatim, from this file.** Write the finding as
143
+ `M-n · <verbatim row text or its threshold> · <measured value>`. If you cannot quote the row, **you do not
144
+ have a finding** — downgrade to an observation. Origin (2026-07-20, instrument defect n+4, the *fourth* in
145
+ a single run): a run fired `M-1 · CLAUDE.md 816 lines — exceeds the FH threshold of 500`. The string `500`
146
+ does not occur anywhere in this file (grep: 0 hits), and the meta-harness row it claimed to read says raw
147
+ line count is **"Not a verdict."** So the run invented a threshold *and* fired a row this skill explicitly
148
+ disables for meta-harnesses — the exact recurrence of the 2026-07-15 inversion documented below, which had
149
+ already been patched *in the skill*. The patch held; the **run** ignored it. A verdict grounded in a
150
+ citation that cannot be quoted is the same defect class as a phantom reference, and it propagates: a
151
+ downstream sidecar judgment inherited the fabricated 500 and reasoned from it until a grep caught it.
152
+
126
153
  **No M-tier in this skill is ever self-discharged — not just the footprint one.** "The cost is priced /
127
154
  accepted", "it's all necessary", "over budget but fine" are **not** verdicts this skill may reach on its
128
155
  own: an M-tier stands in the report and is closed only by an explicit operator acknowledgment logged to
@@ -150,6 +177,16 @@ Always-loaded + pointer-illusion checks are mechanical (found 2026-07-12 — FH
150
177
  # measures whichever harness you happen to be standing in (usually the hub, while diagnosing a
151
178
  # field target) — a wrong-target measurement that reports the hub's number as the target's.
152
179
  TARGET="${1:?pass the target root explicitly — cwd is not the target}"
180
+ # MEMORY-INDEX (reported SEPARATELY — see the memory-index row above; do NOT add it to T).
181
+ # It is auto-loaded every session but lives outside $TARGET, so the $TARGET-rooted sum below is
182
+ # structurally blind to it. Measured 2026-07-20: it was 55% the size of CLAUDE.md and invisible here.
183
+ MEMSLUG=$(printf '%s' "$TARGET" | sed 's|^/||; s|/|-|g')
184
+ MEMIDX="$HOME/.claude/projects/-$MEMSLUG/memory/MEMORY.md"
185
+ if [ -f "$MEMIDX" ]; then
186
+ echo "memory-index: $(wc -c < "$MEMIDX") chars — $MEMIDX (lever: /memory-hygiene, NOT salience-splitter)"
187
+ else
188
+ echo "memory-index: not found at $MEMIDX — report as UNMEASURED, not as 0 (a missing file is not an empty one)"
189
+ fi
153
190
  T=0
154
191
  for f in "$TARGET/CLAUDE.md" "$TARGET/CLAUDE.local.md"; do
155
192
  [ -f "$f" ] && T=$((T + $(wc -c < "$f")))
@@ -63,6 +63,26 @@ else
63
63
  fail=1
64
64
  fi
65
65
 
66
+ # pre-push stdin integrity — anchors the 2026-07-20 fail-open hole (a stdin-inheriting subprocess
67
+ # above the ref loop drains git's ref list → Destructive-Op gate silently allows a delete/force push).
68
+ # Wired here, not left standalone: an unwired checker is the exact defect this session found in
69
+ # session_close_check.sh — building the test and not running it repeats it one layer up.
70
+ # Package-mode guard: neither the test nor its subject (templates/.git-hooks/pre-push) is in
71
+ # package.json files[] — both are source-tree-only infra. Without this guard the SHIPPED selfcheck
72
+ # fails for every consumer running `npm test` on the installed package. Caught pre-publish 2026-07-20
73
+ # by reproducing package mode; mirrors the ref-path SKIP below.
74
+ if [ ! -f templates/.git-hooks/pre-push ]; then
75
+ echo "SKIP pre-push stdin integrity (package mode: templates/.git-hooks absent)"
76
+ elif [ -f scripts/test_prepush_stdin_integrity.sh ]; then
77
+ if ! bash scripts/test_prepush_stdin_integrity.sh; then
78
+ fail=1
79
+ fi
80
+ else
81
+ # source tree HAS the hook but NOT the test => the anchor was deleted. That is a real failure.
82
+ echo "FAIL pre-push stdin integrity: hook present but scripts/test_prepush_stdin_integrity.sh missing"
83
+ fail=1
84
+ fi
85
+
66
86
  # Referenced-path existence is a source-tree check. The npm package intentionally
67
87
  # ships a narrower runtime surface, so package-mode selfcheck skips this section.
68
88
  if [ -d ".claude/rules" ]; then