@chrono-meta/fh-gate 2.4.0 → 2.5.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.4.0",
14
+ "version": "2.5.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.4.0",
20
+ "version": "2.5.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/CLAUDE.md CHANGED
@@ -355,7 +355,29 @@ The forge-harness hub has a dual identity: **(a) a seed for others** + **(b) you
355
355
  - AI may commit and push automatically (when changes are approved) — **to a feature branch, never to the integration branch**
356
356
  - **PR creation requires explicit user request** ("create PR", "PR 올려줘", "pull request")
357
357
  - **Reason:** Prevents PR fragmentation — logical units should be grouped into meaningful PRs, not atomized per commit
358
- - Default workflow: branch → commit → push branch → wait for explicit PR request
358
+ - Default workflow: **claim** → branch → commit → push branch → wait for explicit PR request
359
+
360
+ 🟥 **공유 체크아웃에서는 브랜치를 «잡는» 단계가 별도로 있다 — 그리고 그 기계는 이미 있다**
361
+ (2026-08-18 실측 신설). 세션 여럿이 **한 체크아웃**을 쓰면 HEAD 는 하나뿐이라, 남이 옮기면
362
+ 내 발밑이 바뀐다. 순서는 이렇다:
363
+
364
+ ```
365
+ switch 직전 git branch --show-current ← 실시간 HEAD. claim 파일이 아니다
366
+ 자른 직후 git log main..HEAD --oneline ← 0 줄이 아니면 남의 커밋 위에 앉았다
367
+ 잡을 때 bash scripts/branch_claim.sh claim ← 이 줄이 없으면 pre-commit 이 막는다
368
+ 확인 bash scripts/branch_claim.sh check
369
+ ```
370
+
371
+ 🟥 **`.git/fh-claims/*` 를 읽는 것만으로는 못 막는다** — claim 은 lock 이 아니라 **쓰여진 시점의
372
+ 스냅샷**이고, 남이 브랜치를 옮겨도 내 파일은 안 바뀐다. **자기 세션에 대해서도 거짓말한다**(실측:
373
+ claim 이 `main` 인 동안 실제 HEAD 는 peer 브랜치였다 — 두 세션이 독립 재현). 그래서 판별자는
374
+ 파일이 아니라 **위 두 줄의 실시간 실행**이고, claim 은 *기록하는* 명령으로만 쓴다.
375
+
376
+ **남은 잔여 둘, 이름으로 남긴다**: ⓐ 게이트는 **커밋 시점**이라 `switch -c` 사고 자체는 못 막는다
377
+ (그래서 위 두 줄이 여전히 사람 몫이다 — [[feedback_gate_binding_point_not_check_point]])
378
+ ⓑ 반대 방향 — 내가 브랜치를 쥔 동안 남이 되돌리고 커밋하면 **내 staged 파일이 index 에 살아
379
+ 있다.** 실측 사례에서 안 섞인 것은 그 세션이 파일 지정 `add` 를 썼기 때문이지 게이트 덕이 아니다.
380
+ ⇒ **공유 체크아웃에서 `git add -A` 금지**([[feedback_shared_checkout_ops_touch_others_work]]).
359
381
 
360
382
  **Integration branch is PR-only** (operator decision 2026-07-20). Never `git push origin main`
361
383
  directly. Normal path: `git switch -c <branch>` → push the branch → `gh pr create` → after review
@@ -884,6 +906,39 @@ Sequence, in order, and do not skip to the end:
884
906
  3. **Then set the interval**, informed by (2). An expedition's cadence has to be derived from what one
885
907
  actually costs and yields — a number picked before the first run is a guess wearing a schedule.
886
908
 
909
+ 🟥 **개시 요건 — 과녁 정체성 한 줄 (2026-08-18, 원정 1차 답습이 만든 규칙).** 원정을 여는 카드는
910
+ **어느 정체성을 겨냥하는지**를 이름과 현재 등급으로 적는다. 판별은 기계적이다: `ship_readiness_gate.md`
911
+ 의 등급표를 **열어서** 비-🟢 를 읽고, 그중 무엇을 겨냥하는지 쓴다.
912
+
913
+ ```
914
+ 과녁: ② 인큐베이터 (🔵 RC) — 챔버 정식 EMIT 을 실상황에서 낸다
915
+ 과녁: 없음 — 이번은 ⓑ 전용(약점 강화). 비-🟢(②·④)는 안 겨냥한다
916
+ ```
917
+
918
+ **둘째 형태도 정당한 값이다** — 금지되는 것은 «안 적는 것»뿐이다. 이유: **선언 없는 선택은 사후에
919
+ 누락과 구분되지 않고, 저자는 언제나 「고른 것」이라고 회상한다.**
920
+
921
+ **근거 — 이 규칙은 실측에서 나왔다.** 원정 1차(2026-08-17)의 ⓐ 채점은 **0 건**이다(2026-08-18 답습,
922
+ 사전등록 봉인 후 cross-family 독립 수렴). 원인은 노력이 아니라 겨냥이었다: 세 갈래(기여·클러스터·약점)가
923
+ **전부 이미 🟢 인 정체성**(Ⓑ·①·③) 위에 떨어졌고, **비-🟢 인 ②·④ 를 건드린 산출이 하나도 없었다.**
924
+ 즉 ⓐ=0 은 **개시 시점에 구조적으로 예정돼 있었다.** 정본: `tracks/_meta/expedition_2026-08-18_absorption1.md`.
925
+ 🟥 ⓐ 를 «알아냈다»로 읽지 마라 — 완주선은 «알아냈나»가 맞지만 **ⓐ 는 «등급을 옮기는 조각»을 요구한다.**
926
+ 두 정의를 섞으면 과계상이 된다(cross-family 지목, 자력 적발 0).
927
+
928
+ **주기 — 1차 답습 후에도 아직 안 정한다, 그리고 그 이유가 기록이다 (2026-08-18, 운영자 승인).**
929
+ 위 3단계를 다 밟았는데도 숫자가 안 나온다: ⓐ 비용 입력이 **부분 계상**이고(거버너 토큰·벽시계 미측정 —
930
+ 1차 기록 §5 가 스스로 적었다) ⓑ 1차는 갈래가 셋이라 **대표성이 없으며** ⓒ 결정적으로 **겨냥이 틀린
931
+ 원정 1회**라, 그 비용/수확비로 주기를 세우면 틀린 표본으로 스케줄을 만든다.
932
+ ⇒ 주기는 **2차 이후**로 미룬다. 대신 **2차 개시에 계측 3항이 의무**다 — 방법까지 여기 적는다
933
+ (초안은 셋을 요구만 하고 ②③의 *방법*을 안 적었고, 플로어 티어 블라인드 sim 이 그 구멍을 지목했다):
934
+ - ① **과녁 정체성 선언** — 위 형식 그대로, 개시 카드에.
935
+ - ② **벽시계** — 개시 카드에 시작 시각, 완주 선언 줄에 완주 시각. 그냥 적는 것이고 계기가 필요 없다.
936
+ - ③ **거버너 토큰** — 🟥 **세션은 자기 소비를 직접 못 읽는다**(1차 §5 가 이미 실측한 제약). 그러므로
937
+ 의무는 «총액을 대라»가 아니라 **«읽히는 것을 다 적고, 안 읽히는 칸을 이름으로 남겨라»**다:
938
+ 서브에이전트 토큰(완료 알림의 `subagent_tokens`) · 사이드카 토큰(각 CLI 가 출력) · **거버너 = `UNMEASURED`**.
939
+ 🟥 **합계를 쓰지 마라** — 미측정 칸을 0 으로 접는 것이다([[feedback_not_found_is_not_zero_family]]).
940
+ 셋이 없으면 3차에서도 «못 정한다»가 나온다.
941
+
887
942
  ⚠️ **This deliberately does NOT use the `operations.md` `accepted ≥ 60%` promotion gate.** That gate
888
943
  measures how often a proposal class is *accepted*, which is the wrong quantity here: an expedition
889
944
  could be accepted every time and still not warrant a schedule, or be proposed once and clearly warrant
@@ -73,12 +73,24 @@ tags: [canon, three-layer, engines, identity, verification-axes]
73
73
  >
74
74
  > ✅ **2026-08-17 부로 마커도 이 배열이다** — 날짜 ≥ 2026-08-17 인 마커는 `axes-run` 이
75
75
  > **기호 여섯 글자(ⓐ~ⓕ)**를 요구하고, 그 이전 마커는 옛 ASCII 넷을 그대로 쓴다(소급 강제 없음).
