@chrono-meta/fh-gate 2.6.0 → 2.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/rules/fh_4axis_gate.md +26 -3
- package/.claude-plugin/marketplace.json +2 -2
- package/AGENTS.md +28 -3
- package/CLAUDE.md +146 -168
- package/README.ja.md +144 -24
- package/README.ko.md +135 -22
- package/README.md +204 -27
- package/README.zh.md +126 -21
- package/docs/ETHOS.md +10 -3
- package/knowledge/shared/dialogue/ai_dialogue_playbook.md +131 -0
- package/knowledge/shared/harness-core/claude_md_gate_details.md +90 -0
- package/knowledge/shared/harness-core/dispatch_conditional_prohibition.md +75 -0
- package/knowledge/shared/harness-core/fh_three_layer_canon.md +77 -3
- package/knowledge/shared/harness-core/field_verdict_crossfamily_gate.md +92 -5
- package/knowledge/shared/harness-core/harness_incubator_doctrine.md +12 -2
- package/knowledge/shared/harness-core/multi_model_sidecar_strategy.md +32 -0
- package/knowledge/shared/harness-core/ship_readiness_gate.md +77 -8
- package/knowledge/shared/learnings/subagent_invocations_log.yaml +196 -0
- package/knowledge/shared/rules/knowledge_layer_seam.md +1 -1
- package/knowledge/shared/rules/multi_session_close_protocol.md +7 -3
- package/package.json +15 -2
- package/plugins/fh-commons/.claude-plugin/plugin.json +1 -1
- package/plugins/fh-meta/.claude-plugin/plugin.json +1 -1
- package/plugins/fh-meta/CHANGELOG.md +157 -0
- package/plugins/fh-meta/agents/persona-innovator.md +170 -0
- package/plugins/fh-meta/skills/cross-ecosystem-synergy-detection/SKILL.md +37 -0
- package/plugins/fh-meta/skills/public-surface-audit/SKILL_detail.md +16 -1
- package/plugins/fh-meta/skills/steel-quench/SKILL.md +97 -0
- package/scripts/adapters/peer_resolve.sh +58 -6
- package/scripts/branch_claim.sh +3 -1
- package/scripts/cluster_capability_scan.sh +42 -13
- package/scripts/digest_landing_check.sh +142 -2
- package/scripts/fh_hub_identity.sh +83 -0
- package/scripts/fh_session_load.sh +53 -5
- package/scripts/fh_track_resolve.sh +114 -0
- package/scripts/field_canon_preload.sh +50 -5
- package/scripts/listing_watch.sh +187 -0
- package/scripts/package_coverage_check.sh +8 -0
- package/scripts/prior_art_prompt.sh +168 -0
- package/scripts/psa_scan_lib.sh +201 -15
- package/scripts/residency_admission_check.sh +204 -0
- package/scripts/selfcheck.sh +103 -0
- package/scripts/test_adapter_lanes.sh +67 -2
- package/scripts/test_heavy_classifier_lanes.sh +144 -0
- package/scripts/test_listing_watch_lanes.sh +162 -0
- package/scripts/test_marker_defense_lanes.sh +152 -0
- package/scripts/test_marker_soul_check_lanes.sh +211 -0
- package/scripts/test_prior_art_prompt_lanes.sh +128 -0
- package/scripts/test_psa_singlefile_lanes.sh +351 -1
- package/scripts/test_residency_admission_lanes.sh +60 -0
- package/scripts/test_track_resolve_lanes.sh +158 -0
- package/scripts/test_wizard_snippet_merge_lanes.sh +40 -0
- package/templates/.git-hooks/pre-commit +400 -4
- package/templates/.git-hooks/pre-push +17 -2
- package/templates/settings.PriorArt.snippet.json +44 -0
|
@@ -190,9 +190,32 @@ controls: n/a — no measurement in this delta (<reason>)
|
|
|
190
190
|
```
|
|
191
191
|
|
|
192
192
|
**`standpoint:`** — closed enum, canonical spec in
|
|
193
|
-
`knowledge/shared/harness-core/field_verdict_crossfamily_gate.md §7`. **Still validated
|
|
194
|
-
— zero hook lines, no fixture suite
|
|
195
|
-
|
|
193
|
+
`knowledge/shared/harness-core/field_verdict_crossfamily_gate.md §7`. 🟥 **CORRECTED 2026-08-20, then CORRECTED AGAIN the same hour.** This used to read "Still validated
|
|
194
|
+
by nothing — zero hook lines, no fixture suite", which is FALSE: `validate_standpoint_leg()` lives in
|
|
195
|
+
`templates/.git-hooks/pre-commit` (grep the function name — **line numbers are deliberately not cited
|
|
196
|
+
here; the first version of this fix cited `:798`/`:1575` and a commit landed the same hour that moved
|
|
197
|
+
them to `:878`/`:1665`**), and `scripts/test_marker_standpoint_lanes.sh` is wired through
|
|
198
|
+
`scripts/selfcheck.sh`.
|
|
199
|
+
🟥 **But the first correction over-shot, and cross-family caught that too.** It said "the value enum
|
|
200
|
+
IS closed and the grounds ARE required". Only the first half holds. Measured by varying ONE variable
|
|
201
|
+
at a time — the original known-pair varied two and mis-attributed the result:
|
|
202
|
+
|
|
203
|
+
```
|
|
204
|
+
standpoint: tier2(qasp) — ran <cmd>, saw <out> rc=0 ✅
|
|
205
|
+
standpoint: tier2(qasp) (no grounds) rc=0 ⚠️ warns, does NOT block
|
|
206
|
+
standpoint: tier2 (no parens) rc=1 ❌ not an enum member
|
|
207
|
+
standpoint: banana(qasp) rc=1 ❌ not an enum member
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
So: **the enum is closed and enforced; the execution grounds for `tier2`+ are ADVISORY.** A marker can
|
|
211
|
+
still record `tier2` without naming a command and pass with a warning — that is the real remaining
|
|
212
|
+
gap, and it is narrower than "validated by nothing" and wider than "grounds are required". Neither
|
|
213
|
+
earlier sentence was accurate, and the accurate one required varying one variable at a time.
|
|
214
|
+
🟥 **This same false claim stood in FIVE places**, not three — `CLAUDE.md` (twice), here, `AGENTS.md`,
|
|
215
|
+
and `field_verdict_crossfamily_gate.md`. Fixing one and stopping is the half-fix propagation failure;
|
|
216
|
+
fixing three and stopping was the same failure one round later. The question is never "is this
|
|
217
|
+
sentence wrong" but **"where else does this sentence live"** — and the answer came from a
|
|
218
|
+
different-family reviewer, not from me.
|
|
196
219
|
|
|
197
220
|
**`thirdparty:` — ⓓ3자 대면의 자기 필드 (2026-08-17 신설).** ⓑ가 `standpoint:` 를 갖는 것과
|
|
198
221
|
같은 형태다: `axes-run` 에는 포인터(`ⓓ=→thirdparty`)만 두고 값은 이 필드가 나른다.
|
|
@@ -11,13 +11,13 @@
|
|
|
11
11
|
"plugins": [
|
|
12
12
|
{
|
|
13
13
|
"name": "fh-meta",
|
|
14
|
-
"version": "2.
|
|
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.
|
|
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
|
|
@@ -127,9 +131,14 @@ Because non-Claude runtimes do not auto-load Claude path rules, apply these rule
|
|
|
127
131
|
2 of the 4 circled-key markers on disk are dated 2026-08-10 and carry the OLD meanings. Aligning
|
|
128
132
|
the notation still helps going forward; it does not work backwards.
|
|
129
133
|
`standpoint:` remains the canonical field for ⓑ (the `axes-run` entry
|
|
130
|
-
is only a pointer to it, and a pointer at an empty field is blocked)
|
|
131
|
-
|
|
132
|
-
|
|
134
|
+
is only a pointer to it, and a pointer at an empty field is blocked). 🟥 **CORRECTED 2026-08-20.** This used to say
|
|
135
|
+
"its value enum is still validated by nothing" — FALSE. `validate_standpoint_leg()` in the
|
|
136
|
+
pre-commit hook enforces a closed enum. Measured by varying one variable at a time:
|
|
137
|
+
`standpoint: banana(qasp)` → **blocked (enum)** · `standpoint: tier2` without parens → **blocked
|
|
138
|
+
(enum)** · `standpoint: tier2(qasp)` with no execution grounds → **passes with a warning** ·
|
|
139
|
+
with grounds → **passes**. So the enum is enforced and the `tier2`+ execution grounds are
|
|
140
|
+
**advisory** — a first version of this correction said grounds were required, which over-shot.
|
|
141
|
+
The hook also cannot check whether `tier2` is **true**. Those two, together, are the gap. Format spec: `.claude/rules/fh_4axis_gate.md §Marker axis fields`.
|
|
133
142
|
(Two drift corrections landed here on 2026-08-17: first this sentence said "four" while its own
|
|
134
143
|
next clause described the +1 — caught by the session-close ④-b CC↔Codex parity check — and then
|
|
135
144
|
the machine layer moved to six the same day.)
|
|
@@ -144,6 +153,22 @@ Because non-Claude runtimes do not auto-load Claude path rules, apply these rule
|
|
|
144
153
|
`❌`. Execution is the half with no substitute; see `field_verdict_crossfamily_gate.md §7`. Read it before recording; §1-c
|
|
145
154
|
holds the sample limits — read it before citing. This record is self-attested and has no hook
|
|
146
155
|
behind it; it is closed by a different-family reader, not by writing it more carefully.
|
|
156
|
+
🟥 **`axis2-defense:` — a marker field added 2026-08-20 that a Codex-side author WILL hit.**
|
|
157
|
+
It is required when the marker records `floor-status: sonnet-floor` or `below-floor`, and it carries
|
|
158
|
+
three sub-answers (on one line, or across continuation lines — the hook reads both) about **your own findings and numbers**:
|
|
159
|
+
`axis2-defense: reproducibility=<exact command or file:line another session runs> fairness=<reps,
|
|
160
|
+
inputs and environment named for BOTH arms> estimation-layer=<per number: measured | estimate |
|
|
161
|
+
quotation; for a measurement, what showed the instrument works on this target>`.
|
|
162
|
+
The hook (`validate_defense_leg`) checks **presence · completeness · non-vacuity** — `ok`/`yes`/
|
|
163
|
+
`n/a` is rejected as a filled form rather than an answer, and all three sub-answers must exist.
|
|
164
|
+
It cannot check whether the answers are true. Why it exists: measured n=6 in the origin field, a
|
|
165
|
+
floor-tier pass runs the attack angles without defect but does **not** spontaneously ask these
|
|
166
|
+
three; that is a checklist gap, not a capability gap, and a harness whose behaviour depends on
|
|
167
|
+
which model drives it is defective by the Sonnet-Floor doctrine.
|
|
168
|
+
Fixtures: `scripts/test_marker_defense_lanes.sh`. Spec: `plugins/fh-meta/skills/steel-quench/SKILL.md`
|
|
169
|
+
§Wave 1-D. **Recorded here because a rule living in only one entry point is invisible to the other
|
|
170
|
+
runtime** — that is the gate-locality principle, and this line is it being applied rather than cited.
|
|
171
|
+
|
|
147
172
|
8. **Branch-surface claims:** GitHub branch protection is two independent layers — legacy
|
|
148
173
|
protection and rulesets coexist, and the strictest wins. Read both
|
|
149
174
|
`/repos/{owner}/{repo}/branches/{branch}/protection` and
|
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단 공정**(엔진을 벼리는 순서: 초기 영혼 → 중간
|
|
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
|
|
@@ -376,8 +389,18 @@ claim 이 `main` 인 동안 실제 HEAD 는 peer 브랜치였다 — 두 세션
|
|
|
376
389
|
**남은 잔여 둘, 이름으로 남긴다**: ⓐ 게이트는 **커밋 시점**이라 `switch -c` 사고 자체는 못 막는다
|
|
377
390
|
(그래서 위 두 줄이 여전히 사람 몫이다 — [[feedback_gate_binding_point_not_check_point]])
|
|
378
391
|
ⓑ 반대 방향 — 내가 브랜치를 쥔 동안 남이 되돌리고 커밋하면 **내 staged 파일이 index 에 살아
|
|
379
|
-
있다.**
|
|
380
|
-
|
|
392
|
+
있다.** 🟥 **2026-08-21 실제로 났고, 섞은 세션은 파일 지정 `add` 를 썼다**(초판은 여기 「파일
|
|
393
|
+
지정 add 를 썼기 때문에 안 섞였다」고 적었는데 거짓이다). 파일 지정 add 는 «내가 무엇을
|
|
394
|
+
**추가**하나»만 통제하고 **index 에 이미 있는 것은 못 막는다.** ⇒ `git add -A` 금지는 필요조건
|
|
395
|
+
이지 충분조건이 아니다. **커밋을 한 호출로 묶고 그 안에서 둘을 확인한다** — 확인은 점이고 위험은
|
|
396
|
+
구간이라, 사이에 턴이 끼면 창이 다시 생긴다(같은 날 두 세션이 시점을 각각 `switch` 직전/직후로
|
|
397
|
+
달리 골랐는데 **둘 다 뚫렸다**):
|
|
398
|
+
```
|
|
399
|
+
B=$(git branch --show-current); [ "$B" = "<내 브랜치>" ] || exit 1
|
|
400
|
+
git diff --cached --name-only # 내 것만 있나 — 남의 것은 restore --staged
|
|
401
|
+
git commit …
|
|
402
|
+
```
|
|
403
|
+
([[feedback_shared_checkout_ops_touch_others_work]] · [[feedback_gate_binding_point_not_check_point]])
|
|
381
404
|
|
|
382
405
|
**Integration branch is PR-only** (operator decision 2026-07-20). Never `git push origin main`
|
|
383
406
|
directly. Normal path: `git switch -c <branch>` → push the branch → `gh pr create` → after review
|
|
@@ -390,47 +413,26 @@ so `--admin` after a completed review is the normal route, not a shortcut).
|
|
|
390
413
|
feature-branch push passes untouched, override honored — over-blocking would just train the override
|
|
391
414
|
into muscle memory and disarm it.
|
|
392
415
|
|
|
393
|
-
> **Two layers, and which one is the floor
|
|
394
|
-
> `enforce_admins: true` with `required_approving_review_count: 0` (
|
|
395
|
-
>
|
|
396
|
-
>
|
|
397
|
-
>
|
|
398
|
-
>
|
|
399
|
-
>
|
|
400
|
-
>
|
|
401
|
-
>
|
|
402
|
-
>
|
|
403
|
-
>
|
|
404
|
-
>
|
|
405
|
-
>
|
|
406
|
-
> **
|
|
407
|
-
>
|
|
408
|
-
>
|
|
409
|
-
|
|
410
|
-
>
|
|
411
|
-
>
|
|
412
|
-
>
|
|
413
|
-
> a layer that is inert in general: disable or retarget the ruleset and the legacy toggle governs
|
|
414
|
-
> again. **Read BOTH layers before declaring any branch surface open or closed** — `/rules/branches/
|
|
415
|
-
> {branch}` shows only what the *rulesets* impose, and `/branches/{branch}/protection` only what
|
|
416
|
-
> *legacy protection* imposes; neither is the effective view alone. A protection-object field read by
|
|
417
|
-
> itself misjudged this three times ([[reference_github_protection_two_layers]]).
|
|
418
|
-
> **Scope of the retraction, stated narrowly on purpose**: it covers *force-push / non-fast-forward*,
|
|
419
|
-
> which is what `non_fast_forward` blocks. Branch **deletion** is a separate rule and is closed on the
|
|
420
|
-
> other layer (`allow_deletions: false`, same GET). PR-routing is likewise a different field —
|
|
421
|
-
> `required_pull_request_reviews` present with `enforce_admins: true` — not something
|
|
422
|
-
> `required_status_checks` says anything about.
|
|
423
|
-
> ⚠️ A *different* residual on `main` is still real and must not be folded into the one just
|
|
424
|
-
> retracted — but the residual's own description was itself stale and needed correction on
|
|
425
|
-
> 2026-08-12 (live re-check, `[[reference_github_protection_two_layers]]`): legacy
|
|
426
|
-
> `required_status_checks.contexts` is **`["validate"]`**, not `[]` — a green `validate` check IS
|
|
427
|
-
> required before a PR can merge, and `GET /rules/branches/main` carries no competing
|
|
428
|
-
> `required_status_checks` rule, so the legacy field is the effective one here. `validate`
|
|
429
|
-
> (`.github/workflows/validate.yml`) is a **separate job from Axis 1** (`regression-guard.yml`) —
|
|
430
|
-
> Axis 1 is still not required, see the 4-axis section below. The gap on `validate` is
|
|
431
|
-
> `strict: false`: that check re-runs on every push to the PR branch, but nothing re-forces it
|
|
432
|
-
> against a **moving** main after it last ran — so a check that passed can still land behind
|
|
433
|
-
> 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.
|
|
434
436
|
|
|
435
437
|
## Permission-Denial Guidance (When Auto-Mode Blocks an Action)
|
|
436
438
|
|
|
@@ -454,6 +456,15 @@ Simplification guard: trivial denials with one obvious fix → state block + sin
|
|
|
454
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
|
|
455
457
|
|
|
456
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.
|
|
457
468
|
|
|
458
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 —
|
|
459
470
|
|
|
@@ -591,58 +602,35 @@ runtime (local wiring visible, not independent) · `tier3(<harness>)` a *differe
|
|
|
591
602
|
target harness ran it · `not-applicable` · degrade triad `DEGRADED_NO_TARGET_ACCESS` could-not /
|
|
592
603
|
`DEGRADED_NOT_RUN` did-not / `UNKNOWN` did-not-look — same shape as `crossfamily:`'s triad,
|
|
593
604
|
**distinct literal values**, do not reuse crossfamily's tokens).
|
|
594
|
-
🟥 **Settle the TARGET CLASS(es) before the tier — §7's `Q0
|
|
605
|
+
🟥 **Settle the TARGET CLASS(es) before the tier — §7's `Q0` (operator decision 2026-08-17).**
|
|
595
606
|
A consumer install **is** another harness; what the enum scopes is not who *receives* the change but
|
|
596
|
-
where it has to be **executed**. Q0 is **not first-match — it can return more than one target, and
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
gets filled by the next one up rather than staying empty.) Naming note: this collides in
|
|
624
|
-
English with FH's own persona/viewpoint sense of "standpoint" (`fh-meta:beginner`/`main-player`/
|
|
625
|
-
`expert`) — a different axis (which persona reviews, not whose repo is ground truth); kept as-is,
|
|
626
|
-
not renamed, but do not conflate the two. 🟥 **CORRECTED 2026-08-20 — this paragraph used to say
|
|
627
|
-
`standpoint:` was "Prose-only today — no pre-commit hook or fixture suite validates this field yet".
|
|
628
|
-
That is FALSE and was false in this same file**: `validate_standpoint_leg()` is defined at
|
|
629
|
-
`templates/.git-hooks/pre-commit:798` and called at `:1575`, and its fixture suite
|
|
630
|
-
`scripts/test_marker_standpoint_lanes.sh` is wired through `scripts/selfcheck.sh:531`. §자기 대조
|
|
631
|
-
above already said so (PR #429), so **one file carried both claims at once** and a reader landed on
|
|
632
|
-
whichever they reached first. Found by the residency-ledger pass, not by a lane — no check compares
|
|
633
|
-
a rule's self-description against the machinery it describes, which is why a stale "we have not
|
|
634
|
-
built this yet" is the quietest form of drift: it reads as honest modesty and it suppresses use of a
|
|
635
|
-
control that already exists. **What is validated is FORM, not truth** — the hook checks that the
|
|
636
|
-
value is inside the closed enum and that its grounds are non-empty; whether `tier2` is *true* is
|
|
637
|
-
still self-attested, exactly as with `crossfamily:`. That residual is real and unchanged; it is the
|
|
638
|
-
sentence above that was wrong, not the caution. Three artifacts, one carrying two
|
|
639
|
-
independent trials (forge-harness PR #368, a sibling field harness's PR #8 reps=3 and its
|
|
640
|
-
known-answer trial, qasp-dev PR #161 as adjacent corroboration) crossed this repo's own evidence
|
|
641
|
-
bar the same day this was formalized — including one caught by this session's own qasp PR #161
|
|
642
|
-
review, not fed in externally, and a second live demonstration the same day when a cross-harness
|
|
643
|
-
standpoint review of this very section caught real residency and citation defects in the first
|
|
644
|
-
draft (fixed in the same commit that added this line).
|
|
645
|
-
|
|
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.
|
|
646
634
|
> **Detail**: See `knowledge/shared/harness-core/field_verdict_crossfamily_gate.md` — the discretion
|
|
647
635
|
> principle, the four-faces failure signature, why same-family review misses it, the full gate
|
|
648
636
|
> mechanics, the n=7 qasp field evidence incl. the **9 default-toward-PASS holes across 3 harnesses**
|
|
@@ -824,7 +812,8 @@ deleted branch was carrying).
|
|
|
824
812
|
**When this gate fires** — *before* any of: branch deletion (local or remote), history rewrite /
|
|
825
813
|
force-push, scrub of tracked history, bulk deletion of session records / tracks content.
|
|
826
814
|
|
|
827
|
-
1. **Enumerate (measured)
|
|
815
|
+
1. **Enumerate (measured)** — 🟥 **this step is run BY A HUMAN; no hook executes it** (measured
|
|
816
|
+
2026-08-20, residency-ledger pass): `bash templates/predelete_check.sh <repo> [base]` — per branch: commits
|
|
828
817
|
off base + unique paths. Verdicts: SAFE (fully merged) · CHECK (0 unique paths but commits off
|
|
829
818
|
base — shared files may hold *newer* content, e.g. an unmerged session card) · REVIEW (unique
|
|
830
819
|
paths — recovery mandatory).
|
|
@@ -845,6 +834,15 @@ prose gate is now stopped); it does **not** close the injected/adversarial one
|
|
|
845
834
|
or errors, this irreversible surface **fails closed** — the pre-push hook blocks (enumerate by hand or
|
|
846
835
|
take the explicit `DESTRUCTIVE_OP_OK=1` override); a tooling-down enumerate step never silently degrades
|
|
847
836
|
into "just delete it."
|
|
837
|
+
🟥 **Read that precisely — the floor is the HOOK, not this script.** `templates/.git-hooks/pre-push`
|
|
838
|
+
implements the per-ref verdict **inline**; it does not call `predelete_check.sh`. Measured 2026-08-20
|
|
839
|
+
(control: the same scan finds `session_close_check` wired in that hook): every in-repo reference to
|
|
840
|
+
`predelete_check.sh` is a **mention, not an execution** — `pre-push:408` lists the path inside a *grep
|
|
841
|
+
pattern*, `destructive_pre_gate.sh:191` *prints the command* as advisory text, and `selfcheck.sh:192`
|
|
842
|
+
runs `bash -n` on it. So the script is the **operator's enumerate tool**, and step 1 above is a human
|
|
843
|
+
step that the machinery reminds you of rather than performs. Stating it the other way round is the
|
|
844
|
+
"prose-invoked floor" the 4-axis marker spec calls M-tier when a rule claims a floor its script has
|
|
845
|
+
no caller for — this section does not make that claim, and this note keeps it from drifting into one.
|
|
848
846
|
|
|
849
847
|
> **Detail**: See `knowledge/shared/harness-core/claude_md_gate_details.md §Destructive-Op-Hook-Coverage`
|
|
850
848
|
> — the per-ref verdict mechanics, what the hook does/does not close (honest scope + adversarial residual),
|
|
@@ -1005,7 +1003,7 @@ Self-healing is not only FH-self-dev (Mode D 4-axis) and reactive (`verify-bidir
|
|
|
1005
1003
|
|
|
1006
1004
|
## Agent Dispatch Operation (FH cwd-Based)
|
|
1007
1005
|
|
|
1008
|
-
> **Runtime authority (canonical):** one explicit governor per context + capability-routed sidecars; sidecar findings are evidence candidates, not terminal verdicts, until source-closed by the governor *via a mechanical anchor* — never governor agreement alone. CC=action/governor · Codex=repo-grounded audit sidecar · Gemini/agy=breadth/multimodal sidecar · other runtimes=portable `AGENTS.md` entrypoint only. Full doctrine + Maintenance-Cost Rule: `knowledge/shared/harness-core/multi_model_sidecar_strategy.md §Runtime Authority`.
|
|
1006
|
+
> **Runtime authority (canonical):** one explicit governor per context + capability-routed sidecars; sidecar findings are evidence candidates, not terminal verdicts, until source-closed by the governor *via a mechanical anchor* — never governor agreement alone. 🟥 **A sidecar audits; it does not WRITE to the target tree** — findings and at-most a proposed patch as text, applied by the governor (measured 2026-08-21: an auditor sidecar edited the tree and its fix introduced a self-referential fail-open that 41 lanes passed). CC=action/governor · Codex=repo-grounded audit sidecar · Gemini/agy=breadth/multimodal sidecar · other runtimes=portable `AGENTS.md` entrypoint only. Full doctrine + Maintenance-Cost Rule: `knowledge/shared/harness-core/multi_model_sidecar_strategy.md §Runtime Authority`.
|
|
1009
1007
|
|
|
1010
1008
|
**Isolated delegation is a component of the identity, not an optional extra** (operator decision,
|
|
1011
1009
|
2026-08-08). FH/PMH are defined as governor + orchestrator; a harness that cannot dispatch is a
|
|
@@ -1020,19 +1018,15 @@ dispatching.** ⓐ the user saying not to, *in this environment* — a veto of *
|
|
|
1020
1018
|
Under a conditional, silence is not permission. ⓐ is FH's own default being withdrawn by its owner;
|
|
1021
1019
|
ⓑ is a sentence in a layer FH does not author. Do not read them as one operation.
|
|
1022
1020
|
|
|
1023
|
-
⚠️ **Neither direction has a confirmed hook-level floor
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
spawning at all — the reference does not name a tool for it, and this repo has no
|
|
1033
|
-
precedent. **Do not cite a blocking mechanism until someone runs the known pair**
|
|
1034
|
-
(configure the deny, attempt a dispatch, observe). Until then: unverified, not absent.
|
|
1035
|
-
```
|
|
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
|
+
|
|
1036
1030
|
**The conditional line, and what a session must do about it.** Some runtimes ship the default
|
|
1037
1031
|
*"Do not call the AgentTool unless the user requested it"* (with a workflows/deep-research twin).
|
|
1038
1032
|
Measured 2026-08-09 on this machine: it is **not** a hard-coded constant and **not** global — it is
|
|
@@ -1099,14 +1093,10 @@ instruction-shaped. A self-test the session administers to itself is the thing
|
|
|
1099
1093
|
> order, the model-bundle gate, the calibrated where-it-is-not table, and the reproduction commands.
|
|
1100
1094
|
> **Read it before citing any of these numbers or claiming the line is absent from a surface.**
|
|
1101
1095
|
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
adversarial reviewer demonstrated that by doing it. Declaring something unmeasurable before trying the
|
|
1107
|
-
cheap tool is [[feedback_impossible_verdict_may_be_unread_half]]; the honest label is *"not yet
|
|
1108
|
-
measured,"* never *"blocked."* A blind target-tier sim then read it back correctly — which shows a sim measures
|
|
1109
|
-
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.
|
|
1110
1100
|
|
|
1111
1101
|
So "default-active" is a **posture, not a guarantee**. Measured 2026-08-08: a session running under
|
|
1112
1102
|
exactly that system-prompt instruction worked alone for a full session and dispatched only at the two
|
|
@@ -1142,28 +1132,28 @@ Three execution paths:
|
|
|
1142
1132
|
|
|
1143
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.
|
|
1144
1134
|
|
|
1145
|
-
**Fourth reason — gate-integrity in a worktree, and
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
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.
|
|
1167
1157
|
|
|
1168
1158
|
**Therefore: do not commit FH assets from a worktree.** Not "carry the evidence in carefully" — a
|
|
1169
1159
|
carried marker and a fabricated one are byte-identical, so *marker provenance* is unenforceable by
|
|
@@ -1310,36 +1300,24 @@ Closing phrase detected ("wrap up", "done", "good work", "end session", etc.)
|
|
|
1310
1300
|
`package.json`) → Pre-Publish gate → `npm publish` → `git tag vX.Y.Z` at publish. **Propose, don't
|
|
1311
1301
|
auto-publish.** (Why lockstep — Codex caches on plugin.json version — + drift-check + tag-drift caveat → §detail below.)
|
|
1312
1302
|
|
|
1313
|
-
🟥 **WHICH DIGIT —
|
|
1314
|
-
|
|
1315
|
-
for the same delta on three different (and each individually defensible) grounds. Decide by
|
|
1316
|
-
**what the number tells a reader**, not by whether anything technically broke:
|
|
1303
|
+
🟥 **WHICH DIGIT — 운영자 결정(2026-08-17). 의도적으로 strict semver 가 아니다.**
|
|
1304
|
+
판단 기준은 **무엇이 기술적으로 깨졌나**가 아니라 **번호가 읽는 이에게 무엇을 말하나**다.
|
|
1317
1305
|
|
|
1318
|
-
|
|
|
1306
|
+
| major `+1.0.0` | ⓐ 완전히 새로 지음 · ⓑ 정체성 **다섯이 «전부» 🟢**(= `identity-v1.0.0` 급 사건. 🟥 하나가 🟢 로 올라선 순간이 **아니고**, 정체성 등급은 npm 이 나르는 신호가 **아니다**) · ⓒ capability **class** 가 생기거나 교체됨. 🟥 **이미 있던 게이트를 조인 것에는 절대 안 쓴다** |
|
|
1319
1307
|
|---|---|
|
|
1320
|
-
| **
|
|
1321
|
-
| **
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
Against that, strict semver would burn a major on every gate we tighten — this repo took 2.0.0
|
|
1334
|
-
for a publish-freshness gate one day and would have taken 3.0.0 for a commit gate the next.
|
|
1335
|
-
**A major number that arrives monthly stops meaning anything**, and the milestone it should be
|
|
1336
|
-
reserved for would have no word left.
|
|
1337
|
-
|
|
1338
|
-
⚠️ **The condition that makes this honest, and it is not optional**: a minor that breaks gate
|
|
1339
|
-
acceptance MUST carry `BREAKING (gate): <what now blocks> — <the one-line remedy>` in the
|
|
1340
|
-
release description AND the CHANGELOG. Without it this policy is just burying breaks in minors.
|
|
1341
|
-
**Applies from 2026-08-17 forward, not retroactively** (2.0.0 was the same class and is left
|
|
1342
|
-
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
|
+
> 그 정직성 조건 — **버전 자릿수를 실제로 정할 때 읽어라.**
|
|
1343
1321
|
→ ④-c Handoff lifecycle (cross-machine continuity) — when a durable **result artifact lands** this
|
|
1344
1322
|
session (mechanical hint: a new `*result*`/`*signal*`/`*_run_*` file in your companion store or
|
|
1345
1323
|
`tracks/`), do two things: **(a) ④-c stamps** any `"run this/start here"` run-handoff whose
|