@chrono-meta/fh-gate 2.3.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.
Files changed (39) hide show
  1. package/.claude/rules/fh_4axis_gate.md +25 -0
  2. package/.claude-plugin/marketplace.json +2 -2
  3. package/CLAUDE.md +107 -7
  4. package/README.ja.md +14 -2
  5. package/README.ko.md +14 -1
  6. package/README.md +16 -2
  7. package/README.zh.md +12 -1
  8. package/knowledge/shared/harness-core/fh_three_layer_canon.md +18 -6
  9. package/knowledge/shared/harness-core/field_verdict_crossfamily_gate.md +262 -7
  10. package/knowledge/shared/harness-core/harness_incubator_doctrine.md +215 -1
  11. package/knowledge/shared/harness-core/ship_readiness_gate.md +168 -1
  12. package/knowledge/shared/harness-core/sonnet_floor_doctrine.md +16 -0
  13. package/knowledge/shared/learnings/subagent_invocations_log.yaml +120 -0
  14. package/knowledge/shared/rules/multi_session_close_protocol.md +124 -2
  15. package/package.json +8 -1
  16. package/plugins/fh-commons/.claude-plugin/plugin.json +1 -1
  17. package/plugins/fh-meta/.claude-plugin/plugin.json +1 -1
  18. package/plugins/fh-meta/CHANGELOG.md +105 -0
  19. package/plugins/fh-meta/skills/auto-decorrelation/SKILL.md +20 -0
  20. package/plugins/fh-meta/skills/steel-quench/SKILL.md +25 -2
  21. package/scripts/adapters/mate_agent_boundary.sh +27 -7
  22. package/scripts/capability_effect_probe.sh +173 -5
  23. package/scripts/capability_registry_check.sh +69 -3
  24. package/scripts/digest_landing_check.sh +168 -13
  25. package/scripts/fh_session_load.sh +71 -0
  26. package/scripts/relay_channel.sh +151 -6
  27. package/scripts/selfcheck.sh +47 -0
  28. package/scripts/target_freeze.sh +239 -0
  29. package/scripts/test_adapter_lanes.sh +17 -0
  30. package/scripts/test_evidence_root_psa_lanes.sh +78 -0
  31. package/scripts/test_marker_standpoint_lanes.sh +83 -0
  32. package/scripts/test_marker_thirdparty_lanes.sh +73 -0
  33. package/scripts/test_regression_guard_ci_lanes.sh +170 -0
  34. package/scripts/test_relay_channel_lanes.sh +146 -17
  35. package/scripts/test_satellite_publish_gate_lanes.sh +339 -0
  36. package/scripts/test_target_freeze_lanes.sh +203 -0
  37. package/templates/.git-hooks/pre-commit +306 -6
  38. package/templates/PRE-PUBLISH-CHECKLIST.md +22 -0
  39. package/templates/regression_guard.sh +32 -4
@@ -157,8 +157,12 @@ engine under the other — and the two candidates for "④" are **context-contin
157
157
  external-grounding**, which currently hold different grades, so the ambiguity is not cosmetic.
158
158
  The collision is worse than one file's internal disagreement: **the identities are numbered ①–⑤ and the
159
159
  engines are not numbered at all**, so a bare ① in any record is undecidable without its sentence. This
160
- file shows it — a paragraph enumerating engines sits four lines above `③⑤ are 🟢, ①②④ are 🔵 RC`,
160
+ file shows it — a paragraph enumerating engines sits four lines above `①③⑤ are 🟢, ②④ are 🔵 RC`,
161
161
  where those numerals mean *identities*.
162
+ (🟥 That example string was itself stale until 2026-08-17: it still read `③⑤ are 🟢, ①②④ are 🔵 RC`,
163
+ which 632 had already superseded — so the illustration pointed at text no longer in the file.
164
+ Same **in-file half-fix propagation** this document names elsewhere; fixed here, and the grade
165
+ values in an *example* must be re-checked whenever the table moves.)
162
166
 
163
167
  > **Legacy decode (do not delete — session records already use numbers).** Records written before
164
168
  > 2026-08-13 say 엔진 ①~④. They decode by the **engine table order above**:
