@chrono-meta/fh-gate 2.5.0 → 2.6.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-plugin/marketplace.json +2 -2
- package/AGENTS.md +11 -0
- package/CATALOG.md +41 -0
- package/CLAUDE.md +45 -10
- package/README.ja.md +4 -3
- package/README.ko.md +4 -3
- package/README.md +4 -3
- package/README.zh.md +4 -3
- package/docs/USER_GUIDE.md +118 -0
- package/docs/platform_sustainability.md +174 -0
- package/knowledge/shared/GLOSSARY.md +26 -1
- package/knowledge/shared/harness-core/fh_detail_protocols.md +44 -2
- package/knowledge/shared/harness-core/harness_incubator_doctrine.md +117 -0
- package/knowledge/shared/learnings/subagent_invocations_log.yaml +50 -0
- package/package.json +5 -2
- package/plugins/fh-commons/.claude-plugin/plugin.json +1 -1
- package/plugins/fh-meta/.claude-plugin/plugin.json +1 -1
- package/plugins/fh-meta/CHANGELOG.md +37 -0
- package/plugins/fh-meta/skills/auto-decorrelation/SKILL.md +44 -0
- package/plugins/fh-meta/skills/fh/SKILL.md +31 -0
- package/plugins/fh-meta/skills/goal-quench/SKILL_detail.md +1 -1
- package/plugins/fh-meta/skills/harness-doctor/SKILL.md +7 -1
- package/plugins/fh-meta/skills/harvest-loop/SKILL.md +32 -0
- package/scripts/adapters/fixtures/mate_agent_boundary_known_negative.md +31 -0
- package/scripts/adapters/fixtures/mate_agent_boundary_known_positive.md +56 -0
- package/scripts/cluster_capability_scan.sh +18 -5
- package/scripts/digest_landing_check.sh +39 -8
- package/scripts/package_coverage_check.sh +9 -0
- package/scripts/selfcheck.sh +29 -1
- package/scripts/test_satellite_publish_gate_lanes.sh +0 -339
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# [CALIBRATION FIXTURE — known-positive] 정보경계 불변식 합성 명세서
|
|
2
|
+
|
|
3
|
+
> 🟥 **이것은 실행되는 에이전트 정의가 아니다.** `scripts/blackbox_invariant_check.sh` 의
|
|
4
|
+
> 캘리브레이션 쌍 중 **통과해야 하는 쪽**(expect = PASS, exit 0)이다. 짝은
|
|
5
|
+
> `agent_boundary_known_negative.md` 이고 그쪽은 막혀야 한다(expect = FAIL, exit 1).
|
|
6
|
+
>
|
|
7
|
+
> **왜 실물 명세서를 쓰지 않나**: 실물은 팀이 계속 고치는 살아있는 문서라, 그것을 양성
|
|
8
|
+
> arm 으로 쓰면 계기의 판정이 남의 편집에 따라 조용히 뒤집힌다(감사 대상은 얼려야 한다).
|
|
9
|
+
> 실물 명세서는 인자 없는 기본 대상으로 계속 검사된다 — 이 파일이 그것을 대체하지 않는다.
|
|
10
|
+
>
|
|
11
|
+
> 식별자는 전부 합성이다. 실제 서비스·레포·필드 이름은 한 건도 담지 않는다.
|
|
12
|
+
|
|
13
|
+
## 입력 인터페이스
|
|
14
|
+
|
|
15
|
+
외부 정적분석에서 온 findings 를 받되, 이 에이전트는 그 findings 의 **원본 소스**를 절대
|
|
16
|
+
읽지 않는다. 주입 측이 투영한 결과만 본다.
|
|
17
|
+
|
|
18
|
+
- `finding_id` — 불투명 식별자. 어휘 제약: `^[a-f0-9]{6,64}$` 만 허용한다.
|
|
19
|
+
자유문자열이면 경로·발췌를 실어 나르는 우회 운반 채널이 된다.
|
|
20
|
+
- `location` — allowlist 정규식 `^<FE-REDACTED>::[0-9]+$` 만 허용한다.
|
|
21
|
+
denylist(“특정 접두어가 보이면 폐기”)는 상대경로·`file:///` 등으로 뚫린다.
|
|
22
|
+
|
|
23
|
+
## 투영 규칙
|
|
24
|
+
|
|
25
|
+
**투영을 수행하는 주체는** 주입 측(파이프라인)이다. 수행 주체를 적지 않으면 redact 규칙이
|
|
26
|
+
수행자 없는 공수표가 된다. 따라서 이 에이전트는 입력을 **"그대로" 전달하지 않는다** —
|
|
27
|
+
투영된 형태만 하위로 넘긴다.
|
|
28
|
+
|
|
29
|
+
금지 대상은 **위치가 아니라 출처**로 정의한다. 레포 안에 복사된 사본, 빌드 산출물,
|
|
30
|
+
`sourcesContent` 를 담은 소스맵 전부 동일하게 금지다. "레포 밖"으로 정의하면 레포 안
|
|
31
|
+
사본이 통째로 면제된다.
|
|
32
|
+
|
|
33
|
+
### 현재 배선 상태
|
|
34
|
+
|
|
35
|
+
이 투영 파이프는 **아직 코드로 구현되어 있지 않다.** 미구현 통제를 구현된 것처럼 적으면
|
|
36
|
+
그 자체가 낙관 방향 결함이다.
|
|
37
|
+
|
|
38
|
+
그래서 **슬롯은 현재 사용하지 않는다.** 정의되지 않은 절차에 must-never 불변식을 얹지
|
|
39
|
+
않기 위해, 활성화 **경로를 두지 않는다.**
|
|
40
|
+
|
|
41
|
+
## 안전 규칙
|
|
42
|
+
|
|
43
|
+
1. 판정 근거는 인용 가능한 증거로 남긴다.
|
|
44
|
+
2. 증거 없는 추정은 신뢰도를 올리지 않는다.
|
|
45
|
+
3. 실패를 성공으로 삼키지 않는다.
|
|
46
|
+
4. 재현 절차 없이 수정안을 제시하지 않는다.
|
|
47
|
+
5. 도메인 데이터는 로그에 남기지 않는다.
|
|
48
|
+
6. **메모리 쓰기 금지** — **출처가 화이트박스면 저장하지 않는다.** 저장된 값은 다음 호출에
|
|
49
|
+
자동 주입되므로, 읽지 않을 기회조차 없이 세션 경계를 넘어 오염이 지속된다.
|
|
50
|
+
7. 상한 불변식: 외부 findings 근거만 있고 런타임 증거(XML)가 없으면 신뢰도는 MEDIUM 을
|
|
51
|
+
넘지 못한다. 이 조항은 **다른 모든 조항에 우선**한다.
|
|
52
|
+
8. 금지된 소스의 **능동 탐색**을 하지 않는다. 이 금지는 **도구 무관**이다 — Read·Grep·Glob
|
|
53
|
+
뿐 아니라 `Bash` 를 경유한 열람도 같은 위반이다. 도구를 열거하는 형태로 적으면 열거되지
|
|
54
|
+
않은 경로가 그대로 우회로가 된다.
|
|
55
|
+
필수 채널(리포트·첨부)에서 **조우**한 경우는 별개다: 열기 전에는 알 수 없으므로
|
|
56
|
+
"읽지 마라"는 이행 불가능한 의무가 된다. 조우 시에는 중단하고 보고한다.
|
|
@@ -590,12 +590,25 @@ EOF
|
|
|
590
590
|
# ([[feedback_ci_measures_state_not_transition]] 의 데이터 판본).
|
|
591
591
|
# 앵커를 **추적되는 파일**로 옮긴다 — `.claude/capabilities/*.cap` 은 커밋돼 있어
|
|
592
592
|
# 어느 체크아웃에서도 존재한다. 수집 경로가 죽으면 이 카운트가 0 이 되어 빨개진다.
|
|
593
|
+
# 🟥 2026-08-20 — 이 레인은 **두 군데가 저자의 체크아웃에 결박**돼 있었고, 소비자 설치에서
|
|
594
|
+
# 전건 적색이었다(실측: 레지스트리 실물 2.5.1 에서 `discover` rc=10 → selfcheck FAIL).
|
|
595
|
+
# ⓐ 전제: `discover` 는 `tracks/` 매핑 목록을 전제하는데 `tracks/` 는 gitignored 라
|
|
596
|
+
# **배포물에 구조적으로 존재할 수 없다.** 부재는 «능력 0» 이 아니라 **미측정**이므로
|
|
597
|
+
# FAIL 이 아니라 이름 있는 SKIP 으로 낸다([[feedback_not_found_is_not_zero_family]]).
|
|
598
|
+
# ⓑ 🟥 **초판이 여기서 틀렸고, cross-family(codex/gpt-5.5)가 잡았다 — 자력 적발 0.**
|
|
599
|
+
# 기대 문자열 `^forge-harness\(hub\)` 를 «폴더명 결박» 으로 읽고 `basename` 유도로
|
|
600
|
+
# 바꿨는데, **생산자(:128)는 리터럴 `forge-harness(hub)` 를 낸다.** 즉 유도로 바꾸면
|
|
601
|
+
# 이름이 다른 트리에서 기대와 산출이 갈려 **거짓 FAIL** 이 된다 — 이 파일이 바로 위에서
|
|
602
|
+
# 경고하는 divergent-normalizer 를 수리가 새로 만든 꼴이다. 되돌렸다.
|
|
603
|
+
# 진단 정정: 이 라벨은 «디렉터리 이름»이 아니라 **허브의 상수 식별자**다. 양쪽이 같은
|
|
604
|
+
# 상수를 쓰는 한 어느 체크아웃에서도 일치하므로 결박이 아니다. 결박은 ⓐ 하나였다.
|
|
605
|
+
local _hubroot
|
|
606
|
+
_hubroot="$(cd -P "$(dirname "$SELF")/.." && pwd)"
|
|
607
|
+
tracked_n="$(_cap_files "$_hubroot/.claude/capabilities" | wc -l | tr -d ' ')"
|
|
593
608
|
out="$(bash "$SELF" discover 2>&1)"; rc=$?
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
tracked_n="$(_cap_files "$(cd -P "$(dirname "$SELF")/.." && pwd)/.claude/capabilities" | wc -l | tr -d ' ')"
|
|
598
|
-
if [ "${tracked_n:-0}" -lt 1 ]; then
|
|
609
|
+
if [ ! -d "$_hubroot/tracks" ]; then
|
|
610
|
+
echo " ⏭ L13c SKIP — tracks/ 부재라 discover 의 전제가 없다(gitignored, 배포물에 구조적 부재). 미측정이지 «0건» 아님"
|
|
611
|
+
elif [ "${tracked_n:-0}" -lt 1 ]; then
|
|
599
612
|
f=$((f+1)); echo " ❌ L13c 전제 파손 — 추적되는 .claude/capabilities/*.cap 이 0건이다(앵커 대상 부재)"
|
|
600
613
|
elif printf '%s' "$out" | grep -qE '^forge-harness\(hub\)[[:space:]]+OK[[:space:]]+'"$tracked_n"'[[:space:]]'; then
|
|
601
614
|
p=$((p+1)); echo " ✅ L13c 실물 수집이 살아 있다 — 허브 자신의 추적 선언 ${tracked_n}건을 실제로 집었다"
|
|
@@ -100,7 +100,12 @@ CHECKER="$SELF_DIR/utterance_landing_check.sh"
|
|
|
100
100
|
# 다중 경로 지원과의 트레이드오프라 오늘은 **문서화만** 했고 기계 검사는 없다.
|
|
101
101
|
DLC_TRACKED_PATHS="${DLC_TRACKED_PATHS:-knowledge CLAUDE.md}" # git 추적축 (커밋시각)
|
|
102
102
|
DLC_IGNORED_DIR="${DLC_IGNORED_DIR-tracks/_meta}" # gitignored 축 (mtime). 빈 값 = 그 축 없음
|
|
103
|
-
|
|
103
|
+
# 🟥 2026-08-19 — 이 정규식은 **FH 자기 어휘**였고 오버라이드가 없었다. 위성 산출의 절 제목은
|
|
104
|
+
# 대상 프로필이 정한다(`## <대상> Application Candidates`) — 즉 계기가 **대상 레포에서는 구조적으로
|
|
105
|
+
# 후보를 못 찾는다.** 실측: forge-wiki·the-bible 둘 다 rc=10. R1(디렉터리를 타깃 파일로 넘김)과
|
|
106
|
+
# 같은 계열이다 — 「배선 완료」로 보고된 계기가 대상 축에서 죽어 있는 형태.
|
|
107
|
+
# 기본값은 종전 그대로라 FH 자기 런은 무변경.
|
|
108
|
+
SECTION_RE="${DLC_SECTION_RE:-^## .*Immediate Application Candidates}"
|
|
104
109
|
|
|
105
110
|
# 후보 표에서 (id, 판별토큰 OR 정규식) 을 뽑는다. 토큰 없으면 id 만 내고 정규식은 빈 값.
|
|
106
111
|
_extract() { # $1 = digest path
|
|
@@ -362,6 +367,18 @@ do_check() {
|
|
|
362
367
|
}
|
|
363
368
|
|
|
364
369
|
do_self_test() {
|
|
370
|
+
# 🟥 2026-08-20 — 아래 레인들은 컨트롤을 **픽스처가 실제로 담은 토큰으로 고정**한다.
|
|
371
|
+
# 고정 전에는 컨트롤이 `basename "$FH"` 로 유도됐고, 픽스처 카드가 리터럴
|
|
372
|
+
# `forge-harness session card` 를 담고 있어서 **체크아웃 디렉터리 이름이 `forge-harness`
|
|
373
|
+
# 일 때만** 컨트롤이 살았다. npm 소비자는 `node_modules/@chrono-meta/fh-gate` 에 깔리므로
|
|
374
|
+
# 거기서는 컨트롤이 전건 사망 → 착지 판정 레인 5개가 전부 rc=10 이 됐다.
|
|
375
|
+
# known-pair 실측(같은 바이트, 디렉터리명만 교체): `forge-harness/` 15/15 PASS ·
|
|
376
|
+
# `some-consumer-app/` 5/15 FAIL. 즉 계기가 **저자의 폴더 이름에 결박**돼 있었다.
|
|
377
|
+
# 🟥 «10 을 기대하는» 레인들도 같이 고정한다 — 그 레인들은 고정 전에도 10 을 냈지만
|
|
378
|
+
# 그건 **의도한 사유가 아니라 컨트롤 사망** 때문이었다(거짓 초록).
|
|
379
|
+
# 🟥 N1(컨트롤 사망)·★N-ctl(유도가 도는가)·★N-ctl-re 는 **일부러** 유도/사망을 주장하므로
|
|
380
|
+
# 고정하지 않는다. 거기에 넣으면 그 레인의 주장이 뒤집힌다.
|
|
381
|
+
# 선행 관용구 = 이 파일의 ★N-git 레인(“컨트롤은 픽스처가 담은 토큰으로 고정”).
|
|
365
382
|
local T; T="$(mktemp -d -t dlc_t.XXXXXX)" || return 10
|
|
366
383
|
local pass=0 fail=0 rc
|
|
367
384
|
_t() { if [ "$2" = "$3" ]; then echo "✅ $1 → rc=$3"; pass=$((pass+1));
|
|
@@ -384,12 +401,12 @@ EOF
|
|
|
384
401
|
printf 'forge-harness session card\nallow_force_pushes 잔여가 거짓임을 실측했다\n' > "$T/tgt/card.md"
|
|
385
402
|
|
|
386
403
|
# P1 — 착지분과 미착지분이 섞이면 rc=1 (미착지 있음)
|
|
387
|
-
rc=0; bash "$SELF_DIR/$(basename "${BASH_SOURCE[0]}")" "$T/digest.md" "$T/tgt/card.md" >/dev/null 2>&1 || rc=$?
|
|
404
|
+
rc=0; DLC_CONTROLS="forge-harness session" bash "$SELF_DIR/$(basename "${BASH_SOURCE[0]}")" "$T/digest.md" "$T/tgt/card.md" >/dev/null 2>&1 || rc=$?
|
|
388
405
|
_t "M2 착지 · R2 미착지 → 미착지 검출(1)" 1 "$rc"
|
|
389
406
|
|
|
390
407
|
# P2 — 둘 다 착지시키면 0
|
|
391
408
|
printf 'prime_agent_sister_asset 도 기록했다\n' >> "$T/tgt/card.md"
|
|
392
|
-
rc=0; bash "$SELF_DIR/$(basename "${BASH_SOURCE[0]}")" "$T/digest.md" "$T/tgt/card.md" >/dev/null 2>&1 || rc=$?
|
|
409
|
+
rc=0; DLC_CONTROLS="forge-harness session" bash "$SELF_DIR/$(basename "${BASH_SOURCE[0]}")" "$T/digest.md" "$T/tgt/card.md" >/dev/null 2>&1 || rc=$?
|
|
393
410
|
_t "둘 다 착지 → 전건 착지(0)" 0 "$rc"
|
|
394
411
|
|
|
395
412
|
# N1 — 컨트롤 사망(타깃에 컨트롤 토큰이 없다) → HARNESS-ERROR(10), PASS 도 FAIL 도 아님
|
|
@@ -506,7 +523,7 @@ EOF
|
|
|
506
523
|
# N2a — 후보가 **전부** 판별불가면 TARGET 이 0건이다. 이건 "미착지" 가 아니라
|
|
507
524
|
# **계기 부적용**이고, 착지 검증기가 rc=10(PASS 도 FAIL 도 아님)을 낸다.
|
|
508
525
|
# 초판은 여기 기대값을 1 로 적었는데 **내 기대가 틀렸다** — 전부 못 쟀으면 에러다.
|
|
509
|
-
rc=0; bash "$SELF_DIR/$(basename "${BASH_SOURCE[0]}")" "$T/digest_unchk.md" "$T/tgt/card.md" >/dev/null 2>&1 || rc=$?
|
|
526
|
+
rc=0; DLC_CONTROLS="forge-harness session" bash "$SELF_DIR/$(basename "${BASH_SOURCE[0]}")" "$T/digest_unchk.md" "$T/tgt/card.md" >/dev/null 2>&1 || rc=$?
|
|
510
527
|
_t "판별불가만 있는 digest → HARNESS-ERROR(10), '착지 0건' 아님" 10 "$rc"
|
|
511
528
|
|
|
512
529
|
# N2b ★ 진짜 중요한 레인 — **혼합**. 잴 수 있는 건 전부 착지했는데 판별불가가 섞였다.
|
|
@@ -522,20 +539,34 @@ EOF
|
|
|
522
539
|
|
|
523
540
|
## end
|
|
524
541
|
EOF
|
|
525
|
-
rc=0; bash "$SELF_DIR/$(basename "${BASH_SOURCE[0]}")" "$T/digest_mixed.md" "$T/tgt/card.md" >/dev/null 2>&1 || rc=$?
|
|
542
|
+
rc=0; DLC_CONTROLS="forge-harness session" bash "$SELF_DIR/$(basename "${BASH_SOURCE[0]}")" "$T/digest_mixed.md" "$T/tgt/card.md" >/dev/null 2>&1 || rc=$?
|
|
526
543
|
_t "★혼합(착지 전건 + 판별불가 1) → 0 아님(미측정을 분모에서 안 지운다)" 1 "$rc"
|
|
527
544
|
|
|
528
545
|
# N3 — 후보 절이 없는 digest → 10 (0건과 미검출을 가른다)
|
|
529
546
|
printf '# digest\n## 다른 절\n내용\n' > "$T/nosection.md"
|
|
530
|
-
rc=0; bash "$SELF_DIR/$(basename "${BASH_SOURCE[0]}")" "$T/nosection.md" "$T/tgt/card.md" >/dev/null 2>&1 || rc=$?
|
|
547
|
+
rc=0; DLC_CONTROLS="forge-harness session" bash "$SELF_DIR/$(basename "${BASH_SOURCE[0]}")" "$T/nosection.md" "$T/tgt/card.md" >/dev/null 2>&1 || rc=$?
|
|
531
548
|
_t "후보 절 부재 → HARNESS-ERROR(10), '0건 착지' 아님" 10 "$rc"
|
|
532
549
|
|
|
550
|
+
# N3-b — **대상 어휘 절 제목**은 기본 정규식으로 못 찾고, DLC_SECTION_RE 로는 찾는다.
|
|
551
|
+
# 🟥 2026-08-19 첫 실사용 발견: 위성 산출의 절 이름은 대상 프로필이 정하는데
|
|
552
|
+
# (`## <대상> Application Candidates`) 체커 기본값은 FH 어휘(`Immediate ...`)라
|
|
553
|
+
# **위성에서는 구조적으로 rc=10** 이었다(forge-wiki·the-bible 양쪽 실측).
|
|
554
|
+
# 🟥 픽스처의 후보 머리는 **`**` 형식**이어야 한다 — 평범한 `- ` 불릿은 항목으로 안 잡혀
|
|
555
|
+
# arm 도 10 을 내고, 그러면 이 레인이 «오버라이드가 안 먹는다» 는 거짓 결론을 낸다
|
|
556
|
+
# (초판이 그렇게 틀렸다 — 픽스처는 뚫리는 표기로 골라야 한다).
|
|
557
|
+
printf '# digest\n## the-target Application Candidates\n**[A] 후보** — `%s` 를 고친다\n' "card.md" > "$T/targetvocab.md"
|
|
558
|
+
rc=0; DLC_CONTROLS="forge-harness session" bash "$SELF_DIR/$(basename "${BASH_SOURCE[0]}")" "$T/targetvocab.md" "$T/tgt/card.md" >/dev/null 2>&1 || rc=$?
|
|
559
|
+
_t "★N3-b control — 대상 어휘 절은 기본 정규식으로 못 찾는다(10)" 10 "$rc"
|
|
560
|
+
rc=0; DLC_SECTION_RE='^## .*Application Candidates' \
|
|
561
|
+
DLC_CONTROLS="forge-harness session" bash "$SELF_DIR/$(basename "${BASH_SOURCE[0]}")" "$T/targetvocab.md" "$T/tgt/card.md" >/dev/null 2>&1 || rc=$?
|
|
562
|
+
_t "★N3-b arm — DLC_SECTION_RE 오버라이드가 절을 찾는다(10 아님)" "not10" "$([ "$rc" -eq 10 ] && echo is10 || echo not10)"
|
|
563
|
+
|
|
533
564
|
# N4 — digest 파일 자체가 없음 → 10
|
|
534
|
-
rc=0; bash "$SELF_DIR/$(basename "${BASH_SOURCE[0]}")" "$T/does-not-exist.md" >/dev/null 2>&1 || rc=$?
|
|
565
|
+
rc=0; DLC_CONTROLS="forge-harness session" bash "$SELF_DIR/$(basename "${BASH_SOURCE[0]}")" "$T/does-not-exist.md" >/dev/null 2>&1 || rc=$?
|
|
535
566
|
_t "digest 부재 → rc=10" 10 "$rc"
|
|
536
567
|
|
|
537
568
|
# N5 컨트롤 — P2 가 여전히 0 인가 (앞 레인이 상태를 오염시키지 않았는지)
|
|
538
|
-
rc=0; bash "$SELF_DIR/$(basename "${BASH_SOURCE[0]}")" "$T/digest.md" "$T/tgt/card.md" >/dev/null 2>&1 || rc=$?
|
|
569
|
+
rc=0; DLC_CONTROLS="forge-harness session" bash "$SELF_DIR/$(basename "${BASH_SOURCE[0]}")" "$T/digest.md" "$T/tgt/card.md" >/dev/null 2>&1 || rc=$?
|
|
539
570
|
_t "컨트롤 — 정상 케이스 재확인" 0 "$rc"
|
|
540
571
|
|
|
541
572
|
rm -rf "$T"
|
|
@@ -110,6 +110,15 @@ ACCEPTED_ABSENT=(
|
|
|
110
110
|
# honest state is "declared, and the declaration records a debt" — carried to the card.
|
|
111
111
|
"scripts/test_chamber_run_lanes.sh"
|
|
112
112
|
"scripts/test_frontier_digest_retry.sh"
|
|
113
|
+
# · test_satellite_publish_gate_lanes.sh / test_satellite_profile_schema_lanes.sh
|
|
114
|
+
# — 2026-08-20. 같은 모양이고, 둘 다 **이미 files[] 에 들어간 채 배포된 뒤에** 잡혔다.
|
|
115
|
+
# 주체가 frontier_digest_daily.sh(아래 ACCEPTED_ABSENT)라 소비자 머신엔 잴 대상이 없다.
|
|
116
|
+
# 🟥 실측(레지스트리 실물 2.5.1, 소비자 설치에서 실행): publish_gate 4 passed / 21 failed,
|
|
117
|
+
# `rc=127`(러너 부재) → selfcheck 가 하드 FAIL → **배포본이 `SELFCHECK: FAIL` 이었다.**
|
|
118
|
+
# 🟥 이 검사기는 그걸 rc=0 으로 통과시켰다 — 여기는 「참조된 경로가 출하되나」를 보지
|
|
119
|
+
# 「출하된 레인의 **주체**가 출하되나」를 안 본다. 그 갭은 아직 안 닫혔다(명시 잔여).
|
|
120
|
+
"scripts/test_satellite_publish_gate_lanes.sh"
|
|
121
|
+
"scripts/test_satellite_profile_schema_lanes.sh"
|
|
113
122
|
"scripts/residency_closure_scan.py"
|
|
114
123
|
"scripts/test_residency_closure_lanes.sh"
|
|
115
124
|
# ── The two settings destinations, surfaced 2026-08-13 by fixing this file's own extractor ────
|
package/scripts/selfcheck.sh
CHANGED
|
@@ -707,7 +707,18 @@ fi
|
|
|
707
707
|
# 🟥 이 배선이 없어서 CI 가 `lane-runner: lane suite(s) with no runner and no declaration` 로
|
|
708
708
|
# 빨갰다. 스위트를 신설하고 아무 데서도 안 돌린 것 — 검사기의 표현대로
|
|
709
709
|
# *"A suite nothing executes is prose."* 그 검사기가 내 신설 레인을 잡았다.
|
|
710
|
-
|
|
710
|
+
# 🟥 2026-08-20 — 대상 축 가드. 이 두 레인의 **주체는 `scripts/frontier_digest_daily.sh`** 이고
|
|
711
|
+
# 그 러너는 의도적으로 출하 대상이 아니다(소비자 계정으로 `claude` CLI 를 태우고 `tracks/` 에 쓴다 —
|
|
712
|
+
# `package_coverage_check.sh` ACCEPTED_ABSENT 가 그 이유를 명시한다). 가드 전에는 레인 파일 존재만
|
|
713
|
+
# 봤기 때문에, 소비자 설치에서 러너가 없는 채로 레인이 실행돼 **rc=127 로 무더기 FAIL** 했다.
|
|
714
|
+
# 실측(레지스트리 실물 2.5.1): publish_gate 4 passed / 21 failed → `SELFCHECK: FAIL`.
|
|
715
|
+
# 🟥 그리고 통과한 쪽이 더 나빴다 — "G1b dispatch 자체가 안 일어남 ✅" 은 러너가 **없어서** 통과한
|
|
716
|
+
# 거짓 초록이다([[feedback_not_found_is_not_zero_family]]).
|
|
717
|
+
# 판정은 `_absent_subject_verdict` 한 곳에 위임한다 — 「files[] 에 없고 부재」면 SKIP,
|
|
718
|
+
# 「출하 선언됐는데 부재」면 삭제/깨진 설치라 FAIL, 매니페스트를 못 읽으면 UNDECIDABLE 로 FAIL.
|
|
719
|
+
if [ ! -f scripts/frontier_digest_daily.sh ]; then
|
|
720
|
+
_absent_subject_verdict "test_satellite_publish_gate_lanes.sh" "scripts/frontier_digest_daily.sh" || fail=1
|
|
721
|
+
elif [ ! -f scripts/test_satellite_publish_gate_lanes.sh ]; then
|
|
711
722
|
echo "FAIL test_satellite_publish_gate_lanes.sh: missing — publish gate has no anchor"
|
|
712
723
|
fail=1
|
|
713
724
|
elif _out=$(bash scripts/test_satellite_publish_gate_lanes.sh < /dev/null 2>&1); then
|
|
@@ -718,6 +729,23 @@ else
|
|
|
718
729
|
fail=1
|
|
719
730
|
fi
|
|
720
731
|
|
|
732
|
+
# test_satellite_profile_schema_lanes — 프로필 스키마 게이트(2026-08-19, 처방 1+3 · C-2).
|
|
733
|
+
# 🟥 신설하고 안 배선해서 `lane-runner: A suite nothing executes is prose` 로 CI 가 빨갰다.
|
|
734
|
+
# 바로 윗 블록이 **같은 사고의 기록**인데 그걸 읽고도 같은 실수를 했다 — 산문은 자기
|
|
735
|
+
# 바로 위에 있어도 안 읽힌다는 실측이고, 잡은 것은 검사기다.
|
|
736
|
+
if [ ! -f scripts/frontier_digest_daily.sh ]; then
|
|
737
|
+
_absent_subject_verdict "test_satellite_profile_schema_lanes.sh" "scripts/frontier_digest_daily.sh" || fail=1
|
|
738
|
+
elif [ ! -f scripts/test_satellite_profile_schema_lanes.sh ]; then
|
|
739
|
+
echo "FAIL test_satellite_profile_schema_lanes.sh: missing — 프로필 스키마 게이트에 앵커 없음"
|
|
740
|
+
fail=1
|
|
741
|
+
elif _out=$(bash scripts/test_satellite_profile_schema_lanes.sh < /dev/null 2>&1); then
|
|
742
|
+
echo "PASS test_satellite_profile_schema_lanes.sh ($(printf '%s\n' "$_out" | grep -oE 'PASS=[0-9]+ FAIL=[0-9]+' | tail -1))"
|
|
743
|
+
else
|
|
744
|
+
echo "FAIL test_satellite_profile_schema_lanes.sh: 프로필 스키마 레인 실패"
|
|
745
|
+
_show_failure "$_out"
|
|
746
|
+
fail=1
|
|
747
|
+
fi
|
|
748
|
+
|
|
721
749
|
# test_evidence_root_psa_lanes — 워크트리에서 기밀성 오버라이드를 찾는가 (R4, 2026-08-18).
|
|
722
750
|
# 🟥 `EVIDENCE_ROOT` 에는 레인이 **하나도 없었다** — 그래서 `tracks/` 만 옮기고 gitignored
|
|
723
751
|
# 패턴 파일은 안 옮긴 반쪽-픽스가 그대로 출하됐다. 되돌림 프로브로 E1 만 적색 확인.
|
|
@@ -1,339 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bash
|
|
2
|
-
# test_satellite_publish_gate_lanes.sh — known-pair anchor for the satellite's publish gate.
|
|
3
|
-
#
|
|
4
|
-
# WHY (2026-08-18, 원정 2차)
|
|
5
|
-
# frontier_digest_daily.sh 는 FH 자신만 대상으로 지어졌고, FH 의 digest 는 gitignored
|
|
6
|
-
# `tracks/` 에 떨어진다 — 그래서 **공개 노출 문제가 없었다**. 위성이 **공개 레포**를 대상으로
|
|
7
|
-
# 돌면 **매 런이 publish** 다(비가역 표면). §Irreversibility Surface-Class Degrade Invariant:
|
|
8
|
-
# 비가역 표면은 fail-CLOSED — 스캐너가 못 재면 «통과»가 아니라 «보류»다.
|
|
9
|
-
#
|
|
10
|
-
# 🟥 이 스위트의 진짜 주장은 «스캔한다»가 아니라 **«세 값을 두 값으로 접지 않는다»** 다.
|
|
11
|
-
# CLEAN(0) · LEAK(1) · NOT-SCANNED(3) 은 처방이 각각 다르다: 각각 게시 / 격리 / 보류.
|
|
12
|
-
# 접으면 «못 쟀다»가 «깨끗하다»로 렌더된다 — [[feedback_not_found_is_not_zero_family]].
|
|
13
|
-
#
|
|
14
|
-
# Lanes
|
|
15
|
-
# P1 CLEAN → rc=0, 파일 그대로 (게시)
|
|
16
|
-
# P2 LEAK → rc=2, 파일이 .QUARANTINE 로 격리 (게시 안 됨)
|
|
17
|
-
# P3 NOT-SCAN → rc=3, 파일이 .UNSCANNED 로 보류 (게시 안 됨) — 스캐너가 죽어도 fail-closed
|
|
18
|
-
# N1 CONTROL — FD_PUBLIC_TARGET 미설정 → 게이트 자체가 안 돈다 (FH 프로덕션 경로 무변경)
|
|
19
|
-
# N2 CONTROL — P2 와 P3 의 rc 가 **다르다**(2 vs 3). 같으면 두 실패가 한 값으로 접힌 것이다
|
|
20
|
-
# P4 착지 증언이 **실제로 로그에 찍힌다** — 직전 digest 가 없으면 «SKIPPED (not a pass)».
|
|
21
|
-
# 배선했다 ≠ 발화한다. 그리고 SKIP 을 통과로 렌더하지 않는 것까지 주장한다
|
|
22
|
-
#
|
|
23
|
-
# R1 착지 증언이 **살아 있다** — 러너가 부르는 형태로 rc=10(계기 사망)이 아니어야 한다
|
|
24
|
-
# R1n CONTROL — 옛 형태(디렉터리를 타깃으로)는 지금도 rc=10 이다. 고친 게 이거라는 증명
|
|
25
|
-
# R2 공개 대상이면 로그가 **OUT_DIR 밖**이다 / R2n CONTROL — 비공개면 종전 자리 그대로
|
|
26
|
-
# R2b LEAK 로그에 **토큰 원문이 없다**(리댁션) — 유출을 격리하며 같은 자리에 복사하지 않는다
|
|
27
|
-
# R3 같은 날 파일이 둘이고 **뒤엣것이 LEAK** 이면 rc=2 — head -1 이면 CLEAN 이 나온다
|
|
28
|
-
#
|
|
29
|
-
# Exit 0 = 전 레인.
|
|
30
|
-
set -u
|
|
31
|
-
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
32
|
-
# 🟥 arm 간 전달 파일을 **고정 `/tmp` 이름**으로 쓰면 안 된다 (보안 패스 2026-08-18, MED·재현됨).
|
|
33
|
-
# `/tmp/.lw_clean` · `/tmp/.lg_leak` 처럼 이름이 6개 전부 고정이라 심볼릭 링크 선점으로
|
|
34
|
-
# 임의 파일이 덮인다(`cp` 가 링크를 따라간다). 게다가 정리 코드가 없어 게이트 **로그 사본**이
|
|
35
|
-
# `/tmp` 에 644 로 영구히 남았다 — 기밀성 축의 정반대 방향이다.
|
|
36
|
-
SCRATCH="$(mktemp -d "${TMPDIR:-/tmp}/fh_satlane.XXXXXX")" || exit 1
|
|
37
|
-
trap 'rm -rf "$SCRATCH"' EXIT
|
|
38
|
-
pass=0; fail=0
|
|
39
|
-
t() { if [ "$2" = "$3" ]; then echo " ✅ $1"; pass=$((pass+1)); else echo " ❌ $1 — got [$3] want [$2]"; fail=$((fail+1)); fi }
|
|
40
|
-
|
|
41
|
-
run() { # $1 = digest body · $2 = psa_lib override ("dead") · $3 = arm 이름 → echoes "rc|state"
|
|
42
|
-
local td; td=$(mktemp -d)
|
|
43
|
-
mkdir -p "$td/scripts" "$td/out" "$td/.claude/rules"
|
|
44
|
-
cp "$ROOT/scripts/frontier_digest_daily.sh" "$td/scripts/"
|
|
45
|
-
cp "$ROOT/.claude/rules/.public-surface-patterns.defaults" "$td/.claude/rules/" 2>/dev/null
|
|
46
|
-
# 🟥 오버라이드 파일이 없으면 스캐너는 `override_absent(HIGH operator literals unscanned)` 로
|
|
47
|
-
# **NOT SCANNED** 를 낸다 — MED 히트를 찾고도 «부분 커버리지는 판정이 아니다»라며 거부한다.
|
|
48
|
-
# 엄격하게 옳은 동작이고, 그래서 이 픽스처는 **합성 리터럴**로 자립시킨다: 운영자의 실제
|
|
49
|
-
# 리터럴에 의존하면 이 스위트가 그 파일의 존재 여부에 따라 갈린다.
|
|
50
|
-
printf 'HIGH\tZZ_SYNTHETIC_LEAK_TOKEN_ZZ\n' > "$td/.claude/rules/.public-surface-patterns"
|
|
51
|
-
if [ "$2" = "dead" ]; then printf '#!/usr/bin/env bash\npsa_load(){ :; }\npsa_scan_file(){ return 3; }\n' > "$td/scripts/psa_scan_lib.sh"
|
|
52
|
-
else cp "$ROOT/scripts/psa_scan_lib.sh" "$td/scripts/"; fi
|
|
53
|
-
printf '%s\n' "$1" > "$td/out/frontier_digest_$(date +%Y_%m_%d).md"
|
|
54
|
-
# 러너가 digest_ready 로 이미 있는 파일을 보고 조기 종료하지 않도록, 게이트 경로를 직접 태운다:
|
|
55
|
-
# attempt 루프 진입 전에 skip 하므로 여기서는 러너 본체 대신 게이트 분기만 재현할 수 없다.
|
|
56
|
-
# → 러너를 그대로 돌리되 CLAUDE_BIN 을 no-op 스텁으로 줘서 attempt 를 태운다.
|
|
57
|
-
printf '#!/usr/bin/env bash\nexit 0\n' > "$td/scripts/stub-claude"; chmod +x "$td/scripts/stub-claude"
|
|
58
|
-
local out rc
|
|
59
|
-
# R2 이후 공개 대상의 로그는 OUT_DIR 밖이다 — arm 은 자기 위치를 명시한다(레인이 로그를 읽어야 하므로)
|
|
60
|
-
out=$(cd "$td" && FD_FH_DIR="$td" FD_OUT_DIR="out" FD_PUBLIC_TARGET=1 \
|
|
61
|
-
FD_LOG_DIR="$td/logs" \
|
|
62
|
-
FD_CLAUDE_BIN="$td/scripts/stub-claude" FD_MAX_ATTEMPTS=1 FD_ATTEMPT_TIMEOUT_SECS=20 \
|
|
63
|
-
FD_POLL_SECS=1 bash scripts/frontier_digest_daily.sh 2>&1); rc=$?
|
|
64
|
-
local state=none
|
|
65
|
-
ls "$td/out/"*.QUARANTINE >/dev/null 2>&1 && state=quarantine
|
|
66
|
-
ls "$td/out/"*.UNSCANNED >/dev/null 2>&1 && state=unscanned
|
|
67
|
-
ls "$td/out/"*.md >/dev/null 2>&1 && [ "$state" = none ] && state=published
|
|
68
|
-
# 착지 증언이 로그에 남았는지 (P4 가 읽는다)
|
|
69
|
-
# 🟥 arm 마다 따로 남긴다. 초판은 단일 파일에 덮어써서 **마지막 arm(P3, 스캐너 사망)** 것을
|
|
70
|
-
# 잡았는데, 거기선 게이트가 실패해 증언이 안 도는 게 정상이다 — 레인이 정상 동작을 실패로
|
|
71
|
-
# 렌더할 뻔했다. 판정 대상 arm 을 이름으로 고른다.
|
|
72
|
-
grep -h "landing witness" "$td/logs/"*.log 2>/dev/null | head -1 > "$SCRATCH/lw_$3" || :
|
|
73
|
-
# R2 레인이 읽는다: LEAK arm 의 로그에 토큰 원문이 남았나
|
|
74
|
-
cp "$td/logs/"*.log "$SCRATCH/lg_$3" 2>/dev/null || :
|
|
75
|
-
echo "$rc|$state"
|
|
76
|
-
rm -rf "$td"
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
CLEAN_BODY="# digest
|
|
80
|
-
A clean digest with no operator-private tokens. $(head -c 1200 /dev/zero | tr '\0' 'x')"
|
|
81
|
-
LEAK_BODY="# digest
|
|
82
|
-
this line carries ZZ_SYNTHETIC_LEAK_TOKEN_ZZ which the fixture pattern file flags HIGH. $(head -c 1200 /dev/zero | tr '\0' 'x')"
|
|
83
|
-
|
|
84
|
-
r=$(run "$CLEAN_BODY" live clean); t "P1 CLEAN → 게시" "0|published" "$r"
|
|
85
|
-
r=$(run "$LEAK_BODY" live leak); t "P2 LEAK → 격리(.QUARANTINE)" "2|quarantine" "$r"; P2RC=${r%%|*}
|
|
86
|
-
r=$(run "$CLEAN_BODY" dead dead); t "P3 스캐너 사망 → 보류(.UNSCANNED)" "3|unscanned" "$r"; P3RC=${r%%|*}
|
|
87
|
-
|
|
88
|
-
# N1 — 게이트 미활성(FD_PUBLIC_TARGET 없음)이면 LEAK 본문이어도 게시된다 = FH 경로 무변경
|
|
89
|
-
td=$(mktemp -d); mkdir -p "$td/scripts" "$td/out" "$td/.claude/rules"
|
|
90
|
-
cp "$ROOT/scripts/frontier_digest_daily.sh" "$ROOT/scripts/psa_scan_lib.sh" "$td/scripts/"
|
|
91
|
-
cp "$ROOT/.claude/rules/.public-surface-patterns.defaults" "$td/.claude/rules/" 2>/dev/null
|
|
92
|
-
printf '%s\n' "$LEAK_BODY" > "$td/out/frontier_digest_$(date +%Y_%m_%d).md"
|
|
93
|
-
printf '#!/usr/bin/env bash\nexit 0\n' > "$td/scripts/stub-claude"; chmod +x "$td/scripts/stub-claude"
|
|
94
|
-
out=$(cd "$td" && FD_FH_DIR="$td" FD_OUT_DIR="out" FD_CLAUDE_BIN="$td/scripts/stub-claude" \
|
|
95
|
-
FD_MAX_ATTEMPTS=1 FD_POLL_SECS=1 bash scripts/frontier_digest_daily.sh 2>&1); n1rc=$?
|
|
96
|
-
n1state=published; ls "$td/out/"*.QUARANTINE >/dev/null 2>&1 && n1state=quarantine
|
|
97
|
-
t "N1 control — 게이트 미활성이면 안 돈다(FH 경로 무변경)" "0|published" "$n1rc|$n1state"
|
|
98
|
-
rm -rf "$td"
|
|
99
|
-
|
|
100
|
-
lw=$(cat "$SCRATCH/lw_clean" 2>/dev/null) # 게이트가 CLEAN 인 arm 에서만 증언이 돈다
|
|
101
|
-
case "$lw" in *"landing witness"*) r=logged ;; *) r=absent ;; esac
|
|
102
|
-
t "P4 착지 증언이 로그에 찍힌다(배선했다≠발화한다)" "logged" "$r"
|
|
103
|
-
case "$lw" in *"SKIPPED (not a pass)"*) r=honest ;; *"ALL-LANDED"*) r=honest ;; *"SOME-UNLANDED"*) r=honest ;; *"HARNESS-ERROR"*) r=honest ;; *) r=other ;; esac
|
|
104
|
-
t "P4b SKIP 을 통과로 렌더하지 않는다" "honest" "$r"
|
|
105
|
-
|
|
106
|
-
t "N2 control — LEAK 과 NOT-SCANNED 의 rc 가 다르다" "different" "$([ "${P2RC:-x}" != "${P3RC:-y}" ] && echo different || echo collapsed)"
|
|
107
|
-
|
|
108
|
-
# ── FD_PROFILE 갈래 (2026-08-18) ──────────────────────────────────────────
|
|
109
|
-
# 🟥 이 배선은 **한 번 소실됐다.** forge-wiki 워킹 사본에만 넣었다가 PR 정리 때 rm 했고,
|
|
110
|
-
# 그 사실을 몰라 다음 대상의 약한 산출을 «입장 티어가 낮다»·«스킬을 못 불렀다»로 오진했다.
|
|
111
|
-
# 산출물은 커밋됐는데 그걸 만든 코드가 없던 상태 — 그래서 레인으로 못 박는다.
|
|
112
|
-
_prompt() { FH_DIR="$1" OUT_DIR=out HUMAN_DATE=2026-08-18 TODAY=2026_08_18 PROFILE_PATH="$2" \
|
|
113
|
-
bash -c "$(sed -n '/^_build_prompt()/,/^}/p' "$ROOT/scripts/frontier_digest_daily.sh")
|
|
114
|
-
_build_prompt"; }
|
|
115
|
-
pd=$(mktemp -d); printf 'PROFILE_CANARY_BODY
|
|
116
|
-
' > "$pd/p.md"
|
|
117
|
-
case "$(_prompt "$pd" "p.md")" in *"PROFILE_CANARY_BODY"*) r=in ;; *) r=missing ;; esac
|
|
118
|
-
t "P5 프로필이 프롬프트에 실제로 실린다" "in" "$r"
|
|
119
|
-
case "$(_prompt "$pd" "p.md")" in *"STANDPOINT"*) r=yes ;; *) r=no ;; esac
|
|
120
|
-
t "P5b 입장 지시(대상 소스를 열어라)가 실린다" "yes" "$r"
|
|
121
|
-
case "$(_prompt "$pd" "")" in *"STANDPOINT"*|*"TARGET HARNESS"*) r=leaked ;; *) r=clean ;; esac
|
|
122
|
-
t "N3 control — 프로필 미설정이면 종전 문자열 그대로(FH 경로 무변경)" "clean" "$r"
|
|
123
|
-
case "$(_prompt "$pd" "nonexistent.md")" in *"STANDPOINT"*) r=leaked ;; *) r=clean ;; esac
|
|
124
|
-
t "N4 control — 프로필 경로가 없으면 조용히 종전 경로(존재하지 않는 파일을 실었다고 안 한다)" "clean" "$r"
|
|
125
|
-
rm -rf "$pd"
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
# ── R1~R3 (2026-08-18) · 압축 후 수리분 앵커 ───────────────────────────────
|
|
129
|
-
# 🟥 세 결함 다 **내가 같은 날 만들었고**, 셋 다 레인이 없어서 「배선 완료」로 보고됐다.
|
|
130
|
-
|
|
131
|
-
# R2 · 공개 대상이면 로그가 OUT_DIR **밖**이다
|
|
132
|
-
_logloc() { # $1 = FD_PUBLIC_TARGET 값 → echoes inside|outside
|
|
133
|
-
local td; td=$(mktemp -d); mkdir -p "$td/scripts" "$td/out" "$td/.claude/rules"
|
|
134
|
-
cp "$ROOT/scripts/frontier_digest_daily.sh" "$td/scripts/"
|
|
135
|
-
cp "$ROOT/scripts/psa_scan_lib.sh" "$td/scripts/"
|
|
136
|
-
cp "$ROOT/.claude/rules/.public-surface-patterns.defaults" "$td/.claude/rules/" 2>/dev/null
|
|
137
|
-
printf 'HIGH\tZZ_SYNTHETIC_LEAK_TOKEN_ZZ\n' > "$td/.claude/rules/.public-surface-patterns"
|
|
138
|
-
printf '#!/usr/bin/env bash\nexit 0\n' > "$td/scripts/stub-claude"; chmod +x "$td/scripts/stub-claude"
|
|
139
|
-
printf 'clean body — 아무 토큰도 없다\n%s\n' "$(head -c 1200 /dev/zero | tr '\0' 'x')" \
|
|
140
|
-
> "$td/out/frontier_digest_$(date +%Y_%m_%d).md"
|
|
141
|
-
( cd "$td" && FD_FH_DIR="$td" FD_OUT_DIR="out" FD_PUBLIC_TARGET="$1" \
|
|
142
|
-
FD_CLAUDE_BIN="$td/scripts/stub-claude" FD_MAX_ATTEMPTS=1 FD_POLL_SECS=1 \
|
|
143
|
-
bash scripts/frontier_digest_daily.sh ) >/dev/null 2>&1
|
|
144
|
-
local r=outside
|
|
145
|
-
[ -d "$td/out/logs" ] && r=inside
|
|
146
|
-
echo "$r"; rm -rf "$td"
|
|
147
|
-
}
|
|
148
|
-
t "R2 공개 대상이면 로그가 OUT_DIR 밖에 앉는다" "outside" "$(_logloc 1)"
|
|
149
|
-
t "R2n control — 비공개면 종전 자리 그대로(FH 경로 무변경)" "inside" "$(_logloc 0)"
|
|
150
|
-
|
|
151
|
-
# R2b · LEAK 로그에 토큰 원문이 남지 않는다 (run() 이 "$SCRATCH/lg_leak" 에 복사해 둔다)
|
|
152
|
-
if [ -f "$SCRATCH/lg_leak" ]; then
|
|
153
|
-
if grep -q 'ZZ_SYNTHETIC_LEAK_TOKEN_ZZ' "$SCRATCH/lg_leak"; then r=raw
|
|
154
|
-
elif grep -q 'REDACTED' "$SCRATCH/lg_leak"; then r=redacted
|
|
155
|
-
else r=nofinding; fi
|
|
156
|
-
else r=nolog; fi
|
|
157
|
-
t "R2b LEAK 로그가 토큰 원문을 안 적는다(리댁션)" "redacted" "$r"
|
|
158
|
-
# R2c · 리댁션이 **allowlist 줄 형태**(끝이 `)`)도 가린다 — 초판은 줄 끝 앵커라 놓쳤다
|
|
159
|
-
_red() { bash -c "$(sed -n '/^_redact()/,/^}/p' "$ROOT/scripts/frontier_digest_daily.sh")
|
|
160
|
-
_redact \"\$1\"" _ "$1"; }
|
|
161
|
-
case "$(_red " ⚪ allowlisted — f.md: 'ZZ_TOK_ZZ' (row: f.md :: ZZ_TOK_ZZ)")" in
|
|
162
|
-
*ZZ_TOK_ZZ*) r=raw ;; *REDACTED*) r=redacted ;; *) r=other ;;
|
|
163
|
-
esac
|
|
164
|
-
t "R2c 리댁션이 allowlist 줄 형태도 가린다" "redacted" "$r"
|
|
165
|
-
case "$(_red " ❌ HIGH leak — f.md: 'ZZ_TOK_ZZ'")" in
|
|
166
|
-
*ZZ_TOK_ZZ*) r=raw ;; *REDACTED*) r=redacted ;; *) r=other ;;
|
|
167
|
-
esac
|
|
168
|
-
t "R2c-n control — 종전 형태(줄 끝 인용)도 여전히 가린다" "redacted" "$r"
|
|
169
|
-
|
|
170
|
-
# R2d · **경로 쪽** 토큰 (cross-family/codex F2) — 파일명에 토큰이 들어가면 왼쪽이 남았다
|
|
171
|
-
_leaky_name() {
|
|
172
|
-
local td; td=$(mktemp -d); mkdir -p "$td/scripts" "$td/out" "$td/.claude/rules"
|
|
173
|
-
cp "$ROOT/scripts/frontier_digest_daily.sh" "$ROOT/scripts/psa_scan_lib.sh" "$td/scripts/"
|
|
174
|
-
cp "$ROOT/.claude/rules/.public-surface-patterns.defaults" "$td/.claude/rules/" 2>/dev/null
|
|
175
|
-
printf 'HIGH\tZZ_SYNTHETIC_LEAK_TOKEN_ZZ\n' > "$td/.claude/rules/.public-surface-patterns"
|
|
176
|
-
printf '#!/usr/bin/env bash\nexit 0\n' > "$td/scripts/stub-claude"; chmod +x "$td/scripts/stub-claude"
|
|
177
|
-
local d; d=$(date +%Y_%m_%d)
|
|
178
|
-
# 🟥 파일명 자체에 토큰이 들어간 케이스. 본문에도 넣어야 스캐너가 히트를 낸다.
|
|
179
|
-
printf 'ZZ_SYNTHETIC_LEAK_TOKEN_ZZ\n%s\n' "$(head -c 1200 /dev/zero | tr '\0' 'x')" \
|
|
180
|
-
> "$td/out/frontier_digest_${d}-ZZ_SYNTHETIC_LEAK_TOKEN_ZZ.md"
|
|
181
|
-
( cd "$td" && FD_FH_DIR="$td" FD_OUT_DIR="out" FD_PUBLIC_TARGET=1 FD_LOG_DIR="$td/logs" \
|
|
182
|
-
FD_CLAUDE_BIN="$td/scripts/stub-claude" FD_MAX_ATTEMPTS=1 FD_POLL_SECS=1 \
|
|
183
|
-
bash scripts/frontier_digest_daily.sh ) >/dev/null 2>&1
|
|
184
|
-
if grep -q 'ZZ_SYNTHETIC_LEAK_TOKEN_ZZ' "$td/logs/"*.log 2>/dev/null; then echo raw
|
|
185
|
-
elif grep -q 'FILENAME REDACTED' "$td/logs/"*.log 2>/dev/null; then echo redacted
|
|
186
|
-
else echo other; fi
|
|
187
|
-
rm -rf "$td"
|
|
188
|
-
}
|
|
189
|
-
t "R2d 파일명에 든 토큰도 로그에 안 남는다" "redacted" "$(_leaky_name)"
|
|
190
|
-
|
|
191
|
-
# R3 · 같은 날 파일이 둘이면 **전부** 스캔한다 (head -1 이면 앞엣것만 보고 CLEAN 을 낸다)
|
|
192
|
-
_two_files() {
|
|
193
|
-
local td; td=$(mktemp -d); mkdir -p "$td/scripts" "$td/out" "$td/.claude/rules"
|
|
194
|
-
cp "$ROOT/scripts/frontier_digest_daily.sh" "$td/scripts/"
|
|
195
|
-
cp "$ROOT/scripts/psa_scan_lib.sh" "$td/scripts/"
|
|
196
|
-
cp "$ROOT/.claude/rules/.public-surface-patterns.defaults" "$td/.claude/rules/" 2>/dev/null
|
|
197
|
-
printf 'HIGH\tZZ_SYNTHETIC_LEAK_TOKEN_ZZ\n' > "$td/.claude/rules/.public-surface-patterns"
|
|
198
|
-
printf '#!/usr/bin/env bash\nexit 0\n' > "$td/scripts/stub-claude"; chmod +x "$td/scripts/stub-claude"
|
|
199
|
-
local d; d=$(date +%Y_%m_%d)
|
|
200
|
-
# 🟥 «먼저 걸리는» 쪽을 깨끗하게 둔다 — 초판(head -1)이면 이쪽만 보고 CLEAN 을 냈다.
|
|
201
|
-
printf 'aaa clean\n%s\n' "$(head -c 1200 /dev/zero | tr '\0' 'x')" > "$td/out/frontier_digest_${d}.md"
|
|
202
|
-
printf 'zzz ZZ_SYNTHETIC_LEAK_TOKEN_ZZ\n%s\n' "$(head -c 1200 /dev/zero | tr '\0' 'x')" \
|
|
203
|
-
> "$td/out/frontier_digest_${d}_b.md"
|
|
204
|
-
local rc
|
|
205
|
-
( cd "$td" && FD_FH_DIR="$td" FD_OUT_DIR="out" FD_PUBLIC_TARGET=1 FD_LOG_DIR="$td/logs" \
|
|
206
|
-
FD_CLAUDE_BIN="$td/scripts/stub-claude" FD_MAX_ATTEMPTS=1 FD_POLL_SECS=1 \
|
|
207
|
-
bash scripts/frontier_digest_daily.sh ) >/dev/null 2>&1; rc=$?
|
|
208
|
-
local q=no; ls "$td/out/"*_b.md.QUARANTINE >/dev/null 2>&1 && q=yes
|
|
209
|
-
echo "$rc|$q"; rm -rf "$td"
|
|
210
|
-
}
|
|
211
|
-
r=$(_two_files)
|
|
212
|
-
t "R3 둘째 파일의 LEAK 을 놓치지 않는다(rc)" "2" "${r%%|*}"
|
|
213
|
-
t "R3b 둘째 파일이 실제로 격리된다" "yes" "${r##*|}"
|
|
214
|
-
|
|
215
|
-
# R3c · 선택자 자기모순(digest_ready 참인데 게이트가 볼 파일 0건) → **보류**, 게시 아님
|
|
216
|
-
_selector_race() {
|
|
217
|
-
local td; td=$(mktemp -d); mkdir -p "$td/scripts" "$td/out" "$td/.claude/rules"
|
|
218
|
-
cp "$ROOT/scripts/frontier_digest_daily.sh" "$ROOT/scripts/psa_scan_lib.sh" "$td/scripts/"
|
|
219
|
-
cp "$ROOT/.claude/rules/.public-surface-patterns.defaults" "$td/.claude/rules/" 2>/dev/null
|
|
220
|
-
printf 'HIGH\tZZ_SYNTHETIC_LEAK_TOKEN_ZZ\n' > "$td/.claude/rules/.public-surface-patterns"
|
|
221
|
-
# digest_files 를 «참이라 말하고 목록은 비게» 만든다 — 레이스의 최소 재현
|
|
222
|
-
cat > "$td/drv.sh" <<'EOD'
|
|
223
|
-
FD_FH_DIR="$PWD"; export FD_FH_DIR
|
|
224
|
-
eval "$(sed -n '/^publish_gate()/,/^}/p' scripts/frontier_digest_daily.sh)"
|
|
225
|
-
eval "$(sed -n '/^_redact()/,/^}/p' scripts/frontier_digest_daily.sh)"
|
|
226
|
-
digest_files() { :; } # 0건
|
|
227
|
-
FH_DIR="$PWD"; OUT_DIR=out; LOG_FILE=/dev/null; FD_PUBLIC_TARGET=1
|
|
228
|
-
publish_gate; echo "rc=$?"
|
|
229
|
-
EOD
|
|
230
|
-
local o; o=$(cd "$td" && bash drv.sh 2>&1); rm -rf "$td"; echo "${o##*rc=}"
|
|
231
|
-
}
|
|
232
|
-
t "R3c 선택자 자기모순은 게시가 아니라 보류(3)" "3" "$(_selector_race)"
|
|
233
|
-
|
|
234
|
-
# R1 · 착지 증언이 **러너를 통해** 살아 있다
|
|
235
|
-
# 🟥 초판 레인은 checker 를 **직접** 불러서, R1 을 원복해도 초록이었다 — 호출부를 우회한
|
|
236
|
-
# 장식 앵커다([[feedback_anchor_can_be_decorative]]). 되돌림 프로브가 그걸 잡았다.
|
|
237
|
-
# 지금은 **러너를 돌리고 그 로그**를 읽는다. 러너가 어떻게 부르는지가 판정 대상이다.
|
|
238
|
-
_runner_witness() { # echoes verdict-word from the log
|
|
239
|
-
local td; td=$(mktemp -d)
|
|
240
|
-
( cd "$td" && git init -q . && git config user.email t@t && git config user.name t ) >/dev/null 2>&1
|
|
241
|
-
mkdir -p "$td/scripts" "$td/out" "$td/knowledge"
|
|
242
|
-
cp "$ROOT/scripts/frontier_digest_daily.sh" "$ROOT/scripts/digest_landing_check.sh" \
|
|
243
|
-
"$ROOT/scripts/utterance_landing_check.sh" "$td/scripts/"
|
|
244
|
-
chmod +x "$td/scripts/digest_landing_check.sh"
|
|
245
|
-
printf '#!/usr/bin/env bash\nexit 0\n' > "$td/scripts/stub-claude"; chmod +x "$td/scripts/stub-claude"
|
|
246
|
-
local d; d=$(date +%Y_%m_%d)
|
|
247
|
-
cat > "$td/out/frontier_digest_2001_01_01.md" <<'EOF'
|
|
248
|
-
# prev digest
|
|
249
|
-
## 📌 FH Immediate Application Candidates
|
|
250
|
-
|
|
251
|
-
| # | 티어 | 내용 |
|
|
252
|
-
|---|---|---|
|
|
253
|
-
| **M1** | **M** | `ZZ_LANDED_TOKEN_ZZ` 를 배선한다 |
|
|
254
|
-
EOF
|
|
255
|
-
sleep 1
|
|
256
|
-
printf 'ZZ_LANDED_TOKEN_ZZ 배선함 · ZZ_CTL_ZZ\n' > "$td/out/landed.md"
|
|
257
|
-
printf 'today body\n%s\n' "$(head -c 1200 /dev/zero | tr '\0' 'x')" > "$td/out/frontier_digest_${d}.md"
|
|
258
|
-
( cd "$td" && FD_FH_DIR="$td" FD_OUT_DIR="out" FD_LOG_DIR="$td/logs" \
|
|
259
|
-
FD_LANDING_TRACKED="knowledge" FD_LANDING_IGNORED="out" FD_LANDING_CONTROLS="ZZ_CTL_ZZ" \
|
|
260
|
-
FD_CLAUDE_BIN="$td/scripts/stub-claude" FD_MAX_ATTEMPTS=1 FD_POLL_SECS=1 \
|
|
261
|
-
bash scripts/frontier_digest_daily.sh ) >/dev/null 2>&1
|
|
262
|
-
local lw; lw=$(grep -h "landing witness" "$td/logs/"*.log 2>/dev/null | tail -1)
|
|
263
|
-
case "$lw" in
|
|
264
|
-
*HARNESS-ERROR*) echo dead ;;
|
|
265
|
-
*ALL-LANDED*) echo landed ;;
|
|
266
|
-
*SOME-UNLANDED*) echo measured ;;
|
|
267
|
-
*SKIPPED*) echo skipped ;;
|
|
268
|
-
*) echo none ;;
|
|
269
|
-
esac
|
|
270
|
-
rm -rf "$td"
|
|
271
|
-
}
|
|
272
|
-
t "R1 러너가 부르는 형태에서 계기가 살아 있다(HARNESS-ERROR 아님)" "landed" "$(_runner_witness)"
|
|
273
|
-
|
|
274
|
-
# R5 · «직전 다이제스트» 선택이 **표기 혼재**에서도 옳은가 (첫 실사용 발견)
|
|
275
|
-
# 🟥 실물 코퍼스에는 `2026-06-02`(대시)와 `2026_08_17`(언더바)가 **섞여 있다.** 로케일 정렬은
|
|
276
|
-
# 대시본을 뒤로 보내 **두 달 전 파일**을 직전으로 골랐고, 그 파일엔 후보 절이 없어 매 런
|
|
277
|
-
# HARNESS-ERROR 였다. 픽스처가 한 표기만 쓰면 레인 21개가 다 초록인 채로 이게 산다.
|
|
278
|
-
_prev_pick() {
|
|
279
|
-
local td; td=$(mktemp -d); mkdir -p "$td/out"
|
|
280
|
-
# 🟥 **같은 연도**여야 재현된다. 첫 픽스처는 `2020-06-02` 를 썼는데 그건 로케일 정렬에서도
|
|
281
|
-
# 올바르게 뒤로 가서 **버그 판본도 초록**이었다(되돌림 프로브가 잡은 세 번째 장식 앵커).
|
|
282
|
-
# 실물 코퍼스의 표기를 그대로 쓴다: `2026-06-02` vs `2026_08_17`.
|
|
283
|
-
: > "$td/out/frontier_digest_2026-06-02.md" # 옛 대시 표기, 날짜상 더 과거
|
|
284
|
-
: > "$td/out/frontier_digest_2026_08_17.md" # 언더바 표기, 더 최근
|
|
285
|
-
local d; d=$(date +%Y_%m_%d)
|
|
286
|
-
: > "$td/out/frontier_digest_${d}.md" # 오늘 것 (제외 대상)
|
|
287
|
-
# 러너의 선택 표현을 그대로 떼어 쓴다 — 우회하면 앵커가 장식이 된다
|
|
288
|
-
local expr; expr=$(sed -n '/prev=\$(find/,/tail -1)/p' "$ROOT/scripts/frontier_digest_daily.sh")
|
|
289
|
-
local got; got=$( cd "$td" && FH_DIR="$td" OUT_DIR=out TODAY="$d" bash -c "$expr; basename \"\$prev\"" )
|
|
290
|
-
rm -rf "$td"; echo "$got"
|
|
291
|
-
}
|
|
292
|
-
t "R5 표기가 섞여도 «직전»은 날짜상 최신이다" "frontier_digest_2026_08_17.md" "$(_prev_pick)"
|
|
293
|
-
|
|
294
|
-
# R6 · **엔진 루트 ≠ 대상 루트** (첫 실사용 발견, 2026-08-18)
|
|
295
|
-
# 🟥 위성은 이 러너를 복사하지 않고 FH 의 것을 그대로 돈다(launchd 가 FH 경로를 가리킨다).
|
|
296
|
-
# 초판은 스캐너·패턴·checker 를 전부 `$FH_DIR`(=대상 레포)에서 찾아서, 대상에 그 파일이
|
|
297
|
-
# 없으면 **publish gate 가 영영 fail-closed** 였다 — 실측으로 `psa_scan_lib.sh 부재` 를 봤다.
|
|
298
|
-
# 게다가 그 분기는 파일을 **격리하지 않아** «게시 안 함» 이 거짓이었다(digest 는 이미 트리에 있다).
|
|
299
|
-
_engine_vs_target() { # echoes "rc|state"
|
|
300
|
-
local eng tgt; eng=$(mktemp -d); tgt=$(mktemp -d)
|
|
301
|
-
mkdir -p "$eng/scripts" "$eng/.claude/rules" "$tgt/out" # 🟥 대상에는 scripts/ 를 안 만든다
|
|
302
|
-
cp "$ROOT/scripts/frontier_digest_daily.sh" "$ROOT/scripts/psa_scan_lib.sh" "$eng/scripts/"
|
|
303
|
-
cp "$ROOT/.claude/rules/.public-surface-patterns.defaults" "$eng/.claude/rules/" 2>/dev/null
|
|
304
|
-
printf 'HIGH\tZZ_SYNTHETIC_LEAK_TOKEN_ZZ\n' > "$eng/.claude/rules/.public-surface-patterns"
|
|
305
|
-
printf '#!/usr/bin/env bash\nexit 0\n' > "$eng/scripts/stub-claude"; chmod +x "$eng/scripts/stub-claude"
|
|
306
|
-
local d; d=$(date +%Y_%m_%d)
|
|
307
|
-
printf 'clean\n%s\n' "$(head -c 1200 /dev/zero | tr '\0' 'x')" > "$tgt/out/frontier_digest_${d}.md"
|
|
308
|
-
local rc
|
|
309
|
-
( FD_FH_DIR="$tgt" FD_OUT_DIR="out" FD_PUBLIC_TARGET=1 FD_LOG_DIR="$tgt/logs" \
|
|
310
|
-
FD_CLAUDE_BIN="$eng/scripts/stub-claude" FD_MAX_ATTEMPTS=1 FD_POLL_SECS=1 \
|
|
311
|
-
bash "$eng/scripts/frontier_digest_daily.sh" ) >/dev/null 2>&1; rc=$?
|
|
312
|
-
local state=none
|
|
313
|
-
ls "$tgt/out/"*.UNSCANNED >/dev/null 2>&1 && state=unscanned
|
|
314
|
-
ls "$tgt/out/"*.md >/dev/null 2>&1 && [ "$state" = none ] && state=published
|
|
315
|
-
rm -rf "$eng" "$tgt"; echo "$rc|$state"
|
|
316
|
-
}
|
|
317
|
-
r=$(_engine_vs_target)
|
|
318
|
-
t "R6 도구를 엔진 루트에서 찾는다(대상에 없어도 게이트가 돈다)" "0" "${r%%|*}"
|
|
319
|
-
t "R6b 그래서 CLEAN 한 digest 가 실제로 게시된다" "published" "${r##*|}"
|
|
320
|
-
|
|
321
|
-
# R6c · 스캐너가 **진짜로** 없으면 «게시 안 함» 이 말뿐이 아니라 격리까지 간다
|
|
322
|
-
_lib_absent() {
|
|
323
|
-
local eng tgt; eng=$(mktemp -d); tgt=$(mktemp -d)
|
|
324
|
-
mkdir -p "$eng/scripts" "$tgt/out"
|
|
325
|
-
cp "$ROOT/scripts/frontier_digest_daily.sh" "$eng/scripts/" # 🟥 psa_scan_lib.sh 는 안 넣는다
|
|
326
|
-
printf '#!/usr/bin/env bash\nexit 0\n' > "$eng/scripts/stub-claude"; chmod +x "$eng/scripts/stub-claude"
|
|
327
|
-
local d; d=$(date +%Y_%m_%d)
|
|
328
|
-
printf 'body\n%s\n' "$(head -c 1200 /dev/zero | tr '\0' 'x')" > "$tgt/out/frontier_digest_${d}.md"
|
|
329
|
-
local rc
|
|
330
|
-
( FD_FH_DIR="$tgt" FD_OUT_DIR="out" FD_PUBLIC_TARGET=1 FD_LOG_DIR="$tgt/logs" \
|
|
331
|
-
FD_CLAUDE_BIN="$eng/scripts/stub-claude" FD_MAX_ATTEMPTS=1 FD_POLL_SECS=1 \
|
|
332
|
-
bash "$eng/scripts/frontier_digest_daily.sh" ) >/dev/null 2>&1; rc=$?
|
|
333
|
-
local state=published
|
|
334
|
-
ls "$tgt/out/"*.UNSCANNED >/dev/null 2>&1 && state=quarantined
|
|
335
|
-
rm -rf "$eng" "$tgt"; echo "$state"
|
|
336
|
-
}
|
|
337
|
-
t "R6c 스캐너 부재는 말만이 아니라 실제 격리다" "quarantined" "$(_lib_absent)"
|
|
338
|
-
|
|
339
|
-
echo "----"; echo "satellite publish gate: $pass passed, $fail failed"; [ "$fail" -eq 0 ]
|