@chrono-meta/fh-gate 2.0.1 → 2.1.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 (32) hide show
  1. package/.claude/rules/fh_4axis_gate.md +77 -1
  2. package/.claude-plugin/marketplace.json +3 -3
  3. package/AGENTS.md +19 -3
  4. package/CLAUDE.md +240 -4
  5. package/knowledge/shared/harness-core/capability_composition_contract.md +68 -0
  6. package/knowledge/shared/harness-core/fh_three_layer_canon.md +38 -12
  7. package/knowledge/shared/harness-core/field_verdict_crossfamily_gate.md +115 -3
  8. package/knowledge/shared/harness-core/harness_incubator_doctrine.md +82 -0
  9. package/knowledge/shared/harness-core/harness_terminal_correlation_and_recommendations.md +49 -8
  10. package/knowledge/shared/harness-core/ship_readiness_gate.md +205 -1
  11. package/knowledge/shared/learnings/subagent_invocations_log.yaml +66 -0
  12. package/knowledge/shared/rules/sister_asset_protocol.md +12 -0
  13. package/package.json +3 -2
  14. package/plugins/fh-commons/.claude-plugin/plugin.json +1 -1
  15. package/plugins/fh-commons/agents/quench-challenger.md +6 -1
  16. package/plugins/fh-meta/.claude-plugin/plugin.json +1 -1
  17. package/plugins/fh-meta/CHANGELOG.md +43 -0
  18. package/plugins/fh-meta/skills/auto-decorrelation/SKILL.md +14 -2
  19. package/plugins/fh-meta/skills/steel-quench/SKILL_detail.md +13 -0
  20. package/plugins/fh-meta/skills/verify-bidirectional/SKILL.md +34 -1
  21. package/scripts/capability_registry_check.sh +75 -12
  22. package/scripts/chamber_run.sh +24 -3
  23. package/scripts/chamber_witness.sh +25 -0
  24. package/scripts/fh-gate.sh +16 -1
  25. package/scripts/package_coverage_check.sh +10 -0
  26. package/scripts/prepublish_scope_note.sh +139 -0
  27. package/scripts/selfcheck.sh +30 -5
  28. package/scripts/test_fh_gate_regressions.sh +21 -9
  29. package/scripts/test_marker_axes_run_lanes.sh +87 -3
  30. package/scripts/test_marker_crossfamily_lanes.sh +31 -1
  31. package/templates/.git-hooks/pre-commit +225 -10
  32. package/templates/subagent-tally-hook.json +2 -2
@@ -221,13 +221,71 @@ marker, never replacing it. Closed enum, same discipline as `crossfamily:`'s thr
221
221
  not / did not / did not look* split (a free-prose field would let an unrun check read as a clean
222
222
  pass):
223
223
 
224
+ **🟥 DECIDE IN THIS ORDER — first match wins. Do not pick by matching a description.**
225
+
226
+ ```
227
+ Q1. Did anything EXECUTE in the target's repo — a command, a script, a suite?
228
+ NO, I only read files → tier1b(<harness>) STOP.
229
+ NO, I did not touch its repo → tier1 STOP.
230
+ YES → continue to Q2
231
+ ⚠️ tier2 AND tier2b BOTH REQUIRE EXECUTION. This question is first precisely so the
232
+ next one cannot be used to reason backwards into "tier2 must be the non-executing rung."
233
+ Q2. Was the target's own LOCAL / gitignored wiring visible (settings, consent bindings,
234
+ node-local state) — i.e. its real installed runtime, not a bare clone?
235
+ NO (bare clone, tracked content only) → tier2(<harness>)
236
+ YES (the target's real runtime) → tier2b(<harness>)
237
+ Q3. Was it run by a DIFFERENT operator of the target harness, not you?
238
+ YES → tier3(<harness>) (supersedes Q2)
239
+ ```
240
+
241
+ **Why the procedure exists rather than more definition.** `tier2` vs `tier2b` is **wiring
242
+ visibility**, NOT execution-vs-reading — both execute. But `tier2b`'s gloss names "the target's
243
+ real runtime," which reads as *"tier2b is the execution rung"*, and a reader then infers that
244
+ `tier2` must therefore be the non-executing one.
245
+
246
+ 🟥 **RETRACTED (2026-08-17) — the sim evidence formerly cited here is withdrawn.** This paragraph
247
+ read: *"after all three were corrected to say EXECUTED CODE, two independent blind Sonnet reps STILL
248
+ graded a pure cold-read `tier2`"*, and quoted one rep's reasoning verbatim. Those runs had
249
+ **`tool_uses: 0`** — the agents never opened a file, so the quoted reasoning is a cold guess about
250
+ text it did not read, and the grades measure nothing
251
+ (`tracks/_meta/fh_completed_2026-08-16.md:690`). The live re-run **inverted** the result at
252
+ **reps=1**, below this repo's `reps>=3` bar. **Neither direction is established**; do not restore
253
+ the numbers and do not cite the inversion either.
254
+
255
+ What remains, and it is enough to justify ordering the questions: the enum's *wording* really does
256
+ place the execution claim on `tier2b`'s line, so a reader can reach "then `tier2` is the
257
+ non-executing one" **by the text alone** — that is a property of the text, checkable by reading it,
258
+ and it needs no sim. Ordering the questions removes the inference instead of arguing with it.
259
+
224
260
  ```
225
261
  tier1 content-only review — no standpoint decorrelation (the default
226
262
  unless upgraded; NOT itself a failure, most changes have no target
227
263
  standpoint to borrow)
228
- tier2(<target-harness>) peer-simulated — the reviewer instantiated/ran the TARGET's own repo
229
- (a local clone, real content) and executed the change from that
230
- standpoint. Closes shared-body-path defects; a BARE clone cannot see
264
+ tier1b(<target-harness>) STATIC standpoint read — the reviewer read the TARGET's own files
265
+ (cold, from the target's repo, without the author's framing) and
266
+ adjudicated the change against them, but executed NOTHING. Added
267
+ 2026-08-16 because its absence was actively harmful: a run of exactly
268
+ this shape was recorded as `tier2`, since tier1 undersold it and no
269
+ nearer value existed. A missing rung does not stay empty — it gets
270
+ filled by the next one up. Real but weak: see «execution is the
271
+ load-bearing half» below before crediting it.
272
+ tier2(<target-harness>) peer-simulated — the reviewer EXECUTED CODE in the TARGET's own repo
273
+ (a local clone, real content) and observed the result.
274
+ 🟥 DISCRIMINATOR — «reading the target's real files is NOT this rung».
275
+ 🟥 RETRACTED (2026-08-17): the «two blind Sonnet sims both graded a
276
+ cold-read tier2 … 0/2» measurement that stood here is WITHDRAWN —
277
+ tool_uses: 0, the agents never opened a file, so the grades and the
278
+ quoted reasoning measure nothing (fh_completed_2026-08-16.md:690).
279
+ The live re-run INVERTED it at reps=1, below this repo's reps>=3 bar.
280
+ Neither direction is established; restore no number here.
281
+ The AMBIGUITY it was cited for is still checkable WITHOUT a sim: the
282
+ earlier wording said «instantiated/ran the target's own repo», and
283
+ «ran» admits «operated within / engaged with», which a read satisfies.
284
+ That is a property of the text — read the two lines and see it.
285
+ THE TEST, and it is mechanical: **name the command you executed and
286
+ the output you observed.** Cannot name one → `tier1b`, always. An
287
+ agent that read files, however cold and however many, executed
288
+ nothing. Closes shared-body-path defects; a BARE clone cannot see
231
289
  the target's gitignored local wiring (settings, consent bindings,
232
290
  node-local state) — that gap is inherent to a clone, not a defect in
233
291
  a given run. Named exception, not a loophole: if the reviewer's own
@@ -259,6 +317,60 @@ DEGRADED_NOT_RUN did not — target was accessible, standpoint revi
259
317
  UNKNOWN did not look — applicability itself was never assessed
260
318
  ```
261
319
 