@@ -672,6 +676,169 @@ Each remedy is a run that leaves an artifact, tracked in `tracks/_meta/identity_
672
676
  > An identity whose broad path *runs* is not 🔴 ideal-only. Both are 🟡: running, not yet closed. Lesson:
673
677
  > do not score an identity by its hardest sub-mechanism — that reads a live-but-incomplete path as zero.
674
678
 
679
+ ### ④ promotion criteria — 이 절이 **없었다는 것** 자체가 첫 발견 (2026-08-17)
680
+
681
+ ②(438줄)와 Ⓑ(421줄)는 전용 승급 기준 절을 갖고, ①은 행 안에 인라인으로 갖는다.
682
+ **④만 없었다.** 그리고 이 파일이 ② 절 첫머리에 그 절이 왜 필요한지 이미 적어놨다 —
683
+ *"매 라운드가 바닥부터 기준을 재도출하지 않도록"*. **그 처방이 ④에만 적용되지 않았다.**
684
+
685
+ #### 1. 🟥 유일하게 명시돼 있던 조건은 **다른 명제를 잰다**
686
+
687
+ 지금까지 ④에 대해 조건처럼 읽힌 문장은 하나뿐이었다:
688
+ > *"④ file-change ≠ token-introduction — the instrument is a screener, not an adjudicator"*
689
+
690
+ 그런데 그 계기(`scripts/digest_landing_check.sh`)가 **자기 헤더에서 스코프를 자백한다**:
691
+ > *"착지 대상 = 공개 FH 자산 + `tracks/`. 비공개 companion store 는 **보지 않는다** …
692
+ > 따라서 **이 계기가 재는 것은 «조직 전체 전파»가 아니라 «허브 내부 착지»다**"*
693
+
694
+ 반면 ④가 주장하는 명제는 `fh_three_layer_canon.md` — *"바깥에서 온 것이 **조직 안까지** 착지한다"*.
695
+ ⇒ **그 조건을 100% 닫아도 ④의 명제는 한 글자도 안 재진다.** ①이 dominance 를 두 번 측정하고
696
+ «겨냥이 틀렸다»로 판정한 것과 같은 형태이고, ④는 그 판정을 **한 번도 받은 적이 없다**.
697
+
698
+ #### 2. 🟥 그리고 구조적으로 도달 불가다 — P1 과 같은 형태 (**이 파일 안에서는** 지목된 적 없다)
699
+
700
+ 이 파일의 residency 규율(§Ⓑ promotion criteria 3)이 못 박는다:
701
+ > *"조직 환경 실적은 **증언으로 남고 측정으로 세지 않는다.** residency 때문에 이 파일에서
702
+ > 검증할 수 없고, 검증 못 하는 것을 숫자에 넣으면 그 숫자 전체가 못 쓰게 된다"*
703
+
704
+ 그런데 **④는 대상이 조직인 유일한 행**이다. ⇒ 🟢가 요구하는 «구체적 실적 아티팩트»를
705
+ **이 파일 안에서는 원리적으로 만들 수 없다.** ②의 P1이 «mtime은 위조 가능 → 어떤 런도 만족
706
+ 불가»였던 것과 정확히 같은 구조이며, P1 은 지목되어 수리됐고 **이 파일 안에서는** ④ 에 대한
707
+ 같은 지목이 없다. ⚠️ **범위 제한이다** — 이 파일을 읽어서 내린 판단이고, 전 코퍼스 부재 스캔
708
+ (검색어·컨트롤 동반)은 **안 돌렸다**. 「아무도 지목한 적 없다」로 넓혀 읽지 마라.
709
+
710
+ #### 3. 이미 충족돼 있을 가능성 — 못 읽는 지점이 한 단어로 특정된다
711
+
712
+ 조직 착지는 **운영자 증언으로 존재한다 — 이 세션이 검증한 것이 아니고, §2 대로 이 파일에서는
713
+ 검증 불가다**(전부 residency 경계 안이라 종류만 적는다): 정기 조직 보고 채널로의 상시 착지 ·
714
+ 외부 발표 채택과 그 산출이 다시 FH 기계의 근거로 인용됨(**증언 — 「관통」으로 단정하지 않는다**) ·
715
+ 조직 내 정식 공개 1건.
716
+
717
+ 🟥 **라벨을 반드시 붙인다.** Ⓑ 행이 같은 처리를 한다 — *"실적 열거는 **운영자 증언** + 실측
718
+ 2건이고 … **증언으로 표기하고 측정으로 세지 않는다**"*. 증인이 없는 관통을 「관통」으로 적으면
719
+ 다음 라운드가 이 절을 «④는 사실상 충족» 의 근거로 인용한다. 그게 이 파일이 반복해 자책한
720
+ 인용 훼손 경로다.
721
+
722
+ > **못 읽는 지점 = «as ONE pipeline».** 조건이 「착지했나」가 아니라
723
+ > **「하나의 계기로 관통을 증인할 수 있나」**를 요구하는데, 그 증인 계기가 스스로 조직을
724
+ > 스코프 밖으로 선언했다. 계기 헤더도 절반 자백해뒀다 — *"«안 닫힌다»가 아니라
725
+ > **«닫히는데 증인이 없다»**"*, *"**파이프라인은 그날 실제로 관통했다**"*.
726
+
727
+ #### 4. 제안하는 기준 — 막힌 것은 측정이 아니라 **측정의 위치**다
728
+
729
+ ```
730
+ 지금 조직 데이터를 공개 레포로 가져와 재려 한다 → residency 가 막는다 (정당하게)
731
+ 대안 계기를 데이터가 있는 쪽으로 옮긴다 → 조직 밖으로 나오는 것을 최소화한다
732
+ ```
733
+
734
+ 🟥 **초판이 여기서 두 번 틀렸고, 적대검증이 커밋 전에 잡았다. 그 정정을 남긴다.**
735
+
736
+ **틀린 것 ①** — 초판은 *"**판정만** 넘어오므로 residency 를 안 깬다"* 고 적었다. 그런데 §2 가
737
+ 도달 불가의 **근거로** 인용한 것이 Ⓑ-3 의 *"조직 실적은 … 이 파일에서 **검증할 수 없다**"* 다.
738
+ **조직에서 나온 판정을 이 파일 계열의 공개 기록에 넣는 것**이 곧 그 규칙이 금지한 행위다 —
739
+ 블로커로 인용한 규칙을 처방이 우회했다. 순환이 아니라 **자기무효화**다.
740
+
741
+ **틀린 것 ②** — 초판은 챔버 순서 증인(*"해시만 적는다, 본문 유출 0"*)을 유비로 들었다.
742
+ **성립하지 않는다**:
743
+ ```
744
+ 챔버 증인이 넘기는 것 해시 → 원문 N 개 중 무엇인지에 대해 **0 비트**
745
+ 초판의 P4-1 이 넘기는 것 후보별 PASS/FAIL → 후보 N 개에 대해 **N 비트**
746
+ ```
747
+ 「조직이 이 프런티어 항목을 도입했다/안 했다」는 **그 자체가 조직 정보**다.
748
+ *"원본은 한 바이트도 안 나온다"* 는 **바이트 수를 정보량과 혼동한 문장**이었다. 유비를 철회한다.
749
+
750
+ **그래서 좁힌다.** 조직 밖으로 나오는 것은 **집계된 단일 verdict 하나**뿐이다:
751
+
752
+ **P4-1 (mandatory-pass)** — 조직 환경 클론에서 착지 계기가 실행되고, 공개 쪽으로는
753
+ **집계된 단일 verdict(PASS/FAIL 하나)** 만 기록된다.
754
+ 🟥 **후보별 판정·건수·비율을 공개 쪽에 쓰는 것은 금지한다** — N 비트가 새는 경로다.
755
+ 🟥 그리고 residency 예외 절차를 그대로 탄다(`CLAUDE.md §Field-Harness Diagnostic`):
756
+ **명시적 운영자 승인 + gitignored 감사노트**. *"«이게 충분히 sanitize 됐나»는 세션이 혼자
757
+ 내리는 판단이 아니다"* — 이 조건이 없으면 P4-1 은 미충족이다.
758
+
759
+ **P4-1 의 선행조건 — 지금 둘 다 미충족이고, 그걸 적는 것이 이 절의 값이다**
760
+ 1. 🟥 **잴 대상이 조직 클론에 존재해야 한다.** 계기 인터페이스는
761
+ `digest_landing_check.sh <digest.md> [target ...]` 인데, digest 산출물은
762
+ `tracks/_meta/frontier_digest_<날짜>.md` 이고 **`tracks/**` 는 gitignored**, 생성은
763
+ **이 머신의 launchd 매일 09:00** 이다. ⇒ **조직 클론에는 잴 digest 가 구조적으로 없다.**
764
+ 조직 쪽 생성 경로가 생기거나 공개 digest 를 반입할 수 있어야 한다.
765
+ 2. 🟥 **실행 주체를 이름으로 적어야 한다.** 없으면 P4-1 은 **「미도달」로 표기하고 승급 기준으로
766
+ 세지 않는다** — 이름 없는 실행 주체는 P1 이 «어떤 런도 만족 불가» 였던 것과 같은 형태다.
767
+
768
+ **P4-2 (measured)**: 그 verdict 가 known-pair 를 가른다 — 착지한 건과 착지 안 한 건을 실제로
769
+ 구분. 컨트롤 없는 PASS 는 이 조건을 만족시키지 않는다.
770
+
771
+ #### 5. 🟥 남는 잔여 — 닫는 게 아니라 한 칸 올리는 것이다
772
+
773
+ 그 판정은 **비저자가 볼 수 없는 환경에서 나온 자기신고**다. 챔버 증인이 «저자를 신뢰하지 않는
774
+ 기록»을 요구한 것과 **같은 문제가 조직 경계에서 재발한다**. 그래서 이 기준은 ④를 «완전히
775
+ 닫는다»가 아니라 **«증언 → 측정으로 한 칸 올린다»**이고, 그 한계를 조건에 같이 적는다.
776
+ 비저자 실증이 가능해지는 시점(조직 내 다른 운영자가 그 계기를 돌리는 것)이 다음 칸이다.
777
+
778
+ **강등 조건 — 이 절이 승급만 적고 강등을 안 적으면 Ⓑ 절의 목적을 못 따른다**
779
+ (Ⓑ 절 자기 규정: *"«어떻게 올라가나»가 아니라 «**무엇이 이 행을 내릴 수 있나**»"*):
780
+ - **D4-1**: P4-1 의 verdict 가 **known-pair 를 못 가르면**(착지한 건과 안 한 건이 같은 값을 받으면)
781
+ ④는 **🔵 로 되돌린다.** 판별력 없는 PASS 는 측정이 아니다
782
+ - **D4-2**: 선행조건 1·2 중 하나라도 **다시 미충족이 되면**(조직 쪽 digest 경로가 사라지거나
783
+ 실행 주체가 없어지면) ④는 **「미도달」로 되돌아간다** — 한 번 통과한 것으로 고정되지 않는다
784
+ - **D4-3**: residency 예외 절차(운영자 승인 + 감사노트) 없이 조직 판정이 공개 쪽에 기록되면
785
+ 그 기록은 **무효이고 ④는 강등된다.** 이건 등급 문제가 아니라 규율 위반이다
786
+
787
+ #### 6. 부수 — 이 절을 쓰면서 확인된 stale 2건
788
+
789
+ - 🟥 **207·238줄의 «zero callers» 처방은 stale 이 아니다 — 초판이 그렇게 적었고 틀렸다.**
790
+ `scripts/selfcheck.sh:617` 앵커 루프에 들어간 것은 **`--self-test` 레인뿐**이고, 레포 전체에서
791
+ `digest_landing_check.sh <digest.md>` 를 **인자와 함께 부르는 프로덕션 호출부는 0개**다.
792
+ selfcheck 주석 자신이 그렇게 말한다 — *"lanes existed and ran only when a human typed the
793
+ command"*. ⇒ **「배선됐다」가 다른 배선이었다**: 계기의 self-test 는 도는데 계기 자체는 아무도
794
+ 안 부른다. **그리고 이 0 은 §4 P4-1 의 미충족 선행조건이다** — 공개 레포에서조차 실행 경로가
795
+ 없는 계기를 조직 클론에서 돌린다고 쓸 수 없다. (나머지 절반 «네 분기 앵커링»은 **미확인**.)
796
+ - **160줄**이 옛 등급(`③⑤ are 🟢, ①②④ are 🔵`)을 **현재형 예시**로 인용한다. 632줄이 이미
797
+ 갱신했다. 이 파일이 스스로 이름 붙인 **파일 내부 half-fix 전파 결함**의 재발이다.
798
+
799
+ ### §Gate-consequence 의 일관성 — 자백은 적혀 있고 처분은 안 됐다 (2026-08-17)
800
+
801
+ 607–614줄이 **스스로** 이렇게 적어놨다:
802
+ > *"⑤ 는 🟢 on `intent-routing probe 94%` — **a self-measurement, not a head-to-head** …
803
+ > The inconsistency is real and it is **the gate's, not ②'s** … Resolving that is a **separate
804
+ > change** to the status definitions — flagged here, **not silently settled**."*
805
+
806
+ **그 «separate change» 가 오지 않았다.** 실측하면 **6행 중 4행이 비일관**이다:
807
+ ```
808
+ Ⓑ 일관 적용 만족 — 282줄이 "§Gate consequence 를 **면제 없이 그대로 만족**한다" 고 명시
809
+ ③ 일관 적용 보유 (moat 3–4 family blind · HITL 8/8)
810
+ ─────────────────────────────────────────────────
811
+ ① 비일관 예외를 정식 취득 (92-99줄 — 사전등록 2회 측정 후 미성립. 절차는 밟았다)
812
+ ② 비일관 **미결** — 607-614 자백이 "②를 면제할지 ⑤를 재측정할지" 를 안 정했다
813
+ ⑤ 비일관 미보유인 채 🟢 ← 자백의 대상
814
+ ④ 비일관 언급조차 없음
815
+ ```
816
+ 🟥 **초판이 여기서 «6행 중 일관 적용된 행이 없다» 고 적었는데, 바로 아래 자기 표가 그걸
817
+ 반증했다**(Ⓑ 만족 · ③ 보유). 적대검증이 잡았고 정정한다. 그리고 초판은 ②를 **「면제」로 확정
818
+ 표기**했는데, 자백 원문은 **미결**이다 — 절의 결론(«아무것도 정하지 않는다»)과 표가 어긋나 있었다.
819
+ 🟥 **이건 오늘 이 저장소가 반복해 만난 «미측정을 0으로 접었다»와 다른 형태다** — 접힘이 아니라
820
+ **적용 누락**이다. 그리고 자백이 문서에 적혀 있는데 안 고쳐진 것은 「몰랐다」가 아니라
821
+ **「알고 미뤘다」**라서, 다음 라운드가 그 자백을 「이미 인지된 사항」으로 읽고 또 넘길 위험이 크다.
822
+
823
+ **처분(운영자 결정 필요, 여기서 확정하지 않음)** — 둘 중 하나여야 하고 셋째는 없다:
824
+ - **(A) §Gate-consequence 가 모든 🟢 를 구속한다** ⇒ ⑤ 는 과대 채점이고 재측정 대상이다
825
+ - **(B) advisory 다** ⇒ ②·④ 를 거기에 묶어서는 안 되고, ① 이 받은 «예외»는 애초에 필요 없었다
826
+
827
+ ⚠️ 이 절은 **자백을 결정으로 바꾸지 않는다.** 지금 하는 것은 「미뤄졌다는 사실 자체를 기록해서
828
+ 다음 라운드가 그것을 인지된 사항으로 소비하지 못하게」 하는 것뿐이다.
829
+
830
+ 🟥 **그런데 그것만으로는 이 절이 자기가 진단한 실패를 반복한다 — 적대검증 지적, 수용한다.**
831
+ 607-614줄의 자백도 **이 파일의 산문**이었고, 그 매체로 **이미 한 번 실패했다**(그래서 이 절이
832
+ 있다). 같은 매체에 한 번 더 적으면서 앵커·기한·소유자를 안 붙이면 결과가 같다.
833
+ `CLAUDE.md §Mechanization Boundary` 가 **채널(«기록이 있는가»)은 기계화 대상**이라고 정한다.
834
+
835
+ ⇒ **파일 밖 앵커를 건다**: 세션 카드(`tracks/_meta/reference_next_session_starter.md`)의
836
+ 🧵 블록에 **«⑤ dominance 일관성 — 운영자 결정 대기 (제기 2026-08-17)»** 를 등재한다.
837
+ 카드는 매 세션 시작에 읽히고 이 파일은 안 읽힌다 — 그게 차이다.
838
+ 🟥 **이 등재가 없으면 이 절은 자백의 재생산일 뿐이다.**
839
+
840
+ ---
841
+
675
842
  ## For a field harness (e.g. pmh, qasp)
676
843
  Same gate, its own identities. A field harness ships to its team when its identity checklist is all-green,
677
844
  certified by a **실증상세 (demonstration-detail) doc in that harness's own repo** — the QA certificate
@@ -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
 
@@ -2182,3 +2182,123 @@
2182
2182
  outcome: accepted
2183
2183
  evidence: "tool_uses 25(계기 생존 — 카드가 경고한 `tool_uses: 0` 아님). **4/4 앵커 생존**, 매번 대응 레인만 적색(S1→2건·S2→1건·S3→2건·B1→known-pair 2건), 무관 25~28개는 통과 → 과결합 0. 복원 후 29 passed 재확인, 트리 clean. 🟥 substring 8행은 **전부 ✅ 로 판정했는데 코덱스와 갈렸고 이쪽이 졌다** — 「뚫리는 입력을 제시 못 함」을 판별력 있음으로 읽었으나, 그 단언이 *주장*하는 것(«범위 밖 보고가 났다»)은 파일명만으로 증명되지 않는다. **없음을 증명 못 함 ≠ 판별력 있음**"
2184
2184
  cost: 135k tokens
2185
+ - date: 2026-08-18
2186
+ agent: Explore ×4 (isolated) — AX-레디 착수 전 정찰(FH 대상동결 선행자산 · qasp 해석기 어휘 · D2 스캐너 배선 · D3ⓑ 용어 채널 · B5 상태 어휘 · 호출부 0 좌표)
2187
+ purpose: "재발명 방지 + 좌표 확정. 착수 전 «이미 있나» 를 기계로 먼저 묻는다(오늘 이 레포에서 재발명이 한 번 났었다)"
2188
+ outcome: partial
2189
+ evidence: "6축 정찰을 4발주로 묶음(각 대상 지문 `target_freeze.sh verify` 로 시작). **정확했던 것**: 대상동결 선행자산 스캔이 «기계 없음 + 실패 2종 문서화» 를 짚어 3번째 시도의 설계를 결정 · D2 가 `bug_report.py` 호출부 0을 컨트롤 동반으로 확정 · B5 가 `rer_from_act2` 를 «어휘 매핑 어댑터 레퍼런스» 로 지목(재발명 회피) · 근거표 A3 의 팬텀 인용 `PEER_ABSENT` 발견. 🟥 **틀린 것 2건, 둘 다 내가 직접 재현해서 걸렀다**: ⓐ 「`_CAUSE_PLAIN` 커버리지 게이트가 FAIL 레인 4종을 놓친다」 → 그 4종은 `StepEvidence.triage` 가 아니라 이슈-후보 dict 로 가고 소스 주석이 이미 그렇게 갈라놨다(오탐) ⓑ 「`env_cols_source` 가 존재하지 않는다」 → 7히트 실재(주석이 말한 건 *다른 모듈*). ⇒ 정찰 산출은 소스로 닫히기 전엔 좌표가 아니다"
2190
+ cost: ~309k tokens (4건 합)
2191
+ - date: 2026-08-18
2192
+ agent: general-purpose (isolated) — qasp 호출부 0/불일치 스캐너 제작
2193
+ purpose: "«완성된 층 + 호출자 없음» 이 하루 4회 났다 — stdlib ast 기반 계기를 known-pair 로 세우고 전수 1회"
2194
+ outcome: accepted
2195
+ evidence: "**known-pair 양성 2/2 · 음성 5/5**(음성은 호출자 *경로까지* 대조). 전수 1024심볼 · ⓐ162(엄격 32)·ⓑ207·UNDECIDABLE 73. 🟥 **자기 오탐 2계열을 스스로 잡아 고쳤다**: `same_module_refs` 가 import 링크를 요구해 구조적으로 항상 0(→엄격 ⓐ 162→32) · `DeviceAdapter` 덕타이핑 미검출. 진양성 손검증 1건(`RuleAutoExpansionGate` — 외부 참조가 주석 2줄, 그 이름은 **존재하지 않는 철자**). ★ **`target_freeze.sh` 의 첫 실사용이 여기서 났다** — 회수 시 `WRONG-TARGET`(발주 중 내가 커밋 3건 투입), 위임분이 stale 판정을 안 들고 오고 현재 트리에서 전량 재실행. 미해결 자백: 손검증 1건뿐 · 미검출 미측정 · CI 미배선"
2196
+ cost: 167k tokens
2197
+ - date: 2026-08-18
2198
+ agent: codex/gpt-5.5 (cross-family sidecar) — FH `target_freeze.sh` 게이트 적대검증
2199
+ purpose: "감사 대상 동결 게이트의 fail-open / 오탐 / 셸 이식성 — 재현 명령 필수"
2200
+ outcome: accepted
2201
+ evidence: "**6건, 전부 재현 명령 동반, 내가 직접 재현해 6/6 확인.** S급 3건이 **fail-open**(`_sha` 가 `|awk` 로 rc 소실 · `ls-files -o` 실패가 파이프에 먹힘 · 라벨 문자치환 충돌로 **핀한 적 없는 라벨이 MATCH**) + A급 2(서브모듈·심볼릭링크 미검출) + 과탐 1(빈 커밋). 🟥 **레인 11/11 초록인 상태에서 전부 뚫렸다** — 컨트롤 있음 ≠ 판별력 있음. 전부 수리 + 레인 고정"
2202
+ cost: ~40k tokens
2203
+ - date: 2026-08-18
2204
+ agent: agy/gemini (cross-family sidecar, 2번째 계열) — 같은 게이트, **다른 축** 요구
2205
+ purpose: "codex 지적 목록을 먼저 주고 «그 밖의 축»(동시성·env·거짓 안심·인코딩)을 요구 — 한 계열에 몰면 같은 사각이 남는다"
2206
+ outcome: accepted
2207
+ evidence: "**6건 · codex 와 겹친 지적 0.** 최상위는 `GIT_DIR`/`GIT_WORK_TREE` 가 `git -C` 를 이긴다 — **엉뚱한 레포를 재고도 «동결했다» 고 보고**한다(계기가 대상을 틀리는 형태). 그 외 untracked **실행 비트** 미검출(이 레포가 이미 데인 축) · TOCTOU «유령 지문» · 미초기화 서브모듈은 `foreach` 가 건너뜀 · `---` 구분자 경계 · `foreach` 의 `;` rc 소실. 전부 수리, 레인 11→28. ⇒ **계열 분리가 값을 냈다** — 이 6건은 codex 를 한 번 더 돌려서는 안 나온다"
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.3.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",
@@ -114,6 +115,8 @@
114
115
  "scripts/tier_census_grep.sh",
115
116
  "scripts/test_marker_floor_lanes.sh",
116
117
  "scripts/test_marker_crossfamily_lanes.sh",
118
+ "scripts/test_marker_standpoint_lanes.sh",
119
+ "scripts/test_marker_thirdparty_lanes.sh",
117
120
  "scripts/test_marker_axes_run_lanes.sh",
118
121
  "scripts/test_env_purity_lanes.sh",
119
122
  "scripts/.env_purity_tokens.defaults",
@@ -126,10 +129,13 @@
126
129
  "scripts/chamber_candidate_collect.sh",
127
130
  "scripts/chamber_witness.sh",
128
131
  "scripts/digest_landing_check.sh",
132
+ "scripts/test_satellite_publish_gate_lanes.sh",
129
133
  "scripts/relay_channel.sh",
130
134
  "scripts/test_relay_channel_lanes.sh",
131
135
  "scripts/fh_session_load.sh",
132
136
  "scripts/branch_claim.sh",
137
+ "scripts/target_freeze.sh",
138
+ "scripts/test_target_freeze_lanes.sh",
133
139
  "scripts/test_branch_claim_lanes.sh",
134
140
  "scripts/hook_source_lib.sh",
135
141
  "scripts/test_hook_source_gate_lanes.sh",
@@ -138,6 +144,7 @@
138
144
  "templates/degrade_direction_scan.sh",
139
145
  "templates/.git-hooks",
140
146
  "templates/regression_guard.sh",
147
+ "scripts/test_regression_guard_ci_lanes.sh",
141
148
  "templates/predelete_check.sh",
142
149
  "templates/PRE-PUBLISH-CHECKLIST.md",
143
150
  "scripts/degrade_direction_scan.sh",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fh-commons",
3
- "version": "2.3.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.3.0",
3
+ "version": "2.5.0",
4
4
  "engines": {
5
5
  "claudeCode": ">=1.0.0"
6
6
  },