76
- > **표기법이 배열 선언**이라 감사자가 grep 번으로 판별한다. 남은 어긋남은 **하나뿐**
77
- > `standpoint:` 값의 enum **검증하는 코드가 아직 0줄**이다. 아래 「옛 배열」 서술은 유예일
78
- > 이전 마커를 읽을 때만 유효한 이력이다.배열로 줄을
79
- > 기계가 **조용히 다른 축으로 읽으며 오류를 내지 않는다.** 확장은 기존 마커 전부를 무효화하므로
80
- > **운영자 결정 사항으로 열려 있다** 그때까지 마커를 때는 **옛 배열**을 쓰고, 산문으로
81
- > 논할 때는 §1-a-2 6축을 쓴다. 어긋남을 **알고** 쓰는 것이 규율이다.
76
+ > ⚠️ **표기법은 판별자가 아니다 줄의 초판이 그렇게 적었고 코퍼스 실측이 반증했다.**
77
+ > 초판은 *"표기법이 배열 선언이라 감사자가 grep 번으로 판별한다"* 였다. 실측: `axes-run`
78
+ > 보유 **53건 기호 키가 4건**인데 그중 **2건이 2026-08-10 자이면서 4축 의미로 기호를
79
+ > 쓴다**(`ⓑ 첫실사용` · `ⓓ 되돌림` 배열에선 각각 ⓔ·ⓕ), 혼용도 1건 있다. 훅은 그 셋을 안
80
+ > 읽으므로 **커밋은 막지만 감사자의 grep 거기서 틀린 답을 낸다.**
81
+ > **판별자는 마커 파일명의 날짜다** (`< 2026-08-17` = 4축). 이게 유일한 기계 판별자다.
82
+ >
83
+ > 🟥 **그리고 아래 문단은 삭제됐다 — 이 절이 스스로와 모순하고 있었다.** 삭제된 문장은
84
+ > *"확장은 기존 마커 전부를 무효화하므로 운영자 결정 사항으로 열려 있다 — 그때까지 마커를 쓸
85
+ > 때는 **옛 배열**을 쓰고…"* 였다. 바로 위 ✅ 줄(2026-08-17 착지)과 정면으로 어긋나고,
86
+ > **그 줄을 따라 읽은 세션은 오늘 옛 배열로 마커를 써서 훅에 막힌다.** 반쪽 픽스가 위 문단에만
87
+ > 착지하고 아래 문단이 살아남은 형태다(`[[feedback_half_fix_propagation_boundary]]`).
88
+ > 「전량 무효화」 전제 자체도 별도로 반증돼 있다 — 훅은 **오늘·이 브랜치 마커 한 개만** 검증하므로
89
+ > 190건 중 차단 0·재해석 51이었다(`CLAUDE.md` §명칭 충돌).
90
+ >
91
+ > **남은 어긋남은 하나뿐** — `standpoint:` 값의 enum 을 **검증하는 코드가 아직 0줄**이다.
92
+ > 옛 배열로 쓴 줄을 기계가 **조용히 다른 축으로 읽으며 오류를 내지 않는다** — 그래서 옛 마커를
93
+ > 읽을 때는 날짜부터 본다. 산문으로 논할 때는 언제나 §1-a-2 의 6축을 쓴다.
82
94
  >
83
95
  > 🟥 그리고 ③단계는 **「결정론적 기계 스크립트」가 아니다.** 여섯 축 중 다섯이 모델/에이전트
84
96
  > 판단이고, 기계 앵커가 붙은 축은 현재 **되돌림 하나뿐**이다(§ 아래 «자평이다» 절). ③을
@@ -159,6 +159,37 @@ changes which ground truth the review is checked against — they are orthogonal
159
159
  that maxes out the first while leaving the second at zero has not raised its coverage of
160
160
  standpoint-dependent defects at all.*
161
161
 
162
+ **Relationship to the isolation axis — standpoint is isolation whose scope moved up to the
163
+ harness (operator, 2026-08-18).** Operator wording: *"요는 이것도 '격리' 프레이밍이 하네스 단위로
164
+ 확장되는 거지 … 그 하네스 자체의 입장을 돌리는 거니까 (하네스라는 껍질에 모델이라는 알맹이를
165
+ 넣어서 자신이 직접 돌아가게 하니까)."*
166
+
167
+ The ⓒ isolation axis is normally scoped to a **session**: run the reviewer where the author's
168
+ context cannot reach it — outside the repo, so repo-level instructions are not inherited. `tier2`+
169
+ standpoint makes the same move one scope up: rather than isolating a session from the author's
170
+ context, **boot the target harness itself** — its shell, a model as the filling — and let it run.
171
+ What is isolated is no longer a session but an entire harness's operating context.
172
+
173
+ This is also the answer to the question the axis reliably draws — *"how is that different from just
174
+ running it in the target repo myself, which I already do before opening a PR?"* Running it yourself
175
+ carries your own assumptions into the run; the harness running itself does not. That is the same
176
+ failure the session-scoped isolation axis already records (a reviewer spawned inside the repo
177
+ inherits that repo's instructions regardless of the prompt), one scope up.
178
+
179
+ ⚠️ **A framing, not an identity — do not collapse the two axes.** Axis membership is decided by
180
+ *what the reviewer receives* (`fh_three_layer_canon.md §1-a`): ⓒ receives the author's sentences
181
+ plus the current tree, ⓑ receives the target's own canon. Raising isolation scope to the harness
182
+ **also swaps the input** — you cannot boot the target harness without it reading its own canon — so
183
+ ⓑ is *isolation-scope expansion accompanied by input replacement*. That accompaniment is why it
184
+ stays a separate axis instead of becoming a tier of ⓒ.
185
+
186
+ 🚫 **Do not describe this as role-play or persona assignment.** *"Act as if you were harness X"* is
187
+ exactly the prompt-level disguise that isolation failures already refuted; booting the shell is its
188
+ opposite. The tier ladder encodes the distinction — `tier2b` (same operator, target's real runtime,
189
+ local wiring visible) sits below `tier3` (a different operator of the target harness runs it)
190
+ precisely because the remaining gap is *whose context is still in the room*, not what the reviewer
191
+ was told to pretend.
192
+
162
193
  **Why the same author cannot close this by working inside the target repo and opening the PR
163
194
  there — corrected framing (2026-08-14, after a cross-harness standpoint review of this section
164
195
  itself).** The claim is *not* "the author is structurally blind to their own work" — a controlled
@@ -40,6 +40,22 @@ markers) — never silently drop a capability.
40
40
  day. Structure-enforcing checks are tier-blind by construction — so the harness raises the floor
41
41
  for weak models *and* guards the ceiling for strong ones. Weak-model benefit is the larger term
42
42
  (H1), top-tier benefit is the existence proof that the harness is not scaffolding-only.