320
+ **🟥 Execution is the load-bearing half — a static standpoint read is largely subsumed by the other
321
+ axes (operator decision, 2026-08-16).** The reason to pay for a standpoint at all is not that
322
+ someone re-read the diff from a different chair; it is that **the target harness was actually made
323
+ to run.** Operator's framing, verbatim: *"그 하네스의 입장에서 정적리뷰하는 것만으로도 뭔가 잡을
324
+ 수야 있겠지만 그건 다른 검증축으로도 커버가 아마 가능하지 않을까. 진짜로 중요한 건, 그 하네스
325
+ 입장에서 돌려봐서 구동이 되는지를 로컬에서 완벽하게 확인하는 것."* A static read competes with
326
+ cross-family review (§3) and isolated grounding for the same defect classes and mostly loses —
327
+ those axes are cheaper and already routine. Execution has no substitute, because the class it
328
+ catches is *unreachable by reading*: the target's own environment differs (absent files, different
329
+ resolution order, a lane that has never once run there).
330
+
331
+ **Measured the same day this was written, on one delta (pmh-dev PR #72)**:
332
+
333
+ | Arm | Found |
334
+ |---|---|
335
+ | `tier1b` static standpoint read (isolated agent, target's own files, cold) | **1** — a 2-tier-vs-3-tier root-path resolution mismatch |
336
+ | Running the target's own `selfcheck.sh` to completion, locally | **2 more**, both invisible to any read: a test fixture keying on a file that does not exist in that repo, and an npm-shipping check whose premise is inapplicable there. One of them printed **neither `FAIL` nor `❌`** anywhere in its output (it used its own vocabulary, `INSTRUMENT ERROR`) and needed a `bash -x` trace to locate — a defect that is *structurally* undiscoverable by reading, since the reader must already know which string to look for. |
337
+
338
+ n=1 delta, same operator, same session — reported as a directional observation, not a rate. It is
339
+ recorded because it is the first time the two arms were run *separately on the same change* and
340
+ their yields could be attributed. ⚠️ **Do not read the table as "static review is worthless"** — it
341
+ found a real defect that shipped a fix. Read it as: *static is the half that has substitutes;
342
+ execution is the half that does not.*
343
+
344
+ **🟥 What dynamic standpoint review DOES and DOES NOT subsume (operator + governor, agreed
345
+ 2026-08-16 after both arms were measured).** Operator's proposal: *"FH가 기여하는 다른 레포들도 다
346
+ 마찬가지일 테니, 그쪽 입장에서의 동적 리뷰는 소넷을 상주시켜 돌려보는 거지. 이건 굳이 짓지 않아도
347
+ 동적 입장리뷰만 잘 시킨다면 알아서 커버될 거라고 생각해."* Agreed, with one boundary — and the
348
+ agreement is evidenced, not deferential:
349
+
350
+ - **SUBSUMES: building per-target instruments.** Do not write a new scanner for each contributed
351
+ repo, language, or defect class. Execution is **stack-agnostic**; an instrument is not. Measured
352
+ the same day: `degrade_direction_scan.sh` is bound to shell/python *and* to verdict vocabulary —
353
+ a faithful Python port of a real upstream defect scores CLEAN, because the fail-open value was
354
+ ordinary *data*, not a verdict token. An instrument carries a scope boundary into every repo it
355
+ visits; running the target's own suite does not.
356
+ - **DOES NOT SUBSUME: adversarial reading.** **Execution is a detector, not a generator.** It
357
+ answers *does this break · does it fire · does the environment differ*; it cannot answer *is
358
+ there a defect class nobody has instrumented yet*. The upstream `clawd-on-desk` PR #888 defect
359
+ was **not** found by running that repo's tests — it was found by reading and conceiving the
360
+ unreadable-file case, after which a test was written. And where the target ships no runnable
361
+ suite, execution has nothing to run at all.
362
+
363
+ **The measured split, same delta, same day**: static read → **1** finding · execution → **2** more.
364
+ Neither arm was zero, which is the whole result. So both run: reading generates the hypothesis,
365
+ execution confirms or refutes it, **and the hypothesis that survives becomes a test left behind in
366
+ the target** — which is exactly what our own upstream contribution did (the survivor-lane pattern,
367
+ `tracks/_meta/fh_signal_2026-08-16_clawd-survivor-lane-air.md`).
368
+
369
+ **Consequence for the marker**: a `tier2`/`tier2b`/`tier3` claim asserts that something was RUN. If
370
+ the review only read, the honest value is `tier1b` — and since `tier1b` is explicitly the weak rung,
371
+ recording it truthfully is what surfaces that the execution arm is still owed. (This rule exists
372
+ because it was broken on the day it was written: see the `tier1b` entry above.)
373
+
262
374
  **Residual this enum split names rather than hides**: for a harness pair with one shared human
263
375
  operator (this repo and a sibling field harness the same operator also runs), `tier3` is either
264
376
  unreachable or collapses into "the same author ran it in the other repo" — which is exactly the
@@ -277,6 +277,88 @@ recommended path is *simulate inside the chamber first, then emit the initial mo
277
277
  build-immediately. (Wired as a recommendation branch in `CLAUDE.md §Onboarding / Acceleration
278
278
  Autopilot`; build-immediately remains correct for clear, small, low-failure-cost projects.)
279
279
 
280
+ ### 3-c. The EMIT bar — «walks on its own» (operator-forged, 2026-08-16)
281
+
282
+ > **Relationship to §3's EMIT-worthiness criterion — two different questions, do not merge them.**
283
+ > That one screens candidates *going in*: is this worth emitting at all (net-new · artifact-shaped ·
284
+ > precision-adequate). This one judges a candidate *coming out*: is it ready to stand. A candidate can
285
+ > clear the first and fail this one (worth building, not yet alive), or clear this one and fail the
286
+ > first (alive, but a reinvention). Both are required; neither substitutes.
287
+
288
+ Until now the chamber's EMIT threshold was **implicit**, and that is why its record (9 runs,
289
+ 8 KILL, 1 EMIT) could not be read: with no stated bar, "screened well" and "over-screened" are
290
+ the same picture. An instrument whose output is almost always one value is indistinguishable
291
+ from an instrument stuck on that value — the dead-control signature this repo keeps re-finding.
292
+ The bar is therefore stated, and stated **low on purpose**:
293
+
294
+ > **A candidate EMITs when it can stand on its own — not when it is good.**
295
+ >
296
+ > ① It **runs standalone**, with no defect severe enough to prevent execution.
297
+ > ② Every necessary function **fires at least weakly**. Firing, not performing.
298
+ > ③ It is in a state where it can **fill itself in through back-and-forth with a human**.
299
+ > ④ **Weakness is not a KILL.** Only inability-to-run is.
300
+
301
+ Newborn-foal semantics: it staggers, and it is standing. Shortcomings are expected and are the
302
+ *point* — an emitted harness is raised, not delivered finished.
303
+
304
+ **The mechanical discriminator, and it is already in hand.** ② is not a judgment call, because
305
+ "fired weakly" and "did not fire" separate cleanly at the exit boundary:
306
+
307
+ ```
308
+ dead — dies before doing anything e.g. a gate that aborts on its own version line (rc=1)
309
+ alive — ran and returned a TYPED verdict e.g. the same gate returning HARNESS_ERROR (rc=10)
310
+ ```
311
+
312
+ `HARNESS_ERROR` is a *bad* result and it satisfies ②: the unit ran and said why it could not
313
+ finish. `rc=1`-before-anything is not a weak firing, it is absence. This is the same
314
+ `not found ≠ 0` line the rest of this repo runs on, applied to birth.
315
+
316
+ **Where the judgment must happen: outside the author's environment.** Measured 2026-08-16 — a
317
+ gate suite read 31/31 green in the harness that wrote it and was structurally dead in the sibling
318
+ that inherited it, because the author's repo happened to supply a file the code assumed. An EMIT
319
+ verdict rendered inside the incubator's own environment cannot see that class at all. So the EMIT
320
+ check is run the way a recipient would run it: a clean checkout, none of the author's local state,
321
+ each declared function exercised once.
322
+
323
+ **Calibration owed, not claimed.** This bar makes the chamber testable for the first time; it does
324
+ not retroactively validate the existing ledger. The 8 KILLs were decided against an unstated bar,
325
+ so whether each died on "cannot run" (correct) or on "weak" (over-screen) is **unknown from the
326
+ record**. Known-pair to run before the ledger is cited as evidence of anything: a known-positive
327
+ (a field harness the operator judges already stands on its own) must EMIT; a ledger KILL whose
328
+ recorded reason is explicitly *cannot run* must KILL. If the known-positive is KILLed, the
329
+ instrument over-screens and every prior KILL is weakened by that much.
330
+
331
+ ### 3-d. What separates incubating from boosting — the AUTHORITY, not the effort (operator, 2026-08-16)
332
+
333
+ Operator, verbatim: *"부스팅보다 인큐베이터의 장점은 그 레포 전체(또는 출하하기 전 상태의 플젝)를
334
+ FH가 감싸서 **모든 것을 만들어내고 재설계한다**에 있어. 그래서 모든 것을 빠삭히 알아야 하고,
335
+ 그러면서도 **모든 것을 조작할 수 있는 권한**이 있는 거야. 부스팅과는 다른 지점이 이것이기도 하다."*
336
+
337
+ The two identities are not «small help» vs «big help». They differ in **scope of authority over the
338
+ target**, and the two properties are a matched pair — neither is optional:
339
+
340
+ | | Ⓑ Project Booster | ② Project Incubator |
341
+ |---|---|---|
342
+ | Touches | the point that was asked about | **the whole repo — including redesigning what already works** |
343
+ | Must know | enough for that point | **the entire target, thoroughly** |
344
+ | Reads the codebase | on demand, to answer | **as a precondition, before proposing anything** |
345
+
346
+ **Why the pair is load-bearing**: total authority without total knowledge is vandalism, and total
347
+ knowledge without authority is a booster that reads a lot. An incubation session that has not read
348
+ the target's design canon, gate code, and existing verification surfaces has not *earned* the second
349
+ column — and the correct move there is to read first, not to scope down to a booster-shaped change
350
+ and call it incubation.
351
+
352
+ **Where this bit, same day**: the-bible's ⓐ run scoped itself to «invariant-preserving» — correct as
353
+ a *choice the operator made for that request*, and it was then mistaken for the identity's own reach.
354
+ It is not. ⓐ/ⓑ is the operator setting the blast radius for one job; the incubator's standing
355
+ authority is the full repo either way. A session that reads a per-request scope as the identity's
356
+ ceiling will never propose the redesign that was the point of incubating.
357
+
358
+ **Relationship to 3-a's «day one» bar**: 3-a says what the *born thing* must do. This says what the
359
+ *nursery* is allowed to do to it while it is still inside. The first is an exit condition; the second
360
+ is a working posture.
361
+
280
362
  ## 4. Compose ∪ disrupt — two operating modes over other harnesses
281
363
 
282
364
  | Mode | What | FH mechanism |
@@ -12,7 +12,7 @@ tags: [harness, terminal, cmux, orca, architecture, ergonomics, governor-pattern
12
12
  본 분석 보고서는 **AI 에이전트 하네스(Agent Harness)의 발달 수준과 터미널 환경(Multiplexer / Sandbox) 간의 상관관계 및 직교적 계층 구조**를 규명하고, 신뢰성 기반의 최적 운용 모델을 제안합니다.
13
13
 
14
14
  * **핵심 명제**: **"신뢰된 로컬 개발 환경에서는, 터미널 인프라에 의존하지 않는 얇은 하네스(Thin Harness)로 충분하다."** (전칭 «가장 뛰어난» 을 뺐다 — 비교 모집단을 잰 적이 없다)
15
- * **결론**: 에이전트 자체의 오케스트레이션 및 자가 검증(**4축 게이트** — Axis 1 `regression_guard.sh` · Axis 2 `steel-quench` · Axis 3 `phantom-quench` · Axis 4 `edit-manifest`, FH 자산 변경 시 **커밋 경계에서 훅으로 강제**)이 성숙한 환경에서는 터미널 멀티플렉서(`cmux`)를 **가벼운 UI 껍데기**로 활용하고 **거버너(Governor) 에이전트 위임 모델**을 적용하는 것이 인지 부하를 최소화합니다. 단, 비신뢰 코드 실행 및 파괴적 부작용이 수반되는 과제는 **위험도 기반 샌드박싱(Risk-Driven Sandboxing)**에 따라 **실제 커널 경계를 가진 샌드박스**(Firecracker · Kata · gVisor · Docker Sandboxes 계열)를 하부에 계층화하여 방어합니다. 🟥 초판은 이 자리에 `Orca` 를 적었고 그것은 틀렸다(§4 최종추천 2 · §명명된 잔여 1).
15
+ * **결론**: 에이전트 자체의 오케스트레이션 및 자가 검증(**4축 게이트** — Axis 1 `regression_guard.sh` · Axis 2 `steel-quench` · Axis 3 `phantom-quench` · Axis 4 `edit-manifest`, FH 자산 변경 시 커밋 경계에서 훅으로 강제 — ⚠️ **단 그 훅은 기본 활성이 아니다**: `core.hooksPath` 를 배선해야 발동하며, 갓 클론한 레포에서는 `templates/` 안의 템플릿일 뿐이다)이 성숙한 환경에서는 터미널 멀티플렉서(`cmux`)를 **가벼운 UI 껍데기**로 활용하고 **거버너(Governor) 에이전트 위임 모델**을 적용하는 것이 인지 부하를 최소화합니다. 단, 비신뢰 코드 실행 및 파괴적 부작용이 수반되는 과제는 **위험도 기반 샌드박싱(Risk-Driven Sandboxing)**에 따라 **실제 커널 경계를 가진 샌드박스**(Firecracker · Kata · gVisor · Docker Sandboxes 계열)를 하부에 계층화하여 방어합니다. 🟥 초판은 이 자리에 `Orca` 를 적었고 그것은 틀렸다(§4 최종추천 2 · §명명된 잔여 1).
16
16
 
17
17
  ---
18
18
 
@@ -20,7 +20,7 @@ tags: [harness, terminal, cmux, orca, architecture, ergonomics, governor-pattern
20
20
 
21
21
  과거 AI 에이전트 운용 초기에는 에이전트의 오탐, 환각, 호스트 파일시스템 오염을 막기 위해 **외부 인프라(터미널 멀티플렉서, 무거운 Docker/VM 샌드박스)**로 에이전트를 감싸고 통제했습니다.
22
22
 
23
- 그러나 메타 하네스(`forge-harness`) 체계가 도입되면서, 에이전트 스스로 하위 작업을 생성·위임하고, 검증(4축 게이트)과 마감 피어 동기화(`knowledge/shared/rules/multi_session_close_protocol.md` — **마감 순서와 peer 델타 append 규율**이지, 메모리 색인 락이 아니다)를 소프트웨어적 통제 레이어에서 수행할 수 있게 되었습니다.
23
+ 그러나 메타 하네스(`forge-harness`) 체계가 도입되면서, 에이전트 스스로 하위 작업을 생성·위임하고, 검증(4축 게이트)과 마감 피어 동기화(`knowledge/shared/rules/multi_session_close_protocol.md` **(FH 전용 자산 형제 하네스에는 없다. 동기화 시 dangling 참조가 된다)** — **마감 순서와 peer 델타 append 규율**이지, 메모리 색인 락이 아니다)를 소프트웨어적 통제 레이어에서 수행할 수 있게 되었습니다.
24
24
 
25
25
  이에 따라 **개발자 UX를 위한 UI 레이어(`cmux`)**, **거버넌스·오케스트레이션 레이어(`FH`)**, 그리고 **OS/커널 보안 레이어**의 역할 분담 및 선택 기준을 규정할 필요성이 제기되었습니다. 🟥 **초판은 세 번째 자리에 `Orca` 를 놓았으나 Orca 는 보안 레이어가 아니다** — Stably AI 의 멀티에이전트 오케스트레이터 데스크톱 앱이고 격리 기전이 **git worktree** 라, `cmux`·`FH` 와 **같은 층의 경쟁재**다.
26
26
 
@@ -44,7 +44,7 @@ tags: [harness, terminal, cmux, orca, architecture, ergonomics, governor-pattern
44
44
  | 비교 축 | Execution Sandbox (Firecracker · gVisor · Docker Sandboxes) | UI/오케스트레이터 (`cmux` · `Orca`) | Protocol-Native Harness (FH 거버너 위임) |
45
45
  |---|---|---|---|
46
46
  | **계층 역할** | OS/커널 레벨의 물리적 보안 및 자원 격리 | 시각적 탭/창 관리를 위한 UI 껍데기 | 지능적 오케스트레이션 및 소스 앵커링 |
47
- | **격리 범위** | 파일시스템, 네트워크 포트, 커널, CPU/RAM 쿼터 | 🟥 **«없음» 아니다** cmux 는 local / **worktree** / SSH 워크스페이스를 자체 제공한다고 공식 페이지가 밝힌다(<https://cmux.com/>, 2026-08-16 열람). ⚠️ 이는 **벤더 서술이며 격리 강도를 실측한 것이 아니다** | 서브에이전트 컨텍스트 격리 (별도 컨텍스트 윈도우·요약 반환). **worktree 는 FH 의 기본 격리 수단이 아니다** |
47
+ | **격리 범위** | 파일시스템, 네트워크 포트, 커널, CPU/RAM 쿼터 | 🟥 **«없음» 틀렸다. 다만 «worktree 격리 제공»도 과하다** 벤더 페이지(<https://cmux.com/>, 2026-08-16 열람) 확인해 주는 것은 **SSH 원격 워크스페이스 · 탭별 브랜치/작업디렉터리 · 세션 복원**이고, 오히려 *"strict worktree isolation 을 강제하기보다 동시 작업을 정리하는 데 중점"* 이라고 읽힌다. «local/worktree/SSH 격리»는 **2차 출처발**이며 벤더 페이지에서 확인되지 않았다. ⚠️ 어느 쪽이든 **격리 강도는 미실측** | 서브에이전트 컨텍스트 격리 (별도 컨텍스트 윈도우·요약 반환). **worktree 는 FH 의 기본 격리 수단이 아니다** |
48
48
  | **주요 장점** | 비신뢰 코드 실행 시 호스트 시스템 보호(완전 격리는 아니다 — MicroVM 탈출 사례가 실존한다) | 낮은 인지 오버헤드, 빠른 로컬 파일 접근 | 편향 격리(저자 추론을 못 본 채 평가), 컨텍스트 보존, 검증 게이트 |
49
49
  | **주요 단점** | 기동 오버헤드, 피어 감지 및 볼륨 바인딩 마찰 | 자원 경합 및 직접적인 호스트 부작용 무방비 | 에이전트의 거버넌스 능력 필요. 🟥 **worktree 를 쓰면 게이트가 깨진다** (아래 §3.2 주의) |
50
50
  | **선택 기준** | **비신뢰 코드, 패키지 설치, 파괴적 셸 실행** | **신뢰된 로컬 환경 (1~3개 상위 세션)** | **모든 에이전트 오케스트레이션 및 검증** |
@@ -70,8 +70,15 @@ tags: [harness, terminal, cmux, orca, architecture, ergonomics, governor-pattern
70
70
  > 🟥 **worktree 로 위임하지 마라 — 이건 FH 가 실측으로 반대하는 경로다.** `CLAUDE.md §Agent Dispatch
71
71
  > Operation` 이 정본이다: ⓐ 문서가 설치를 지시하는 **상대경로 `core.hooksPath`** 형태에서는
72
72
  > worktree 안의 훅 사본을 고치면 그 worktree 의 게이트가 무력화된다(실측 `rc=0` — 마커 없는 FH 자산
73
- > 커밋이 통과). ⓑ 그와 무관하게 **`tracks/` gitignored 라 worktree 로 따라가지 않으므로**, Axis 2–3
74
- > 마커와 Axis 4 매니페스트가 **구조적으로 부재**한다 만족시킬 없는 게이트는 우회를 훈련시킨다.
73
+ > 커밋이 통과). ⓑ 그와 무관하게 **게이트 증거가 gitignored 라 worktree 로 따라간다** 다만
74
+ > **어디까지 사라지는지는 레포마다 다르다.** 최소 공통은 **Axis 2–3 마커**이고, Axis 4 매니페스트는
75
+ > 레포-국소다. 실측(2026-08-16): FH 는 `.gitignore` 가 `tracks/**` 전면이라 **매니페스트도 사라진다**
76
+ > (`check-ignore` 히트, tracked 0). 형제 하네스 PMH 는 `tracks/*` + `!tracks/_meta/` 라
77
+ > **매니페스트가 추적되고**, 마커만 사라진다. 결론(«worktree 에서 FH 자산을 커밋하지 마라»)은 양쪽
78
+ > 모두에서 성립하지만, **그 이유를 «둘 다 부재»로 적으면 PMH 독자는 자기 레포에서 반증하고 마커
79
+ > 경고까지 같이 버린다.** 각자 확인할 것: `git check-ignore -v tracks/_meta/edit_manifest.yaml`.
80
+ > 🟥 **이 문단은 PMH 입장리뷰가 정정했다** — FH 안에서 읽으면 보편 명제로 보이고, 입장을 바꿔야
81
+ > 국소성이 드러난다. 계열 다양성(codex)은 같은 레포 안에서 읽으므로 이 클래스를 못 잡았다.
75
82
  > ⇒ **FH 자산 커밋은 표준 세션에서 한다.** worktree 는 «자율 하위 격리»의 수단이 아니라 게이트 무결성
76
83
  > 위험이며, 이 문서의 초판은 그것을 강점으로 서술했다(임포트 심사에서 정정).
77
84
 
@@ -96,9 +103,23 @@ graph TD
96
103
 
97
104
  ## 4. 위험도 기반 샌드박싱 의사결정 트리 (Risk-Driven Decision Tree)
98
105
 
106
+ 🟥 **초판 트리에는 뿌리 분기가 «비신뢰 코드인가» 하나뿐이었고, 그건 개인 머신 입장에서만 충분하다.**
107
+ residency 가 걸린 환경(조직 내부·규제·고객 데이터)에서는 **평범한 작업이 전부 그 분기에서 NO 로 떨어져**
108
+ «얇은 하네스 + UI 층» 으로 직행한다 — 정작 그 환경의 구속조건은 코드 신뢰도가 아니라 **데이터 유출**
109
+ 인데도. 형제 하네스 입장리뷰가 지목했고, 뿌리 분기를 하나 앞에 세운다.
110
+
99
111
  ```
100
112
  [ 새로운 작업 오더 ]
101
113
 
114
+ Is the data residency-bound? ← 신설 (입장리뷰)
115
+ (조직 내부·고객·규제 데이터가 관여하는가)
116
+
117
+ ┌────────────┴────────────┐
118
+ YES NO
119
+ │ │
120
+ [ 환경 승인 도구만 · 도구의 telemetry· │
121
+ 상태파일 기록 표면을 먼저 실측 ] │
122
+
102
123
  Is Execution Dangerous / Untrusted?
103
124
  (비신뢰 코드, 외부 패키지, 파괴적 셸)
104
125
 
@@ -120,7 +141,9 @@ graph TD
120
141
  ### 최종 요약 추천
121
142
  1. **신뢰된 로컬 환경 (Trusted Local Setup)**: **`Meta-Harness (forge-harness) + cmux` (가벼운 UI 껍데기 1~3개 탭)**
122
143
  * 메타 하네스가 자가 검증(4축 게이트)과 거버너 오케스트레이션, 서브에이전트 **컨텍스트 격리**를 수행하므로, 인프라 오버헤드가 없는 `cmux` 를 **잠정 권고**합니다(이 운영자 구성에서의 판단, n=1 · cmux 미실측). 여기서 "Thin Harness"는 인프라 샌드박스 대비 소프트웨어 프로토콜 중심이라는 최소 기준을 의미하며, `forge-harness`는 이 계층의 최상위 메타 하네스로 작동합니다.
123
- * ⚠️ **범위 한정**: `cmux` **macOS 전용 네이티브 앱**이다. FH 지식본은 크로스플랫폼이므로 권고는 macOS 노드에만 적용되며, 리눅스/윈도우 노드의 UI 층 선택은 이 문서가 다루지 않는다(미조사).
144
+ * ⚠️ **범위 한정 OS**: 벤더 페이지 기준(2026-08-16) **배포되는 빌드는 Mac 이고 그 외 플랫폼은 waitlist** 다 — «macOS 전용 설계»가 아니라 «현재 Mac 출시»가 정확한 서술이다(초판·1차 정정 모두 이걸 «전용»으로 단정했다). 리눅스/윈도우 노드의 UI 층 선택은 다루지 않는다(미조사).
145
+ * ⚠️ **범위 한정 ② 런타임**: Claude Code 세션을 전제한다. 다른 런타임(OpenCode 등)에서의 적합성은 **판단 불가 — 조사한 적 없다.**
146
+ * 🟥 **범위 한정 ③ residency — 이 문서의 자기모순이었다.** 초판은 §5 에서 **이전 도구가 프롬프트 원문·툴콜을 로컬 상태파일에 기록하더라는 것을 residency 표면으로 지목해 놓고**, 바로 그 다음 절에서 새 UI 층을 **동일 점검 없이** 권고했다. UI 층은 **그 세션의 모든 프롬프트를 보는 구성요소**다. ⇒ **residency 가 걸린 노드에서는 도입 전에 telemetry·상태파일 기록 표면을 실측하고 승인받는다**(§5 와 같은 점검). «macOS 전용»은 맞는 단서지만 **틀린 축의 단서**였다 — 입장리뷰가 지목.
124
147
  2. **비신뢰 및 파괴적 과제 (Untrusted Execution)**: **실제 커널/하이퍼바이저 샌드박스** — Firecracker · Kata Containers · gVisor · Docker Sandboxes 계열
125
148
  * 파괴적 셸 명령, 비신뢰 외부 코드 실행 시에는 커널 경계를 가진 샌드박스를 하부에 배치해 호스트 노출을 크게 줄입니다(«완벽»이 아니다 — 커널/하이퍼바이저 탈출은 실존하는 위협 클래스다).
126
149
  * 🟥 **초판은 여기에 `Orca` 를 «물리 샌드박스»로 적었고 그건 틀렸다. 이 정정이 이 문서에서 가장
@@ -188,6 +211,18 @@ graph TD
188
211
  현재 방어선은 파일 소유 분리라는 *규율*뿐이다.
189
212
  5. **부록의 심사 이력은 저자 런타임 자기신고**이며 재현 불가하다(아래 부록 자체 주석 참조).
190
213
  6. **표본 n=1** — 단일 운영자·단일 머신 구성에서의 판단이다.
214
+ 7. **형제 하네스가 아직 옛 입장을 들고 있다.** PMH 정본(`CLAUDE.md` 상주층)은 «에이전트뷰 기본
215
+ 운용»을 선언하고 있어, 이 문서 §3.2 와 **정면으로 모순**된다. 이 문서를 동기화하면 그쪽에
216
+ 상충하는 상주 지시가 둘 생기고 tiebreaker 가 없다. ⇒ **문서만 옮기지 말고 그쪽 정본의
217
+ carve-out 을 같은 변경에서 처리해야 한다.** 이 PR 범위 밖이며 미해결.
218
+ 8. **런타임 범위 미조사** — cmux × 비-Claude-Code 런타임 조합은 판단하지 않았다.
219
+ 9. **외부 1차 출처가 레포에 스냅샷되어 있지 않다.** Orca·cmux 인용은 열람일만 기록돼 있고
220
+ 본문 스냅샷·커밋해시·아카이브 링크가 없다. 이 레포만 받은 사람은 **정정의 근거를 확인할 수
221
+ 없다** — 초판이 틀렸다는 것도, 정정판이 맞다는 것도. (fresh-clone arm 지목)
222
+ 10. **게이트 강제는 배선 조건부다.** `core.hooksPath` 미배선 클론에서는 훅이 `templates/` 안
223
+ 템플릿일 뿐이고 아무것도 막지 않는다. 초판 요약은 이를 무조건적 기계 사실로 적었다.
224
+ 11. **§5 는 이 레포 안에서 검증 불가다** — 4행 «2026-07-12 실측» 표와 인용된 운영자 결론의
225
+ 출처가 전부 비공개 저장소에 있다. 라벨은 붙었으나 그건 갭을 드러낼 뿐 닫지 않는다.
191
226
 
192
227
  ---
193
228
 
@@ -207,8 +242,14 @@ graph TD
207
242
  > 🟥 **이 부록 전체의 지위**: 저자 런타임의 **자기신고**이며, 위 «잔여 0건»·«PASS» 는 아티팩트로
208
243
  > 뒷받침되지 않는다. FH 자기 규율상 이것은 증거가 아니라 저자의 주장이다
209
244
  > (`fh_4axis_gate.md §Reviewer-visible evidence` 의 degrade 라벨을 그대로 적용).
210
- > **이 문서에 대한 재현 가능한 심사는 임포트 시점의 4축 게이트 기록**이며,델타는
211
- > 부록이 아니라 커밋 이력과 `tracks/_meta/edit_manifest.yaml` 2026-08-16 항목에 있다.
245
+ > **이 문서에 대한 심사는 임포트 시점의 4축 게이트에서 이뤄졌다.** 🟥 **그런데 기록을 «커밋
246
+ > 이력과 `tracks/_meta/edit_manifest.yaml` 있다»고 가리키는 것은, 이 레포를 받는 사람에게는
247
+ > 죽은 포인터다** — `tracks/**` 가 gitignored 라 매니페스트도 마커도 **공개 레포에 애초에 실리지
248
+ > 않는다.** fresh-clone 입장 arm 이 지목했다: 부록의 자기신고를 «증거 아님»으로 강등해 놓고, 그
249
+ > 대체물로 **수령자에게 구조적으로 비어 있는 곳**을 가리켰다. 즉 **강등만 참이고 대체는 거짓**이었다.
250
+ > ⇒ 리뷰어가 실제로 닿을 수 있는 것은 **PR 본문의 증거 캡슐**(PR #402)과 이 파일의 커밋 메시지뿐이며,
251
+ > 마커·매니페스트는 저자 머신에만 존재한다. 이것은 `fh_4axis_gate.md §Reviewer-visible evidence`
252
+ > 가 이미 명명한 구조적 갭이고, 여기서 닫히지 않는다.
212
253
 
213
254
  ---
214
255
  *Authored by an Antigravity (Gemini-family) runtime, 2026-08-15; imported into the FH Knowledge Core and reviewed under the 4-axis gate on 2026-08-16.*
@@ -279,6 +279,7 @@ unchanged and keeps its own 2026-07-14 evidence).
279
279
 
280
280
  | # | Identity | Engines it loads | Status | Evidence / what's missing |
281
281
  |---|---|---|---|---|
282
+ | **Ⓑ** | **프로젝트 부스터** (booster) — 🟥 **다른 다섯과 같은 층이 아니다. 포괄 기능이되 ①②⑤ 를 «포함»하지 않고 «끌어다 쓴다» — 셋 다 부스팅 밖의 고유 범위를 갖는다** — 번호 대신 Ⓑ 를 쓰는 이유이자 §Ⓑ-layering 을 먼저 읽어야 하는 이유 | judgment-circuit + ship-gate | 🟢 **GREEN (신설 2026-08-16)** | **이 행이 없던 것이 이 표의 맹점이었다.** 온보딩 문 ③(«매핑 프로젝트 가속»)이 오래전부터 이 기능을 팔고 있었는데 등급표에 대응 행이 없었다 — 그래서 부스터는 **한 번도 등급이 매겨진 적이 없고, 약점이 발견될 자리도 없었다.** 미할당 기능은 미감사 기능이다. **인접 세 행이 이걸 안 덮는다**: ②는 *새 하네스를 낳고*(성숙한 하네스는 대상 아님), ⑤는 *사람의 의도*를 벼리고(증폭 대상이 하네스가 아니다), ①은 남의 능력을 *FH 가* 쓴다(활용 ∪ 흡수 — 둘 다 FH 가 이득 보는 방향). 부스터는 **FH 의 기계가 상대 하네스의 자체 개발을 가속하는 것**이라 셋 다와 방향이 다르다. **실적(운영자 열거 + 실측)**: pmh 는 *이 경로에서 출발했다* · mate 스킬 출하 + 인프라 배선 · 조직 환경 2건(품질 게이트 인프라 이식, 자산명은 residency 로 미기재) · clawd-on-desk · gstack. **Dominance — §Gate consequence 를 면제 없이 그대로 만족한다.** 경쟁자 = *그 하네스 자신의 개발 과정*, 결과 = 그 과정이 놓친 것을 부스팅이 잡았다: ⑴ **gstack**(외부·운영자 통제 밖) — 이슈 #1890 을 외부인 자격으로 제기, 그 레포 오너가 수정하고 **회귀 테스트 `test/claude-provider-keychain.test.ts` 로 못 박아 릴리스에 실었다**(2026-08-15). 채택 판정이 **우리가 아니라 그쪽 메인테이너**라 자기채점이 아니다. ⑵ **pmh**(2026-08-16 실측) — 이식된 자산이 대상 환경에서 **게이트가 죽은 채** 있었고 selfcheck 35 FAIL 이 CI 부재로 몇 달간 안 보였다; 부스팅 경로가 그걸 드러내고 31/31·35→2 로 닫았다. ①이 받은 dominance 면제는 **이 행에 필요하지 않다** — ①은 산출이 «안 지어도 됐다»라 겨냥이 틀렸던 경우고, 부스터의 산출은 «상대가 못 잡던 걸 잡았다»라 이 절의 정의에 그대로 맞는다. 🟥 **명시 잔여 — 초록 행의 잔여이지 보류 사유가 아니다**(①이 «(d) 안 닫힘»을 안고 🟢인 것과 같은 처리): **부스팅이 이식한 자산이 대상 환경에서 실제로 발화하는지 재는 계기가 없었다.** 2026-08-16 pmh 실측이 그 대가다 — 한 줄(`set -euo pipefail` 아래 `package.json` 읽는 할당문)이 게이트를 즉사시켰고, 30레인 회귀 스위트가 그걸 30번 보고하는데 **아무도 안 봤다**(그 레포에 CI 가 없었으므로). 승급이 아니라 **이 행의 첫 승급 기준**이 거기서 나온다(아래). ⚠️ n 은 세지 않는다 — 실적 열거는 운영자 증언 + 오늘 실측 2건이고, 조직 환경 2건은 이 파일에서 검증 불가(residency)이므로 **증언으로 표기하고 측정으로 세지 않는다** |
282
283
  | ③ | 거버넌스 게이트 (governance) | ship-gate | 🟢 GREEN | pre-commit/pre-push physically block; moat measured 3–4 family blind (HITL 8/8 ABSENT); cross-family caught a real companion-store-name leak 2026-07-14 (fail-closed) |
283
284
  | ⑤ | 증폭자 (amplifier) | judgment-circuit | 🟢 GREEN | short-intent→literature-grounding→ultimate-doc real instances; rules-diet −18.2k measured; intent-routing probe 94% (below) |
284
285
  | ④ | 프런티어→조직 전파 (**🔵 RC, 2026-08-09**) | external-grounding | 🔵 RC | frontier-digest launchd auto + AX submission docs both real, but digest→org never closed as ONE pipeline. **2026-08-09**: the missing link was built — `scripts/digest_landing_check.sh` extracts the digest's candidate table into probes and reuses the existing landing checker (no second verifier). Self-test 8 lanes green. **🔵 RC (2026-08-09)**: the mtime defect that initially held it back is closed — the since-filter now splits two axes (git-tracked → commit time via `git log --since`; gitignored `tracks/**` → mtime, the only evidence that axis has; dirty-tracked → `UNMEASURED`), and **two lanes pin that split**: a file with only a fresh mtime is *not* counted, and a file with only a fresh commit *is* counted even when its mtime is stale. The second lane matters — without it the fix degenerates into "discard all tracked files so only negatives pass" (named by the cross-family reviewer). Self-test **10 lanes** green. **What remains is a named residual, not a calibration gap**: `file-change ≠ token-introduction` — a file committed after the digest may carry the token from before (closing it needs token-level diff, which does not fit the checker's interface). The instrument therefore prints, and this row states, that it is a **screener, not an adjudicator**: hits must be opened. Four real runs, four hand-verifications, four defects found |
@@ -286,6 +287,154 @@ unchanged and keeps its own 2026-07-14 evidence).
286
287
  | ② | 프로젝트 인큐베이터 (**🔵 RC, 2026-08-09**) | context-continuity + judgment-circuit | 🔵 RC | **RC 세 다리가 섰다** — (a) 구현: `chamber_run.sh` 6단계 게이트 (b) known-pair: 러너 게이트 **18 레인**(`test_chamber_run_lanes.sh`, BLOCK/PASS 대칭 — PASS arm 이 있어야 "전부 막는 게이트"도 걸린다) + 순서 증인 **16 레인**(`chamber_witness.sh`) (c) self-test 초록. **실상황 발화 대기 = formal chamber EMIT 아직 0** — 그것이 RC 가 🟢 이 아닌 이유이자 RC 정의 그 자체다. ⚠️ **그 0 의 해석이 2026-08-09 에 바뀌었다**: 지금까지 *"챔버가 엄격해서"* 로 읽었으나, KILL 된 후보 다수가 **메타-형** 이고 유일한 EMIT(`forge-wiki`)만 **필드-형** 이다 — 즉 *낳을 수 없었던* 게 아니라 **애초에 대상이 아닌 후보가 들어왔을** 가능성이 있다. 필드 ⊥ 메타 프로파일과 씨앗(precocial) 기준 정의: `harness_incubator_doctrine.md §3-a`. ⚠️ 그 분류는 **사후에 이뤄졌고 n=9** 라 가설이다 — 사전 등록 후 다음 런을 예측해야 결과가 된다. 아래 옛 판정 줄은 이력으로 남긴다 |
287
288
  | ②-old | (이력) 프로젝트 인큐베이터 | context-continuity + judgment-circuit | 🟡 PARTIAL | incubation is running — **stockbattle is being incubated now** (S1 built, mid-flight) + qasp/pmh spin-out precedent + scaffold-emit shipped (doctrine: "emit shipped today as scaffold+approval; the chamber flow is the named target"). **Corrected 2026-08-08** (the old text read "6 runs, 6 KILL … 0/6", which was stale on both counts, and the ledger itself was missing a run): hand-counted from `tracks/_chamber/INDEX.md` — **9 full runs (#2–#10), 8 KILL, 1 EMIT** (#1 is a trigger probe, not a full run). Runs #5–#6 *measured* the emit-worthiness criterion (net-new ∧ artifact-shaped ∧ real-data-precision-adequate ∧ hub-state-independent); run #6 confirmed the graduation-order principle — hub-internal proof before standalone extraction, never the reverse. **The 🟡 is now held for a different reason than before.** The old reason ("no closed emit-via-incubation yet") is false: run #9 `forge-wiki` emitted and shipped publicly under operator approval with the Pre-Publish gate passed. What is *not* proven is that the **formal chamber flow** produced it — that run's workspace holds only an `EMISSION_VERDICT.md`, with no `INTENT.md`, `BUDGET.md` or `SIM_NOTES.md`, so the intent/budget/blind-persona gates have no artifact and the verdict was written after the fact. The first run to complete the formal flow end-to-end is #10 (2026-08-08, 3 blind isolated personas) and it KILLed. So: **the identity has fired once, the mechanism has not yet been shown to be what fired it**, and the dominance result every 🟢 owes is still outstanding → 🟡 |
288
289
 
290
+ ### <a name="b-layering"></a>§Ⓑ-layering — **프로젝트 부스터**는 여섯 번째 행이 아니라 **다른 층**이다 (운영자, 2026-08-16)
291
+
292
+ > 🟥 **먼저 — 이 절을 위계도로 읽지 마라. 이 표는 분류학이 아니라 재고 목록이다.**
293
+ > 운영자(2026-08-16): *"사실 계층구조로 지으면 5대 정체성은 **서로를 먹고 먹지만**, 그럼에도
294
+ > 정체성을 두는 이유는 **여기에 뭐가 있는지를 볼 수 있게** 하기 위함이야. 실제로는 유기적으로
295
+ > 서로 연결되고 조합하여 사용해내게 되는 거지."*
296
+ >
297
+ > 아래 관계 서술은 **«무엇이 무엇 밑이다»를 굳히려는 게 아니라, 각 행이 서로 다른 범위를 갖는다는
298
+ > 증거**다. 관계를 정밀화할수록 표는 실제 사용과 멀어진다 — 현장에서는 한 작업이 ①⑤ 를 같이
299
+ > 태우고 그 결과가 ② 로 흐른다. **정합한 위계를 못 그리는 것은 이 표의 결함이 아니다.**
300
+ >
301
+ > ⇒ 그래서 Ⓑ 부재의 비용도 «위계가 틀렸다»가 아니다. **목록에 없어서 안 보였고, 안 보이니 감사가
302
+ > 물을 수 없었다** — 그게 전부이고, 그거면 충분히 비싸다.
303
+
304
+ 이 항목의 초판은 부스터를 «⑥» 으로, 즉 나머지 다섯과 **나란한 여섯 번째 정체성**으로 적었다.
305
+ 운영자가 그걸 정정했다: *"증폭자, 하네스클러스터 이 두 개가 사실 부스팅을 위한 **과정적
306
+ 정체성**인데 부스터는 **포괄적 기능**이라고 보는 게 맞을지도 모르겠다"* · *"인큐베이터도
307
+ 비슷한 것 같네."*
308
+
309
+ 🟥 **그리고 그 정정의 초판도 과했다 — 운영자가 같은 자리에서 두 번 고쳤다.** 초판은 위 문장을
310
+ «Ⓑ 가 ①②⑤ 를 **포함**한다»로 옮겨 적었는데, 운영자가 되물었다: *"증폭자는 하네스를 부스팅하기
311
+ 위한 것뿐만이 아니라 **훨씬 범용적으로** 쓸 수 있는 거 아닌가?"* 맞다. 그리고 같은 잣대를 나머지
312
+ 둘에 대면 셋 다 포함관계가 아니다:
313
+
314
+ | 행 | 부스팅 밖의 범위 | 그래서 |
315
+ |---|---|---|
316
+ | ⑤ 증폭자 | **사람의 의도** 전반. `CLAUDE.md §Intent Marshaling` 이 하네스가 전혀 안 끼는 일반 작업(문서·리서치·정리)까지 명시적으로 이 아래 둔다 | Ⓑ 보다 **넓다** |
317
+ | ① 하네스 클러스터 | 남의 능력을 **FH 가** 써서 FH 가 안 짓는다 — 수혜자가 FH 다 | Ⓑ 와 **방향이 반대** |
318
+ | ② 프로젝트 인큐베이터 | **유닛을 낳는다 — 하네스만이 아니다.** 「프로젝트」는 더 큰 틀로 고른 이름이고 범위가 **하네스 · 스킬 · 에이전트 · 하네스 형태가 아닌 일반 레포**까지다(운영자, 2026-08-16). 부스팅은 낳은 뒤에 온다 | **순차**지 종속이 아니다 |
319
+
320
+ ⇒ **관계는 «포함»이 아니라 «끌어다 쓴다»(uses)** 다.
321
+
322
+ ```
323
+ Ⓑ 프로젝트 부스터 ← 포괄 기능이되, 셋을 소유하지 않는다
324
+ ↑ 끌어다 쓴다 (uses, not contains)
325
+ ⑤ 증폭자 · ① 하네스 클러스터 · ② 프로젝트 인큐베이터
326
+ — 각자 부스팅 밖의 고유 범위를 갖는다 (위 표)
327
+ ② 의 산출 유닛 = 하네스 · 스킬 · 에이전트 · 일반 프로젝트 레포
328
+ ```
329
+
330
+ 이 구분이 실질을 바꾼다: 포함이면 ①②⑤ 의 등급이 Ⓑ 의 등급에 종속되고, **끌어다 쓰는 관계면
331
+ 각 행이 자기 승급 기준을 그대로 진다.** 후자가 맞고, 그래서 Ⓑ 신설이 다른 행의 등급을 하나도
332
+ 건드리지 않는다.
333
+
334
+ **이게 왜 «행이 없었나»를 설명한다.** 부스터는 다섯과 같은 층에 없었으므로 다섯을 아무리
335
+ 들여다봐도 나오지 않는다 — 빠진 게 아니라 **층이 하나 접혀 있었다.** 다섯은 각각 자기 자리에서
336
+ 감사됐고, **그것들을 무엇에 쓰고 있었는지**는 표에 적힌 적이 없다.
337
+
338
+ 🟥 **그리고 «왜 아무도 안 적었나»의 답은 «빠뜨렸다»가 아니다.** 운영자: *"부스터가 비워져
339
+ 있던 이유는 사실 FH 자체의 **너무나도 당연한 기본 정체성**이었기 때문이야. 가장 근원적인 것.
340
+ 계속 **숨쉬듯이** 해왔으니까. 그 위에 5개 정체성이 서게 되었는데."*
341
+
342
+ 이건 흔한 사각과 **방향이 반대다.** 보통 놓치는 것은 드물고 눈에 안 띄는 것인데, 이것은
343
+ **항상 하고 있어서 안 보였다.** 사람은 자기가 끊임없이 하는 일을 명제로 적지 않는다 — 적을
344
+ 이유를 못 느끼기 때문이고, 그래서 **가장 근원적인 항목이 가장 늦게 문서화된다.**
345
+
346
+ ⇒ 이 표에 대한 진단 질문이 하나 생긴다: **«우리가 매일 하고 있는데 여기 적혀 있지 않은 것은
347
+ 무엇인가»** — 없는 것을 찾는 게 아니라 **있는데 너무 흔해서 안 세는 것**을 찾는 물음이다.
348
+ `[[feedback_reinvention_reflex_normalization_counterweight]]` 의 사촌이되 반대 극이다: 저쪽은
349
+ 낯선 것을 익숙한 것으로 접는 반사고, 이쪽은 **익숙한 것을 아예 항목으로 세지 않는 반사**다.
350
+
351
+ **난이도 순서가 등급을 설명한다(정합성 확인).** 운영자: *"인큐베이터는 이 부스팅보다
352
+ 어렵기에(**없는 걸 만드는 자리니까**) 초록이 되기까지 오래 걸린 거였고."* ⇒ 있는 것을 빠르게
353
+ 하는 일(Ⓑ) < 없는 것을 만드는 일(②). 그러므로 **Ⓑ 가 🟢 이고 ② 가 🔵 RC 인 것은 이상이
354
+ 아니라 예상되는 순서다.** 만약 반대였다면 둘 중 하나의 등급을 의심해야 했다.
355
+
356
+ **명명이 평행한 것은 우연이 아니다 — 두 행의 유닛 범위가 같기 때문이다(운영자, 2026-08-16).**
357
+ ② 가 「하네스 인큐베이터」가 아니라 **「프로젝트 인큐베이터」**인 이유가 *"하네스를 인큐베이팅하기
358
+ 위한 것도 있지만 **스킬이나 에이전트도** 인큐베이팅하기 위해 더 큰 틀로 프로젝트라 명명한 것"*
359
+ 이고, *"하네스 형태가 아니더라도 **프로젝트 레포**를 만들어 줄 수도 있"*다. 부스터도 같은 범위를
360
+ 다루므로 **「프로젝트 부스터」**다. 초판이 「하네스 부스터」로 적은 것은 ② 를 「하네스를 낳는다」로
361
+ 좁게 적은 것과 **같은 실수**이며, 같은 자리에서 두 번 났다.
362
+
363
+ ```
364
+ 유닛 난이도 사다리 (두 행 공통)
365
+ 일반 프로젝트 레포 < 스킬 < 에이전트 < 하네스
366
+ ↑ 쉽다 ↑ 가장 어렵다
367
+ ```
368
+
369
+ **⇒ 등급 판정 규칙(운영자): «하네스까지 도달해 있으면 이미 초록이다».** 하네스가 사다리 꼭대기라
370
+ 거기 닿았다는 것은 아래 단계를 이미 통과했다는 뜻이다.
371
+ 🟥 **이 사다리는 «하네스까지 할 수 있습니다»이지 «하네스만 가능하다»가 아니다**(운영자, 2026-08-16).
372
+ 포함 관계이지 배타가 아니다 — 하네스에 도달하려면 **그 전까지의 모든 것이 가능해야** 하므로,
373
+ 꼭대기 칸의 실적은 아래 칸들의 실적을 **함께 주장한다**. 그래서 Ⓑ 의 🟢 은 «하네스를 부스팅한다»가
374
+ 아니라 **«일반 레포부터 하네스까지 부스팅한다»**로 읽어야 하고, 반대로 아래 칸 실적만 있는 상태를
375
+ 꼭대기 실적으로 올려 읽어서도 안 된다. 이 자로 두 행을 같이 재면 현재 등급이
376
+ 설명된다 — **Ⓑ 는 하네스 급 대상(pmh · gstack · mate)에서 실적이 있어 🟢**, **② 는 유일한 EMIT 이
377
+ 사다리의 아래쪽 유닛이라 아직 🔵**. 두 행이 다른 등급인 것은 서로 다른 잣대를 써서가 아니라
378
+ **같은 사다리의 다른 칸에 도달했기 때문**이다.
379
+
380
+ **기전(운영자 비유)**: *"실무자도 사회초년생을 가르치는 자보다 **3년 이상 실무한 사람을 옆에서
381
+ 부스팅**해주는 게 훨씬 쉬운 것과 마찬가지."* 3년차에게는 이미 판단·맥락·도는 루프가 있어
382
+ **지렛대를 대면 된다**. 신입에게는 그 엔진 자체를 **만들어 줘야** 한다. 부스터는 전자, 인큐베이터는
383
+ 후자다.
384
+
385
+ 🟥 **그래서 이 행이 실제로 주장하는 범위는 좁게 적어야 한다.** 부스터의 난이도는 **대상의
386
+ 성숙도에 반비례**하고, 위 실적의 대상은 **전부 이미 도는 개발 과정을 가진 하네스**였다(pmh ·
387
+ gstack · mate · 조직 환경 2건 — 어느 것도 무에서 시작하지 않았다). 그러니 이 🟢 은 «성숙한
388
+ 엔진에 지렛대를 댔다»에 대한 초록이지 «무에서 길렀다»에 대한 초록이 아니다 — 후자는 ②의
389
+ 자리이고 ②는 아직 🔵 다.
390
+ ⇒ 승급 기준 4로 승격: **실적을 셀 때 대상의 성숙도를 같이 기록한다.** 안 그러면 «하네스 6개를
391
+ 부스팅했다»가 «도는 엔진 6개를 가속했다»와 «6개를 무에서 길렀다» 사이에서 **어느 쪽인지 모르는
392
+ 숫자**가 된다. 지금까지의 실적은 전부 전자이며, 그렇게 적는다.
393
+
394
+ ⚠️ **③ 과 ④ 는 이 아래로 넣지 않았다 — 운영자가 그 둘을 말하지 않았고, 내가 대신 정할 일이
395
+ 아니다.** 잠정 관찰만 남긴다: ③ 거버넌스 게이트는 부스팅을 *포함한* 모든 행위가 통과하는
396
+ 품질 바닥이라 하위라기보다 **직교**로 보이고, ④ 프런티어→조직 전파는 대상이 하네스가 아니라
397
+ 조직이라 **다른 축**일 수 있다. 둘 다 운영자 판단 대기이며, 그때까지 이 표에서 위치를
398
+ 바꾸지 않는다.
399
+
400
+ ⚠️ 그리고 **계보와 포함은 다른 관계다.** 운영자는 별도로 *"부스터로부터 모든 정체성이
401
+ 발아했다"* 고도 말했는데, 그건 «부스터가 나머지를 포함한다»가 아니라 **«나머지가 거기서
402
+ 나왔다»**다. 씨앗이 나무를 포함하지 않는다 — 각 행은 자기 승급 기준을 그대로 진다.
403
+
404
+ ### §Ⓑ-genealogy — 그리고 계보상으로도 **첫 번째**다 (운영자, 2026-08-16)
405
+
406
+ 운영자 원문: *"부스터로부터 모든 정체성이 발아했다고 보면 될 정도임."* 이 행이 표에 **늦게 추가된
407
+ 것**은 발견 순서이지 계보의 순서가 아니다. 나머지 행들이 전제하는 것을 보면 이유가 보인다:
408
+
409
+ - **① 하네스 클러스터**는 *클러스터할 남의 하네스가 존재하고 연결돼 있어야* 성립한다. 그 하네스들이
410
+ 존재하고 연결된 경위가 부스팅이다. pmh 는 이 경로에서 **출발했다**.
411
+ - **② 인큐베이터**가 방출한 것은 방출로 끝나지 않는다 — 길러진다. 그 기르는 행위가 부스팅이다.
412
+ - **⑤ 증폭자**는 사람의 의도를 벼리고, 부스터는 그렇게 벼려진 것을 **다른 하네스에 실어 나른다**.
413
+
414
+ 🟥 **그래서 이 행의 부재가 비쌌다.** 등급표는 FH 가 자기를 감사하는 계기인데, 계보상 첫 번째인 기능에
415
+ 행이 없으면 그 기능은 매 감사에서 **구조적으로 시야 밖**이다. 2026-08-16 pmh 실측(이식 자산이 대상
416
+ 환경에서 죽어 있었고 몇 달간 안 보였음)은 그 사각의 청구서다.
417
+
418
+ ⚠️ **여기서 «모든 정체성이 부스터에서 나왔다»를 «부스터가 나머지를 포함한다»로 읽지 마라.** 계보와
419
+ 포함은 다른 관계다. 씨앗이 나무를 포함하지 않는다 — 각 행은 자기 승급 기준을 그대로 진다.
420
+
421
+ ### §Ⓑ promotion criteria — 이 행이 지킬 것
422
+
423
+ 🟢 로 신설됐으므로 이 절은 «어떻게 올라가나»가 아니라 **«무엇이 이 행을 내릴 수 있나»**를 적는다.
424
+ 잔여가 닫히는 조건이자, 다음 감사가 이 행에 물어야 할 질문이다.
425
+
426
+ 1. **이식 발화 검사 (핵심 잔여, 미구축).** 부스팅이 대상 하네스에 자산을 이식했을 때, 그 자산이
427
+ **대상 환경에서 실제로 발화하는가**를 재는 계기가 없다. 2026-08-16 의 실패 형태가 정본이다:
428
+ 저자 레포에는 있고 대상 레포에는 없는 전제(여기서는 npm 표면)를 자산이 조용히 깔고 있었고,
429
+ **저자 환경에서는 31/31 초록**이었다. ⇒ 판정은 **대상 환경에서** 이뤄져야 한다. 판별선은
430
+ `harness_incubator_doctrine.md §3-b` 의 것을 그대로 쓴다 — **«아무것도 하기 전에 죽는다»(rc=1)**
431
+ 와 **«돌았고 타입 있는 verdict 를 낸다»(HARNESS_ERROR)** 는 다른 상태다.
432
+ 2. **가속과 오염을 가른다.** 부스팅은 **자산을 이식하는 행위**라, 이식되는 것에는 저자 하네스의
433
+ 결함도 같이 실린다. 이 행의 실적은 «몇 개를 이식했나»가 아니라 «이식된 것이 **거기서** 도나»로
434
+ 센다. 전자는 활동량이고 후자만 결과다.
435
+ 3. **조직 환경 실적은 증언으로 남고 측정으로 세지 않는다.** residency 때문에 이 파일에서 검증할 수
436
+ 없고, 검증 못 하는 것을 숫자에 넣으면 그 숫자 전체가 못 쓰게 된다.
437
+
289
438
  ### ② promotion criteria — and what the criteria themselves turned out not to be able to check
290
439
 
291
440
  ②'s 🟡 has been re-argued on different grounds each round, every round re-deriving the bar from scratch.
@@ -318,7 +467,62 @@ unreachable condition, which is the shape that trains people to delete the thing
318
467
 
319
468
  | | Condition | Check class | Status |
320
469
  |---|---|---|---|
321
- | **P1** | An EMIT run leaves an ordering record that does not depend on trusting the author — the intent/budget/sim record committed, hashed, or otherwise witnessed **outside** the gitignored workspace, before the verdict | mandatory-pass | **channel now exists (2026-08-08)** — `scripts/chamber_witness.sh`, wired into `chamber_run.sh` steps 2–5. **Still unsatisfied**: no run holds a witness yet |
470
+ | **P1** | An EMIT run leaves an ordering record that does not depend on trusting the author — the intent/budget/sim record committed, hashed, or otherwise witnessed **outside** the gitignored workspace, before the verdict | mandatory-pass | **channel exists (2026-08-08)** — `scripts/chamber_witness.sh`, wired into `chamber_run.sh` steps 2–5. 🟥 **and it was UNSATISFIABLE until 2026-08-17 — by construction, not by strictness.** See §P1-2026-08-17 below. **Still unsatisfied**: no run holds a witness yet |
471
+
472
+ <a name="p1-20260817"></a>
473
+ **§P1-2026-08-17 — 첫 형식 완주가 이 조건이 «도달 불가능»이었음을 실측했다. 수리했고, 그 사실을 남긴다.**
474
+
475
+ 챔버 런 **#11**(`persona-simulator-harness`, KILL)은 이 채널을 **처음으로 끝까지** 태운 런이다.
476
+ 그리고 완주하자마자 `verify` 가 **`TAMPERED — 증인 무효`** 를 냈다. 기전은 추측이 아니라 코드다:
477
+
478
+ ```
479
+ step 3 BUDGET.md(ESTIMATE)의 해시를 증인 원장에 기록 ← 사전등록 증인
480
+ step 5 verdict 기록
481
+ step 6 BUDGET.md 에 ^ACTUAL: 을 요구하며 하드 차단(exit 1) ← 그 파일을 변경하도록 강제
482
+ verify 기록된 해시 ≠ 현재 파일 → TAMPERED
483
+ ```
484
+
485
+ ⇒ **COMPLETE 에 도달하려면 반드시 증인 아티팩트를 사후 변경해야 했다. 우회로가 없었다.**
486
+ 즉 P1 은 «완주한 런»으로 만족이 불가능했고, 그것이 ②가 🔵 였던 **기계적** 이유다 — 후보가
487
+ 부족해서가 아니다. 이 절이 2026-08-08 에 *"unreachable condition … trains people to delete the
488
+ thing being counted"* 라고 경고한 그 형태가, **그 경고를 적은 채널 자신에서** 재발했다.
489
+
490
+ **대상 선정 실수가 아니다.** P1 문언이 *"the **intent/budget**/sim record"* 로 BUDGET 을 증인
491
+ 대상으로 **명시 지목**한다. 결함은 **한 파일에 두 역할이 겹친 것**이다 — ①불변을 요구하는 증인 ·
492
+ ②변경을 요구하는 사후 캘리브레이션. **개별로는 둘 다 옳고, 충돌은 아무도 소유하지 않는다.**
493
+ 그래서 어느 쪽 코드를 읽어도 안 보였고, 정적 판독은 양쪽 다 초록으로 읽힌다.
494
+
495
+ **왜 기존 검증이 다 놓쳤나 — 이게 남길 값의 본체다.**
496
+ - `test_chamber_run_lanes.sh` 는 헤더에 *"순서 증인은 이 테스트의 대상이 아니다 — 부수 효과가
497
+ 섞이므로 복사하지 않는다"* 라고 **명시적으로 증인을 제외**했다.
498
+ - `chamber_witness.sh --self-test` 16레인은 증인을 **단독으로** 시험했다(cross-family 가 fail-open
499
+ 7건을 잡은 그 레인들이다).
500
+ - ⇒ **러너 × 증인의 이음매를 어느 쪽도 안 봤다.** 두 테스트 다 자기 범위에선 옳았다.
501
+ - 그리고 러너 픽스처 `_mk_budget()` 이 `ESTIMATE:\nACTUAL: -` 를 **한 번에** 써서, 12레인 어디에도
502
+ «추정→실행→실비용» 이라는 **실제 순서가 존재하지 않았다.** 픽스처가 *상태*를 모델링했고 결함은
503
+ *과정*에 있었다. `[[feedback_adversarial_review_not_substitute_for_first_use]]` 의 교과서 사례다.
504
+
505
+ **수리(2026-08-17)** — 스펙은 안 건드리고 **변경 요구만** 빼낸다:
506
+ - `chamber_run.sh` step 6 → **별도 `ACTUAL.md`**. 정의상 판정 후 산물이므로 **증인에 기록하지 않는다.**
507
+ - `chamber_witness.sh do_record` → 동일 `(run, artifact, sha)` 삼중항 재기록 스킵. 종전엔 무조건
508
+ append 라 4스텝 런에 엔트리 **11개**가 쌓였다(판정은 안 틀리나 공개 tracked 파일이 부풀고 verify
509
+ 출력이 같은 줄을 반복해 **읽는 사람이 「몇 건이 문제인가」를 오독**한다). 🟥 **내용이 바뀐 경우는
510
+ 여전히 새 엔트리로 남는다** — 그게 TAMPERED 를 성립시키는 증거다.
511
+ - `test_chamber_run_lanes.sh` **12 → 26레인**. 신설 축은 **이음매**이고, 어서션이 두 겹이다:
512
+ **L13-a**(완주 후 BUDGET.md 해시 불변) + 🟥 **L13-b**(step 6 이 **지목하는 파일**이 증인 대상이
513
+ 아닐 것). L13-b 가 본체다 — **러너는 BUDGET.md 를 직접 고치지 않고 사람에게 고치라고 시키므로**,
514
+ 파일 해시만 보는 L13-a 는 되돌림 프로브에서 **초록으로 남았다**(즉 그것만으로는 장식이었다).
515
+ 잴 것은 파일이 아니라 **지시**였다. 되돌림 실측: `git show HEAD:` 판으로 되돌리면 L13-b 가
516
+ 적색(`step6 이 증인 아티팩트를 고치라고 시킨다`), 컨트롤은 초록 유지.
517
+
518
+ ⚠️ **런 #11 자신은 TAMPERED 로 남는다. 소급 수리하지 않는다** — 과거 9런을 back-fill 하지 않는 것과
519
+ 같은 이유다(사후에 쓴 기록은 증명하지 않는다). **P1 은 이 수리 이후의 EMIT 런에서 처음 만족 가능하다.**
520
+ 🟥 그리고 이 수리는 **P1 을 만족시키지 않는다** — 만족을 *가능하게* 만들 뿐이다. ②는 🔵 유지.
521
+
522
+ ⚠️ **되돌림 프로브 자체에서 실책 1건(기록)**: 첫 시도가 `sed` 로 따옴표 포함 패턴만 바꿔 **검사는
523
+ BUDGET, 메시지는 ACTUAL 인 잡종**을 만들었고, 그 상태에서 L13-b 가 초록이라 하마터면 «레인이
524
+ 장식이다»로 결론 낼 뻔했다. 되돌림은 **`git show HEAD:` 로 통째 복원**해야 한다 — 부분 되돌림은
525
+ 되돌림이 아니다.
322
526
 
323
527
  **P1's channel was built, and that is not the same as P1 passing.** The row above said *not buildable
324
528
  today*; that is no longer true, and the reason it was true is worth keeping because it names the shape of