@chrono-meta/fh-gate 2.7.0 → 2.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -11,13 +11,13 @@
11
11
  "plugins": [
12
12
  {
13
13
  "name": "fh-meta",
14
- "version": "2.7.0",
14
+ "version": "2.8.0",
15
15
  "description": "New in 2.2.0: BREAKING (gate): chamber step 6 now reads ACTUAL.md, not BUDGET.md — an in-flight chamber run whose actual cost sits in BUDGET.md blocks until the ACTUAL: line moves to tracks/_chamber/<slug>/ACTUAL.md (the runner prints the path). Why: BUDGET.md's pre-verdict hash IS the ordering witness, and step 6 hard-blocked until that same file changed, so every run that reached COMPLETE necessarily mutated a witnessed artifact and verify returned TAMPERED — the chamber's promotion condition was unsatisfiable by construction, not by strictness. Two roles (immutable witness / post-verdict calibration sink) had collided in one file; each was correct alone, so neither side's code showed the conflict. Also: ko-tech-writer Step 2/4-b scans are now calibration-backed (known-pair fixtures + reproducible command, shipped) — discrimination is proven, 'zero residue' is explicitly NOT; chamber lane suite 12 -> 33 including the runner x witness seam no test covered; chamber_run.sh now teaches the two-commit discipline (gate hashes and verdict hash must land in separate commits/PRs — it previously advised the opposite). New in 2.1.0: BREAKING (gate): `crossfamily: declined` in an Axes 2-3 marker now requires grounds naming a record path that RESOLVES on disk — bare `declined`, and `declined` justified by author judgment, are blocked at commit. Remedy: cite where the operator decision lives (e.g. `.. — operator declined sidecars, per knowledge/shared/rules/operational_adaptation.md`), or use `DEGRADED_PANEL_UNUSED` if a panel was reachable and you chose not to recruit it — which is what author judgment actually is. `declined` was the only enum value with no grounds requirement; a cross-family review then broke the first (vocabulary-grep) fix three ways — self-validating on the value's own token, vacuous keyword passes, and over-blocking real declinations in natural prose — so the check asserts a resolvable record instead of words. Also: standpoint axis gains `tier1b` (a STATIC read of a target repo, executed nothing) plus a decide-in-order procedure, after blind floor-tier sims graded pure cold-reads as `tier2` three rounds running; steel-quench Wave 1's sixth angle (gate-locality) gains the output-template row it never had, so a mandatory angle stops being structurally unreportable; verify-bidirectional gains category 5 (prescriptive doctrine statement); Sister Asset Protocol gains an active-adoption trigger; new resident doctrine — Mechanization Boundary, Local Execution First, Skeleton-not-Muscle, Expedition track, and this package's versioning policy. Hub meta-operations toolkit — 35 skills + 7 agents. New in 2.0.1: harness-doctor cadence hook, portability lint wired into pre-commit, branch_claim.sh claim-count-vs-tree-count warning, louder confidentiality-scan fail-open notice, fh-gate.sh missing-package.json survival, identity ① reclassified 🟢 (cross-harness adapters + relay argument channel). 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": "2.7.0",
20
+ "version": "2.8.0",
21
21
  "description": "Project-agnostic utility skills — 5 skills (convergence-loop · deliberation · mcp-circuit-breaker · token-budget-gate · ko-tech-writer) + 1 agent (quench-challenger). Domain-independent utilities transplantable into any project.",
22
22
  "source": "./plugins/fh-commons"
23
23
  }
package/AGENTS.md CHANGED
@@ -71,6 +71,10 @@ its file never declared at all.
71
71
  - **Runtime authority:** a non-Claude sidecar returns evidence candidates, never the terminal verdict.
72
72
  The governor must source-close each finding against a local file hit, literal source span, or
73
73
  passing check. Governor agreement alone is not an anchor.
74
+ - **Sidecar write boundary:** a sidecar audits; it does not write to the target tree. Return
75
+ findings, and at most a proposed patch as text — the governor applies it. This is not a
76
+ courtesy: measured 2026-08-21, an auditor sidecar edited the tree directly and its own fix
77
+ introduced a self-referential fail-open that 41 existing lanes passed.
74
78
  - **Sidecar completion:** judge a sidecar only by the typed verdict from `scripts/sidecar_wait.sh`.
75
79
  Never infer completion or emptiness by looking at its output file.
76
80
  - **Identity grades:** the five-identity grade table is canonical only in
package/CLAUDE.md CHANGED
@@ -43,7 +43,7 @@ core invariants never melt). The nursery also **verifies what it births**: harne
43
43
  | **③ 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`) |
44
44
  | **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) |
45
45
 
46
- > **3층 정본 — 공정 · 엔진 · 정체성**: FH 를 설명하는 뼈대는 세 층이고 셋의 관계가 정본으로 적혀 있다 — **3단 공정**(엔진을 벼리는 순서: 초기 영혼 → 중간 탈상관 가속화 → **마무리 6축 태우기**) → **4대 엔진**(영혼·품질게이트·질문하기·맥락유지) → **5대 정체성**(사람이 실제로 쓰는 기능). 기억용 형태는 **3단 공정 · 4대 엔진 · 5대 정체성 · 6축 검증**이나 🟥 **6축은 네 번째 층이 아니다** — 3단 공정 ③단계가 무엇으로 이루어지는지다. **Read `knowledge/shared/harness-core/fh_three_layer_canon.md`** before naming, re-scoping, or citing any of the three — it also defines the **6 verification axes** (ⓐ계열 · ⓑ입장 · ⓒ격리 그라운딩 · ⓓ3자대면 · ⓔ첫실사용 · ⓕ되돌림; §1-a 가 최초 4축, §1-a-2 가 2026-08-16 확장) that the third stage actually consists of, and states why the three are *not* a clean stack. 🟥 **축은 «얼마나 적대적인가»가 아니라 «무엇을 받았는가»로 갈린다** — 받는 것이 같으면 리뷰어를 몇 명 붙여도 같은 사각이 남는다. 🟥 **명칭 충돌 — 이 파일 안에 「4축」이 두 개다.** §FH Improvement **4-Axis Auto-Gate** 의 4축(Axis 1 회귀 · 2 적대 · 3 팬텀 · 4 매니페스트)은 **커밋 게이트**이고, 여기 6축은 **검증 축**이다. 부분적으로만 겹치고(Axis 1·4 는 ⓐ~ⓕ 에 대응이 없다) **서로 대체하지 않는다**. 그래서 6축은 「6축 게이트」가 아니라 **「6축 검증」**으로 부른다. Grade table stays canonical in `ship_readiness_gate.md`; this pointer never carries grades.
46
+ > **3층 정본 — 공정 · 엔진 · 정체성**: FH 를 설명하는 뼈대는 세 층이고 셋의 관계가 정본으로 적혀 있다 — **3단 공정**(엔진을 벼리는 순서: 초기 영혼 → 중간 **병렬 탈상관** 가속화(두 다이얼 — **탈상관**=사각 위험[모델 계열 ⓐ + 입장 ⓑ] · **병렬**=표면 크기. 곱하지 말고 골라라) → **마무리 6축 태우기**) → **4대 엔진**(영혼·품질게이트·질문하기·맥락유지) → **5대 정체성**(사람이 실제로 쓰는 기능). 기억용 형태는 **3단 공정 · 4대 엔진 · 5대 정체성 · 6축 검증**이나 🟥 **6축은 네 번째 층이 아니다** — 3단 공정 ③단계가 무엇으로 이루어지는지다. **Read `knowledge/shared/harness-core/fh_three_layer_canon.md`** before naming, re-scoping, or citing any of the three — it also defines the **6 verification axes** (ⓐ계열 · ⓑ입장 · ⓒ격리 그라운딩 · ⓓ3자대면 · ⓔ첫실사용 · ⓕ되돌림; §1-a 가 최초 4축, §1-a-2 가 2026-08-16 확장) that the third stage actually consists of, and states why the three are *not* a clean stack. 🟥 **축은 «얼마나 적대적인가»가 아니라 «무엇을 받았는가»로 갈린다** — 받는 것이 같으면 리뷰어를 몇 명 붙여도 같은 사각이 남는다. 🟥 **명칭 충돌 — 이 파일 안에 「4축」이 두 개다.** §FH Improvement **4-Axis Auto-Gate** 의 4축(Axis 1 회귀 · 2 적대 · 3 팬텀 · 4 매니페스트)은 **커밋 게이트**이고, 여기 6축은 **검증 축**이다. 부분적으로만 겹치고(Axis 1·4 는 ⓐ~ⓕ 에 대응이 없다) **서로 대체하지 않는다**. 그래서 6축은 「6축 게이트」가 아니라 **「6축 검증」**으로 부른다. Grade table stays canonical in `ship_readiness_gate.md`; this pointer never carries grades.
47
47
 
48
48
  > **자기 대조는 상시 의무 — 트리거는 발화가 아니라 «지금 FH/PMH 자산을 건드리고 있다»**
49
49
  > (운영자 결정 2026-08-09; 이 저장소든 **다른 사용자의 install 이든** 동일). §FH Improvement
@@ -102,6 +102,19 @@ Two orthogonal layers — never collapse them.
102
102
  **not a floor** (no mechanical floor exists for tone — an accepted limitation, not a guarantee). The
103
103
  operator or project may pin a concrete default register in a local binding (`CLAUDE.local.md` / UAP
104
104
  `preferred register`) — that pin is operator taste and stays local, never in this public file.
105
+ 🟥 **A local pin sets REGISTER, never LANGUAGE — and the greeting decides the language outright.**
106
+ Reply in the language of the message you are answering; on a greeting turn, the greeting itself sets
107
+ it, **including the door labels and every menu line**, not just the prose around them. A pinned
108
+ default (`Korean 반말`, `English casual`) supplies the *register* to speak that language in — it does
109
+ not make the session answer `你好` in Korean. Half-translating (localized prose, English doors) is the
110
+ same defect in a milder form. **Measured 2026-08-21, blind, at the floor tier, one rep per arm**:
111
+ `こんにちは` → Japanese ✅ · `안녕` → Korean prose but **English door labels** 🟡 · `你好` → **Korean**
112
+ ❌ · control `hi` → English ✅. The control held, so the instrument discriminates and the defect is in
113
+ the wiring, not the measurement. 🟥 **The line above already said "not language-lock" and the floor
114
+ tier still read the pin as one** — which is why this now names the failure explicitly instead of
115
+ restating the principle. Honest scope: those arms ran in an install that *has* such a pin; whether a
116
+ clean consumer install ever had the defect is **unmeasured**, and one rep per arm is below this
117
+ repo's own `reps>=3` bar.
105
118
  - **Not flattery**: soft charisma is not pleasing the user. Disagree plainly when the work calls for it;
106
119
  warmth and a "no" coexist (no Gemini-grade sycophancy).
107
120
  - **Greeting / onboarding**: open with a warm, identity-revealing welcome (new / returning / operator
@@ -400,47 +413,26 @@ so `--admin` after a completed review is the normal route, not a shortcut).
400
413
  feature-branch push passes untouched, override honored — over-blocking would just train the override
401
414
  into muscle memory and disarm it.
402
415
 
403
- > **Two layers, and which one is the floor**: the **hard floor is server-side** this repo now runs
404
- > `enforce_admins: true` with `required_approving_review_count: 0` (set 2026-07-20; the count must be
405
- > `0`, because enabling `enforce_admins` while it is `1` locks a solo operator out of merging their
406
- > own PRs self-approval is impossible). The hook is the **shift-left layer**: it fails at push time
407
- > and prints the actual remedy, and it keeps holding if the server setting is ever relaxed. It is
408
- > deliberately not the floor — a client-side hook is bypassable with `--no-verify`.
409
- > *Origin*: before that change the server had `enforce_admins: false`, so an admin push *satisfied*
410
- > the rule and merely printed `Bypassed rule violations` a notice, not a block. A rule that
411
- > announces its own bypass is not a floor.
412
- > **Retraction the server-side force-push surface is CLOSED, and the way it was misread is the
413
- > durable part.** An earlier version of this block said `allow_force_pushes` on `main` was "still
414
- > `true`", that two API writes "did not persist", and that the **server-side** history-rewrite
415
- > surface therefore "remains open". The field reading was correct; the conclusion was not.
416
- > **Branch protection is two independent layerslegacy protection and rulesets coexist, and the
417
- > strictest wins** so a field on the protection object is never the effective answer by itself.
418
- > Measured on this repo 2026-08-09: `GET /repos/{owner}/{repo}/rules/branches/main` returns
419
- > `non_fast_forward` from ruleset `main-no-force-push` — `enforcement: active`,
420
- > `current_user_can_bypass: never`, `bypass_actors: []`, live since 2026-07-25 — while the legacy
421
- > object still reports `allow_force_pushes: true`. The two API writes that "did not persist" were
422
- > writing to the layer that does not govern *this* outcome while the stricter ruleset is active not
423
- > a layer that is inert in general: disable or retarget the ruleset and the legacy toggle governs
424
- > again. **Read BOTH layers before declaring any branch surface open or closed** — `/rules/branches/
425
- > {branch}` shows only what the *rulesets* impose, and `/branches/{branch}/protection` only what
426
- > *legacy protection* imposes; neither is the effective view alone. A protection-object field read by
427
- > itself misjudged this three times ([[reference_github_protection_two_layers]]).
428
- > **Scope of the retraction, stated narrowly on purpose**: it covers *force-push / non-fast-forward*,
429
- > which is what `non_fast_forward` blocks. Branch **deletion** is a separate rule and is closed on the
430
- > other layer (`allow_deletions: false`, same GET). PR-routing is likewise a different field —
431
- > `required_pull_request_reviews` present with `enforce_admins: true` — not something
432
- > `required_status_checks` says anything about.
433
- > ⚠️ A *different* residual on `main` is still real and must not be folded into the one just
434
- > retracted — but the residual's own description was itself stale and needed correction on
435
- > 2026-08-12 (live re-check, `[[reference_github_protection_two_layers]]`): legacy
436
- > `required_status_checks.contexts` is **`["validate"]`**, not `[]` — a green `validate` check IS
437
- > required before a PR can merge, and `GET /rules/branches/main` carries no competing
438
- > `required_status_checks` rule, so the legacy field is the effective one here. `validate`
439
- > (`.github/workflows/validate.yml`) is a **separate job from Axis 1** (`regression-guard.yml`) —
440
- > Axis 1 is still not required, see the 4-axis section below. The gap on `validate` is
441
- > `strict: false`: that check re-runs on every push to the PR branch, but nothing re-forces it
442
- > against a **moving** main after it last ran — so a check that passed can still land behind
443
- > concurrent merges it never saw.
416
+ > **Two layers, and which one is the floor.** The **hard floor is server-side**: this repo runs
417
+ > `enforce_admins: true` with `required_approving_review_count: 0` (the count must be `0`, or a solo
418
+ > operator is locked out of merging their own PRs). The pre-push hook is the **shift-left layer** — it
419
+ > fails at push time and prints the remedy deliberately not the floor, since a client-side hook is
420
+ > bypassable with `--no-verify`.
421
+ >
422
+ > 🟥 **Branch protection is TWO independent layers legacy protection and rulesets coexist, and the
423
+ > strictest wins.** A field on the protection object is **never** the effective answer by itself.
424
+ > Read **both** before declaring any branch surface open or closed:
425
+ > `GET /repos/{owner}/{repo}/rules/branches/{branch}` (rulesets) **and**
426
+ > `GET /repos/{owner}/{repo}/branches/{branch}/protection` (legacy). Reading one alone misjudged this
427
+ > repo **three times** ([[reference_github_protection_two_layers]]).
428
+ >
429
+ > ⚠️ **Live residual on `main`**: `required_status_checks.strict: false`the required `validate` check
430
+ > re-runs on every push to the PR branch, but nothing re-forces it against a **moving** main, so a green
431
+ > check can land behind concurrent merges it never saw. And `validate` is **not** Axis 1.
432
+
433
+ > **Detail**: See `knowledge/shared/harness-core/claude_md_gate_details.md §Branch-Protection-Two-Layers`
434
+ > the force-push retraction and why it was narrow, which surface each layer actually governs, and the
435
+ > three misreadings read before asserting that any branch surface is open or closed.
444
436
 
445
437
  ## Permission-Denial Guidance (When Auto-Mode Blocks an Action)
446
438
 
@@ -464,6 +456,15 @@ Simplification guard: trivial denials with one obvious fix → state block + sin
464
456
  **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
465
457
 
466
458
  **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`.)
