@chrono-meta/fh-gate 1.4.63 → 1.4.65
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 +2 -2
- package/AGENTS.md +32 -0
- package/CLAUDE.md +139 -234
- package/knowledge/shared/harness-core/claude_md_gate_details.md +14 -0
- package/knowledge/shared/harness-core/fh_detail_protocols.md +49 -0
- package/knowledge/shared/harness-core/harness_incubator_doctrine.md +33 -0
- package/knowledge/shared/harness-core/hub_compounding_loop.md +10 -3
- package/knowledge/shared/harness-core/measurement-integrity-checklist.md +62 -0
- package/package.json +1 -1
- package/plugins/fh-commons/.claude-plugin/plugin.json +1 -1
- package/plugins/fh-meta/.claude-plugin/plugin.json +1 -1
- package/plugins/fh-meta/skills/agent-composer/SKILL.md +44 -0
- package/plugins/fh-meta/skills/auto-decorrelation/SKILL.md +59 -4
- package/plugins/fh-meta/skills/harness-doctor/SKILL.md +84 -0
- package/scripts/selfcheck.sh +20 -0
|
@@ -11,13 +11,13 @@
|
|
|
11
11
|
"plugins": [
|
|
12
12
|
{
|
|
13
13
|
"name": "fh-meta",
|
|
14
|
-
"version": "1.4.
|
|
14
|
+
"version": "1.4.65",
|
|
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.
|
|
20
|
+
"version": "1.4.65",
|
|
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,38 @@ 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: three 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 three 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
|
+
3. **Before calling a material work product done, name what you are blind to.** CLAUDE.md routes the
|
|
126
|
+
everyday "commit and merge this" moment to `agent-composer` **§Author-Exposure Table** — a review
|
|
127
|
+
pass keyed on *what the author cannot self-detect* (cold entry → `beginner` · everyday friction →
|
|
128
|
+
`main-player` · outside currency → `expert` · optimistic self-verification → `challenger` +
|
|
129
|
+
cross-family · rebuilding what exists → `fact-checker` · ungrounded numbers → `phantom-quench`),
|
|
130
|
+
with a materiality gate and an `Exposure-unclear → challenger` default so "no row applies" is not
|
|
131
|
+
an exit. **This row exists because the triggering utterance names no agent** — nothing will fire it
|
|
132
|
+
for you. Your runtime *can* run these lenses: substitute `Agent(subagent_type=...)` per §M2 above
|
|
133
|
+
(`fh-run`, or `codex exec` reading the agent spec). The lens returns evidence, never the verdict.
|
|
134
|
+
|
|
135
|
+
The irreversible-surface gates (Pre-Publish · Destructive-Op) likewise live in CLAUDE.md and fire on
|
|
136
|
+
**intent**, not on a file — read them before any publish, delete, or history-rewrite. `pre-push` enforces
|
|
137
|
+
the git-side destructive surface mechanically for every runtime.
|
|
138
|
+
|
|
107
139
|
### Entry point for Codex users
|
|
108
140
|
|
|
109
141
|
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` ·
|
|
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.
|
|
@@ -139,10 +176,36 @@ The forge-harness hub has a dual identity: **(a) a seed for others** + **(b) you
|
|
|
139
176
|
- **Implementation:** Skills such as `harvest-loop` follow this principle — they generate skill drafts, prepare commits automatically, and propose PR creation. However, the final decision to submit a PR must always require the user's explicit approval (`y`). This ensures Human-in-the-loop while maximizing AI contribution.
|
|
140
177
|
|
|
141
178
|
**PR Creation Principle:**
|
|
142
|
-
- AI may commit and push automatically (when changes are approved)
|
|
179
|
+
- AI may commit and push automatically (when changes are approved) — **to a feature branch, never to the integration branch**
|
|
143
180
|
- **PR creation requires explicit user request** ("create PR", "PR 올려줘", "pull request")
|
|
144
181
|
- **Reason:** Prevents PR fragmentation — logical units should be grouped into meaningful PRs, not atomized per commit
|
|
145
|
-
- Default workflow: commit → push → wait for explicit PR request
|
|
182
|
+
- Default workflow: branch → commit → push branch → wait for explicit PR request
|
|
183
|
+
|
|
184
|
+
**Integration branch is PR-only** (operator decision 2026-07-20). Never `git push origin main`
|
|
185
|
+
directly. Normal path: `git switch -c <branch>` → push the branch → `gh pr create` → after review
|
|
186
|
+
`gh pr merge --squash --delete-branch --admin` (self-approval is impossible when you authored the PR,
|
|
187
|
+
so `--admin` after a completed review is the normal route, not a shortcut).
|
|
188
|
+
|
|
189
|
+
**Mechanically enforced** by `templates/.git-hooks/pre-push`, which blocks a direct push to
|
|
190
|
+
`main`/`master` unless the explicit `MAIN_PUSH_OK=1` acknowledgment is set (same channel shape as
|
|
191
|
+
`DESTRUCTIVE_OP_OK` / `PUBLIC_SURFACE_OK`). Known-pair calibrated: direct-to-main blocks,
|
|
192
|
+
feature-branch push passes untouched, override honored — over-blocking would just train the override
|
|
193
|
+
into muscle memory and disarm it.
|
|
194
|
+
|
|
195
|
+
> **Two layers, and which one is the floor**: the **hard floor is server-side** — this repo now runs
|
|
196
|
+
> `enforce_admins: true` with `required_approving_review_count: 0` (set 2026-07-20; the count must be
|
|
197
|
+
> `0`, because enabling `enforce_admins` while it is `1` locks a solo operator out of merging their
|
|
198
|
+
> own PRs — self-approval is impossible). The hook is the **shift-left layer**: it fails at push time
|
|
199
|
+
> and prints the actual remedy, and it keeps holding if the server setting is ever relaxed. It is
|
|
200
|
+
> deliberately not the floor — a client-side hook is bypassable with `--no-verify`.
|
|
201
|
+
> *Origin*: before that change the server had `enforce_admins: false`, so an admin push *satisfied*
|
|
202
|
+
> the rule and merely printed `Bypassed rule violations` — a notice, not a block. A rule that
|
|
203
|
+
> announces its own bypass is not a floor.
|
|
204
|
+
> ⚠️ **Unresolved residual**: `allow_force_pushes` on `main` is still `true`. Two documented API
|
|
205
|
+
> attempts to set it `false` were accepted without error and did **not** persist (verified by
|
|
206
|
+
> independent GET, not by the write response). Force/non-ff pushes are blocked locally by this same
|
|
207
|
+
> hook, so the honest-model case is covered — but the **server-side** history-rewrite surface on
|
|
208
|
+
> `main` remains open. Re-check before relying on it.
|
|
146
209
|
|
|
147
210
|
## Permission-Denial Guidance (When Auto-Mode Blocks an Action)
|
|
148
211
|
|
|
@@ -165,7 +228,7 @@ Simplification guard: trivial denials with one obvious fix → state block + sin
|
|
|
165
228
|
|
|
166
229
|
**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
230
|
|
|
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
|
|
231
|
+
**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
232
|
|
|
170
233
|
- **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
234
|
|
|
@@ -185,150 +248,30 @@ Compose session-card candidates **into door ③ (field) and the 🔧 door (FH-de
|
|
|
185
248
|
|
|
186
249
|
**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
250
|
|
|
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
|
|
251
|
+
**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
252
|
**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
253
|
|
|
191
254
|
## New Skill Creation Pre-Commit Gate
|
|
192
255
|
|
|
193
|
-
|
|
256
|
+
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
257
|
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
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.
|
|
258
|
+
**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.
|
|
259
|
+
|
|
260
|
+
> **정본**: `.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
261
|
|
|
215
262
|
---
|
|
216
263
|
|
|
217
264
|
## FH Improvement 4-Axis Auto-Gate (Self-Verification Orchestrator)
|
|
218
265
|
|
|
219
|
-
**
|
|
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.
|
|
266
|
+
**FH 자산을 수정하면**(SKILL.md · `.claude/rules/*.md` · `knowledge/shared/rules/*.md` · `templates/` · `CLAUDE.md` · substantive `knowledge/`·`docs/*.md` · `AGENTS.md`) **4축 검증 체인이 그 세션 첫 커밋 전에 자동 실행된다.** 사용자 요청 불요 — 제안이 아니라 의무 단계다.
|
|
222
267
|
|
|
223
|
-
|
|
268
|
+
**기계 floor**: `git commit` 은 `templates/.git-hooks/pre-commit` 이 **하드 차단**한다. 축이 전부 PASS 할 때까지 커밋 자체가 안 된다. 아래 상세가 로드되지 않아도 **훅이 막는다** — 이 산문은 훅 위의 살리언스 층이지 유일 floor 가 아니다.
|
|
224
269
|
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
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
|
-
```
|
|
270
|
+
> **상세 정본**: `.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).
|
|
271
|
+
> (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 이 된다.)
|
|
272
|
+
> **의무**: 이 요약에는 **축 이름·마커 필수 필드·경량 예외 기준이 없다.** 4축을 실제로 실행하거나 마커를 쓰기 전에 위 파일을 **반드시 직접 읽어라** — 안 읽고 마커를 쓰면 필드를 지어내게 된다(2026-07-20 Sonnet sim 이 스스로 지목한 실패 모드).
|
|
273
|
+
> **잔여(살리언스 층에 한함, 훅은 무관)**: ⓐ 트리거가 read 라서 **신규 SKILL.md 를 Write 로 새로 만드는** 경로는 규칙이 안 실린다 ⓑ `CLAUDE.md` 는 glob 에서 의도적 제외라 CLAUDE.md-only 세션은 이 요약 + 훅만 본다. **두 경로에선 위 "반드시 읽어라"가 유일한 살리언스 층이다** — 단, 둘 다 pre-commit 훅이 여전히 커밋을 하드 차단한다.
|
|
240
274
|
|
|
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
275
|
|
|
333
276
|
## Field-Harness Load-Bearing Change Gate (cross-family, pre-merge)
|
|
334
277
|
|
|
@@ -369,66 +312,53 @@ pipeline**, not an afterthought, and a below-floor orchestrator RUNS the review
|
|
|
369
312
|
|
|
370
313
|
## Field-Harness Diagnostic — "진단해줘 / 개선해줘" on a mapped project (compose → rank → HITL)
|
|
371
314
|
|
|
372
|
-
The
|
|
373
|
-
the
|
|
374
|
-
|
|
375
|
-
(
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
**
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
> **
|
|
393
|
-
> (incl. loop-readiness mechanics + its adversarial pairing), the 2026-07-08 dogfood examples, and
|
|
394
|
-
> guard rationale — read when actually running the diagnostic.
|
|
315
|
+
The **on-demand pull sibling** of the gate above: a *project-level* "diagnose / improve this harness" ask
|
|
316
|
+
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
|
|
317
|
+
integrity (`/phantom-quench` **Step 2.7**) · token/salience (`/context-doctor` · `/salience-splitter`) · structure
|
|
318
|
+
(`/harness-doctor`) · verdict degrade (`scripts/degrade_direction_scan.sh`) · loop-readiness
|
|
319
|
+
(`loop_engineering.md`) — into **one ranked `M`/`S`/`R` list**. No-reinvention: it only routes and ranks.
|
|
320
|
+
|
|
321
|
+
**Resident guards (do not defer these to the detail file)**: **nothing is auto-fixed** — the list is the
|
|
322
|
+
skill's job, the *go* is the human's; and **company residency (absolute)** — **raw company source, secrets,
|
|
323
|
+
hostnames, internal repo/asset names, stack traces, and unredacted findings never leave the local machine**:
|
|
324
|
+
not to an external **or same-family** cloud model, not through a browser/API tool, not into a log, comment,
|
|
325
|
+
or paste. Leak lenses run **locally**; anything dispatched outward is a **sanitized summary only**.
|
|
326
|
+
Company-sensitive findings are *surfaced* for operator decision, never auto-fixed. Any exception needs
|
|
327
|
+
**explicit operator approval + a gitignored audit note**. (A leak does not un-happen — absolute, not
|
|
328
|
+
deferrable, and "is this sanitized enough?" is not a call the session makes alone.) **Autonomy floor**:
|
|
329
|
+
compose/rank is trusted at opus-tier+; below-floor, run the individual checks and present raw —
|
|
330
|
+
**never silently skip a lens**.
|
|
331
|
+
|
|
332
|
+
> **Detail**: See `knowledge/shared/harness-core/field_harness_diagnostic.md` — the full lens table (incl.
|
|
333
|
+
> loop-readiness mechanics + adversarial pairing), the remaining guards (project-level-only · once-per-ask ·
|
|
334
|
+
> autonomy floor · how to scale to the size of the ask), and the 2026-07-08 dogfood examples.
|
|
335
|
+
> **Read it before running the diagnostic** — this summary names the lenses, not how to run them.
|
|
395
336
|
|
|
396
337
|
## Onboarding / Acceleration Autopilot — "새 프로젝트 · 하네스 작성 · 가속화" (discover → compose → rank → install-HITL)
|
|
397
338
|
|
|
398
|
-
The **install-direction twin of the
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
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.
|
|
339
|
+
The **install-direction twin** of the Diagnostic above — same `compose → rank → HITL` engine, deciding
|
|
340
|
+
what to *install/wire* rather than what to *fix*. Four phases: **Phase 0** state audit + branch
|
|
341
|
+
(*new-build* / *extend-existing* — found→extend, never fork / *maintain* → use the Diagnostic instead) →
|
|
342
|
+
**innovator-centered recommend** → **ranked `M`/`S`/`R` install plan** (an official/built-in that covers
|
|
343
|
+
the need outranks a net-new scaffold) → **install**.
|
|
344
|
+
|
|
345
|
+
**Resident guards (inviolable — never deferred)**: **non-overwriting** — propose a merge, never clobber an
|
|
346
|
+
existing `.claude/` · **company residency** — a company sibling repo is **surfaced, never auto-mapped or leaked**; `residency` is a
|
|
347
|
+
machine field on the skill registry, so any recommendation naming a `company`/`operator-private` entry lands
|
|
348
|
+
**only** in gitignored `tracks/_meta/` or the private companion store — never in a tracked file, and the
|
|
349
|
+
absolute no-raw-company-data rule in the Diagnostic above applies here unchanged · **per-item gate routing** —
|
|
350
|
+
installed **FH assets** run the **4-axis gate**; **field scaffolds** run **`asset-placement-gate` +
|
|
351
|
+
`steel-quench`** (the FH pre-commit hook is repo-local and does **not** reach a scaffold installed into another
|
|
352
|
+
repo, so this routing is not redundant with it) · **autonomy floor** — discover/rank trusted at opus-tier+;
|
|
353
|
+
below-floor, present the raw recommend and ask · **HITL per item**, and `"끝까지 해줘 / 자율로 완주"` → full-autonomy under the `/goal-quench`
|
|
354
|
+
gate: autonomy removes the per-item *prompt*, **never the gate**. Honesty boundary that must not soften in
|
|
355
|
+
summary: the chamber to date **screens**; it has not *birthed* — simulate-first is a one-line HITL
|
|
356
|
+
recommendation, never a push-button autonomous emit.
|
|
357
|
+
|
|
358
|
+
> **Detail**: See `knowledge/shared/harness-core/onboarding_acceleration_autopilot.md` — full Phase-0 branch
|
|
359
|
+
> logic + `chamber_run.sh` scope, the per-phase skill composition, the remaining guards (no-reinvention
|
|
360
|
+
> tiering · autonomy floor · once-per-door-entry), revfactory provenance, and chamber-run-#7 guard evidence.
|
|
361
|
+
> **Read it before running the autopilot.**
|
|
432
362
|
|
|
433
363
|
## Irreversibility Gates — Surface-Class Degrade Invariant (shared spine of the two gates below)
|
|
434
364
|
|
|
@@ -538,7 +468,7 @@ force-push, scrub of tracked history, bulk deletion of session records / tracks
|
|
|
538
468
|
2. **Recover (judged — depth-sensitive)**: every CHECK/REVIEW item gets a content-direction look;
|
|
539
469
|
live un-integrated state (cards · handoffs · signals · session records) is integrated to main
|
|
540
470
|
**before** anything is deleted. This step exists because the loss class is silent — run it at the
|
|
541
|
-
strongest available tier (floor semantics
|
|
471
|
+
strongest available tier (floor semantics: `multi_model_sidecar_strategy.md §Tier-floor resolution`); a below-floor pass is provisional.
|
|
542
472
|
3. **Destroy** only what passed — REVIEW blocks a scripted delete chain (script exits 1).
|
|
543
473
|
|
|
544
474
|
**Mechanical floor (pre-push hook — git-side surfaces)**: at *push* time, **remote branch/ref deletion**
|
|
@@ -565,15 +495,7 @@ into "just delete it."
|
|
|
565
495
|
At any point during a session, when the following signals are detected, propose the relevant skill in one line.
|
|
566
496
|
Proposal format: `"I see [X]. Want me to run /[skill] to [one-line description]?"`
|
|
567
497
|
|
|
568
|
-
> **Row diet (2026-07-17
|
|
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.
|
|
498
|
+
> **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
499
|
|
|
578
500
|
| Conversation Signal Keywords | Proposed Skill |
|
|
579
501
|
|---|---|
|
|
@@ -585,6 +507,7 @@ Proposal format: `"I see [X]. Want me to run /[skill] to [one-line description]?
|
|
|
585
507
|
| "keep watching X", "poll this", "check every N minutes", recurring WATCH item | built-in `/loop` (interval runner) — pair with the WATCH list, don't hand-poll |
|
|
586
508
|
| "research this deeply", "survey the literature", "comprehensive analysis", "deep research", "look this up thoroughly", "조사해줘", "리서치" (general topic research, not trend-scan) | **Deep-Research Capability Ladder** (`knowledge/shared/harness-core/deep_research_capability_ladder.md`) — route to the highest available rung: built-in `/deep-research` if present → else Claude `WebSearch`+`WebFetch` synthesis (tier-sensitive) → `/frontier-digest` only if it's AI/harness trend-scan. No-reinvention: FH routes, does not build a research engine. |
|
|
587
509
|
| "orchestrate agents", "parallel dispatch", "combine skills", "multiple agents" | `/agent-composer` |
|
|
510
|
+
| **a material work product is about to be called done / merged / published** — public or irreversible surface · affects others · carries external claims or numbers · new behavior · security/data/permissions (proactive; the everyday "커밋하고 머지하자" utterance does **not** name an agent, so agent-composer never self-fires here — that is why this row exists) | `agent-composer` **§Author-Exposure Table** — name the exposure row, dispatch that review pass, then decide. Materiality gate + `Exposure-unclear → challenger` default live there; the lens returns evidence, never the verdict |
|
|
588
511
|
| "broaden the grounded corpus", "add another version of the corpus", "ingest the full source as the grounding axiom", "여러 버전으로 통째로 가져와" (verbatim-relay corpus expansion — fail-closed grounding, no generator) | `/corpus-grounding-expander` |
|
|
589
512
|
| "broaden these personas", "what other voices fit this cast", "map these roles to a decision lens", "페르소나 후보군 더 넓혀" (persona seed → tiered judgment-mapped cast; pairs with `persona-innovator` for naming) | `/persona-roster-expander` |
|
|
590
513
|
| "connect a project", "map this project", "link to hub" | `auto_project_mapping.md` (mapping) |
|
|
@@ -593,7 +516,7 @@ Proposal format: `"I see [X]. Want me to run /[skill] to [one-line description]?
|
|
|
593
516
|
| "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
517
|
| "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
518
|
| **"새 기능 검증해줘", "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) |
|
|
519
|
+
| "지난주에 뭐 했지", "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
520
|
| "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
521
|
| "did my rule change break anything", "regression check", "test harness changes" | `/prompt-regression` |
|
|
599
522
|
| "review for the team", "CTO review", "decision-maker", "share with leadership", "approval deck" | `/apex-review` |
|
|
@@ -604,8 +527,8 @@ Proposal format: `"I see [X]. Want me to run /[skill] to [one-line description]?
|
|
|
604
527
|
| "memory feels bloated", "clean up memory", "memory too large", "memory hygiene" | `/memory-hygiene` |
|
|
605
528
|
| "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
529
|
| **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
|
|
608
|
-
| **"새 프로젝트", "하네스 작성해줘", "이 프로젝트 가속화", "harness-ify this", "accelerate this project"** — an onboarding/acceleration door (returning-menu ①②③) | **Onboarding / Acceleration Autopilot** (see §Onboarding / Acceleration Autopilot
|
|
530
|
+
| **"진단해줘", "개선해줘", "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) |
|
|
531
|
+
| **"새 프로젝트", "하네스 작성해줘", "이 프로젝트 가속화", "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
532
|
|
|
610
533
|
**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
534
|
For per-skill utterance patterns, see the relevant `SKILL.md §Trigger Phrases` section.
|
|
@@ -707,28 +630,8 @@ Tiers: S=light(~5K) · M=standard(~15K, FH default) · L=full(~30K) · XL=max(~6
|
|
|
707
630
|
|
|
708
631
|
## Operational Status
|
|
709
632
|
|
|
710
|
-
**Current: Beta → External Validation Achieved** — v1.0 formal release conditions: additional external install evidence + at least 1 external PR.
|
|
711
|
-
|
|
712
633
|
> 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
634
|
|
|
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
635
|
## Session Wrap-up — Card Update Protocol
|
|
733
636
|
|
|
734
637
|
**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 +650,18 @@ Closing phrase detected ("wrap up", "done", "good work", "end session", etc.)
|
|
|
747
650
|
→ ③ Sync local/gitignored session state to your durable companion store, if you keep one
|
|
748
651
|
→ ④ Memory hygiene — update stale entries + record new session findings
|
|
749
652
|
→ ④-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
|
|
751
|
-
drift check** — the script (`session_close_check.sh`) auto-*fires a candidate reminder*
|
|
752
|
-
(file co-occurrence, not topical parity), then **you judge
|
|
753
|
-
actually
|
|
754
|
-
|
|
755
|
-
|
|
653
|
+
knowledge/ · docs/ · README · AGENTS.md · CLAUDE.md · CHEATSHEET · CATALOG.md): **first an entry-point
|
|
654
|
+
drift check — BIDIRECTIONAL** — the script (`session_close_check.sh`) auto-*fires a candidate reminder*
|
|
655
|
+
by cheap grep (file co-occurrence, not topical parity), then **you judge** whether the changed topic
|
|
656
|
+
actually mirrors a section on the other side; sync it, else record `drift:none`. The grep flags; it does
|
|
657
|
+
not determine — the parity call is judged. **Both directions fire, because the two entry points are read
|
|
658
|
+
by different runtimes and a rule living in only one is invisible to the other**:
|
|
659
|
+
▸ *CC→Codex* — `CLAUDE.md`/`knowledge/` changed, `AGENTS.md`/`docs/codex-compat.md` did not
|
|
660
|
+
▸ *Codex→CC* — `AGENTS.md`/`docs/codex-compat.md` changed, `CLAUDE.md`/`knowledge/` did not
|
|
661
|
+
Version lockstep invalidates the plugin.json *cache* but is **orthogonal** to
|
|
756
662
|
entry-point *content* — a version-only bump can ship a stale Codex entry point (gate-locality,
|
|
757
663
|
Codex side). Then **propose republish**: version bump **in lockstep**
|
|
758
|
-
across `package.json` + every `.claude-plugin/plugin.json` +
|
|
664
|
+
across `package.json` + every `.claude-plugin/plugin.json` + `.claude-plugin/marketplace.json` (single-source =
|
|
759
665
|
`package.json`) → Pre-Publish gate → `npm publish` → `git tag vX.Y.Z` at publish. **Propose, don't
|
|
760
666
|
auto-publish.** (Why lockstep — Codex caches on plugin.json version — + drift-check + tag-drift caveat → §detail below.)
|
|
761
667
|
→ ④-c Handoff lifecycle (cross-machine continuity) — when a durable **result artifact lands** this
|
|
@@ -775,8 +681,7 @@ Closing phrase detected ("wrap up", "done", "good work", "end session", etc.)
|
|
|
775
681
|
> when executing that close step.
|
|
776
682
|
|
|
777
683
|
**Card-last guard**: ①–④-c (incl. ①-b open-PR sweep, ④-c handoff lifecycle) must ALL complete before
|
|
778
|
-
⑤ runs. **Mechanical floor**: `
|
|
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,
|
|
684
|
+
⑤ 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
685
|
new findings, a carry item flipped to DONE) feeds INTO ⑤ — card is never written mid-sequence and
|
|
781
686
|
then left open for more work to accumulate after it.
|
|
782
687
|
|
|
@@ -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.
|
|
61
|
-
|
|
62
|
-
|
|
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
|
@@ -63,6 +63,50 @@ For each subtask in the composition plan:
|
|
|
63
63
|
| Code generation | `writes: true` + code tools | `writes: false` or no code tools |
|
|
64
64
|
| Audit-only | `writes: false` (safe) | `writes: true` (risky for audit) |
|
|
65
65
|
|
|
66
|
+
### Author-Exposure Table — a review pass, not a second executor
|
|
67
|
+
|
|
68
|
+
The table above picks **who does the subtask**. This one adds a different question at a different
|
|
69
|
+
stage: **what failure is the author structurally exposed to, now that the work is claimed done?**
|
|
70
|
+
It never replaces capability fit and never selects the agent that performs the work — it adds a
|
|
71
|
+
**review pass** before the work is released. A doc-writing subtask scores no "adversarial review"
|
|
72
|
+
fit, yet its author is blind to cold-entry failure, and capability fit never surfaces that.
|
|
73
|
+
|
|
74
|
+
**Materiality gate — run this pass only when the work product is material.** At least one of:
|
|
75
|
+
public or otherwise irreversible surface · affects users other than the author · carries external
|
|
76
|
+
claims, numbers, or citations · introduces new behavior · touches security, data, deletion, or
|
|
77
|
+
permissions. Internal notes, wording fixes, and one-line edits do **not** trigger it — an
|
|
78
|
+
unbounded trigger just trains the pass into being skipped.
|
|
79
|
+
|
|
80
|
+
| Failure the author cannot self-detect | Review mechanism | Type |
|
|
81
|
+
|---|---|---|
|
|
82
|
+
| Cold entry — first contact breaks (missing install step, undefined term, no success signal) | `beginner` | agent |
|
|
83
|
+
| Everyday-use friction invisible to the designer | `main-player` | agent |
|
|
84
|
+
| Currency vs the outside field (needs external citation, not assertion) | `expert` | agent |
|
|
85
|
+
| Self-verification only fails in the optimistic direction | `challenger` + `auto-decorrelation` | agent + pipeline |
|
|
86
|
+
| Rebuilding something that already exists | `fact-checker` · `asset-placement-gate` | agent · skill |
|
|
87
|
+
| Numbers/citations living in the artifact without grounding | `phantom-quench` | skill |
|
|
88
|
+
| **Exposure unclear** (material, but no row above fits) | `challenger` | agent — default, not a skip |
|
|
89
|
+
|
|
90
|
+
The `Type` column matters for the capability-fit checks above: `writes`/tooling scoring applies to
|
|
91
|
+
**agent** rows only; skill and pipeline rows are invoked, not scored.
|
|
92
|
+
|
|
93
|
+
**Behavioral rule — no silent skip, and "no row applies" is not an exit.** Name the row before the
|
|
94
|
+
agent. If you believe none applies, you must (a) state which rows you considered, (b) give a
|
|
95
|
+
one-line reason each is excluded, and (c) fall through to the **Exposure-unclear** row — the
|
|
96
|
+
default is `challenger`, never nothing. (Origin: 2026-07-21 — four dispatches in one session were
|
|
97
|
+
chosen by orchestrator judgment alone. They were right; that is luck, not a mechanism. In the same
|
|
98
|
+
session one `beginner` dispatch blocked a public-repo merge on 4 findings the author had not seen.)
|
|
99
|
+
|
|
100
|
+
**Behavioral rule — the lens does not hold the verdict.** A review pass returns `evidence`,
|
|
101
|
+
`risk`, and a `recommended decision` only. It may **not** emit a terminal `block`/`approve`; the
|
|
102
|
+
orchestrator declares the outcome, on its own stated grounds, and approval on an irreversible
|
|
103
|
+
surface stays with the human regardless of what the lens returned.
|
|
104
|
+
|
|
105
|
+
**Row-growth criterion (anti-case-crafting).** A new row is admissible only if the failure type has
|
|
106
|
+
been **observed more than once**, is **not coverable by an existing row**, and names a *verifiable
|
|
107
|
+
exposure axis* rather than a job title or a favorite tool. If rows keep accreting, that is the
|
|
108
|
+
signal to fold the table into a smaller set of principled axes — not to keep appending.
|
|
109
|
+
|
|
66
110
|
**Behavioral rule**: A `writes: false` agent (e.g. fact-checker, hub-persona-auditor) must NOT be assigned a task requiring edits. Capability fit scoring catches this statically before dispatch.
|
|
67
111
|
|
|
68
112
|
**Behavioral rule**: Degraded composition — when any required-weight role is filled with general-purpose fallback, output `⚠️ degraded: [role]` in the composition plan. Do not silently use general-purpose for a specialized role.
|
|
@@ -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
|
-
|
|
56
|
-
|
|
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
|
-
|
|
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,14 +105,17 @@ 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 |
|
|
115
117
|
| weekly_audit 30+ days elapsed | M-tier |
|
|
118
|
+
| `tracks/_meta/*.md` **reference assets** (excluding dated chronological records — `fh_completed_*` · `fh_signal_*` · `frontier_digest_*` · `session_*` · `weekly_audit_*` · `*_log_*`, whose date lives in the filename by design) missing **both** a role/type tag and a version/date stamp | R-tier — taxonomy gap, not urgent. ⚠️ **Measured FP rate before you act on this**: run against FH itself 2026-07-21 it flagged **99/161 (61%)** un-narrowed and **19/26 (73%)** after narrowing — a row that flags most of a directory is noise, not signal. ⚠️ **No consumer**: grep found **no skill that reads `role`/`type` from these files**. Until one exists this is taxonomy for taxonomy's sake — treat as an inventory observation, never escalate |
|
|
116
119
|
|
|
117
120
|
**Per-unit ≠ aggregate — do not slide between them.** "Every section earns its scope" (the per-unit
|
|
118
121
|
doctrine test) and "the always-loaded total is affordable" (the budget test) are **different questions, and
|
|
@@ -123,6 +126,31 @@ budget but every unit earns its scope, the remaining lever is **capability-level
|
|
|
123
126
|
governance unit — **not** a salience split, which by construction only moves narrative and returns ~nothing
|
|
124
127
|
when the content is behavioral.
|
|
125
128
|
|
|
129
|
+
**Any scan-derived count must be calibrated before it is reported.** Before a number from a scan
|
|
130
|
+
(broken refs, INACTIVE skills, footprint chars, orphan counts, coverage) enters the report, run it
|
|
131
|
+
against **one known-positive and one known-negative** and record both outcomes; then **hand-verify the
|
|
132
|
+
single case the scan is most confident about**. If either step is skipped the number ships labeled
|
|
133
|
+
`UNCALIBRATED` and may not ground a tier. `not found` is reported as `UNMEASURED`, never as `0` — a
|
|
134
|
+
scan that dies mid-run reports a low number, and low numbers read as PASS.
|
|
135
|
+
Origin (2026-07-20, three instrument defects in one session): a footprint scan omitted 61% of the
|
|
136
|
+
resident surface it claimed to measure · a size ratio was used as a proxy for content coverage · an
|
|
137
|
+
ASCII-token scanner run over a Korean corpus produced ~96% false positives and a "70%" figure that was
|
|
138
|
+
published to three records before one hand-check reduced it to 3 items. **Suspect the instrument before
|
|
139
|
+
the target whenever a value is impossible** (all-pass, all-fail, or a self-scan that fails to detect the
|
|
140
|
+
running tool itself). Full procedure: `knowledge/shared/harness-core/measurement-integrity-checklist.md
|
|
141
|
+
§Instrument-Calibration`.
|
|
142
|
+
|
|
143
|
+
**Every M/S-tier must cite the row it fired — verbatim, from this file.** Write the finding as
|
|
144
|
+
`M-n · <verbatim row text or its threshold> · <measured value>`. If you cannot quote the row, **you do not
|
|
145
|
+
have a finding** — downgrade to an observation. Origin (2026-07-20, instrument defect n+4, the *fourth* in
|
|
146
|
+
a single run): a run fired `M-1 · CLAUDE.md 816 lines — exceeds the FH threshold of 500`. The string `500`
|
|
147
|
+
does not occur anywhere in this file (grep: 0 hits), and the meta-harness row it claimed to read says raw
|
|
148
|
+
line count is **"Not a verdict."** So the run invented a threshold *and* fired a row this skill explicitly
|
|
149
|
+
disables for meta-harnesses — the exact recurrence of the 2026-07-15 inversion documented below, which had
|
|
150
|
+
already been patched *in the skill*. The patch held; the **run** ignored it. A verdict grounded in a
|
|
151
|
+
citation that cannot be quoted is the same defect class as a phantom reference, and it propagates: a
|
|
152
|
+
downstream sidecar judgment inherited the fabricated 500 and reasoned from it until a grep caught it.
|
|
153
|
+
|
|
126
154
|
**No M-tier in this skill is ever self-discharged — not just the footprint one.** "The cost is priced /
|
|
127
155
|
accepted", "it's all necessary", "over budget but fine" are **not** verdicts this skill may reach on its
|
|
128
156
|
own: an M-tier stands in the report and is closed only by an explicit operator acknowledgment logged to
|
|
@@ -150,6 +178,16 @@ Always-loaded + pointer-illusion checks are mechanical (found 2026-07-12 — FH
|
|
|
150
178
|
# measures whichever harness you happen to be standing in (usually the hub, while diagnosing a
|
|
151
179
|
# field target) — a wrong-target measurement that reports the hub's number as the target's.
|
|
152
180
|
TARGET="${1:?pass the target root explicitly — cwd is not the target}"
|
|
181
|
+
# MEMORY-INDEX (reported SEPARATELY — see the memory-index row above; do NOT add it to T).
|
|
182
|
+
# It is auto-loaded every session but lives outside $TARGET, so the $TARGET-rooted sum below is
|
|
183
|
+
# structurally blind to it. Measured 2026-07-20: it was 55% the size of CLAUDE.md and invisible here.
|
|
184
|
+
MEMSLUG=$(printf '%s' "$TARGET" | sed 's|^/||; s|/|-|g')
|
|
185
|
+
MEMIDX="$HOME/.claude/projects/-$MEMSLUG/memory/MEMORY.md"
|
|
186
|
+
if [ -f "$MEMIDX" ]; then
|
|
187
|
+
echo "memory-index: $(wc -c < "$MEMIDX") chars — $MEMIDX (lever: /memory-hygiene, NOT salience-splitter)"
|
|
188
|
+
else
|
|
189
|
+
echo "memory-index: not found at $MEMIDX — report as UNMEASURED, not as 0 (a missing file is not an empty one)"
|
|
190
|
+
fi
|
|
153
191
|
T=0
|
|
154
192
|
for f in "$TARGET/CLAUDE.md" "$TARGET/CLAUDE.local.md"; do
|
|
155
193
|
[ -f "$f" ] && T=$((T + $(wc -c < "$f")))
|
|
@@ -192,6 +230,52 @@ FAIL, the safe direction); and the scope test reads directory *existence*, so th
|
|
|
192
230
|
field→meta (acceptable: the operator names the target, and the footprint rows apply to **both** scopes
|
|
193
231
|
regardless — but it does skip the field-only line rows).
|
|
194
232
|
|
|
233
|
+
**Context-File Taxonomy check** (mechanical grep, R-tier only — a coverage lens, not a mandate): L1 (Step 2)
|
|
234
|
+
checks `CLAUDE.md` / `.claudeignore` / `.claude/` existence, but nothing checks `tracks/_meta/*.md` context-file
|
|
235
|
+
existence or taxonomy — this adds both. Note: `tpa_schema.md` classifies this file class (`session_card`) as
|
|
236
|
+
**low** risk / "ephemeral state, low blast radius" — most `tracks/_meta/*.md` files are untagged by design, and
|
|
237
|
+
that is expected, not a defect. This check surfaces untagged files for optional triage on the subset that
|
|
238
|
+
function as durable references (e.g. `reference_next_session_starter.md`); it is not a mandate that every file
|
|
239
|
+
in the directory carry a tag.
|
|
240
|
+
|
|
241
|
+
Scan for two markers per file — a role/type tag (`role:` or `type:` in frontmatter, or a leading `# Role:`
|
|
242
|
+
line) and a version/date stamp (a `YYYY-MM-DD` date or a `version:` frontmatter key, either in the first 10
|
|
243
|
+
lines). A file missing either marker is untagged — report the file list and count; do not escalate past R
|
|
244
|
+
without a human judging whether the specific file's staleness is actually a problem.
|
|
245
|
+
|
|
246
|
+
```bash
|
|
247
|
+
# find | while, not a glob — same reason as the always-loaded footprint scan above: an unmatched
|
|
248
|
+
# glob aborts under zsh, and a silent zero-match run must still report, not disappear.
|
|
249
|
+
TARGET="${1:?pass the target root explicitly — cwd is not the target}"
|
|
250
|
+
total=0; untagged=0
|
|
251
|
+
while IFS= read -r f; do
|
|
252
|
+
[ -n "$f" ] || continue
|
|
253
|
+
total=$((total + 1))
|
|
254
|
+
# 연대기 기록물은 파일명에 날짜가 있는 것이 설계다 — taxonomy 대상이 아니다(FP 원인의 78/99)
|
|
255
|
+
case "$(basename "$f")" in fh_completed_*|fh_signal_*|frontier_digest_*|session_*|weekly_audit_*|*_log_*) continue ;; esac
|
|
256
|
+
grep -qE '^(role|type):|^# ?Role:' "$f" && tag=yes || tag=no
|
|
257
|
+
head -10 "$f" | grep -qE '[0-9]{4}-[0-9]{2}-[0-9]{2}|^version:' && stamp=yes || stamp=no
|
|
258
|
+
if [ "$tag" = no ] || [ "$stamp" = no ]; then
|
|
259
|
+
untagged=$((untagged + 1))
|
|
260
|
+
echo "UNTAGGED: $f (role-tag=$tag version-stamp=$stamp)"
|
|
261
|
+
fi
|
|
262
|
+
done < <(find "$TARGET/tracks/_meta" -maxdepth 1 -name '*.md' 2>/dev/null)
|
|
263
|
+
echo "context-file-taxonomy: $untagged untagged of $total files"
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
**Named residuals of this scan**: `head -10` can miss a stamp in unusually long frontmatter; `^type:` is not
|
|
267
|
+
fence-scoped, so a stray body line starting `type:` outside frontmatter false-positives `tag=yes` — both push
|
|
268
|
+
toward under-reporting, not over-reporting.
|
|
269
|
+
|
|
270
|
+
Origin (2026-07-20, frontier-auto): surfaced via [Frontier Digest 2026-07-14](https://github.com/chrono-meta/forge-harness/issues/102#issuecomment-4964058520),
|
|
271
|
+
which described a durable-context-file pattern (role-tagged, versioned files shared across 50+ specialized
|
|
272
|
+
agents) citing `aimultiple.com/llm-orchestration` as its source. A `/phantom-quench` pass on 2026-07-20 found
|
|
273
|
+
that page's retrievable content does not actually discuss this pattern — the digest's citation is mis-attributed
|
|
274
|
+
and no verified primary source has been located. The qualitative taxonomy idea (role/version tagging on context
|
|
275
|
+
files) is adopted here on the digest's description alone and is `SPECULATIVE` per H1/H1-b until a verified
|
|
276
|
+
primary source is found; the "40% fewer tool calls" figure the digest also reported is not cited anywhere in
|
|
277
|
+
this check for the same reason.
|
|
278
|
+
|
|
195
279
|
### Step 3-L. Language Lint (`--lint` mode only)
|
|
196
280
|
|
|
197
281
|
> Activate with `/harness-doctor --lint` or when harvest-loop surfaces a P10-series signal. Skipped in standard runs.
|
package/scripts/selfcheck.sh
CHANGED
|
@@ -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
|