43
+ - **External academic grounding (arXiv:2605.30621, "Harness Updating Is Not Harness Benefit,"
44
+ May 2026 — surfaced via issue #102 Frontier Digest, 2026-08-15)**: the paper separates the
45
+ *evolver* role (writes harness updates) from the *beneficiary* role (runs on the updated
46
+ harness) and finds harness-**updating** flat across model capability — a Qwen3.5-9B evolver
47
+ induces gains comparable to a Claude Opus 4.6 evolver, i.e. evolver strength does not predict
48
+ beneficiary gain. Harness-**benefit**, by contrast, is non-monotonic — and the shape matters, so
49
+ all three tiers are quoted rather than only the one that suits this section: **weak-tier models
50
+ benefit little, mid-tier benefit most, and strong-tier benefit *less* than mid-tier.** The paper
51
+ traces the weak-tier shortfall to two named failure modes: failing to *activate* relevant harness
52
+ artifacts, or activating them but failing to *follow* them faithfully. This is independent
53
+ grounding for the floor split below: sub-Sonnet stays `below-floor` because
54
+ activation/faithful-following is where payoff collapses, while Sonnet is named the floor
55
+ precisely because it clears that bar. ⚠️ **The strong-tier half is NOT folded in as support for
56
+ the ceiling-guard clause above** — the paper measures benefit from *self-evolved harness updates*,
57
+ not from structure-enforcing checks, so mid > strong is an adjacent finding this doctrine has not
58
+ reconciled, and is recorded as open rather than read in the author-favorable direction.
43
59
 
44
60
  ## The defect class: tier-gated capability
45
61
 
@@ -2206,3 +2206,99 @@
2206
2206
  outcome: accepted
2207
2207
  evidence: "**6건 · codex 와 겹친 지적 0.** 최상위는 `GIT_DIR`/`GIT_WORK_TREE` 가 `git -C` 를 이긴다 — **엉뚱한 레포를 재고도 «동결했다» 고 보고**한다(계기가 대상을 틀리는 형태). 그 외 untracked **실행 비트** 미검출(이 레포가 이미 데인 축) · TOCTOU «유령 지문» · 미초기화 서브모듈은 `foreach` 가 건너뜀 · `---` 구분자 경계 · `foreach` 의 `;` rc 소실. 전부 수리, 레인 11→28. ⇒ **계열 분리가 값을 냈다** — 이 6건은 codex 를 한 번 더 돌려서는 안 나온다"
2208
2208
  cost: ~35k tokens
2209
+ - date: 2026-08-17
2210
+ agent: general-purpose (isolated) ×3 — 원정 1차 정찰 (qasp rule 세트 · FH 등록 바 · clawd 후보 A)
2211
+ purpose: "원정 착수 전 3면 동시 정찰. 노드 선언 성립성 / 등록 바가 기계로 강제하는 것 / 외부 기여 후보 실태"
2212
+ outcome: accepted
2213
+ evidence: "3팔 전부 근거명령 동반. ⓐ qasp: 진입점 실재(python -m 게이트 CLI 3종)·exit 이미 typed(0/1/2/3, 3=스캔0개 fail-closed)·known-pair 가 peer 테스트에 대조군 형태로 존재·FH grep 0히트 net-new. ⓑ FH 등록 바: .cap 파서 «네 벌» 헤더 주장을 실측 확인(6파일 언급 중 실제 파싱 4) · M1~M6 각 검사 내용 · test_adapter_lanes.sh 는 **하드코딩**(자동발견 없음) · cluster_capability_scan 은 재귀 find 라 자동. 🟥 여기서 부수로 «.cap 이 pre-commit HEAVY/CARVEOUT/LIGHT 어디에도 없다»가 나왔고 그게 이 세션 최대 FH 발견의 실마리였다. ⓒ clawd 후보 A: **반증** — 이미 호출부 12곳 + 전용 테스트 766줄, 「앵커 갭」 아님. 카드 등재 후보가 미조사였음이 드러남"
2214
+ cost: 405k tokens (3팔 합)
2215
+ - date: 2026-08-17
2216
+ agent: general-purpose (isolated) ×3 — clawd 기여 후보 평가 → 레인 구축 → 리베이스/재측정
2217
+ purpose: "후보 A 기각 후 대체 후보(fix/validate-theme-*) 를 #888 바에 맞추기. 로컬 완주·되돌림 프로브·upstream 기준선 재측정"
2218
+ outcome: accepted
2219
+ evidence: "평가팔: 컨트롤 붙여 «main 도 동일 실패» 확인 → 이 diff 가 깬 것 0. 되돌림으로 «앵커가 장식이 아니라 **부재**» 확정(test/ 에 validate-theme 0건). 판정 «지금은 못 보낸다». 구축팔: spawnSync 실 CLI 기동 레인 5케이스 + 픽스처 근거 in-comment, 되돌림 3단 통과. 재측정팔: 🟥 **리베이스 전 수치가 PR 트리의 수치가 아니었다** — fork main(7커밋 뒤처짐) 59건 → upstream/main 30건. 운영자 지적(«리베이스부터 하고 재봐야») 이 없었으면 틀린 숫자가 PR 본문에 박힐 뻔했다. 리베이스 충돌 0, 차집합 양방향 공집합, upstream 파일 md5 일치로 선행수정 없음 확인"
2220
+ cost: 420k tokens (3팔 합)
2221
+ - date: 2026-08-17
2222
+ agent: general-purpose (isolated) ×2 — 입장 리뷰 정적 + 동적 (upstream 유지관리자 시점)
2223
+ purpose: "운영자 지시 «입장리뷰는 정적 동적 모두». 정적=관례·호출부·문서·기존 테스트 관용구 / 동적=소비자 경로 실행·CI 로컬 재현·5입력 대조·재현성"
2224
+ outcome: accepted
2225
+ evidence: "🟥 **둘의 발견이 거의 안 겹쳤다** — 같은 축인데 정적/동적으로 갈리자 다른 것을 잡았다. 정적: exit 2 가 이 레포 다른 스크립트와 충돌 안 함을 grep 으로 확인 · 호출부 실측 · **문서 갭**(계약이 스크립트 헤더에만, README/가이드 없음) · 임시디렉토리 미정리. 판정 «수정 요청». 동적: 프로그램적 소비자 **0건** 실증 · 5입력 기준선 vs 브랜치 rc 대조표 · 3회반복/다른 cwd/TZ·LANG arm 전부 통과 · **누수 수치 실측 63→66(런당 +3)**. 정적이 «정리 안 함»을 지적하고 동적이 그 수치를 냈다"
2226
+ cost: 250k tokens (2팔 합)
2227
+ - date: 2026-08-17
2228
+ agent: general-purpose (isolated) — 3자대면 (스펙 ↔ 구현 ↔ TC)
2229
+ purpose: "우리가 TC 를 새로 썼으므로 출제자=응시자. 구현의 process.exit 전수 열거로 «TC 가 안 덮는 종료 경로»를 강제 탐색"
2230
+ outcome: accepted
2231
+ evidence: "🟥 **이 세션 최대 발견 — 다른 세 축이 전부 놓쳤다.** theme.json 이 파싱되지만 객체가 아닌 값(null/숫자/문자열/불리언)이면 130줄에서 uncaught TypeError → **Node 기본 종료 exit 1**. 1 은 이 PR 이 방금 「검증했고 오류 있음」이라 정의한 값인데 검증을 한 줄도 못 돌렸다 — **PR 이 자기 목적을 무효화한다**. 경계까지 실측: `[]` 는 객체라 크래시 안 하고 정상 exit 1(→ 가드는 isPlainObject 여야지 truthy 가 아니다). 추가로 catch 가 읽기실패를 「파싱 실패」로 오라벨(EISDIR 실측). 판정 «구조적 불일치», 수리는 3면 동시여야 한다고 지정"
2232
+ cost: 125k tokens
2233
+ - date: 2026-08-17
2234
+ agent: codex/gpt-5.5 (cross-family, headless) — clawd exit enum 변경 적대 리뷰
2235
+ purpose: "exit code 계약 변경 = Load-Bearing 트리거. 「반증하라」로 발주 — exit 2 안전성·파괴성·테스트 트리비얼 만족 가능성·미재분류 경로·픽스처 취약성"
2236
+ outcome: accepted
2237
+ evidence: "다른 셋이 못 잡은 것 2건: 인자 파서가 값 없는 `--assets` 를 조용히 무시 → **exit 0 가능**(헤더의 「bad usage=2」와 정면 충돌) · `--assets /오타` 가 exit 1 로 렌더(검증이 의도한 애셋에 안 돌았는데). 그리고 유일하게 **위험을 해소**한 축 — exit 2 안전성을 1차 출처 3개(nodejs.org process exit codes · docs.npmjs.com scripts exiting · GH Actions exit codes)로 확인. 내가 「아마 괜찮겠지」로 넘어간 자리였다"
2238
+ cost: 68k tokens
2239
+ - date: 2026-08-17
2240
+ agent: general-purpose (isolated) — clawd 통합 수리 (결함 5종 3면 동시)
2241
+ purpose: "네 리뷰의 findings 를 한 번에 수리. 결함별로 구현+스펙헤더+TC 를 같은 커밋에"
2242
+ outcome: accepted
2243
+ evidence: "6커밋. 되돌림 프로브 4개 전부 «정확히 그것만» 확인 — 객체 가드 되돌리자 null/숫자/문자열/불리언 4케이스만 적색이고 **`[]` 컨트롤은 초록 유지**(가드가 과하게 안 넓다는 증거). 기존 관용구 준수(isPlainObject 재사용·install.test.js 의 afterEach 정리 패턴). 누수 재측정 96→96(순증 0, 이전 +3/런). 🟡 팔의 차집합 보고가 33 이었는데 거버너 재측정은 37 — **또 숫자가 갈렸다**. 판정에 쓰는 건 차집합(양방향 공집합)이라 영향 없었고, 그래서 PR 본문에 건수를 안 썼다"
2244
+ cost: 216k tokens
2245
+ - date: 2026-08-17
2246
+ agent: general-purpose (isolated) — 축 선언 원장 부착점 3후보 known-pair 측정
2247
+ purpose: "이 세션 자신의 축 누락(ⓐⓑⓓ 미실행)에 대한 처방의 **전제 측정**. 짓지 않는 것이 명시 지시"
2248
+ outcome: accepted
2249
+ evidence: "🟥 **결론이 «셋 다 이 사건 모양을 못 잡는다»** — 그리고 그게 이 측정의 값이다(안 재고 지었으면 못 막는 게이트를 얹고 닫았다고 적었을 것). ⓐ close-check: `gh pr list --author @me` 가 **cwd remote 스코프**라 외부 레포 미조회 · ⓑ gh 래퍼: known-pair 는 갈리나(BLOCK exit1 / 통과 exit0) 미설치 + **절대경로 호출로 무음 우회** 실측 · ⓒ pre-commit: **구조적 불가** — clawd-on-desk 는 core.hooksPath 미설정·.git/hooks/pre-commit 부재라 FH 훅이 볼 수 없다. 부수 발견: **CLAUDE.md ①-b 가 `gh search prs` cross-repo 를 배선된 것처럼 서술하는데 스크립트엔 0히트**(문서-코드 드리프트)"
2250
+ cost: 131k tokens
2251
+ - date: 2026-08-17
2252
+ agent: general-purpose (isolated) — qasp 노드 M6 `writes:` 실행 관측
2253
+ purpose: "소스 grep 이 write 0히트였으나 거버너 실행에서 import 부작용(기동 시 경고 출력)이 드러남. 선언이 아니라 실측으로 정해야 함"
2254
+ outcome: accepted
2255
+ evidence: "🟥 **warm-cache 아티팩트를 잡았다.** peer 실제 트리 5축 diff 는 전부 공집합 → 이 머신에서 M6 돌렸으면 거짓 `read-only` 가 통과했을 것. cold checkout 격리 클론에서: arm A `바이트코드 캐시 0→5 디렉토리 · 0→18 파일 · 런타임 디렉토리 3개 생성` / arm B(PYTHONDONTWRITEBYTECODE=1) `바이트코드는 0→0 이지만 런타임 디렉토리 3개는 여전히 생성`. 기전 = peer 의 설정 모듈이 import 시점에 «필요 디렉토리 보장» 루틴을 무조건 실행(감사 모듈 import 체인 경유). known-positive 컨트롤로 계기 생존 확인. 문제의 기동 경고는 소스 직독으로 in-memory 전용 확인(grep 부재 아님). ⇒ 정직한 선언은 `write-local`(닫힌 enum: read-only|write-local|write-remote — 팔이 제안한 산문은 HARNESS_ERROR 로 떨어졌을 것, 거버너가 확인)"
2256
+ cost: 144k tokens
2257
+
2258
+ - date: 2026-08-18
2259
+ agent: codex/gpt-5.5 + agy/gemini-3.1-pro-high (cross-family sidecars, 2 families)
2260
+ model: opus (orchestrator)
2261
+ purpose: "Adversarial review of an outbound PR to a third-party repo (clawd-on-desk #892) before force-push — CLI arg-parser hardening + exit-code contract removal, reshaped at maintainer request"
2262
+ prompt_summary: "Arm 1 (codex): given the diff + the maintainer's written request, find scope creep, parser regressions, and vacuous tests. Arm 2 (agy): given codex's findings first, explicitly required to find a DIFFERENT axis."
2263
+ outcome: accepted
2264
+ finding: "Both arms BLOCK. codex: strict parsing made a path beginning with '-' unreachable (2 forms) — a real regression vs upstream main, plus silent last-wins on a repeated flag and a flattened stat-error message. agy on a different axis: switching the guard to `=== null` let an EMPTY-STRING path through, so `path.resolve('')` sent the validator at the caller's cwd. All 4 reproduced by hand against upstream main before acting; all fixed with tests."
2265
+ note: "🟥 Orchestrator self-detection was ZERO on all of them — the author wrote every one of these lines. BUT the run does NOT test family diversity: arm 2 was handed arm 1's findings plus a steer, so the manipulated variable was WHAT IT RECEIVED, not its family. No same-family control was run either, so even codex's catch cannot be attributed to family rather than to a second pair of eyes. Cite as evidence for the receives-different-input axis, never as evidence that mixing families works."
2266
+
2267
+ - date: 2026-08-18
2268
+ agent: fh-meta:beginner (4 rounds, same agent resumed)
2269
+ model: inherited
2270
+ purpose: "Cold-read the outbound PR follow-up comment as the maintainer, before posting — natural-voice check plus does-it-answer-the-ask"
2271
+ prompt_summary: "Read the drafted comment cold as the maintainer who wrote the request; quote before judging; report findings only, no rewriting. Rounds 2-4 re-read the repaired text with the changelog of what was edited."
2272
+ outcome: accepted
2273
+ finding: "R1 caught a whole missing item — the maintainer had explicitly asked to KEEP the malformed-top-level-JSON fix and the draft never confirmed it — plus unprompted flattery and a matched rhetorical headline pair. R2/R3 each found NEW defects introduced by the previous round's repair (a contradiction seam between two sections; a dangling 'same way as last time' reference with no antecedent for the reader). R4 clean, so the loop closed on new-findings-0 AND text-unchanged."
2274
+ note: "Two data points for repair-is-a-defect-source inside one hour, both self-detection ZERO. Honest limit: an in-repo subagent inherits project instructions, so this is WEAK isolation by this hub's own standard — a repo-external headless run would be the strong form."
2275
+
2276
+ - date: 2026-08-18
2277
+ agent: general-purpose (isolated) — Sister Asset 감사 (omnigent-ai/omnigent)
2278
+ model: inherited
2279
+ purpose: "오늘자 frontier-digest 후보 [C]. FH 정체성 주장과 최대로 겹친다고 지목된 외부 자산에 Sister Asset Protocol §Active adoption 적용 — 해상도 차이 기록 + 수입/전파 양방향 목록"
2280
+ prompt_summary: "정본(sister_asset_protocol.md)을 먼저 읽고 그 절차대로. 🟥 정규화 금지를 명시 조건으로 박고 §Envelope-Boundary 를 읽게 함. 양방향(수입 ∧ 전파) 둘 다 없으면 미완으로 규정. 1차 출처 직독 요구, 접근 실패는 «없다» 아닌 실패로 기록."
2281
+ outcome: accepted
2282
+ finding: "실제 클론(HEAD 65021dc) 후 파일:줄 인용으로 반환. 🟥 디제스트가 못 본 정체성 사실 적발 — Databricks 내부 레포의 OSS 익스포트다(NOTICE:1 · sync 워크플로). 「meta-harness」가 같은 단어로 다른 대상을 가리킴을 확정(저쪽=실행 기질 교체 / FH=방법론 인큐베이터) ⇒ 직교. 수입 후보 10건 중 A1(라이브 triad + DRIFT, verdict.py:110-137)이 FH 정본이 스스로 «carrier 없음»이라 유보해 둔 자리를 정확히 메운다. A3(미측정 7값 enum · SKIPPED≠UNKNOWN 을 타입으로 강제, verdict.py:22-27,57-60). 전파 후보 7건 중 B1 = 저쪽의 팬텀 참조 37건 실측(존재하지 않는 designs/*.md 를 openapi.json 스키마 description 까지 인용)."
2283
+ note: "🟥 정규화가 무너뜨렸을 항목이 실제로 3건이라고 스스로 보고 — 셋 다 «우리도 그거 있다»로 접었으면 사라진다. 자기 미확인 목록을 8항 열거(harness_bench 미실행이라 A1 은 «코드가 그렇게 적혀 있다»까지만 근거 · ★ 수치는 GH API 단일 출처 · shallow clone 이라 팬텀 참조의 이력 확인 불가). 미검증 강도를 스스로 깎은 것이 신뢰도를 올렸다."
2284
+ cost: 183k tokens
2285
+
2286
+ - date: 2026-08-18
2287
+ agent: agy/gemini-3.1-pro-high (cross-family sidecar, 2번째 계열)
2288
+ model: opus (orchestrator)
2289
+ purpose: "운영자가 전달한 외부 영상 3편(OpenWiki · Anthropic 인증시험 안티패턴 · Buzz)의 자막에 대해, 거버너가 이미 추출한 목록을 주고 «그 밖의 축»을 요구"
2290
+ prompt_summary: "1번 팔(Claude) 추출 결과를 전부 나열하고 «이걸 다시 말하면 0점» 을 명시. 요구한 축 = 영상 간 모순 · 자기붕괴 지점 · FH 에 나쁜 조언이 될 항목 · 정량 주장의 근거 유무. 항목마다 트랜스크립트 원문 인용 의무, 인용 못 붙이면 «미확인» 으로 분리."
2291
+ outcome: accepted
2292
+ finding: "6건 중 확정 2 · 기각 2 · 반쪽 1 · 자기모순 1. 🟥 **초판이 이 팔을 `partial` 로 채점했는데 운영자가 정정했다 — 발견기를 정밀도로 채점한 오류다.** 탈상관은 오라클이 아니라 **값싼 발견기**이고(다른 사고방식을 그대로 써서 다른 각도로 묻는 것이 가장 싸고 빠르다), **발견이 어렵고 채점이 싸다.** 그러면 오탐 4건은 실패가 아니라 정상 작동이고, 채점 기준은 «거버너가 혼자서는 못 낸 것을 표면화했는가» 다. 그 기준으로는 통과한다 — 아래 ⓐ가 정확히 그것이다. ✅ 확정: ⓐ 「15만 토큰 압축 임계」가 **근거 없는 하드코딩 예시값**(발표자가 슬라이드 코드의 >150000 을 읽은 것) — 🟥 거버너가 이미 자기 보고에 기준선처럼 적어 넣은 뒤였고 대조 없이는 카드까지 갔다 ⓑ cron 기반 문서 갱신이 커밋-시점 게이트 결속을 깬다. ❌ 기각: OpenWiki 자기모순 주장은 agents.md(포인터)와 log.md(변경로그)를 합친 것 · compact 가 frontmatter/[[link]] 그래프를 파손한다는 주장은 컨텍스트 압축이 디스크 파일을 안 고친다는 점에서 기전 오류(인접 위험은 실재)."
2293
+ note: "채점 기준 정정의 함의: 이 원장에서 `partial`/`rejected` 는 **발견기의 정밀도**를 뜻하지 않는다 — 그건 정상 비용이다. 🟥 사이드카가 자기 자신과 모순했다 — §1 에서 「툴 4~5개는 화자 자체 모순」이라 적고 §3 에서 같은 숫자를 「공식 규격에서 기인, 근거 있음」으로 승격. 원문에 그 근거가 없고 Anthropic 실제 스펙 대조도 안 했다(미검증을 검증으로 렌더). 인용 6개는 기계 대조로 5/6 원문 확인 + 1건은 표기 변형(슬랙↔슬렉)뿐. ⇒ 값은 「많이 잡는다」가 아니라 **「거버너가 이미 쓴 것 중 틀린 걸 잡는다」** 쪽에서 나왔다."
2294
+ cost: 미측정 (agy 토큰 미보고 — 0 으로 렌더하지 말 것)
2295
+
2296
+ - date: 2026-08-18
2297
+ agent: general-purpose (isolated)
2298
+ model: opus (orchestrator) / 위임 기본 티어
2299
+ purpose: "운영자가 원정 2차 중 공유한 유튜브(S_PeI8JUqMg)를 흡수해 보고 — 위성 설계에 반영할 선행자산인지 판정"
2300
+ prompt_summary: "video-ingest 스킬을 먼저 읽고 그 라우팅을 따르라(방법 발명 금지) · 🟥 막히면 추측 요약 대신 «무엇이 막혔는지» 보고 · 기존 다른 영상 인제스트 파일 덮지 말 것 · 파일 쓰지 말고 보고만(착지 위치는 거버너가 정한다) · 인용 가능한 구체는 «영상 실제 발화인지» 표시"
2301
+ outcome: accepted
2302
+ finding: "OpenWiki(2026-08-17 발표, MIT) — 우리가 같은 날 지은 위성과 **정면으로 겹치는 선행자산**. 자막 원본 영어 트랙으로 음성 100% 흡수, 🟥 슬라이드 0%(그래서 토큰 감소 수치는 **미확보** — 발표자 본인이 'I don't have it here'). 채택 1건: **PR 로 낸다, 직접 쓰지 않는다**(우리 «AI 는 PR 을 제안한다» 규칙을 위성에 적용하는 걸 남이 먼저 검증해 준 형태). 기각 3건을 사유와 함께: 델타게이트=정의역 불일치(저쪽 델타는 레포 안, 위성은 바깥을 긁는다) · log.md 사람용 분리=닫는 결함 미확정 · quickstart/OKF=이미 있음. 🟥 반증 1건: 저쪽이 «에이전트만 읽을 거라 생각했다»가 현장에서 즉시 깨졌다 — 위성 노드를 에이전트용으로만 최적화하지 말라는 실측 반례."
2303
+ note: "🟥 이 arm 은 «막히면 안 지어낸다» 지시를 지켰고 인용마다 «영상 발화 ✅ / 슬라이드 추정 ❌» 를 갈랐다 — 그 덕에 eval 수치(20개 중 7~8 → 9~10)에 발표자 본인의 'about' 단서가 보존됐고, 벤치마크명은 자동캡션 전사가 불안정해 «DeepSWE 추정, 미확인» 으로 남았다. 인용 전 확인이 필요한 항목이 그대로 표시된 채 왔다는 것이 이 위임의 실제 값이다."
2304
+ cost: 138,973 tokens (subagent_tokens · tool_uses 5 · 105s)
@@ -57,7 +57,7 @@ main 최근 200커밋 중 no-op 1건 (2026-08-09 측정, d2c7f55). **기계화
57
57
  재발 — pmh→FH 는 아직 FH 재현 0. **FH 재현 1회 시 즉시 기계화** — pmh `merge_noop_check.sh` 를
58
58
  가져오면 된다(exit 계약까지 이미 있다).
59
59
 
60
- ## 2. 가지를 각각 못 믿는다
60
+ ## 2. 가지를 각각 못 믿는다
61
61
 
62
62
  ### 2-a. 보냈다 ≠ 닿았다
63
63
  크로스세션 메시지는 **수신자 사용자 승인 대기로 보류**될 수 있고, 그래도 발신 호출은 성공을
@@ -110,6 +110,123 @@ working 세션 → 접기 전에 물어라
110
110
  (전자는 마저 닫기, 후자는 다시 접기). `session_close_check.sh` ①-d 가 마감 게이트 통과를 세서
111
111
  2회 이상이면 알린다. **자기신고다** — 패턴을 감지하지 증명하지 않는다.
112
112
 
113
+ ### 2-d. **내 계정이다 ≠ 내 것이다** — 그리고 목록의 «상태»도 못 믿는다
114
+
115
+ 병렬 세션은 대개 **같은 GitHub 계정**으로 돈다. 그러면 `gh pr list --author @me` 가 **모든
116
+ 세션의 PR 을 「내 PR」로** 보여준다. 이건 필터가 고장난 게 아니라 **그 필터가 세션을 모르는
117
+ 것**이고, 마감할 때 두 가지를 동시에 망친다:
118
+
119
+ ```
120
+ 귀속 오독 남의 PR 을 내 처분 대상으로 카드에 싣는다 (또는 그 반대로 남에게 떠넘긴다)
121
+ 상태 오독 목록이 내 것이라고 믿는 순간 그 목록의 state 도 확인 없이 받아 적는다
122
+ ```
123
+
124
+ **2026-08-18 실측, 3축 마감에서 세 세션이 각각 한 번씩 틀렸다:**
125
+
126
+ | 세션 | 무엇을 | 어떻게 틀렸나 |
127
+ |---|---|---|
128
+ | A | PR 소유권 | 계정 목록을 근거로 「peer 소관」이라 적었는데 한 건은 자기 것이었다 |
129
+ | B | PR 소유권 | **브랜치명 ↔ peer 발화 내용을 매칭해서 추론.** 라벨이 소유권 증거가 아니다 |
130
+ | C | PR **상태** | 계정 목록을 근거로 「#442·#443 머지됨」이라 보고 — **실측 둘 다 OPEN** |
131
+
132
+ 🟥 **B 의 오류가 가장 교훈적이다**: 그 세션은 *"계정으로는 못 가르니 브랜치명으로 귀속해라"*
133
+ 라고 **쓴 바로 그 메시지 안에서** 추론으로 귀속했다. 규칙을 적는 행위가 지켰다는 감각을
134
+ 만든다([[feedback_citing_a_rule_is_not_obeying_it]]).
135
+
136
+ **규율**
137
+ 1. **소유권의 유일한 확정자는 «본인 확인»이다.** 살아있는 peer 에게 물어라(§1 의 질문에
138
+ *"이 PR 들 중 네 것이 뭐냐"* 를 포함시킨다). 브랜치명·커밋 시각·작업 내용 매칭은 **후보를
139
+ 좁힐 뿐** 확정하지 못한다.
140
+ 2. **peer 가 죽었거나 회신이 없으면 «미상»으로 적는다.** 추론해서 이름을 붙이지 마라 —
141
+ 틀린 귀속은 카드에서 다음 세대로 그대로 승계된다(§3).
142
+ 3. **상태는 목록이 아니라 대상에서 읽는다.** `gh pr view <n> --json state` 를 **번호마다**
143
+ 돌려라. 목록의 state 는 캐시·필터 조합에 따라 어긋날 수 있고, 무엇보다 **내 것이라고 믿는
144
+ 순간 검증을 건너뛰게 된다.**
145
+ 4. 카드에는 **판별 근거를 같이 적는다** — `#442 f9(본인확인) OPEN(gh pr view)`. 근거 없는
146
+ 귀속은 다음 세션이 재검증할 방법이 없다.
147
+
148
+ ### 2-d-2. 🟥 **작업 중인 세션은 커밋 전까지 무방비다** — 그리고 위 규율이 그걸 못 막는다
149
+
150
+ §2-d 와 「스위치 직전 `git branch --show-current`」 류의 규율은 전부 **«내가 남을 밟는 것»** 을
151
+ 막는다. **«내가 밟히는 것»** 은 못 막는다 — 내가 규율을 완벽히 지켜도, 내가 편집하는 동안 남이
152
+ 체크아웃을 옮기면 내 미커밋은 그 사람의 `stash` 로 딸려가거나 `reset` 에 날아간다.
153
+
154
+ **2026-08-18 실측, 하루 3회** — 세 세션이 돌아가며 한 번씩 밟았다(A→B · ?→A · B→C). 마지막
155
+ 사례에서 C 는 **자기 규율을 다 지킨 상태였다**: 브랜치를 잡고, 자른 직후 `git log main..HEAD`
156
+ 로 0줄을 확인하고, `branch_claim.sh claim` 까지 갱신했다. 그리고도 밟혔다.
157
+ ⇒ **구조가 원인의 절반이다.** 브랜치 이동은 공유 트리에서 구조적으로 나지만, **`stash -u`
158
+ 는 타이핑한 명령**이다. 그래서 「누가 조심했나」로 전부 갈리지도 않고, 전부 안 갈리지도 않는다 —
159
+ **구조가 노출 구간을 만들고, 넓은 명령이 그 구간을 실제 사고로 바꾼다.** 아래 3번이 그 명령이다.
160
+
161
+ **규율 — 노출 시간을 줄이는 쪽으로만 갈린다**
162
+ 1. **편집을 시작하기 전에** 브랜치를 잡아라. 편집 후에 잡으면 그 사이가 통째로 노출 구간이다.
163
+ 2. **자를 수 있는 단위로 자주 커밋해라.** 파일 여러 개를 다 고치고 한 번에 커밋하려는 습관이
164
+ 노출 시간을 배로 만든다(위 C 가 그랬다 — 두 파일을 다 고치고 한 번에 가려다 둘 다 잃었다).
165
+ 3. 🟥 **공유 체크아웃에서 `git stash` 는 `git add -A` 와 같은 급이다 — 아니, 더 넓다.**
166
+ `add -A` 는 «스테이징» 이라도 남기는데 `stash -u` 는 **트리 전체를 치운다.** 2026-08-18
167
+ 사고의 실제 원인이 이것이다: 한 세션이 selfcheck 을 깨끗한 트리에서 돌리려고 `git stash -q -u`
168
+ 를 쳤고, 그게 **peer 의 미커밋까지 같이 담았다.** 친 사람은 그것을 «내 것만 치운다» 로 알고
169
+ 있었다. ⇒ 깨끗한 트리가 필요하면 stash 가 아니라 **`git worktree add` 로 별도 트리**를
170
+ 쓰거나, 최소한 **치우기 전에 `git status` 로 남의 파일이 섞였는지 보고 살아있는 peer 에게
171
+ 한 줄 알려라.** (`git stash push -- <경로>` 로 경로를 한정하는 방법도 있으나, 그것도
172
+ «내 파일 목록을 내가 정확히 안다» 를 전제한다.)
173
+ 4. **밟혔다면 먼저 `git stash list` 를 봐라.** 남이 스위치할 때 내 미커밋이 **그 사람의
174
+ stash 로** 들어가 있을 수 있다. 위 사례는 거기서 **전량 회수**됐다(`git show stash@{0}:<path>`).
175
+ 🟥 **`stash pop` 은 하지 마라** — 그 stash 엔 **남의 파일도 같이** 들어있다. 파일 단위로
176
+ 뽑고 stash 는 그대로 둬라. 그 사람이 자기 것을 회수해야 한다.
177
+ 5. 🟥 **`claim` 은 중재가 아니라 «내가 본 HEAD 의 스냅샷» 이다 — 여러 세션이 같은 값을 동시에
178
+ claim 할 수 있다.** 2026-08-18 실측, `.git/fh-claims/` 4건이 **전부 같은 브랜치**를 기록하고
179
+ 그중 3개가 LIVE 였다. 그 셋 중 실제로 그 브랜치에서 작업하던 것은 **하나**다. 어떻게 그렇게
180
+ 되나: 한 세션이 `git switch <다른브랜치>` 를 쳤는데 **peer 의 staged 변경 때문에 abort** 됐고,
181
+ 그 실패를 **안 읽고** 다음 줄에서 `claim` 을 실행했다 — 그래서 남의 브랜치를 자기 것으로
182
+ 기록했다(rc 를 안 보고 다음 줄로 간 것). ⇒ 게이트가 잡는 것은 **«내가 기록한 뒤 HEAD 가
183
+ 움직였다»** 하나뿐이고, **소유권을 중재하지 못한다.** 「claim 했으니 안전」으로 읽지 마라 —
184
+ claim 파일 여러 개가 같은 브랜치를 가리키는 것은 **정상 상태**이고 아무 경고도 안 난다.
185
+ (짝: `git switch` 는 **실패할 수 있다.** rc 를 읽어라 — 안 읽으면 그 다음 줄이 전부 거짓
186
+ 전제 위에서 돈다.)
187
+ 6. 회수 후에는 **내용 검증을 해라** — 파일이 있다 ≠ 내 최신 편집이다. 마지막에 넣은 수리가
188
+ 들어있는지 토큰으로 확인해라(위 사례는 cross-family 수리 3종을 grep 으로 확인했다).
189
+
190
+ ### 2-d-3. 운영 형태 — **오늘의 사실**이지 «정해진 것» 이 아니다
191
+
192
+ 게이트는 «세션당 worktree» 를 권하는데 **FH 자산은 워크트리에서 커밋이 안 된다.** 그래서
193
+ 현재의 운영 형태는 이렇게 갈린다:
194
+
195
+ ```
196
+ FH 자산 커밋 → **메인 트리 전용.** 병렬이면 직렬화된다(먼저 필요한 쪽이 잡고, 두 번째는
197
+ 기다리거나 얹는다 — 운영자 규칙 2026-08-18)
198
+ 필드 작업·읽기·검증 → **워크트리로 빠져라.** 메인 트리의 HEAD 를 안 건드리고, 감사 대상도 안 흔든다
199
+ (2026-08-18 실측: qasp 코드 수정·리뷰어 주행을 전부 워크트리에서 했고
200
+ 사고 0. 사고 3건은 **전부 FH 자산 커밋 경합**에서 났다)
201
+ ```
202
+
203
+ 🟥 **이것을 «정본» 으로 읽지 마라 — 훅의 경로 해석 한 줄이 만든 사실이다.**
204
+ 훅은 `REPO_ROOT=$(git rev-parse --show-toplevel)` 로 마커/매니페스트 경로를 만드는데, 워크트리에선
205
+ 그게 워크트리를 가리켜 `tracks/` 가 없다. 그런데 **`git rev-parse --git-common-dir` 은 워크트리
206
+ 에서도 메인 트리의 `.git` 을 준다**(2026-08-18 실측, 3트리 대조 — 메인 트리에서는 같은 값이라
207
+ 하위호환도 성립). 즉 「구조적으로 불가능」이 아니라 **「아직 그렇게 안 해석한다」**이다. 초판이
208
+ 이 절을 «구조적 부재» 로 적었는데 과했다 — `[[feedback_impossible_verdict_may_be_unread_half]]`.
209
+
210
+ **해제 조건 (다음 델타의 설계 포인트)**
211
+ 1. 훅의 evidence-root 를 `--git-common-dir` 기준으로 해석 — 마커는 파일명이 `브랜치_날짜` 라
212
+ 워크트리끼리 **안 겹친다**.
213
+ 2. 🟥 **진짜 설계 문제는 `edit_manifest.yaml` 이다** — 단일 공유 파일이고 **gitignored 라 머지
214
+ 기계가 없다.** §4 의 「자기 소유 파일·즉시 커밋」 규율이 여기엔 안 먹는다(커밋할 수 없는
215
+ 파일이라서). 동시 append 를 어떻게 할지가 그 델타의 본체다.
216
+ 3. 열면 **fail-closed 를 하나 잃는다** — 지금은 「워크트리에서 FH 자산 커밋 불가」가 사실상
217
+ 안전장치로 굴렀다. 다만 트리가 분리되면 오늘 같은 사고는 안 나므로 **위험의 종류가 바뀌는
218
+ 것**이지 늘어나는 것은 아니라고 본다(판단이지 실측 아님).
219
+
220
+ ⚠️ **터미널·멀티세션 도구(Orca 류)만으로는 안 풀린다.** 그건 «세션이 어디서 도는지» 를 바꾸고,
221
+ 이 문제는 «증거가 어디 있는지» 다. 격리 도구를 쓰면 오늘의 HEAD/stash 사고는 사라지지만 **대신
222
+ 아무도 FH 자산을 커밋 못 하게 된다** — 위 1번이 같이 가야 진짜 병렬이 된다.
223
+
224
+ ⚠️ **기계화 안 한다(오늘은).** `gh` 는 세션 개념이 없고, 커밋 author/committer 도 같은 계정이라
225
+ 같은 한계를 공유한다. 유일하게 기계적인 후보는 `.git/fh-claims/` 인데 그건 **브랜치**를 기록하지
226
+ **PR** 을 기록하지 않고, 이미 「스냅샷이지 lock 이 아니다」로 한 번 틀린 필드다. ⇒ 지금은 산문 +
227
+ 본인 확인이 정직한 층이다. **PR 번호를 claim 에 적는 형태**가 후보로 남지만, 세션이 자기 것을
228
+ 자기가 적는 자기신고라 위조는 여전히 못 막는다.
229
+
113
230
  ## 3. 세대 간 승계 — 동료-질문으로는 구조적으로 안 잡힌다
114
231
 
115
232
  §1의 질문은 **동료 세션**을 향한다. **직전 세대 카드 자신의 이월분**은 그 질문의 사정거리 밖이다.
@@ -145,5 +262,10 @@ close check 는 **형식**만 본다(카드가 로그보다 새로운가, 필수
145
262
  - ①-c 의 peer 판별은 **cwd 매칭**이라 **다른 worktree 의 peer 를 못 잡는다**(Orca 류 격리 사용 시).
146
263
  - ①-d 스탬프와 §5 검사 결과는 **자기신고**다. 형식은 잡고 위조는 못 잡는다.
147
264
  - §1 의 질문은 **사람/세션이 해야 한다** — 기계 트리거가 없다. ①-c 는 «물어라» 를 띄울 뿐이다.
148
- - 문서 자체가 n=1(2026-08-09 2축 마감 1회) 위에 서 있다. **두 번째 사례가 나오면 다시 봐라** —
265
+ - ~~이 문서 자체가 n=1~~ → **n=2 가 됐다 (2026-08-18, 3축 마감).** 사례가 실제로 것은
266
+ §2-d(귀속·상태 오독) 하나이고, **§0~§5 의 나머지는 반증도 확증도 안 됐다** — 3축 마감이
267
+ 2축과 다르게 굴러서가 아니라 이번엔 §1 질문이 제대로 돌아 나머지가 시험대에 안 올랐다.
268
+ ⚠️ §2-d 자체도 **한 번의 3축 마감**에서 나왔다(세 세션이 각각 한 번씩 틀린 것이 표본의
269
+ 전부다). 세 번째 사례를 계속 기다린다.
270
+ - (원문) 이 문서 자체가 n=1(2026-08-09 2축 마감 1회) 위에 서 있었다 —
149
271
  특히 §0 의 「거버너+위임이 기본형」은 그 한 번에서 나온 판단이다.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@chrono-meta/fh-gate",
3
- "version": "2.4.0",
3
+ "version": "2.5.0",
4
4
  "description": "FH runtime adapters — run FH governance, skills, and agents via Claude or Codex with machine-parseable gates.",
5
5
  "license": "MIT",
6
6
  "keywords": [
@@ -80,6 +80,7 @@
80
80
  "scripts/prepublish_scope_note.sh",
81
81
  "scripts/lane_runner_check.sh",
82
82
  "scripts/test_package_coverage_lanes.sh",
83
+ "scripts/test_evidence_root_psa_lanes.sh",
83
84
  "scripts/adapters/peer_resolve.sh",
84
85
  "scripts/adapters/gstack_content_safety.sh",
85
86
  "scripts/adapters/mate_agent_boundary.sh",
@@ -128,6 +129,7 @@
128
129
  "scripts/chamber_candidate_collect.sh",
129
130
  "scripts/chamber_witness.sh",
130
131
  "scripts/digest_landing_check.sh",
132
+ "scripts/test_satellite_publish_gate_lanes.sh",
131
133
  "scripts/relay_channel.sh",
132
134
  "scripts/test_relay_channel_lanes.sh",
133
135
  "scripts/fh_session_load.sh",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fh-commons",
3
- "version": "2.4.0",
3
+ "version": "2.5.0",
4
4
  "engines": {
5
5
  "claudeCode": ">=1.0.0"
6
6
  },
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fh-meta",
3
- "version": "2.4.0",
3
+ "version": "2.5.0",
4
4
  "engines": {
5
5
  "claudeCode": ">=1.0.0"
6
6
  },
@@ -10,6 +10,54 @@ Format: [Keep a Changelog](https://keepachangelog.com/en/1.1.0/)
10
10
 
11
11
  ## Plugin Level
12
12
 
13
+ ### [2.5.0] — 2026-08-18
14
+
15
+ **정체성 ④(프런티어→조직 전파)의 «조직 = 레포» 축.** 다이제스트 러너가 FH 한 곳만 대상으로 지어져 있어 ④ 가 «자기 소비» 에 머물렀다. 대상 축을 열고, 그 산출이 **복제가 아니라 응용**이 되도록 프로필을 싣고, 공개 표면과 착지를 각각 기계로 잰다.
16
+
17
+ **위성 — `scripts/frontier_digest_daily.sh`**
18
+ - `FD_OUT_DIR`(대상 레포의 어디에) · `FD_MODEL`(위성별 티어 핀)
19
+ - `FD_PROFILE` — 대상 하네스가 **자기를 설명하는 파일**을 프롬프트에 싣는다. 🟥 없으면 산출은 **복제**다(실측: 대상 어휘 0 · FH 어휘 11 · Route 0). 있으면 **응용**(실측 2대상: 대상 어휘 0→33 · **Route 0→19**). **변인은 프로필 하나였다**
20
+ - `publish_gate()` — 공개 레포 대상이면 **매 런이 publish** 다(비가역). `0 게시 / 1 격리 / 그 외 보류` — 🟥 **세 값을 두 값으로 접지 않는다**
21
+ - `landing_witness()` — 직전 다이제스트 후보의 착지를 매일 기록. 차단하지 않는다(선별기). 프로덕션 호출부 **0 → 3**
22
+ - 앵커: `scripts/test_satellite_publish_gate_lanes.sh` (초판 **11 레인**, 아래 후속 수리로 **22 레인**), 되돌림 다중 arm
23
+
24
+ **착지 검증기 파서 — `scripts/digest_landing_check.sh`**
25
+ - 후보를 **표로만** 읽고 있었다. 실측 60건 중 표는 **4건(6.7%)**. 문단·헤딩·번호 리스트를 더해 **후보 절이 있는 56건 전부** 추출. 판별자 추출은 두 경로가 **공유**(중복 정규화기 방지)
26
+ - 🟥 이 결함은 **호출부가 0 이라 가려져 있었다.** 배선해서 처음 돌린 그 실행이 뱉었다 ⇒ **self-test 만 도는 스크립트는 실물과 어긋나 있어도 초록이다**
27
+
28
+ **규율 — `CLAUDE.md`**
29
+ - **§Expedition**: 원정 개시에 **«과녁 정체성» 한 줄** 의무. 근거는 1차 ⓐ 채점 **0건**이고 원인이 노력이 아니라 **겨냥**이었다(세 갈래가 전부 이미 🟢 인 정체성 위에 떨어졌다). 주기는 2차 이후로 연기, **계측 3항을 방법까지** 명시(거버너 토큰은 `UNMEASURED` 를 이름으로 남기고 **합계 금지**)
30
+ - **§AI Contribution Model**: 기본 워크플로에 **claim** 단계 + `scripts/branch_claim.sh` 를 이름으로. 기계는 이미 있었는데 산문이 그 이름을 안 불러 두 세션이 «없다»로 결론했다
31
+
32
+ **게이트 (peer 동시 착지분 #447·#448)**
33
+ ```
34
+ BREAKING (gate): edit_manifest.yaml 에 `date` 만 있는 엔트리가 있으면 커밋이 차단된다
35
+ — 동시 append 로 손상된 매니페스트의 지문이다(종전엔 무음 통과).
36
+ remedy: 훅이 지목한 엔트리를 손으로 확인해 필드를 복구하거나 제거한다.
37
+ ```
38
+ 실측: 이 레포 매니페스트 411건 중 date-only **0건** — **건강한 매니페스트를 가진 소비자는 안 막힌다.** 막히는 것은 동시 append 로 손상된 경우이고, 그 손상은 종전에 **조용히 통과**했다.
39
+
40
+ **동작 변경(차단 아님)**: 워크트리에서 FH 자산 커밋이 **가능해진다**(evidence-root 를 `--git-common-dir` 로 해석). 종전엔 `tracks/` 가 안 따라와 Axis 2+3·Axis 4 가 구조적으로 부재했다 — 즉 이 항목은 **완화**다.
41
+ ⚠️ **위 둘은 같은 사건의 앞뒤다.** 경로 변경으로 워크트리 소비자에게 게이트가 **처음 도달**하는데, 그 순간 `core.hooksPath` 가 **상대 경로**면 워크트리가 **자기 훅 사본**을 돌아 자기무력화가 가능하다.
42
+ 권고: `git config core.hooksPath "$(git rev-parse --show-toplevel)/templates/.git-hooks"`
43
+
44
+ **같은 날 후속 수리 — 위 배선이 만든 결함 5 + 타계열 3 (#452)**
45
+ 🟥 위 항목들을 「배선 완료」로 보고한 뒤 **되돌림 프로브·첫 실사용·타계열 패널**이 다음을 찾았다.
46
+ - **착지 증언이 배선 첫날부터 죽어 있었다** — 러너가 checker 에 **디렉터리를 «타깃 파일»로** 넘겨 매 런 `rc=10`. 손으로 잰 형태(1인자)와 러너가 부르는 형태(2인자)가 달랐다. 컨트롤 토큰도 하드코딩이라 대상 레포에선 고쳐도 죽은 채였다 ⇒ 스코프·컨트롤을 `DLC_*` 로 외부화, 유도 기본값은 **리터럴**(레포명에 정규식 메타문자가 있으면 «아무거나 매치»했다)
47
+ - **「직전 다이제스트」를 로케일 `sort` 로 골라 두 달 전 파일을 집었다** — 실물 코퍼스에 `2026-06-02`(대시)와 `2026_08_17`(언더바)가 섞여 있다 ⇒ `LC_ALL=C`. 🟥 **이건 레인이 아니라 첫 실사용이 잡았다**(그 시점 레인 21개는 전부 초록)
48
+ - **`publish_gate` 가 `head -1` 로 한 파일만 스캔**했고, 선택자가 `digest_ready` 와 갈려 있었다 ⇒ 단일 선택자 + 전 파일 순회 + 최악값. 선택자 자기모순은 **게시가 아니라 보류(3)**
49
+ - **공개 대상 트리 «안»에 로그를 팠고 findings 가 토큰 원문을 찍었다** ⇒ 트리 밖 + 리댁션 3단(인용 스팬·row 꼬리·경로). ⚠️ **이 러너는 출하 대상이 아니므로 npm 소비자에겐 해당 없다** — 러너를 복사해 쓰는 위성에서만 참이다
50
+ - **`pre-commit` 이 gitignored 패턴 오버라이드를 `REPO_ROOT` 에서만 찾았다** ⇒ `EVIDENCE_ROOT` 우선 + 폴백. **이건 출하된다.** 종전엔 워크트리 커밋이 매번 defaults-only 로 돌아 회사명·실명 클래스가 UNSCANNED 였고, 게다가 비차단 경고라 조용했다. ⓑ #448 의 반쪽-픽스였다
51
+ - **훅 주석 정정**: «절대 hooksPath 면 자기무력화가 **구조적으로 막힌다**» 는 과대주장 — 훅이 `$REPO_ROOT/scripts/*` 를 source 하므로 «한 겹 좁아진다» 가 정확하다
52
+ - 🟥 **셸 에러가 착지율 시계열에 «실측값»으로 들어갔다** (첫 실사용 발견). `set -u` + bash 3.2 에서 **빈 배열의 `${a[@]}` 는 unbound 에러**다. 대상 레포에 digest 이후 커밋이 없으면 타깃이 0건이 되고, 그러면 필터 루프가 터져 스크립트가 **판정을 인쇄하지 못한 채 rc=1** 로 끝난다 — 러너는 그 1 을 「SOME-UNLANDED」로 적는다. 올바른 값은 **rc=10(타깃 0건 = HARNESS-ERROR)**. 실측: forge-wiki 첫 런 로그가 정확히 그 형태였고 본문이 비어 있었다
53
+ - 🟥 **엔진 루트 ≠ 대상 루트** (첫 실사용 발견). 위성은 이 러너를 복사하지 않고 FH 의 것을 그대로 도는데(launchd 가 FH 경로를 가리킨다), 초판은 스캐너·패턴·checker 를 전부 `$FH_DIR`(=**대상 레포**)에서 찾았다 ⇒ 대상에 `scripts/psa_scan_lib.sh` 가 없으니 **publish gate 가 영영 fail-closed**. 게다가 그 분기는 파일을 **격리하지 않아** 「게시 안 함」이 **거짓**이었다(digest 는 이미 트리에 쓰여 있다). ⇒ 도구는 `ENGINE_DIR`, 대상만 env. 부재 분기도 실제 격리
54
+ - 🟥 **게시 직전 보안 패스가 신설 레인 2개에서 실 결함을 냈다**(MED·재현됨): 고정 `/tmp` 경로(`/tmp/.r4out` · `/tmp/.lw_*` · `/tmp/.lg_*`)라 공유 `/tmp` 에서 **심볼릭 링크 선점으로 임의 파일이 덮인다**(CWE-377). 이 스위트들은 **출하되고** `selfcheck.sh` 에 배선돼 있어 소비자가 셀프체크만 돌려도 발동했다 ⇒ `mktemp` + `trap` 정리. 재현으로 확인: 링크를 걸고 돌려도 피해 파일이 그대로다
55
+ - 앵커: 위성 **25 레인** · 착지 self-test **13 레인** · **`test_evidence_root_psa_lanes.sh` 신설 5 레인**(이 경로엔 앵커가 0개였다) · 착지 self-test 12. 되돌림 **8/8 이 각각 그 레인만** 적색
56
+
57
+ **호환성 — 위성 축은 BREAKING 아님.** 미설정 시 **종전 동작 그대로**이고(`N1`/`N3` 컨트롤이 그것을 주장), FH 자신의 일일 런은 무변경이다. ⚠️ `frontier_digest_daily.sh` 는 **출하 대상이 아니다**(종전 동일 — 출하되는 것은 `frontier_digest_autopilot.sh`).
58
+
59
+ **위성 주기 (2026-08-18 신설)**: `launchd` 2대 등록 — `com.forge-harness.satellite-forge-wiki`(10:00) · `satellite-the-bible`(11:00). FH 자신(09:00)과 시차를 둔다. 🟥 **엔진은 FH 에 있고 대상만 환경변수로 바뀐다** — 러너를 대상 레포에 복사하지 않는다(그게 복제다).
60
+
13
61
  ### [2.4.0] — 2026-08-18
14
62
 
15
63
  🟥 **BREAKING (gate) ①**: the Axes 2–3 marker's **`standpoint:` and `thirdparty:` fields are now