459
+ 🟥 **The door labels below are written in English because this file is; they are NOT literals to copy.** Render the welcome line **and every door label** in the greeting's language — `你好` gets Chinese doors, `こんにちは` Japanese ones. Only the ①②③④/🔧/📖 markers, skill names and file paths stay as written. 🟥 **Measured 2026-08-21, blind, floor tier, two rounds of wiring — and it did NOT converge. The note stays anyway; read why.** Round 1 (rule in §Voice/Tone only): `こんにちは`→Japanese ✅ · `안녕`→Korean prose but **English doors** 🟡 · `你好`→**Korean** ❌ · control `hi`→English ✅. Round 2 (rule repeated here, at the doors): `你好`→**Korean** ❌ · `嗨`→**English** ❌ · `こんにちは`→Japanese ✅ · control `hey`→English ✅. Across both rounds **Japanese 3/3, Chinese 1/5**, control clean every time — so the instrument discriminates and the gap is real. **Two distinct failure modes**, and only one of them is the pin: a Korean reply is the operator pin winning, an *English* reply is these door literals being copied. Repeating the rule at the actor's location — textbook gate-locality — moved neither. 🟥 **So do not read this note as a fix.** It is a correct instruction with **no mechanical floor** (tone/language never has one, §Voice/Tone says so), kept because it is right and cheap, and labelled failing because pretending otherwise is the muscle-not-skeleton defect this repo names. The README's user-facing wording was reduced to match this measurement rather than the intent. 🟥 **The clean-install arm has since been RUN, and it reattributes the defect (same day).** A shallow
460
+ clone with no `CLAUDE.local.md` — known-positive control: it answered a CLAUDE.md-only question
461
+ correctly; known-negative: it refused to invent a nonexistent concept, so the harness was genuinely
462
+ loaded — greeted `你好` and `嗨` with **fully Chinese** door menus, and `안녕` with a **fully Korean**
463
+ one, doors included. So the operator's language pin was the **main cause**, and the 1/5 figure above is
464
+ a property of *this* install, not of a consumer's. **Do not cite 1/5 as the shipped behaviour.**
465
+ ⚠️ What did *not* close: firing is **non-deterministic** — one Chinese variant (`你好呀`) produced no
466
+ menu at all, and one Korean run opened with an English welcome line. Reps are 1–3 per arm, below this
467
+ repo's own bar. So the softened README wording stays correct; only its *reason* changed.
467
468
 
