@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.
- package/.claude/rules/fh_4axis_gate.md +25 -0
- package/.claude-plugin/marketplace.json +2 -2
- package/CLAUDE.md +107 -7
- package/README.ja.md +14 -2
- package/README.ko.md +14 -1
- package/README.md +16 -2
- package/README.zh.md +12 -1
- package/knowledge/shared/harness-core/fh_three_layer_canon.md +18 -6
- package/knowledge/shared/harness-core/field_verdict_crossfamily_gate.md +262 -7
- package/knowledge/shared/harness-core/harness_incubator_doctrine.md +215 -1
- package/knowledge/shared/harness-core/ship_readiness_gate.md +168 -1
- package/knowledge/shared/harness-core/sonnet_floor_doctrine.md +16 -0
- package/knowledge/shared/learnings/subagent_invocations_log.yaml +120 -0
- package/knowledge/shared/rules/multi_session_close_protocol.md +124 -2
- package/package.json +8 -1
- package/plugins/fh-commons/.claude-plugin/plugin.json +1 -1
- package/plugins/fh-meta/.claude-plugin/plugin.json +1 -1
- package/plugins/fh-meta/CHANGELOG.md +105 -0
- package/plugins/fh-meta/skills/auto-decorrelation/SKILL.md +20 -0
- package/plugins/fh-meta/skills/steel-quench/SKILL.md +25 -2
- package/scripts/adapters/mate_agent_boundary.sh +27 -7
- package/scripts/capability_effect_probe.sh +173 -5
- package/scripts/capability_registry_check.sh +69 -3
- package/scripts/digest_landing_check.sh +168 -13
- package/scripts/fh_session_load.sh +71 -0
- package/scripts/relay_channel.sh +151 -6
- package/scripts/selfcheck.sh +47 -0
- package/scripts/target_freeze.sh +239 -0
- package/scripts/test_adapter_lanes.sh +17 -0
- package/scripts/test_evidence_root_psa_lanes.sh +78 -0
- package/scripts/test_marker_standpoint_lanes.sh +83 -0
- package/scripts/test_marker_thirdparty_lanes.sh +73 -0
- package/scripts/test_regression_guard_ci_lanes.sh +170 -0
- package/scripts/test_relay_channel_lanes.sh +146 -17
- package/scripts/test_satellite_publish_gate_lanes.sh +339 -0
- package/scripts/test_target_freeze_lanes.sh +203 -0
- package/templates/.git-hooks/pre-commit +306 -6
- package/templates/PRE-PUBLISH-CHECKLIST.md +22 -0
- package/templates/regression_guard.sh +32 -4
|
@@ -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
|
|
@@ -224,6 +255,37 @@ pass):
|
|
|
224
255
|
**🟥 DECIDE IN THIS ORDER — first match wins. Do not pick by matching a description.**
|
|
225
256
|
|
|
226
257
|
```
|
|
258
|
+
Q0. WHICH TARGETS? — settle the target CLASS(es) before reaching for a tier.
|
|
259
|
+
🟥 NOT first-match. Q0 can return MORE THAN ONE target, and each one owes its own tier.
|
|
260
|
+
A release that also alters a named peer's contract owes both arms; recording only the
|
|
261
|
+
first shadows the second (caught by cross-family review, 2026-08-17).
|
|
262
|
+
|
|
263
|
+
ⓐ Does a NAMED PEER HARNESS carry this surface?
|
|
264
|
+
Mechanical test, in this order — do not decide from memory or from a name list:
|
|
265
|
+
· a local repo of a cluster peer carries the file this delta changes
|
|
266
|
+
(`for d in ~/projects/*; do test -f "$d/<changed-path>"; done`), OR
|
|
267
|
+
· the peer is declared in `.claude/capabilities` / the cluster registry, OR
|
|
268
|
+
the change edits an adapter under `scripts/adapters/` naming it
|
|
269
|
+
YES → target = that repo (one per peer) → run Q1 for each
|
|
270
|
+
ⓑ Does this delta change CONSUMER-VISIBLE BEHAVIOR — what a consumer's gate blocks or
|
|
271
|
+
passes, what a consumer's session is instructed to do, what an install receives?
|
|
272
|
+
YES → target = a CLEAN INSTALL of the packed artifact → run Q1
|
|
273
|
+
🟥 This binds NOW, at the change, pre-push (§Sequencing) — NOT deferred to
|
|
274
|
+
the eventual release. Deferral was the first draft's hole: "not a release
|
|
275
|
+
yet" would have let a behavior change ship unexamined and left the releaser
|
|
276
|
+
holding a delta they did not write.
|
|
277
|
+
ⓒ Neither ⓐ nor ⓑ → `not-applicable` STOP.
|
|
278
|
+
|
|
279
|
+
🟥 A consumer install IS another harness — settled, not open. What Q0 scopes is not WHO
|
|
280
|
+
RECEIVES the change but WHERE IT HAS TO BE EXECUTED, and 🟥 **not «is this file shipped»**:
|
|
281
|
+
almost everything here is shipped, so shipped-ness cannot be the discriminator (see
|
|
282
|
+
«Target class» below). The discriminator is ⓑ's *behavior* clause — the same effect-based
|
|
283
|
+
trigger this section already uses, applied to the consumer as a target rather than as an
|
|
284
|
+
audience.
|
|
285
|
+
Reading Q1/Q2 when the target is an install tree rather than a repo: Q1's "executed in the
|
|
286
|
+
target's repo" = "executed inside the extracted/installed tree"; Q2's local-wiring question
|
|
287
|
+
is answered NO for a bare extraction (`tier2`), YES only if a real consumer node's own
|
|
288
|
+
settings/state were in play (`tier2b`).
|
|
227
289
|
Q1. Did anything EXECUTE in the target's repo — a command, a script, a suite?
|
|
228
290
|
NO, I only read files → tier1b(<harness>) STOP.
|
|
229
291
|
NO, I did not touch its repo → tier1 STOP.
|
|
@@ -269,6 +331,24 @@ tier1b(<target-harness>) STATIC standpoint read — the reviewer read the TA
|
|
|
269
331
|
nearer value existed. A missing rung does not stay empty — it gets
|
|
270
332
|
filled by the next one up. Real but weak: see «execution is the
|
|
271
333
|
load-bearing half» below before crediting it.
|
|
334
|
+
🟥 «FROM THE TARGET'S REPO» IS LOAD-BEARING, and a field case the
|
|
335
|
+
day this rung shipped shows why. A session changed FH code that would
|
|
336
|
+
make two peer harnesses' capability declarations start being REJECTED
|
|
337
|
+
— genuinely applicable — and reached for `tier1b` because it had
|
|
338
|
+
*read files*. The files it read were FH-local records ABOUT those
|
|
339
|
+
peers (`tracks/_meta/relay/*.cap`), not the peers' own files. Reading
|
|
340
|
+
your own repo's description of a peer is NOT a standpoint read; the
|
|
341
|
+
whole point of the axis is whose ground truth the review was checked
|
|
342
|
+
against, and that was still your own. The honest value there is
|
|
343
|
+
`DEGRADED_NOT_RUN(<peers>)` — applicable, target reachable, nothing
|
|
344
|
+
done at the target. Note the direction of the risk has INVERTED since
|
|
345
|
+
this rung was added: tier1b was created because a real static read had
|
|
346
|
+
no home and got recorded one rung too high; the new failure mode is
|
|
347
|
+
local reading being recorded as tier1b because "I read something"
|
|
348
|
+
feels the same. 🟥 Two different questions get merged here and must
|
|
349
|
+
not be: *does a target exist and is it affected* is **Q0**; *what did
|
|
350
|
+
you actually do at that target* is the **tier**. "The impact is real"
|
|
351
|
+
answers the first and says nothing about the second.
|
|
272
352
|
tier2(<target-harness>) peer-simulated — the reviewer EXECUTED CODE in the TARGET's own repo
|
|
273
353
|
(a local clone, real content) and observed the result.
|
|
274
354
|
🟥 DISCRIMINATOR — «reading the target's real files is NOT this rung».
|
|
@@ -305,8 +385,18 @@ tier2b(<target-harness>) same operator, target's real runtime — the SAME h
|
|
|
305
385
|
tier3(<target-harness>) actual peer — a DIFFERENT human operator of the target harness ran
|
|
306
386
|
the change in their real runtime. The only tier with both local
|
|
307
387
|
wiring AND reviewer independence from the author.
|
|
308
|
-
not-applicable the change has no target-harness standpoint to borrow
|
|
309
|
-
|
|
388
|
+
not-applicable the change has no target-harness standpoint to borrow — Q0 found
|
|
389
|
+
neither a named peer harness NOR a release/publish surface, so there
|
|
390
|
+
is no repo and no install to run this from. 🟥 Read the second half
|
|
391
|
+
literally: «no cross-repo consumer contract» does NOT mean «this file
|
|
392
|
+
is never shipped». Almost everything here is shipped (measured
|
|
393
|
+
2026-08-17: 192/200 recent commits touch an npm-shipped path, and that
|
|
394
|
+
96% is a LOWER bound — `package.json` is packed without appearing in
|
|
395
|
+
`files[]`). Reading shipped-ness as the trigger makes this value
|
|
396
|
+
reachable in under 4% of commits, i.e. effectively unreachable, and an
|
|
397
|
+
unreachable value teaches authors to delete what they are counting
|
|
398
|
+
(`[[feedback_unreachable_done_when_trains_evasion]]`). The trigger is
|
|
399
|
+
the RELEASE, not the path — distinct
|
|
310
400
|
from a degrade value; this is a scoping fact, not a miss. Carries the
|
|
311
401
|
same substantive-grounds-on-the-same-line discipline as a degrade
|
|
312
402
|
value below — asserting non-applicability without naming what was
|
|
@@ -382,11 +472,22 @@ data point.
|
|
|
382
472
|
**Mechanization status — `standpoint:` is prose-only today, and this must not be read as more than
|
|
383
473
|
that.** `crossfamily:`'s degrade triad is hard-blocked at commit (`templates/.git-hooks/pre-commit`,
|
|
384
474
|
`scripts/test_marker_crossfamily_lanes.sh` — grep-verified: ~20 crossfamily references in the hook,
|
|
385
|
-
validated fixtures). `standpoint:` has **
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
475
|
+
validated fixtures). `standpoint:` has **no value-enum validation and no fixture suite** — nothing stops an author from
|
|
476
|
+
writing `not-applicable` with a thin justification, and no marker-shape check catches a wrong value.
|
|
477
|
+
|
|
478
|
+
🟥 **Two sentences that stood here were STALE and are corrected (2026-08-17, re-measured — a
|
|
479
|
+
cross-family reviewer flagged the second, the first fell out of checking it).** They read
|
|
480
|
+
*"`standpoint:` has **zero** matches in that hook"* and *"§Marker required fields in
|
|
481
|
+
`.claude/rules/fh_4axis_gate.md` does not yet list `standpoint:` either"*. Both are false as of this
|
|
482
|
+
date: `grep -c standpoint templates/.git-hooks/pre-commit` → **15**, and the hook *does* enforce one
|
|
483
|
+
property (when `axes-run` carries `ⓑ=→standpoint`, the `standpoint:` line must exist and be non-empty
|
|
484
|
+
— `pre-commit:780-782`); `.claude/rules/fh_4axis_gate.md` lists the field at **§133 and §192**.
|
|
485
|
+
**What is still true is the narrower claim**: the *value* is unvalidated — «the line exists» is
|
|
486
|
+
enforced, «the value is right» is deliberately reserved (§Mechanization Boundary). Do not read the
|
|
487
|
+
corrected sentence as "now mechanized"; read it as "the channel is checked, the judgment is not".
|
|
488
|
+
The distinction this stale text destroyed is exactly the one that matters here, and it destroyed it
|
|
489
|
+
in the *pessimistic* direction — under-claiming coverage is not a safe error either, because it
|
|
490
|
+
invites someone to rebuild a lane that already exists. This is the honest current state, not a placeholder apology: the field exists so a
|
|
390
491
|
human reader can ask for it and so the *next* occurrence of a false `not-applicable` has something
|
|
391
492
|
concrete to point at — mechanize on that first recorded false value
|
|
392
493
|
(`[[feedback_mechanize_at_repetition_prose_before]]`), not before. **Ownership**: this field lives
|
|
@@ -449,6 +550,160 @@ proposal (pmh-dev issue #68, verified verbatim in that thread: *"대상 후보
|
|
|
449
550
|
behavioral reading after that same review found the file-class reading false for at least one real
|
|
450
551
|
pair.
|
|
451
552
|
|
|
553
|
+
**Target class — «누가 받나» is not the question; «어디서 돌려야 하나» is (operator decision,
|
|
554
|
+
2026-08-17).** The trigger above says *effect, not file-class*, and that was still not enough: three
|
|
555
|
+
independent marker-audit legs, run the same day against three different markers, all failed at the
|
|
556
|
+
same place — each reasoned *"it ships, therefore there are consumers, therefore a cross-repo consumer
|
|
557
|
+
contract exists, therefore applicable"*. That reading is not obviously wrong; the enum's own words
|
|
558
|
+
(*"no cross-repo consumer contract"*) invite it. What kills it is the size: **192 of the last 200
|
|
559
|
+
commits touch an npm-shipped path (96%, a lower bound — `package.json` ships without being listed in
|
|
560
|
+
`files[]`, so at least one of the 8 remaining is a false negative too)**. A value reachable in under
|
|
561
|
+
4% of commits is not a scoping value — it prices the axis at a rate this section's own **Trigger**
|
|
562
|
+
paragraph already rejects as over-triggering (*"almost every commit would qualify, which is the
|
|
563
|
+
over-pricing this trigger is trying to avoid, not invoke"*). That is the argument, and it was
|
|
564
|
+
already in this document.
|
|
565
|
+
|
|
566
|
+
⚠️ **A citation is withdrawn here.** The first draft justified this with
|
|
567
|
+
`[[feedback_unreachable_done_when_trains_evasion]]` — *"an unreachable condition teaches people to
|
|
568
|
+
delete what they are counting"*. An adversarial round showed the direction is **inverted**: that
|
|
569
|
+
memory is about an unreachable **pass condition** a person must reach, whereas `not-applicable` is an
|
|
570
|
+
**exemption**. An unreachable exemption does not make anyone delete anything; it makes the obligation
|
|
571
|
+
fire almost always, and the failure mode is over-pricing and formality, not evasion. Same discomfort,
|
|
572
|
+
different mechanism — do not re-import the citation.
|
|
573
|
+
|
|
574
|
+
🟥 **State precisely what that 96% does and does not establish — it is narrower than it looks, and a
|
|
575
|
+
cross-family reviewer caught the first draft overreaching on exactly this.** It is a *file-class*
|
|
576
|
+
count, which this very section rejects as a trigger. It is admissible for **one** claim: the legs'
|
|
577
|
+
argument *was* the file-class argument (*"it ships, therefore consumers, therefore applicable"*), so
|
|
578
|
+
the number measures **that argument's reach**, and shows that adopting it collapses `not-applicable`
|
|
579
|
+
to under 4%. It does **NOT** establish how often the *behavioral* trigger (Q0-ⓑ) actually fires —
|
|
580
|
+
that number is **unmeasured**, and the step from "touched a shipped path" to "a consumer standpoint
|
|
581
|
+
obligation arose" is precisely the step Q0-ⓑ exists to make someone take by hand. Anyone citing 96%
|
|
582
|
+
as the applicability rate is citing it wrong.
|
|
583
|
+
|
|
584
|
+
**Corrected figure, and the instrument defect behind it — surfaced only because an adversarial round
|
|
585
|
+
demanded the hand-check.** The first pass reported **192/200 (96%)** with 8 non-touching commits. Two
|
|
586
|
+
faults, in opposite directions:
|
|
587
|
+
- **Instrument**: the scan ran `--first-parent` *including merge commits*, and `--name-only` emits no
|
|
588
|
+
file list for a merge — so merges were silently scored *non-touching*. Re-run with `--no-merges`:
|
|
589
|
+
the ratio held at 192/200, but the non-touching set collapsed to **6 real cases** (2 commits
|
|
590
|
+
legitimately carry no files).
|
|
591
|
+
- **Hand-check of all 6** (this repo's own publish-a-number rule; N=6 made it trivially cheap):
|
|
592
|
+
**2 are `package.json`-only**, which npm packs regardless of `files[]` — they *are* shipped. The
|
|
593
|
+
other 4 are genuinely unshipped (`.gitignore` · `knowledge/shared/learnings/…` · two `scripts/`
|
|
594
|
+
paths absent from `files[]`).
|
|
595
|
+
|
|
596
|
+
⇒ **Measured: 194/200 = 97%, every exception hand-verified.** ⚠️ One direction stays unexamined: the
|
|
597
|
+
scan applies **today's** `files[]` to **past** commits, and that manifest has only grown, so older
|
|
598
|
+
commits are over-counted as shipped. That FP direction is **unmeasured** — read 97% as *"under the
|
|
599
|
+
current manifest"*, never as a historical claim.
|
|
600
|
+
|
|
601
|
+
🟥 **And read the reachability argument in BOTH directions, which the first draft did not.** It
|
|
602
|
+
measured only what the *rejected* reading does to `not-applicable` (collapses it to <4%). It never
|
|
603
|
+
measured what the *adopted* reading does — Q0-ⓑ is a judged behavioral test, so no scan settles it,
|
|
604
|
+
and the honest statement is that **the new rate is unknown in both tails**: the value could stay rare
|
|
605
|
+
(if most shipped-path commits do change consumer-visible behavior) or become near-universal (if most
|
|
606
|
+
do not), and a near-universal exemption is a rubber stamp, which is its own failure — not the one
|
|
607
|
+
this edit was fixing. Watch the next 20 markers rather than assuming this landed in the middle.
|
|
608
|
+
⚠️ **The «unreachable ⇒ trap» premise is also weaker here than the first draft implied**: `tier1` is
|
|
609
|
+
explicitly *"NOT itself a failure"*, so even under the rejected reading an author had a cheap honest
|
|
610
|
+
value to write and was not cornered into deleting anything.
|
|
611
|
+
|
|
612
|
+
⚠️ **Two different denominators, both of which happen to be 200 — do not merge them.** The 192/200 is
|
|
613
|
+
over the **last 200 commits**. The 177/200 below is over the **200 markers in
|
|
614
|
+
`tracks/_meta/.axes_23_passed_*.marker`**. Commits and markers are different populations (a marker
|
|
615
|
+
covers a delta, not a commit; unmarked commits exist), and their coincident size is an accident of
|
|
616
|
+
this corpus. No ratio may be carried from one to the other.
|
|
617
|
+
|
|
618
|
+
So the split is by **execution site**:
|
|
619
|
+
|
|
620
|
+
| Q0 target class | What discharges the standpoint arm | Binds at |
|
|
621
|
+
|---|---|---|
|
|
622
|
+
| named peer harness (qasp · pmh · mate · gstack · sibling hub) | the enum as written — `tier1b`/`tier2`/`tier2b`/`tier3` against that repo | the change, pre-push |
|
|
623
|
+
| generic consumer install | run the **packed artifact in a clean install** — see the split below; the *presence* half already runs at ship time, the *execution* half does not exist yet | the **release/publish** delta |
|
|
624
|
+
| neither | `not-applicable` | — |
|
|
625
|
+
|
|
626
|
+
**🟥 What that arm is actually covered by today — corrected in the same session that wrote it, by
|
|
627
|
+
reading the lanes instead of naming them.** The first draft of this table said the consumer-install
|
|
628
|
+
arm was *"already mechanized"* by `publish_freshness_check.sh` · `package_coverage_check.sh
|
|
629
|
+
--vs-tarball` · `test_capability_entrypoint_shipping.sh`. Reading those three shows they answer a
|
|
630
|
+
narrower question than the arm asks:
|
|
631
|
+
|
|
632
|
+
```
|
|
633
|
+
covered, AT PUBLISH `prepublishOnly` = prepublish_scope_note · publish_freshness_check ·
|
|
634
|
+
version_lockstep_check · package_coverage_check --vs-tarball ·
|
|
635
|
+
public_surface_scan_files ← read from package.json, not recalled
|
|
636
|
+
covered, BUT IN CI test_capability_entrypoint_shipping.sh is NOT in that chain — it runs under
|
|
637
|
+
the selfcheck anchor loop (`npm test`/CI). Naming it as a ship-time lane was
|
|
638
|
+
wrong; a green CI is not a publish gate (§Local Execution First).
|
|
639
|
+
NOT covered (exec) extract the tarball into a clean directory, run the gate as a consumer would,
|
|
640
|
+
observe it behaves as intended. Measured 2026-08-17: of the lanes that invoke
|
|
641
|
+
`npm pack`, ZERO extract or execute the result — `--vs-tarball` compares a
|
|
642
|
+
FILE LIST (`npm pack --dry-run --json`), it never unpacks.
|
|
643
|
+
```
|
|
644
|
+
|
|
645
|
+
This matters because it is the same asymmetry this section already argues for: *"execution is the
|
|
646
|
+
load-bearing half"*. An arm discharged by presence checks alone is a `tier1b`-shaped arm wearing a
|
|
647
|
+
`tier2` label — the exact substitution the `tier1b` rung was added to stop. **So: the presence half
|
|
648
|
+
is mechanized and free; the execution half is a named residual, discharged by hand
|
|
649
|
+
(`npm pack` → extract to a clean dir → run the gate → record the command and the output, per the
|
|
650
|
+
`tier2` discriminator) until a lane exists.** Do not cite this arm as fully mechanized. The
|
|
651
|
+
decision's «no new machinery» framing was correct about the *presence* half and overstated about
|
|
652
|
+
the whole — recorded here rather than quietly narrowed, because a reader reaching for this table
|
|
653
|
+
mid-release is exactly the reader who would otherwise skip the half that has no lane.
|
|
654
|
+
|
|
655
|
+
**What this decision costs, stated rather than hidden.** Of the three legs, **leg B was right and
|
|
656
|
+
the other two were wrong to generalize it**: the `release_2.3.0` marker's `not-applicable` IS a
|
|
657
|
+
defect under this closure (a release delta whose own grounds line concede *"소비자 install 의 게이트
|
|
658
|
+
수용은 바뀐다 (BREAKING 2건)"* — that is the trigger being met, written out in the field that denies
|
|
659
|
+
it), while an ordinary commit touching a shipped script correctly stays `not-applicable`. Row 1
|
|
660
|
+
(PR #368) needs no reclassification: its target was a sibling hub with its own repo, a named peer.
|
|
661
|
+
⚠️ Those three legs were **not decorrelated** — same family, same prompt shape, same canon — so their
|
|
662
|
+
3/3 agreement is closer to one observation than three; it is cited here as *the pattern that exposed
|
|
663
|
+
the definitional hole*, never as three confirmations
|
|
664
|
+
(`[[feedback_decorrelation_axis_is_what_you_send]]`).
|
|
665
|
+
|
|
666
|
+
**Measured after this edit shipped, and it REFUTES the residual this paragraph first carried.** The
|
|
667
|
+
original text read: *"177 of the 200 corpus markers carry no `standpoint:` line at all … that pool is
|
|
668
|
+
larger than the one measured and remains unexamined."* It has now been examined, and the pool is not
|
|
669
|
+
larger — it barely exists:
|
|
670
|
+
|
|
671
|
+
```
|
|
672
|
+
201 markers · 24 carry `standpoint:` · 177 do not
|
|
673
|
+
172 predate the field itself (born 2026-08-14, PR #370 landed 14:13) — structural, not a miss
|
|
674
|
+
2 written the same day but BEFORE 14:13 (12:29 · 12:39) — also structural
|
|
675
|
+
3 written after the field existed (16:41 · 19:10 · 21:06) ← the entire real pool
|
|
676
|
+
0 absences dated 2026-08-15 or later — adoption is 100% from day two onward
|
|
677
|
+
```
|
|
678
|
+
|
|
679
|
+
🟥 **The first step was decomposition, not adjudication.** Counting "no field" as "not recorded"
|
|
680
|
+
folds *the field did not exist yet* into *the author skipped it* — the same `not-found ≠ 0` collapse
|
|
681
|
+
this session hit three separate times (`[[feedback_not_found_is_not_zero_family]]`). Splitting by the
|
|
682
|
+
field's own birth timestamp is what turned 177 into 3.
|
|
683
|
+
|
|
684
|
+
**Hand-check of all 3, judged from the real diffs** (their markers use the pre-2026-08-17 four-letter
|
|
685
|
+
`axes-run` notation, where `b` means first-real-use and NOT standpoint — reading the marker's own
|
|
686
|
+
self-description instead of the diff would have inverted two axes):
|
|
687
|
+
|
|
688
|
+
| commit | delta | verdict under Q0 |
|
|
689
|
+
|---|---|---|
|
|
690
|
+
| #375 `cedd8ac` | `version_lockstep_check.sh` +11 lines, **all comment** | `not-applicable` would have been correct — a **missing line**, not a wrong judgment |
|
|
691
|
+
| #374 `0690ba7` | 7 files, +409 — shipped gate scripts plus `templates/degrade_direction_scan.sh` | 🟥 **genuinely under-recorded** (Q0-ⓑ, and `templates/` propagates to field harnesses) |
|
|
692
|
+
| #373 `549a4bc` | `ko-tech-writer/SKILL.md` +63/−12 (shipped plugin) | 🟥 **genuinely under-recorded** (Q0-ⓑ) |
|
|
693
|
+
|
|
694
|
+
**The direction matches §6's earlier finding: over-claiming 0, under-recording only.** A gate that
|
|
695
|
+
tightens *"were you really tier2?"* cannot catch this direction by construction.
|
|
696
|
+
|
|
697
|
+
⚠️ **Retroactive-application caveat**: Q0 was written 2026-08-17 and these three are 2026-08-14, so
|
|
698
|
+
their authors could not have applied it. What survives the caveat is narrower and still real — the
|
|
699
|
+
**field existed** by then, so the absent line is a gap independent of Q0.
|
|
700
|
+
|
|
701
|
+
**Consequence for sequencing**: the argument for postponing mechanization was *"absence is the
|
|
702
|
+
dominant reality, so validating values would only tighten a recording minority."* That premise is
|
|
703
|
+
**dead** — recording is 100% from 2026-08-15 onward. ⚠️ The refutation does **not** travel to peers:
|
|
704
|
+
pmh-dev's 42 markers carry the field 0 times, and whether that is late arrival or non-adoption is
|
|
705
|
+
**unmeasured** there. `thirdparty:` likewise stands at 2 corpus instances — unmeasured, not clean.
|
|
706
|
+
|
|
452
707
|
**Relationship to `harness_verification_core_extended.md`'s core/extended axis**: tier2 and tier3
|
|
453
708
|
are both "extended" in that document's sense (they require a cluster member's engine or repo to
|
|
454
709
|
discharge) — this field does not compete with that doctrine, it subdivides one corner of it.
|
|
@@ -110,6 +110,11 @@ this chamber's field emit terminus); an **FH-internal utility** (a skill/script/
|
|
|
110
110
|
field harness) instead routes through the **New-Skill Pre-Commit gate + `asset-placement-gate`** (the
|
|
111
111
|
same gate every FH asset passes). KILL emits nothing — the workspace stays as the evidence record.
|
|
112
112
|
|
|
113
|
+
> 🟥 **2026-08-17 이후 이 문단은 단독으로 읽으면 틀린다.** 아래 «clears **all four**» 중
|
|
114
|
+
> **(1) net-new 는 더 이상 KILL 사유가 아니다**(→ `CURATED` 라우팅) — §3-SCREEN-2026-08-17 로
|
|
115
|
+
> 대체됐고, (2) 는 `NOT-APPLICABLE` 라우팅이다. **(3)·(4) 는 KILL 로 그대로 유효하다.**
|
|
116
|
+
> 아래 본문은 그 정정 이전의 원문이며 이력으로 보존한다.
|
|
117
|
+
|
|
113
118
|
**EMIT-worthiness — the measured screening criterion (runs #5–#6, 2026-07-14)**: six chamber runs, EMIT
|
|
114
119
|
0/6, all KILL. A candidate is emit-worthy only if it clears **all four** of — (1) **net-new** (not a
|
|
115
120
|
reinvention of an existing FH/official asset, nor a cosmetic re-wrap of code that already ships — runs
|
|
@@ -132,6 +137,90 @@ standalone graduations — not yet *birthing*. **Graduation order** (run #6's po
|
|
|
132
137
|
hub-state-dependent capability graduates hub-internal → proven in use → THEN extracted portable, never
|
|
133
138
|
speculated standalone-first — the only path every successfully-portable FH asset actually took.
|
|
134
139
|
|
|
140
|
+
---
|
|
141
|
+
|
|
142
|
+
### 🟢 §3-SCREEN-2026-08-17 — **(1) net-new 는 더 이상 KILL 사유가 아니다** (운영자 결정)
|
|
143
|
+
|
|
144
|
+
> *"사람들이 자신이 구상한 하네스를 인큐베이팅으로 해서 출하하려는데, 그럴 때마다 항상
|
|
145
|
+
> **«이미 있는 기능이야»라고 리젝시키면 쓰고 싶은 생각이 들까?** 그것보다는 «이미 이러한
|
|
146
|
+
> 레퍼런스가 있는데 **너만의 방법으로 커스터마이징하고 싶다면 여기서 출발해보자**»가 되어야 할
|
|
147
|
+
> 것 같아. **인큐베이팅이 필요없다면 큐레이팅으로 가면 되는 거고.**"*
|
|
148
|
+
> · *"**그 사람이 만들려는 걸 인큐베이터가 막을 필요가 있을까. 그냥 만들게 두면 되지.**"*
|
|
149
|
+
> · *"인큐베이터는 **훈수를 놓게 하기 위한 장치가 아니라**, 원하는 프로젝트나 하네스를
|
|
150
|
+
> **출하 전부터 미리 굴려보고 사용해보게 하는 에뮬레이션**과 그로 인해 자신만의 것을
|
|
151
|
+
> **성숙하게 출하시키기 위한 장치**"*
|
|
152
|
+
|
|
153
|
+
**바뀌는 것 — 기준은 남고, 그 기준의 «판정 결과»가 바뀐다:**
|
|
154
|
+
```
|
|
155
|
+
전 net-new 미달 → KILL (후보가 회수된다. 사용자는 빈손으로 돌아간다)
|
|
156
|
+
후 net-new 미달 → **CURATED** (선행 목록 + 가장 가까운 것 + 그것이 안 덮는 델타를 준다)
|
|
157
|
+
→ 사용자가 «그거 쓸게» 면 거기서 끝(큐레이팅 종료)
|
|
158
|
+
→ 사용자가 «내 걸 만들래» 면 **인큐베이터로 들어간다**
|
|
159
|
+
```
|
|
160
|
+
🟥 **전환점은 판정이 아니라 의사다.** 인큐베이터는 「이게 새로운가」를 묻지 않고 「너 만들 거냐」를
|
|
161
|
+
묻는다. 그리고 선행 목록은 **회수 통보가 아니라 재료 목록**이다 — 아래 §3-SCREEN-b.
|
|
162
|
+
|
|
163
|
+
🟥 **초판이 여기서 게이트를 무력화했고, 적대검증이 커밋 전에 잡았다. 그 정정을 남긴다.**
|
|
164
|
+
초판은 «진짜 KILL» 을 셋으로 줄이며 **(3) 을 「precision 을 만들 수 없음(원리적 불가)」으로
|
|
165
|
+
바꾸고 (4) 를 「형태 라우팅」으로 격하**했다. 둘 다 틀렸다:
|
|
166
|
+
- **(3) 의 원문은 «원리적 불가» 가 아니라 «실측 미달» 이다** — *"run #5's rule scored **5/5
|
|
167
|
+
false-positive** on 111 real files; run #6's heuristic scored **14/22 false-fire**"*.
|
|
168
|
+
초판 문장대로면 **런 #5·#6 이 KILL 이 아니게 된다**(둘 다 precision 을 *만들 수는* 있었다).
|
|
169
|
+
- **합산이 진짜 문제였다**: 이 절이 챔버의 실증된 값어치를 셋으로 적는데
|
|
170
|
+
(*"preventing **reinventions** · **low-precision births** · **premature standalone
|
|
171
|
+
graduations**"*), 초판이 재발명→CURATE · (3)→원리적불가 · (4)→형태라우팅 으로
|
|
172
|
+
**셋 다 뺐다.** 남는 entry 스크린이 「사용자가 만들겠다고 하나」 하나뿐이 됐다.
|
|
173
|
+
|
|
174
|
+
**그래서 이렇게 정리한다 — entry 와 exit 를 섞지 않는다** (§3-c 가 *"two different questions,
|
|
175
|
+
**do not merge them**"* 이라고 명시한 그 분리):
|
|
176
|
+
|
|
177
|
+
```
|
|
178
|
+
── ENTRY (들어갈 때, 이 절) ──────────────────────────────────────────────
|
|
179
|
+
(1) net-new 미달 → **CURATED** 라우팅. KILL 아님 (§3-SCREEN-2026-08-17)
|
|
180
|
+
(2) artifact-shaped 미달 → **NOT-APPLICABLE**. 판단-방법은 이 인큐베이터의 산출 형태가 아니다
|
|
181
|
+
(3) precision **실측 미달** → **KILL 유지** 🟥 «못 만든다» 가 아니라 «돌려봤더니 나빴다» 다
|
|
182
|
+
(4) hub-state 의존 → **KILL 유지** 🟥 premature standalone graduation 방지가 이 축의 일이고,
|
|
183
|
+
§3 말미의 Graduation order(hub-internal → proven → extract)가 그 처방이다
|
|
184
|
+
★ 사용자가 «안 만들래» → **종료**(큐레이팅으로 끝. KILL 원장에 세지 않는다)
|
|
185
|
+
|
|
186
|
+
── EXIT (나올 때, §3-c) ──────────────────────────────────────────────────
|
|
187
|
+
«설 수 없다»(inability-to-run) → **KILL**. 약함은 KILL 아님(§3-c ④)
|
|
188
|
+
```
|
|
189
|
+
🟥 **원리적으로 precision 을 만들 수 없는 대상**(판별 쌍을 구성할 수 없는 것)은 KILL 이 아니라
|
|
190
|
+
**`NOT-APPLICABLE`** 이다 — 후보의 실패가 아니라 **이 인큐베이터의 바가 안 맞는 것**이다.
|
|
191
|
+
|
|
192
|
+
⚠️ **§3-c 의 한 문장이 이 정정으로 갱신된다**: *"clear this one and fail the first
|
|
193
|
+
(**alive, but a reinvention**)"* — 그 분기는 이제 KILL 이 아니라 **CURATED 로 라우팅**된다.
|
|
194
|
+
|
|
195
|
+
**⚠️ 경계가 사라지는 것은 아니다.** 재발명이라는 *사실*은 여전히 측정하고 기록한다. 바뀐 것은
|
|
196
|
+
그 사실을 **누구에게 무엇으로 주느냐**다: 게이트의 판정 근거 → 제작자의 출발점.
|
|
197
|
+
|
|
198
|
+
### §3-SCREEN-b — **선행은 재료다** (인큐베이팅 가속화, 운영자)
|
|
199
|
+
|
|
200
|
+
> *"앞서 찾았거나 정말 새로운 거라면 검색한 레포 중에서 **배워올 만한 것들을 일부만 빌려와서
|
|
201
|
+
> 개발해 나가는 것**이 곧 인큐베이팅 **가속화**의 방법이 되기도 하겠지. 제로부터 자신만의
|
|
202
|
+
> 아이디어만으로 하는 게 아니라 **프런티어에서 배워옴으로서 시작점부터 프런티어급 가능성을
|
|
203
|
+
> 품은 채 태어나게 하는 것.** 개발자들이 코드를 다 새로 짜는 게 아니라 **구글링하는 전통**이
|
|
204
|
+
> 있던 것처럼."*
|
|
205
|
+
|
|
206
|
+
🟥 **가장 날카로운 형태**: **재발명 위험이 높다는 것은, 그만큼 빌려올 선행이 많다는 뜻이다.**
|
|
207
|
+
옛 taxonomy 는 이것을 **거꾸로** 읽었다 — 재료가 풍부할수록 죽였다.
|
|
208
|
+
```
|
|
209
|
+
전 레퍼런스 발견 → KILL 근거 → 배출 확률 0 · 사용자는 빈손
|
|
210
|
+
후 레퍼런스 발견 → 빌드 재료 → 시작점부터 프런티어급 · 사용자는 목록을 들고 간다
|
|
211
|
+
```
|
|
212
|
+
**같은 정보, 소비처만 바꾸면 정반대로 작동한다.** 그리고 이건 §3-c 의 EMIT 바(«설 수 있나»)를
|
|
213
|
+
**더 쉽게 넘게 만든다** — 즉 큐레이팅은 인큐베이팅의 **관문이 아니라 성공률을 올리는 장치**다.
|
|
214
|
+
|
|
215
|
+
**실물 대조(챔버 런 #13 `n-eff-probe`, 2026-08-17)**: K1(재발명)으로 KILL 됐고, 그 근거였던
|
|
216
|
+
선행 5건(capture-recapture · double-fault measure · Snyk VulnBench · BenchGuard · SAST overlap)은
|
|
217
|
+
새 taxonomy 에서 **부품 목록**이다 — 통계량은 기성품을 쓰고 새로 만들 것이 「크로스-노드 배선 +
|
|
218
|
+
픽스처」 하나로 줄어든다. **판정을 소급해 무르지는 않는다**(사전등록 원칙). 바뀐 것은
|
|
219
|
+
**다음 후보가 같은 자리에서 어떻게 처리되는가**다.
|
|
220
|
+
|
|
221
|
+
> **정본**: `tracks/_meta/fh_signal_2026-08-17_incubator-is-not-a-gate.md`
|
|
222
|
+
> — 흐름 전체 · 큐레이팅의 자리(⑤ 증폭자) · 진입로 B(축적 기반 제안) · 원장 과소계상 실측.
|
|
223
|
+
|
|
135
224
|
**Chamber scope — what belongs in the chamber at all (run #7, 2026-07-14)**: run #7 tested a hub-internal
|
|
136
225
|
reactivation of the cluster-wizard signal and KILLed it — decisively on its own merits (its "narrow
|
|
137
226
|
net-new" claim collapsed against the real shipped registry and an already-existing synergy skill), but
|
|
@@ -218,7 +307,89 @@ meta harness easy to birth (a declaration starts one) │ needs endless tendi
|
|
|
218
307
|
|
|
219
308
|
A meta-harness cannot clear a bar that reads *"walks on day one"* — not because it is worse, but
|
|
220
309
|
because unbounded growth is its point. FH itself is the standing evidence: it is tended continuously,
|
|
221
|
-
by design.
|
|
310
|
+
by design. ~~**Therefore a meta-harness candidate is not a chamber candidate.**~~
|
|
311
|
+
|
|
312
|
+
### 🟥 §3-a-1-2026-08-17 — 위 결론 문장은 **폐기한다. 범위가 과했다** (운영자 결정)
|
|
313
|
+
|
|
314
|
+
**폐기 사유 ① — 아래쪽 범위는 이미 넓혀져 있었고, 이 파일이 그 확장을 반영하지 않았다.**
|
|
315
|
+
`ship_readiness_gate.md §Ⓑ-layering`(2026-08-16, 운영자 발화 기반)이 ② 의 범위를 이렇게 적는다:
|
|
316
|
+
> *"② 프로젝트 인큐베이터 | **유닛을 낳는다 — 하네스만이 아니다.** … 범위가 **하네스 · 스킬 ·
|
|
317
|
+
> 에이전트** · 하네스 형태가 아닌 일반 레포까지다"*
|
|
318
|
+
|
|
319
|
+
🟥 **초판은 이걸 «8일 전에 뒤집혔는데 안 고쳐졌다 = half-fix 전파 결함» 이라고 적었다. 틀렸고,
|
|
320
|
+
적대검증이 잡았다** — 그 줄이 넓힌 것은 사다리의 **아래쪽**(스킬·에이전트·일반 레포)이고,
|
|
321
|
+
폐기 대상 문장은 **위쪽**(meta-**harness**)에 대한 진술이라 **둘은 논리적으로 양립한다**
|
|
322
|
+
(하위를 포함한다고 상위가 포함되지 않는다). 게다가 그 줄에 **「md 규율」은 없다** — 그건
|
|
323
|
+
2026-08-17 운영자 발화에서만 나온다. **결함 귀속을 철회하고 사유를 약화한다**: 뒤집힌 게
|
|
324
|
+
아니라 **범위 확장이 이 파일에 반영되지 않은 것**이다. (그리고 폐기 자체는 사유 ③ 으로 선다.)
|
|
325
|
+
|
|
326
|
+
**폐기 사유 ② — 논거가 실제로 덮는 범위는 «하네스 급» 뿐이다.**
|
|
327
|
+
위 논거는 *"unbounded growth 가 본질이라 day-one walk 를 못 넘는다"* 인데, 그건 **meta-harness**
|
|
328
|
+
에 대한 진술이다. 스킬 · 에이전트 · md 규율은 **day-one walk 가 가능하다 — 🟥 단 미검증이다.**
|
|
329
|
+
|
|
330
|
+
⚠️ **초판은 «실제로 넘고 있다» 고 적었는데 근거가 없었고, 반례가 같은 레포에 있다.**
|
|
331
|
+
day-one walk 의 정의는 *"on the first run, with the user adding nothing, the thing produces
|
|
332
|
+
something useful"* 이고 반대말이 `built-but-not-wired`, 그리고 *"**wiring is part of the birth**"*
|
|
333
|
+
다. **md 규율은 구조적으로 호출부가 없다**(살리언스). 실제 반례:
|
|
334
|
+
`.claude/rules/fh_4axis_gate.md` 의 `standpoint:` 필드 — *"Still validated by nothing — zero hook
|
|
335
|
+
lines, no fixture suite"* 였고, `tier1b` 등급이 **없어서 정적 리뷰가 tier2 로 기록**됐다.
|
|
336
|
+
`axes-run` 기호 키도 53건 중 2건이 옛 의미로 쓰였다. **태어났고 안 걸은 md 규율들**이다.
|
|
337
|
+
|
|
338
|
+
⇒ **유닛 클래스별 day-one walk 판정자를 따로 건다**:
|
|
339
|
+
```
|
|
340
|
+
스킬 · 에이전트 첫 런에서 사용자가 아무것도 안 더하고 쓸 만한 산출이 나오는가
|
|
341
|
+
md 규율 🟥 **블라인드 floor-tier sim 이 실제로 그 규율을 발화하는가**
|
|
342
|
+
(CLAUDE.md §Skeleton, Not Muscle — "done 은 블라인드 세션이 실제로 발화하는 것")
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
**폐기 사유 ③ — 그 셋이 이 인큐베이터의 최대 산출이다** (운영자, 2026-08-17):
|
|
346
|
+
> *"**FH 의 스킬 상당수는 후자식(축적 기반)으로 만들어졌고** 전자도 거기에 해당하지.
|
|
347
|
+
> FH 스킬은 **내 아이디어로 발명**한 거니까."* ·
|
|
348
|
+
> *"인큐베이터의 **최대 레버는 하네스**이지만 그 **하위의 것들은 다 포함**된다.
|
|
349
|
+
> 스킬 · 에이전트 · **md 규율** 등…"* ·
|
|
350
|
+
> *"인큐베이션 대상은 마감시점 정리 시 **FH 자체가 될 수도 있다.**"*
|
|
351
|
+
|
|
352
|
+
### 🟥 그러면 경계가 필요하다 — 판별 기준 (운영자)
|
|
353
|
+
|
|
354
|
+
경계 없이 폐기만 하면 인큐베이터 정의가 **«FH 가 한 모든 것»**이 되어 계상이 무한대가 되고,
|
|
355
|
+
그건 1건만 세는 것과 똑같이 못 쓴다. 기준은 이것이다:
|
|
356
|
+
|
|
357
|
+
> *"**스킬 없이도 FH 는 동작하지만, 그걸 단축시킬 유닛을 낳은 것까지는 인큐베이팅으로 봐야
|
|
358
|
+
> 한다.**"*
|
|
359
|
+
|
|
360
|
+
```
|
|
361
|
+
❌ 「FH 가 그 일을 했나」 — 이러면 전부가 인큐베이팅이라 측정 불능
|
|
362
|
+
⭕ 조건 1 「그 일을 **단축시키는 유닛을 낳았나**」
|
|
363
|
+
⭕ 조건 2 「그 유닛이 **자기 소비처를 새로 갖는가**」 ← 🟥 **크기 축. 둘 다 필요하다**
|
|
364
|
+
(별도 레포 · 플러그인 엔트리 · 독립 호출면 — «호출부가 새로 생겼나»)
|
|
365
|
+
|
|
366
|
+
범위 하네스 ← 최대 레버
|
|
367
|
+
⊃ 스킬 · 에이전트 · **md 규율**
|
|
368
|
+
⊃ 하네스 형태가 아닌 일반 레포
|
|
369
|
+
```
|
|
370
|
+
🟥 **조건 1 만으로는 계상이 무한대가 된다 — 적대검증이 반례를 냈다.**
|
|
371
|
+
> `templates/.git-hooks/pre-commit` 에 필드 검사 한 줄 추가 → ⓐ md 규율이고 ⓑ 그 일을 단축시키고
|
|
372
|
+
> ⓒ 「유닛」으로 셀 수 있다 = **세 조건 충족.** 그런데 그건 평범한 Mode D 자기개발이고
|
|
373
|
+
> **4축 게이트가 이미 관할한다.** 여기에 «대상이 FH 자체일 수 있다» 가 붙으면
|
|
374
|
+
> **모든 FH 세션의 대부분 커밋이 인큐베이팅**이 된다.
|
|
375
|
+
|
|
376
|
+
**조건 2 가 그걸 자른다**: 기존 훅에 줄을 더하는 것은 **소비처가 이미 있던 것**이라 탈락하고,
|
|
377
|
+
`dashboard-dev`·`ko-tech-writer`(플러그인 엔트리 신설)·`the-bible`(별도 레포)은 통과한다.
|
|
378
|
+
**「일을 했다」와 「유닛이 태어났다」를 가르는 것이 조건 1, 「유닛」과 「기존 것의 확장」을
|
|
379
|
+
가르는 것이 조건 2** 다.
|
|
380
|
+
|
|
381
|
+
⚠️ **그래도 남는 잔여**: 조건 2 는 「소비처가 새로 생겼나」라는 **사후 관측**이라, 만드는 중에는
|
|
382
|
+
판정이 유보된다. 사전 판정이 필요하면 «이것이 태어나면 어디서 불리는가» 를 INTENT 에 적게 하는
|
|
383
|
+
것이 대응이지만 **미구축**이다.
|
|
384
|
+
|
|
385
|
+
### 위 ⚠️ 회고 관찰은 어떻게 되나 — **재분류하되 폐기하지 않는다**
|
|
386
|
+
|
|
387
|
+
아래 회고 관찰(«KILL 된 것 중 chamber-internal metering · hub-internal orchestration ·
|
|
388
|
+
cluster wizardry · org relay 는 meta-shaped 였다»)은 **여전히 유효한 관찰**이다. 다만 그
|
|
389
|
+
처분이 바뀐다: **「스코프 밖이라 KILL」이 아니라 「meta-*harness* 급이라 day-one walk 바를
|
|
390
|
+
다르게 받아야 한다」**이다. `NOT-APPLICABLE` 분리(아래 문단)는 그대로 필요하고, 오히려
|
|
391
|
+
이 정정으로 **더 필요해진다** — 이제 통이 셋이다: `KILL`(못 선다) · `CURATED`(선행이 있다,
|
|
392
|
+
§3-SCREEN-2026-08-17) · `NOT-APPLICABLE`(meta-harness 급이라 이 바가 안 맞는다).
|
|
222
393
|
|
|
223
394
|
⚠️ **Retrospective observation, not a finding.** Re-reading the run ledger along this axis: of the
|
|
224
395
|
KILLed candidates, those aimed at chamber-internal metering, hub-internal orchestration, cluster
|
|
@@ -387,6 +558,49 @@ one harness sees runtime behaviour and not source structure, another sees source
|
|
|
387
558
|
runtime. **The meta-harness's job is not to dig a deeper well; it is to make outputs flow across the
|
|
388
559
|
boundary between wells.**
|
|
389
560
|
|
|
561
|
+
### 4-c. The return leg, and why the cluster exists at all (operator, 2026-08-17)
|
|
562
|
+
|
|
563
|
+
§4-b says outputs **flow across** the boundary. It does not say what happens to what flows *in*,
|
|
564
|
+
nor why FH pays for the crossing. Both were load-bearing and neither was written down. Operator's
|
|
565
|
+
formulation, in three parts — and the third is the one that makes the first two a strategy rather
|
|
566
|
+
than a nice habit:
|
|
567
|
+
|
|
568
|
+
```
|
|
569
|
+
1 BORROW-EXECUTE (standing) FH does not endlessly BUILD the capability it lacks.
|
|
570
|
+
It reaches into a cluster harness and RUNS theirs.
|
|
571
|
+
2 INTERNALIZE (selective) Of the insight that comes back, only what is genuinely worth
|
|
572
|
+
adopting is PROPOSED and absorbed. Never automatic.
|
|
573
|
+
3 THE POINT IS TIME Not capability breadth. What FH buys by not-building is time to
|
|
574
|
+
sharpen its OWN edge — and that is what lets it keep pace with a
|
|
575
|
+
fast-moving model layer instead of being outrun by it.
|
|
576
|
+
```
|
|
577
|
+
|
|
578
|
+
🟥 **Without (3), (1) inverts on reading.** "We borrow instead of building" reads as *"FH need not
|
|
579
|
+
have capabilities"* — which turns the cluster into dependency. The operator's claim is the opposite:
|
|
580
|
+
**borrowing is how FH protects its own sharpness.** State (3) whenever (1) is cited.
|
|
581
|
+
|
|
582
|
+
**The asymmetry in (2) is the whole filter.** Borrowing is constant; absorbing is rare and gated by
|
|
583
|
+
a proposal. Automatic absorption produces a collage of other harnesses' capabilities wearing FH's
|
|
584
|
+
name — the exact opposite of (3), because a collage has no edge to sharpen.
|
|
585
|
+
|
|
586
|
+
**First recorded run of the full loop (2026-08-17, gstack → qasp, FH as governor).** FH did not
|
|
587
|
+
build a DX/product lens; it stood up the gstack persona (`/plan-devex-review`, `/qa-only`) against a
|
|
588
|
+
qasp change and observed. The review returned three findings FH's and qasp's lenses structurally do
|
|
589
|
+
not ask (guide-promises-vs-delivered-bundle · the shipped document's readability · release-doc
|
|
590
|
+
drift). Then the filter ran, and **it rejected more than it accepted**:
|
|
591
|
+
|
|
592
|
+
| finding | disposition |
|
|
593
|
+
|---|---|
|
|
594
|
+
| anchor should be *discovery-based*, not a hand-kept list | **rejected** — measured against FH and the transfer did not hold; a control showed the suites believed unwired do run by another path |
|
|
595
|
+
| guide promises ≠ delivered bundle | **rejected** — `package_coverage_check.sh` already covers it |
|
|
596
|
+
| release docs did not follow | **rejected** — §④-b entry-point drift covers half; not enough delta |
|
|
597
|
+
| **a shipped document is never read as a reader before it ships** | **accepted** — and NOT because gstack said so: FH reached the same place independently the same day from a different axis, recording that *"readability is measured only by rendering it or by a person; a static scan catches what is ABSENT, never what is UNREADABLE"* with 12 findings and **0** caught by static scanners. **Two independent arrivals is the internalization signal.** One source alone leaves it a candidate. |
|
|
598
|
+
|
|
599
|
+
⚠️ **Honest scope**: one run, one target, one third harness. This is an existence proof that the
|
|
600
|
+
loop closes, not a rate. And the filter rejecting 3 of 4 is the expected shape — if it accepted
|
|
601
|
+
everything it would not be a filter, it would be a funnel.
|
|
602
|
+
|
|
603
|
+
|
|
390
604
|
Three rules, in falling order of how easily they are broken:
|
|
391
605
|
|
|
392
606
|
1. **Crossing must not overwrite the receiving harness's identity.** If harness B is deliberately
|