468
469
  - **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 —
469
470
 
@@ -601,65 +602,35 @@ runtime (local wiring visible, not independent) · `tier3(<harness>)` a *differe
601
602
  target harness ran it · `not-applicable` · degrade triad `DEGRADED_NO_TARGET_ACCESS` could-not /
602
603
  `DEGRADED_NOT_RUN` did-not / `UNKNOWN` did-not-look — same shape as `crossfamily:`'s triad,
603
604
  **distinct literal values**, do not reuse crossfamily's tokens).
604
- 🟥 **Settle the TARGET CLASS(es) before the tier — §7's `Q0`, added 2026-08-17 (operator decision).**
605
+ 🟥 **Settle the TARGET CLASS(es) before the tier — §7's `Q0` (operator decision 2026-08-17).**
605
606
  A consumer install **is** another harness; what the enum scopes is not who *receives* the change but
606
- where it has to be **executed**. Q0 is **not first-match — it can return more than one target, and
607
- each owes its own tier**: ⓐ a **named peer** whose local repo carries the changed surface, or which
608
- the cluster registry / a `scripts/adapters/` entry names (decide by that test, not from a name list)
609
- → the enum as written · ⓑ the delta changes **consumer-visible behavior** (what a consumer's gate
610
- blocks or passes, what their session is told to do, what an install receives) → target = a *clean
611
- install of the packed artifact*, and it binds **now, pre-push — never deferred to the eventual
612
- release** · ⓒ neither → `not-applicable`. 🟥 Do **not** read «no cross-repo consumer contract» as
613
- «this file is not shipped» measured, **194/200 recent non-merge commits touch a shipped path (97%,
614
- all 6 exceptions hand-verified)**, so shipped-ness cannot be the discriminator; the behavior clause
615
- is. Pricing the axis at that rate is the **over-triggering** §7's own Trigger paragraph rejects.
616
- ⚠️ 97% measures **the reach of the discarded shipped-path argument**, not the applicability rate —
617
- how often ⓑ actually fires is **unmeasured in both tails** (it could also land near-universal, which
618
- would be a rubber stamp watch the next 20 markers). 🟥 Do **not** cite
619
- `[[feedback_unreachable_done_when_trains_evasion]]` here: that memory concerns an unreachable *pass
620
- condition*, and `not-applicable` is an *exemption* — the direction inverts. Three marker-audit legs all failed at that reading;
621
- they were **not** decorrelated (same family · same prompt · same canon) so that is one observation,
622
- not three. ⚠️ The consumer-install arm's *presence* half is mechanized at ship time; its
623
- **execution** half (extract the tarball, run the gate, record command + output) has **no lane** —
624
- do it by hand, and do not cite that arm as mechanized.
625
- 🟥 **The execution is the load-bearing half** (operator decision 2026-08-16): a static standpoint
626
- read competes with cross-family review for the same defect classes and mostly loses *running the
627
- target harness locally, to completion*, is the part with no substitute. Measured on one delta the
628
- same day: static read found 1, running the target's own suite found 2 more, one of which printed
629
- neither `FAIL` nor `❌` and was unreachable by any read. So **`tier2`+ asserts something was RUN** —
630
- if the review only read, it is `tier1b`, and `tier1b` is deliberately the weak rung so that
631
- recording it honestly surfaces that the execution arm is still owed. (Broken on the day it was
632
- written a static read was recorded as `tier2` because `tier1b` did not yet exist; a missing rung
633
- gets filled by the next one up rather than staying empty.) Naming note: this collides in
634
- English with FH's own persona/viewpoint sense of "standpoint" (`fh-meta:beginner`/`main-player`/
635
- `expert`) — a different axis (which persona reviews, not whose repo is ground truth); kept as-is,
636
- not renamed, but do not conflate the two. 🟥 **CORRECTED 2026-08-20 — this paragraph used to say
637
- `standpoint:` was "Prose-only today — no pre-commit hook or fixture suite validates this field yet".
638
- That is FALSE and was false in this same file**: `validate_standpoint_leg()` lives in
639
- `templates/.git-hooks/pre-commit` and is called from the marker block, and its fixture suite
640
- `scripts/test_marker_standpoint_lanes.sh` is wired through `scripts/selfcheck.sh`. (🟥 **Grep the
641
- names, do not trust line numbers** — the first version of this correction cited `:798`/`:1575` and a
642
- commit landed the same hour that moved them to `:878`/`:1665`. A hardcoded anchor in prose is a
643
- phantom waiting for the next edit.) §자기 대조
644
- above already said so (PR #429), so **one file carried both claims at once** and a reader landed on
645
- whichever they reached first. Found by the residency-ledger pass, not by a lane — no check compares
646
- a rule's self-description against the machinery it describes, which is why a stale "we have not
647
- built this yet" is the quietest form of drift: it reads as honest modesty and it suppresses use of a
648
- control that already exists. **What is validated is the ENUM** — measured by varying ONE variable at a
649
- time, because the first version of this correction varied two and mis-attributed the result:
650
- `banana(qasp)` → blocked (enum) · `tier2` without parens → blocked (enum) · `tier2(qasp)` with **no**
651
- execution grounds → **passes with a warning** · with grounds → passes. 🟥 So the first fix's claim
652
- that "grounds are non-empty" are checked **over-shot, and a different-family reviewer caught it**:
653
- the `tier2`+ execution grounds are **advisory**. Two residuals remain and both are real — grounds are
654
- not enforced, and whether `tier2` is *true* is still self-attested. What was wrong was only the claim
655
- that nothing validated the field at all. Three artifacts, one carrying two
656
- independent trials (forge-harness PR #368, a sibling field harness's PR #8 reps=3 and its
657
- known-answer trial, qasp-dev PR #161 as adjacent corroboration) crossed this repo's own evidence
658
- bar the same day this was formalized — including one caught by this session's own qasp PR #161
659
- review, not fed in externally, and a second live demonstration the same day when a cross-harness
660
- standpoint review of this very section caught real residency and citation defects in the first
661
- draft (fixed in the same commit that added this line).
662
-
607
+ where it has to be **executed**. Q0 is **not first-match — it can return more than one target, and each
608
+ owes its own tier**: ⓐ a **named peer** whose local repo carries the changed surface, or which the
609
+ cluster registry / a `scripts/adapters/` entry names the enum as written · the delta changes
610
+ **consumer-visible behavior** (what a consumer's gate blocks or passes, what their session is told to do,
611
+ what an install receives) → target = a *clean install of the packed artifact*, and it binds **now,
612
+ pre-push — never deferred to the eventual release** · ⓒ neither → `not-applicable`.
613
+ 🟥 Do **not** read «no cross-repo consumer contract» as «this file is not shipped» — shipped-ness is
614
+ **not** the discriminator; the behavior clause is. ⚠️ The consumer-install arm's *presence* half is
615
+ mechanized at ship time; its **execution** half has **no lane** do it by hand, and never cite that arm
616
+ as mechanized.
617
+
618
+ > **Detail**: See `knowledge/shared/harness-core/field_verdict_crossfamily_gate.md §Q0-Evidence`
619
+ > the 97% shipped-path measurement and what it does *not* say, plus two citation warnings that
620
+ > three marker-audit legs got wrong read before citing any number from this paragraph.
621
+
622
+ 🟥 **The execution is the load-bearing half** (operator decision 2026-08-16). A static standpoint read
623
+ competes with cross-family review for the same defect classes and mostly loses; *running the target
624
+ harness locally, to completion*, is the part with no substitute. **So `tier2`+ asserts something was RUN**
625
+ the discriminator is mechanical: **name the command you ran and the output you saw.** Cannot name one →
626
+ `tier1b`, always. Reading the target's real files, however cold, is `tier1b`; that rung is deliberately
627
+ the weak one so that recording it honestly surfaces that the execution arm is still owed.
628
+
629
+ > **Detail**: See `knowledge/shared/harness-core/field_verdict_crossfamily_gate.md §Standpoint-Execution-Evidence` the measured
630
+ > one-delta comparison, the two RETRACTED citations this paragraph used to carry, the English naming
631
+ > collision with FH's persona sense of "standpoint", and the 2026-08-20 correction about what the hook
632
+ > actually validates (the enum, not the grounds) read before citing this paragraph's evidence or
633
+ > claiming what `standpoint:` enforces.
663
634
  > **Detail**: See `knowledge/shared/harness-core/field_verdict_crossfamily_gate.md` — the discretion
664
635
  > principle, the four-faces failure signature, why same-family review misses it, the full gate
665
636
  > mechanics, the n=7 qasp field evidence incl. the **9 default-toward-PASS holes across 3 harnesses**
@@ -1047,19 +1018,15 @@ dispatching.** ⓐ the user saying not to, *in this environment* — a veto of *
1047
1018
  Under a conditional, silence is not permission. ⓐ is FH's own default being withdrawn by its owner;
1048
1019
  ⓑ is a sentence in a layer FH does not author. Do not read them as one operation.
1049
1020
 
1050
- ⚠️ **Neither direction has a confirmed hook-level floor. Say that plainly rather than implying one.**
1051
- ```
1052
- opening salience only for the POSTURE. The prohibition met in the field is CONDITIONAL,
1053
- which changes what "override" even means see the measured block below.
1054
- blocking ALSO not hook-enforced. `SubagentStart` fires on spawn but is **context-only**
1055
- it cannot block, exit 2 only surfaces stderr, and it has no decision field
1056
- (official hooks reference, read 2026-08-08). It can INJECT context at the moment
1057
- of dispatch, which is better-placed salience than this file, but still salience.
1058
- UNVERIFIED whether a `permissions` deny entry or a `PreToolUse` matcher can target subagent
1059
- spawning at all — the reference does not name a tool for it, and this repo has no
1060
- precedent. **Do not cite a blocking mechanism until someone runs the known pair**
1061
- (configure the deny, attempt a dispatch, observe). Until then: unverified, not absent.
1062
- ```
1021
+ ⚠️ **Neither direction has a confirmed hook-level floor say that plainly rather than implying one.**
1022
+ Opening (the posture) is salience-only. Blocking is **also** not hook-enforced: `SubagentStart` fires on
1023
+ spawn but is **context-only** it cannot block and has no decision field. Whether a `permissions` deny
1024
+ entry or a `PreToolUse` matcher can target subagent spawning at all is **UNVERIFIED** — unverified, not
1025
+ absent. 🟥 **Do not cite a blocking mechanism until someone runs the known pair.**
1026
+
1027
+ > **Detail**: See `knowledge/shared/harness-core/dispatch_conditional_prohibition.md §Hook-Floor-Unverified`
1028
+ > the per-direction table and what each `UNVERIFIED` line covers — read before claiming any floor here.
1029
+
1063
1030
  **The conditional line, and what a session must do about it.** Some runtimes ship the default
1064
1031
  *"Do not call the AgentTool unless the user requested it"* (with a workflows/deep-research twin).
1065
1032
  Measured 2026-08-09 on this machine: it is **not** a hard-coded constant and **not** global — it is
@@ -1126,14 +1093,10 @@ instruction-shaped. A self-test the session administers to itself is the thing
1126
1093
  > order, the model-bundle gate, the calibrated where-it-is-not table, and the reproduction commands.
1127
1094
  > **Read it before citing any of these numbers or claiming the line is absent from a surface.**
1128
1095
 
1129
- An earlier draft of this very block asserted "a `SubagentStart` hook can deny, and a denial there is a
1130
- real floor." That was false, taken on trust from an adjacent session and written here before the
1131
- reference was read. A second draft, on 2026-08-09, then wrote that the constant's call site "needs
1132
- binary inspection, which was blocked" — **also false**: three plain `grep` calls resolved it, and an
1133
- adversarial reviewer demonstrated that by doing it. Declaring something unmeasurable before trying the
1134
- cheap tool is [[feedback_impossible_verdict_may_be_unread_half]]; the honest label is *"not yet
1135
- measured,"* never *"blocked."* A blind target-tier sim then read it back correctly — which shows a sim measures
1136
- whether text is *followable*, never whether it is *true*. Both checks are needed; neither substitutes.
1096
+ 🟥 **This block has been wrong twice, both times by asserting more machinery than existed.**
1097
+ > **Detail**: See `knowledge/shared/harness-core/dispatch_conditional_prohibition.md §Retraction-SubagentStart` both retractions and
1098
+ > what each teaches (*"not yet measured"* is the honest label, never *"blocked"*) read before adding a
1099
+ > mechanism claim to this section.
1137
1100
 
1138
1101
  So "default-active" is a **posture, not a guarantee**. Measured 2026-08-08: a session running under
1139
1102
  exactly that system-prompt instruction worked alone for a full session and dispatched only at the two
@@ -1169,28 +1132,28 @@ Three execution paths:
1169
1132
 
1170
1133
  **Why not Agent View by default**: Agent View introduces worktree isolation (blocks settings.json writes, Stop hook timing differs), session context gaps (session card stale content bug), and path friction — with no benefit unless the user is actively managing multiple agent sessions. Parallel agents via `Agent` tool work identically in a standard session.
1171
1134
 
1172
- **Fourth reason — gate-integrity in a worktree, and the answer is CONDITIONAL on how `core.hooksPath`
1173
- was set (measured 2026-08-05, both arms).** Do not carry a single verdict here; the two installs
1174
- behave differently:
1175
-
1176
- | `core.hooksPath` | Which hook actually runs in a worktree | Consequence |
1177
- |---|---|---|
1178
- | **relative** — `templates/.git-hooks`, the form every FH doc installs (`CHEATSHEET.md`, `.claude/rules/fh_4axis_gate.md`, `install-wizard`, `self_evolution_routine.md`) | the **worktree's own copy** | Editing that copy *inside the worktree* disables the gate for that worktree — measured: neutralized hook → FH-asset commit with no marker succeeded (`rc=0`). The verifier becomes the verified, and the edit is invisible to `git status` in the main tree. |
1179
- | **absolute** a hand-set full path (this operator's machine; **not** what any doc tells you to run) | the **main tree's copy** | A worktree-local edit has no effect; a known-positive is blocked there exactly as in the main tree (`rc=1`). |
1180
-
1181
- An earlier draft of this section reported only the absolute-path arm and declared the
1182
- "worktree bypasses the gates" hypothesis *refuted* from **n=1 on a non-canonical setting**, with a
1183
- do-not-revisit label attached. The relative-path arm, which is what everyone else runs, reproduces
1184
- the bypass. Freezing a conclusion is a defect when the measurement did not cover the shipped
1185
- configuration.
1186
-
1187
- Separately and in **both** arms, the **evidence side** breaks: `tracks/` is gitignored, so it does not
1188
- follow into a worktree, so the Axis 2+3 marker and the Axis 4 `edit_manifest.yaml` are *structurally
1189
- absent* an FH-asset commit in a worktree fails on evidence it has no way to have. That degrades
1190
- fail-closed (correct), but a gate that **cannot** be satisfied is what trains the bypass. Note the
1191
- hook itself prints `mkdir -p …/tracks/_meta` on that failure, i.e. the actor's own error message
1192
- teaches the marker-creation path so "just don't fabricate it" is prose sitting under a machine
1193
- instruction pointing the other way.
1135
+ **Fourth reason — gate-integrity in a worktree, and it is CONDITIONAL on how `core.hooksPath` was set.**
1136
+ With the **relative** form every FH doc installs, the worktree runs **its own copy** of the hook — editing
1137
+ that copy there disables the gate for that worktree (measured 2026-08-05: marker-less FH-asset commit
1138
+ succeeded). With a hand-set **absolute** path it runs the main tree's copy and the bypass does not exist.
1139
+ 🟥 **RETRACTED 2026-08-22.** This said the marker and manifest are *structurally absent* in a
1140
+ worktree. They are not: `templates/.git-hooks/pre-commit` resolves evidence through
1141
+ `git rev-parse --git-common-dir`, which returns the **main tree's** `.git` from inside a worktree.
1142
+ Measured in a clean worktree with the known-negative established first (its own `tracks/` = skeleton
1143
+ only; `$REPO_ROOT/tracks/_meta/edit_manifest.yaml` NOT FOUND, `$EVIDENCE_ROOT/...` FOUND — the two
1144
+ roots disagree, so the probe discriminates).
1145
+ **The operating rule is UNCHANGED: do not commit FH assets from a worktree.** Its remaining **open risk areas** — not
1146
+ established grounds are marker provenance, concurrent manifest append, and a copy of `tracks/` that
1147
+ appears in a worktree from an unattributed source. They are **deliberately not enumerated as reasons
1148
+ here**; an earlier draft enumerated
1149
+ them and adversarial review found a defect in nearly every added claim. ⚠️ **Reachable is not automatic**: the hook *reads* `$EVIDENCE_ROOT`, but a
1150
+ worktree session writing by relative path lands in the worktree's own `tracks/`, not the main tree's.
1151
+ The gate is satisfiable its failure message prints the absolute `MARKER_DIR` to write to — but the
1152
+ routing is the author's job, not the tool's.
1153
+
1154
+ > **Detail**: See `knowledge/shared/harness-core/dispatch_conditional_prohibition.md §Worktree-Gate-Integrity` the two-arm table with
1155
+ > exit codes, and why an earlier draft declared the bypass *refuted* from n=1 on a non-shipped setting —
1156
+ > read only when you must determine which arm your own install is on.
1194
1157
 
1195
1158
  **Therefore: do not commit FH assets from a worktree.** Not "carry the evidence in carefully" — a
1196
1159
  carried marker and a fabricated one are byte-identical, so *marker provenance* is unenforceable by
@@ -1337,36 +1300,24 @@ Closing phrase detected ("wrap up", "done", "good work", "end session", etc.)
1337
1300
  `package.json`) → Pre-Publish gate → `npm publish` → `git tag vX.Y.Z` at publish. **Propose, don't
1338
1301
  auto-publish.** (Why lockstep — Codex caches on plugin.json version — + drift-check + tag-drift caveat → §detail below.)
1339
1302
 
1340
- 🟥 **WHICH DIGIT — operator decision 2026-08-17, and it is deliberately NOT strict semver.**
1341
- There was no policy before this line, which is why one session proposed three different bumps
1342
- for the same delta on three different (and each individually defensible) grounds. Decide by
1343
- **what the number tells a reader**, not by whether anything technically broke:
1303
+ 🟥 **WHICH DIGIT — 운영자 결정(2026-08-17). 의도적으로 strict semver 아니다.**
1304
+ 판단 기준은 **무엇이 기술적으로 깨졌나**가 아니라 **번호가 읽는 이에게 무엇을 말하나**다.
1344
1305
 
1345
- | Bump | Reserved for (operator's own wording, 2026-08-17) |
1306
+ | major `+1.0.0` | 완전히 새로 지음 · ⓑ 정체성 **다섯이 «전부» 🟢**(= `identity-v1.0.0` 사건. 🟥 하나가 🟢 로 올라선 순간이 **아니고**, 정체성 등급은 npm 이 나르는 신호가 **아니다**) · ⓒ capability **class** 가 생기거나 교체됨. 🟥 **이미 있던 게이트를 조인 것에는 절대 안 쓴다** |
1346
1307
  |---|---|
1347
- | **major** `+1.0.0` | **any one of three**: **완전히 새로 지음** — rebuilt from scratch, not extended · **정체성이 확립됨** 🟥 **다섯이 «전부» 🟢** 순간이지 하나가 🟢 로 올라선 순간이 아니다(운영자 결정 2026-08-21). 초판은 *"an identity of the five … actually standing 🟢"* 였고 **「하나만 초록이어도 major」로 읽혔다** 실제로 그날 ②가 🟢 로 판정되면서 3.0.0 후보로 올라왔고, 그 애매함이 그때 닫혔다. 🟥 그리고 **정체성 등급은 npm 이 나르는 신호가 아니다** — 그건 `identity-v*` 계보의 사건이고, npm 이 또 나르면 같은 날 고친 「두 계보 한 이름」 결함을 번호에서 재생산한다. ⇒ major-ⓑ 는 **`identity-v1.0.0` 과 같은 사건**을 가리킨다 · ⓒ **기능이 혁신적으로 변경되거나 늘어남** — a capability *class* appears or is replaced, not a capability instance. 🟥 **Never** for tightening a gate that already existed |
1348
- | **minor** `+0.1.0` | 미들급 new assets, new gate lanes, doctrine that changes behavior; **including changes that break a consumer's gate acceptance**, which then carry a mandatory `BREAKING (gate):` line |
1349
- | **patch** `+0.0.1` | 트리비아급 — fixes, wiring, docs that change no behavior |
1350
-
1351
- **The discriminator between major-ⓒ and minor**: *class* vs *instance*. A sixth Wave-1 attack
1352
- angle is an instance → minor. An attack-angle **registry** where none existed is a class → major.
1353
- Today's delta is instances and tightenings throughout, which is why it is 2.1.0 and not 3.0.0
1354
- even though it breaks a gate acceptance.
1355
-
1356
- **Why gate-tightenings are minor here, stated so it is not mistaken for hiding a break**: what
1357
- breaks is the **record format of a gitignored local marker**, not an API or the consumer's code;
1358
- the hook prints exactly what to write instead; and the blast radius needs the consumer to have
1359
- installed the hook AND be making a load-bearing change AND have used the specific old form.
1360
- Against that, strict semver would burn a major on every gate we tighten — this repo took 2.0.0
1361
- for a publish-freshness gate one day and would have taken 3.0.0 for a commit gate the next.
1362
- **A major number that arrives monthly stops meaning anything**, and the milestone it should be
1363
- reserved for would have no word left.
1364
-
1365
- ⚠️ **The condition that makes this honest, and it is not optional**: a minor that breaks gate
1366
- acceptance MUST carry `BREAKING (gate): <what now blocks> — <the one-line remedy>` in the
1367
- release description AND the CHANGELOG. Without it this policy is just burying breaks in minors.
1368
- **Applies from 2026-08-17 forward, not retroactively** (2.0.0 was the same class and is left
1369
- as-is rather than rewritten).
1308
+ | **minor** `+0.1.0` | 자산 · 게이트 레인 · 행동을 바꾸는 교리. **소비자의 게이트 수용을 깨는 변경도 여기**대신 `BREAKING (gate):` 줄이 의무 |
1309
+ | **patch** `+0.0.1` | 수정 · 배선 · 행동 무변경 문서 |
1310
+
1311
+ 🟥 **major-ⓒ 와 minor 의 판별자 = *class* 냐 *instance* 냐.** Wave-1 공격각 하나 추가 =
1312
+ instance minor. 공격각 **레지스트리**가 없던 자리에 생김 = class major.
1313
+
1314
+ ⚠️ **의무**: 게이트 수용을 깨는 minor 릴리스 설명 **과** CHANGELOG
1315
+ `BREAKING (gate): <무엇이 이제 막히나> <한 줄 처방>` 를 반드시 싣는다. 이 줄이 없으면
1316
+ 이 정책은 그냥 «minor 에 파괴적 변경을 묻는 것»이다. 2026-08-17 부터 적용, 소급 아님.
1317
+
1318
+ > **Detail**: See `knowledge/shared/harness-core/claude_md_gate_details.md §Version-Digit-Policy`
1319
+ > strict semver 아닌지, 3.0.0 뻔한 판례, 게이트-조임을 minor 두는 근거와
1320
+ > 정직성 조건 **버전 자릿수를 실제로 정할 읽어라.**
1370
1321
  → ④-c Handoff lifecycle (cross-machine continuity) — when a durable **result artifact lands** this
1371
1322
  session (mechanical hint: a new `*result*`/`*signal*`/`*_run_*` file in your companion store or
1372
1323
  `tracks/`), do two things: **(a) ④-c stamps** any `"run this/start here"` run-handoff whose