@chrono-meta/fh-gate 2.4.0 โ 2.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +2 -2
- package/CLAUDE.md +56 -1
- package/knowledge/shared/harness-core/fh_three_layer_canon.md +18 -6
- package/knowledge/shared/harness-core/field_verdict_crossfamily_gate.md +31 -0
- package/knowledge/shared/harness-core/sonnet_floor_doctrine.md +16 -0
- package/knowledge/shared/learnings/subagent_invocations_log.yaml +96 -0
- package/knowledge/shared/rules/multi_session_close_protocol.md +124 -2
- package/package.json +3 -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 +48 -0
- package/scripts/capability_effect_probe.sh +173 -5
- package/scripts/digest_landing_check.sh +168 -13
- package/scripts/fh_session_load.sh +71 -0
- package/scripts/selfcheck.sh +29 -0
- package/scripts/test_evidence_root_psa_lanes.sh +78 -0
- package/scripts/test_satellite_publish_gate_lanes.sh +339 -0
- package/templates/.git-hooks/pre-commit +64 -6
|
@@ -54,6 +54,26 @@ set -f
|
|
|
54
54
|
|
|
55
55
|
RC_OK=0; RC_VIOLATION=1; RC_UNVERIFIABLE=3; RC_HARNESS=10
|
|
56
56
|
|
|
57
|
+
# ๐ฅ **๊ณ๊ธฐ ์ ์ ํ๋ฆฌํ๋ผ์ดํธ** (2026-08-18, ๋์-์ง๋ฌธ ํ์๊ด ํ์ด known-pair ๋ก ์ฌํ).
|
|
58
|
+
# `_snapshot` ์ ํ์ผ ์ถ์ `โฆ | xargs -0 shasum -a 256 2>/dev/null` ์ด๋ค. `shasum` ์ด ์๊ฑฐ๋
|
|
59
|
+
# ์ฃฝ์ผ๋ฉด before/after ๊ฐ **๋ ๋ค ๋น ๋ฌธ์์ด**์ด ๋์ด `changed=0` โ **`โ
VERIFIED ยท ๊ด์ธก=no-write`**.
|
|
60
|
+
# ์ฌํ(๊ฐ์ capfile, PATH ๋ง ๋ค๋ฆ): ์ ์ `๐ฅ VIOLATION rc=1` / shasum=127 `โ
VERIFIED rc=0`.
|
|
61
|
+
# โ ์ด ํ์ผ์ด ํค๋์์ ๊ฒจ๋ ใ๋ฏธ์ธก์ ์ 0 ์ผ๋ก ๋ ๋ใ์ ์๊ธฐ ํ๋ณธ์ด์๊ณ , `UNVERIFIABLE` ์กฐ์ฐจ
|
|
62
|
+
# ์๋๋ผ **VERIFIED** ์๋ค. ๊ณ๊ธฐ๊ฐ ์ฃฝ์ผ๋ฉด ํ์ ์ ๋ด์ง ์๋๋ค.
|
|
63
|
+
# โ
`2>/dev/null` ์ ๋จ๊ธด๋ค โ ๊ฐ๋ณ ํ์ผ ๊ถํ ์ค๋ฅ๋ก ์ ์ฒด๊ฐ ์ฃฝ์ผ๋ฉด ๊ทธ๊ฒ ๋ ๋์๋ค.
|
|
64
|
+
# ๋ง๋ ์ง์ ์ **์ ์ **(๋๊ตฌ ๋ถ์ฌ)์ด์ง ๊ฐ๋ณ ํญ๋ชฉ ์คํจ๊ฐ ์๋๋ค.
|
|
65
|
+
# โ ๏ธ **ํด๋ฐฑ์ด ํ์ํ๋ค**(cross-family ์ง๋ชฉ #3): `shasum` ์ macOS/perl ๊ณ์ด ๊ดํ์ด๊ณ
|
|
66
|
+
# Linux/BusyBox ์๋น์๋ `sha256sum` ๋ง ์๋ ๊ฒฝ์ฐ๊ฐ ํํ๋ค. ์ด ํ์ผ์ `package.json
|
|
67
|
+
# files[]` ๋ก **์ถํ๋๋ฏ๋ก** shasum ๊ฐ์ ๋ ๊ณผ์ฐจ๋จ์ด๋ค.
|
|
68
|
+
HASHER=""
|
|
69
|
+
if command -v shasum >/dev/null 2>&1; then HASHER="shasum -a 256"
|
|
70
|
+
elif command -v sha256sum >/dev/null 2>&1; then HASHER="sha256sum"
|
|
71
|
+
else
|
|
72
|
+
echo "โ HARNESS_ERROR โ \`shasum\` ๋ \`sha256sum\` ๋ PATH ์ ์๋ค." >&2
|
|
73
|
+
echo " ์ค๋
์ท์ ํด์ ์ถ์ด ์ฃฝ์ด ๊ฑฐ์ง \`VERIFIED\` ๊ฐ ๋๋ค. ํ์ ํ์ง ์๊ณ ์ค๋จํ๋ค." >&2
|
|
74
|
+
exit "$RC_HARNESS"
|
|
75
|
+
fi
|
|
76
|
+
|
|
57
77
|
# writes ์ถ ์์ (์ข์ โ ๋์). ๊ด์ธก์ด ์ ์ธ๋ณด๋ค ๋์ผ๋ฉด VIOLATION.
|
|
58
78
|
ORDER_writes="read-only write-local write-remote"
|
|
59
79
|
|
|
@@ -82,7 +102,8 @@ GIT_META_WATCH=""
|
|
|
82
102
|
# ์๋๋ผ **ํ์ผ๋น ํ๋ก์ธ์ค ์คํฐ**์ด์๋ค. `xargs` ๋ฐฐ์น๋ก ํ ๋ฒ์ ๋๊ธฐ๋ฉด ๊ฐ์ ๋์์ ์ฌ๋ฉด์
|
|
83
103
|
# ๋น์ฉ์ด ๋จ์ด์ง๋ค โ ์ ํ๋๋ฅผ ๊น์ ๋น์ฉ์ ๋ง์ถ๋ ค๋ ๊ฒ ์๋ชป๋ ํธ๋ ์ด๋์๋ค.
|
|
84
104
|
|
|
85
|
-
_snapshot() { # $1=dir โ "sha path"
|
|
105
|
+
_snapshot() { # $1=dir โ "file <path>" + "sha path" + dir/๊ธฐํ ์ถ (์ ๋ ฌ)
|
|
106
|
+
local _flist; _flist=$(mktemp "${TMPDIR:-/tmp}/fh_flist.XXXXXX")
|
|
86
107
|
{
|
|
87
108
|
# `.git` ์ ํต์งธ๋ก ์ ์ธํ๋ค โ `git status` ๋ฅ๊ฐ `.git/index` ๋ฅผ ์ ๋นํ๊ฒ ๊ฐฑ์ ํ๋ฏ๋ก
|
|
88
109
|
# ์ ์ฒด๋ฅผ ์ฌ๋ฉด ์ฝ๊ธฐ ์ ์ฉ capability ๊ฐ ๊ฑฐ์ง VIOLATION ์ ๋ฐ๋๋ค. ๋์ ์๋์์
|
|
@@ -101,10 +122,19 @@ _snapshot() { # $1=dir โ "sha path" ๋ชฉ๋ก (์ ๋ ฌ)
|
|
|
101
122
|
case "$w" in "$1"/*|"$1") ;; *) continue ;; esac
|
|
102
123
|
find "$w" -type f 2>/dev/null
|
|
103
124
|
done
|
|
104
|
-
} | LC_ALL=C sort -u
|
|
105
|
-
|
|
106
|
-
|
|
125
|
+
} | LC_ALL=C sort -u > "$_flist"
|
|
126
|
+
# ๐ฅ **์ด๋ฆ ๋ชฉ๋ก ์ถ โ ํด์์ ๋ณ๋๋ก ๋ธ๋ค** (2026-08-18, cross-family ์ง๋ชฉ #1).
|
|
127
|
+
# ํด์ ์ถ๋ง ๋๋ฉด ยซํด์๊ฐ ์คํจํ ํ์ผยป๊ณผ ยซ์๋ ํ์ผยป์ด **๊ตฌ๋ถ ๋ถ๊ฐ**๋ค. ์ค์ธก ๋ฐ๋ก ๋:
|
|
128
|
+
# โ `shasum` ์ด ์กด์ฌํ์ง๋ง exit 1 ์ธ shim โ ํด์ 0์ค โ changed=0 โ โ
VERIFIED
|
|
129
|
+
# โ **๊ฐ์ง ๋๊ตฌ ์์ด๋** `touch f && chmod 000 f` โ ๊ทธ ํ์ผ ํด์๋ง ์คํจ โ
|
|
130
|
+
# `2>/dev/null` ์ด ์ผํด โ โ
VERIFIED
|
|
131
|
+
# โ ์ด๋ฆ ๋ชฉ๋ก์ **ํด์ ๋๊ตฌ์ ๋ฌด๊ดํ๊ฒ** ์์ฑ/์ญ์ ๋ฅผ ์ก๋๋ค. ๋ ์ถ์ ์๋ก์ ํด๋ฐฑ์ด ์๋๋ผ
|
|
132
|
+
# **๋ค๋ฅธ ๊ฒ์ ์ฐ๋ค**(์ด๋ฆ=์กด์ฌ ยท ํด์=๋ด์ฉ). ๋ ๋ค ํ์ํ๋ค.
|
|
133
|
+
LC_ALL=C sed 's/^/file /' "$_flist"
|
|
134
|
+
tr '\n' '\0' < "$_flist" \
|
|
135
|
+
| xargs -0 -n 400 $HASHER 2>/dev/null \
|
|
107
136
|
| LC_ALL=C sort
|
|
137
|
+
rm -f "$_flist"
|
|
108
138
|
# ๐ฅ **๋๋ ํ ๋ฆฌ ์กด์ฌ ์ถ** (2026-08-17). ์ ๋ธ๋ก์ `-type f` ๋ผ **ํ์ผ๋ง** ์ผ๋ค โ ๋น
|
|
109
139
|
# ๋๋ ํ ๋ฆฌ๋ ๊ด์ธก๋ฉด์ ์์ ์์๊ณ , `mkdir -p uploads outputs tmp` ๋ง ํ๋ capability ๊ฐ
|
|
110
140
|
# `writes: read-only` ์ ์ธ์ผ๋ก **โ
VERIFIED** ๋ฅผ ๋ฐ์๋ค(known-pair 3-arm ์ค์ธก).
|
|
@@ -285,6 +315,12 @@ probe_one() { # $1=capfile โ rc
|
|
|
285
315
|
|
|
286
316
|
local before after out rc
|
|
287
317
|
before=$(_snapshot "$sandbox")
|
|
318
|
+
# ๐ฅ ์ค๋
์ท์ **์ ๋ ๋น์ง ์๋๋ค** โ ๋๋ ํ ๋ฆฌ ์ถ์ด ์ต์ํ ๋ฃจํธ ์์ ์ ์ฐ๊ธฐ ๋๋ฌธ์ด๋ค.
|
|
319
|
+
# ๋น์๋ค๋ฉด `find` ์กฐ์ฐจ ์คํจํ ๊ฒ์ด๊ณ , ๊ทธ๊ฑด ๊ด์ธก์ด ์๋๋ผ ๊ณ๊ธฐ ์ฌ๋ง์ด๋ค.
|
|
320
|
+
if [ -z "$before" ]; then
|
|
321
|
+
echo " โ HARNESS_ERROR โ ์ฌ์ ์ค๋
์ท์ด ๋น์๋ค($sandbox). ๊ด์ธก๋ฉด์ด ์ฃฝ์๋ค." >&2
|
|
322
|
+
return "$RC_HARNESS"
|
|
323
|
+
fi
|
|
288
324
|
local out_before; out_before=$(_snapshot "$outside")
|
|
289
325
|
|
|
290
326
|
# ์คํ โ **์ arm ์ ๊ฐ์ ์๋๋ฐ์ค ์ ์ฑ
์ผ๋ก** ๋๋ฆฐ๋ค(2026-08-16 cross-family ์ง๋ชฉ).
|
|
@@ -787,6 +823,106 @@ EOF
|
|
|
787
823
|
fails=$((fails+1)); echo "โ L18 rc=$rc (1 ๊ธฐ๋) โ ๋น์ ๊ท ๋
ธ๋๊ฐ ๊ฐ์๋ฉด ๋ฐ์ด๋ค"
|
|
788
824
|
fi
|
|
789
825
|
|
|
826
|
+
# โโ L19 **์ง๊ณ๊ฐ ์๋ฐ์ ยซ๋ชป ์์ยป์ผ๋ก ์ผํค์ง ์๋๋ค** โโโโโโโโโโโโโโโโโโโโโโโโ
|
|
827
|
+
# RC_VIOLATION=1 ยท RC_UNVERIFIABLE=3 ์ด๋ผ ์์น max ๋ก ์ ์ผ๋ฉด exit 3 ์ด ๋์๋ค.
|
|
828
|
+
cat > "$d/agg_viol.cap" <<EOF
|
|
829
|
+
id: t:aggv
|
|
830
|
+
entry: bash -c 'touch aggregated_violation'
|
|
831
|
+
requires_cwd: $_rs
|
|
832
|
+
writes: read-only
|
|
833
|
+
EOF
|
|
834
|
+
out=$("$0" "$d/agg_viol.cap" "$d/nz_undeclared.cap" 2>&1); rc=$?
|
|
835
|
+
if [ "$rc" = "1" ] && printf '%s' "$out" | grep -q "nz_undeclared" \
|
|
836
|
+
&& printf '%s' "$out" | grep -q "unverifiable=1"; then
|
|
837
|
+
pass=$((pass+1)); echo "โ
L19 ์๋ฐ+๋ฏธ์ธก์ ๋ฐฐ์น: exit=VIOLATION ์ด๊ณ ๋ฏธ์ธก์ ์ด ์์ฝ์ ๋จ๋๋ค"
|
|
838
|
+
else
|
|
839
|
+
fails=$((fails+1)); echo "โ L19 rc=$rc โ ์ง๊ณ๊ฐ ์๋ฐ์ ์ผํค๊ฑฐ๋ ๋ ๋ฒ์งธ capfile ์ ์ ์๋ค"
|
|
840
|
+
fi
|
|
841
|
+
# L19b **์์ ๋ฐ์ ** โ cross-family ์ง๋ชฉ #4: ์๋ฐ์ด ๋จผ์ ๋ฉด short-circuit ํดํ๋ ์ด๋ก์ด๋ค.
|
|
842
|
+
out=$("$0" "$d/nz_undeclared.cap" "$d/agg_viol.cap" 2>&1); rc=$?
|
|
843
|
+
if [ "$rc" = "1" ]; then
|
|
844
|
+
pass=$((pass+1)); echo "โ
L19b ์์๋ฅผ ๋ค์ง์ด๋ VIOLATION ์ด ์ด๊ธด๋ค(๋ฏธ์ธก์ ์ด ๋จผ์ ์ฌ๋)"
|
|
845
|
+
else
|
|
846
|
+
fails=$((fails+1)); echo "โ L19b rc=$rc (1 ๊ธฐ๋) โ ์ฒซ rc ์ ๊ฐํ๊ฑฐ๋ ์ฌ๊ฐ๋๊ฐ ๋ค์งํ๋ค"
|
|
847
|
+
fi
|
|
848
|
+
# L19c ์ปจํธ๋กค โ ์๋ฐ์ด ์์ผ๋ฉด ์ฌ์ ํ ๋ฏธ์ธก์ (3)์ด๋ค(๊ณผ์ฐจ๋จ ๋ฐฉ์ง).
|
|
849
|
+
out=$("$0" "$d/nz_undeclared.cap" 2>&1); rc=$?
|
|
850
|
+
if [ "$rc" = "3" ]; then
|
|
851
|
+
pass=$((pass+1)); echo "โ
L19c ์ปจํธ๋กค โ ์๋ฐ ์๋ ๋ฐฐ์น๋ ์ฌ์ ํ UNVERIFIABLE"
|
|
852
|
+
else
|
|
853
|
+
fails=$((fails+1)); echo "โ L19c rc=$rc (3 ๊ธฐ๋) โ ์ฌ๊ฐ๋ ๋งคํ์ด ๋ฏธ์ธก์ ์ ์๋ชป ์ ๋๋ค"
|
|
854
|
+
fi
|
|
855
|
+
|
|
856
|
+
# โโ L20 ๊ณ์ด **๊ณ๊ธฐ๊ฐ ์ฃฝ์ผ๋ฉด ํ์ ํ์ง ์๋๋ค ยท ์ด์ ์์ผ๋ฉด ๊ณผ์ฐจ๋จํ์ง ์๋๋ค** โโโโโโ
|
|
857
|
+
# ๐ฅ ์ดํ ๋ ์ธ์ ๋ ๋ฒ ํ๋ ธ๋ค(๋ ๋ค ์๋ ฅ ์ ๋ฐ 0):
|
|
858
|
+
# โ `PATH=/nonexistent` ๋ก ์ฌ์ **capfile ํ์ฑ ์คํจ**๋ฅผ ํ๋ฆฌํ๋ผ์ดํธ๋ก ์ค๊ท์ โ ๋๋๋ฆผ
|
|
859
|
+
# 3์ค ํ๋ก๋ธ๊ฐ ์ ๋ฐ(์๋ฆฌ๋ฅผ ๋๋๋ ค๋ ์ด๋ก์ด์๋ค)
|
|
860
|
+
# โ shim ๋น๋๊ฐ `set -f`(์ ์ญ noglob) ๋๋ฌธ์ ํ์ฅ์ด ์ ๋จ โ **์บ๋ฆฌ๋ธ๋ ์ด์
์ง**์ด ์ ๋ฐ
|
|
861
|
+
# ์ฌ๊ธฐ์๋ ๋๊ตฌ๋ฅผ **ํ๋์ฉ** ๋นผ๊ณ , ๋งค arm ์ ๊ธฐ๋๊ฐ์ ๋ค๋ฅด๊ฒ ๊ฑด๋ค.
|
|
862
|
+
# โ
PATH ์์ ๋ถํด๋ ๊ณต๋ฐฑ/๊ธ๋กญ ์์ ํ๊ฒ(`tr` โ ์ค ๋จ์). cross-family ์ง๋ชฉ #7.
|
|
863
|
+
_mkshim() { # $1=shim๊ฒฝ๋ก $2..=์ ์ธํ ๋๊ตฌ๋ช
|
|
864
|
+
local shimd="$1"; shift
|
|
865
|
+
mkdir -p "$shimd"
|
|
866
|
+
printf '%s\n' "$PATH" | tr ':' '\n' > "$d/_pathdirs"
|
|
867
|
+
local _p _f _b _x _skip
|
|
868
|
+
set +f
|
|
869
|
+
while IFS= read -r _p; do
|
|
870
|
+
[ -n "$_p" ] && [ -d "$_p" ] || continue
|
|
871
|
+
for _f in "$_p"/*; do
|
|
872
|
+
[ -e "$_f" ] || continue
|
|
873
|
+
_b=${_f##*/}; _skip=0
|
|
874
|
+
for _x in "$@"; do [ "$_b" = "$_x" ] && { _skip=1; break; }; done
|
|
875
|
+
[ "$_skip" = 1 ] && continue
|
|
876
|
+
[ -e "$shimd/$_b" ] || ln -s "$_f" "$shimd/$_b" 2>/dev/null
|
|
877
|
+
done
|
|
878
|
+
done < "$d/_pathdirs"
|
|
879
|
+
set -f
|
|
880
|
+
}
|
|
881
|
+
|
|
882
|
+
# L20 ํด์ ๋๊ตฌ๊ฐ **๋ ๋ค** ์์ผ๋ฉด ํ์ ํ์ง ์๋๋ค.
|
|
883
|
+
_mkshim "$d/bin_none" shasum sha256sum
|
|
884
|
+
out=$(PATH="$d/bin_none" "${BASH:-/bin/bash}" "$0" "$d/agg_viol.cap" 2>&1); rc=$?
|
|
885
|
+
if [ "$rc" = "10" ] && printf '%s' "$out" | grep -q "sha256sum"; then
|
|
886
|
+
pass=$((pass+1)); echo "โ
L20 ํด์ ๋๊ตฌ ์ ๋ฌด๋ HARNESS_ERROR (์ด์ ๋ ์ฐํ๋ค)"
|
|
887
|
+
else
|
|
888
|
+
fails=$((fails+1)); echo "โ L20 rc=$rc (10 ๊ธฐ๋) โ ๊ณ๊ธฐ ์ฌ๋ง์ด ํต๊ณผ/ํ์ ์ผ๋ก ๋ ๋๋๋ค"
|
|
889
|
+
fi
|
|
890
|
+
# L20b **๊ณผ์ฐจ๋จ ๋ฐฉ์ง** โ `shasum` ๋ง ์๊ณ `sha256sum` ์ด ์์ผ๋ฉด ์ ์ ํ์ ํด์ผ ํ๋ค.
|
|
891
|
+
# cross-family ์ง๋ชฉ #3: ์ด ํ์ผ์ files[] ๋ก ์ถํ๋๊ณ Linux ์๋น์๋ sha256sum ๋ง ๊ฐ๋๋ค.
|
|
892
|
+
if command -v sha256sum >/dev/null 2>&1; then
|
|
893
|
+
_mkshim "$d/bin_s256" shasum
|
|
894
|
+
out=$(PATH="$d/bin_s256" "${BASH:-/bin/bash}" "$0" "$d/agg_viol.cap" 2>&1); rc=$?
|
|
895
|
+
if [ "$rc" = "1" ]; then
|
|
896
|
+
pass=$((pass+1)); echo "โ
L20b shasum ๋ถ์ฌ+sha256sum ์กด์ฌ โ ํด๋ฐฑ์ด ์ ์ ํ์ (๊ณผ์ฐจ๋จ ์์)"
|
|
897
|
+
else
|
|
898
|
+
fails=$((fails+1)); echo "โ L20b rc=$rc (1 ๊ธฐ๋) โ ํด๋ฐฑ์ด ์๊ฑฐ๋ ๊ณผ์ฐจ๋จํ๋ค"
|
|
899
|
+
fi
|
|
900
|
+
else
|
|
901
|
+
echo "โญ L20b SKIP โ ์ด ๋จธ์ ์ sha256sum ์ด ์๋ค(๋ฏธ์ธก์ , ํต๊ณผ ์๋)"
|
|
902
|
+
fi
|
|
903
|
+
# L20c **ยซ์๋๋ฐ ๊ณ ์ฅ๋ยป ํด์ ๋๊ตฌ** โ cross-family ์ง๋ชฉ #1. ํ๋ฆฌํ๋ผ์ดํธ๋ ํต๊ณผํ๋ค.
|
|
904
|
+
_mkshim "$d/bin_broken" shasum sha256sum
|
|
905
|
+
printf '#!/bin/sh\nexit 1\n' > "$d/bin_broken/shasum"; chmod +x "$d/bin_broken/shasum"
|
|
906
|
+
out=$(PATH="$d/bin_broken" "${BASH:-/bin/bash}" "$0" "$d/agg_viol.cap" 2>&1); rc=$?
|
|
907
|
+
if [ "$rc" = "1" ]; then
|
|
908
|
+
pass=$((pass+1)); echo "โ
L20c ํด์ ๋๊ตฌ๊ฐ ๊ณ ์ฅ๋๋ ํ์ผ ์์ฑ์ ์กํ๋ค(์ด๋ฆ ๋ชฉ๋ก ์ถ)"
|
|
909
|
+
else
|
|
910
|
+
fails=$((fails+1)); echo "โ L20c rc=$rc (1 ๊ธฐ๋) โ ๊ณ ์ฅ๋ ๊ณ๊ธฐ๊ฐ ๊ฑฐ์ง VERIFIED ๋ฅผ ๋ธ๋ค"
|
|
911
|
+
fi
|
|
912
|
+
# L20d **์ฝ์ ์ ์๋ ํ์ผ** โ ๊ฐ์ง ๋๊ตฌ ์์ด ์ฌํ๋๋ ํํ(cross-family ์ง๋ชฉ #1 ๋ ๋ฒ์งธ).
|
|
913
|
+
cat > "$d/unreadable.cap" <<EOF
|
|
914
|
+
id: t:unread
|
|
915
|
+
entry: bash -c 'touch hidden_regular && chmod 000 hidden_regular'
|
|
916
|
+
requires_cwd: $_rs
|
|
917
|
+
writes: read-only
|
|
918
|
+
EOF
|
|
919
|
+
out=$(probe_one "$d/unreadable.cap" 2>&1); rc=$?
|
|
920
|
+
if [ "$rc" = "1" ]; then
|
|
921
|
+
pass=$((pass+1)); echo "โ
L20d chmod 000 ํ์ผ ์์ฑ๋ ์๋ฐ์ด๋ค(ํด์ ์คํจ๊ฐ ์ผํค์ง ์๋๋ค)"
|
|
922
|
+
else
|
|
923
|
+
fails=$((fails+1)); echo "โ L20d rc=$rc (1 ๊ธฐ๋) โ ํด์ ์คํจ๊ฐ ํ์ผ ์์ฑ์ ์ผํจ๋ค"
|
|
924
|
+
fi
|
|
925
|
+
|
|
790
926
|
rm -rf "$d"
|
|
791
927
|
echo "โโ capability_effect_probe lanes: $pass PASS / $fails FAIL โโ"
|
|
792
928
|
[ "$fails" = "0" ]
|
|
@@ -797,9 +933,41 @@ case "${1:-}" in
|
|
|
797
933
|
"") echo "usage: $0 <capfile> [...] | --self-test" >&2; exit "$RC_HARNESS";;
|
|
798
934
|
esac
|
|
799
935
|
|
|
936
|
+
# ๐ฅ **์ง๊ณ๋ ์์น max ๊ฐ ์๋๋ผ ์ฌ๊ฐ๋ max ๋ค** (2026-08-18, ๋์-์ง๋ฌธ ํ์๊ด ํ ์ง๋ชฉ).
|
|
937
|
+
# `RC_VIOLATION=1` ยท `RC_UNVERIFIABLE=3` ์ด๋ผ ์์น `-gt` ๋ก ์ ์ผ๋ฉด
|
|
938
|
+
# **์ค์ ์๋ฐ(1) + ๋ชป ์์(3) โ exit 3** ์ด ๋๋ค. ํค๋๊ฐ 3 ์ ใํ์ ์๋ใ์ผ๋ก ์ ์ํด ๋จ์ผ๋
|
|
939
|
+
# `rc==1` ๋ก ์๋ฐ์ ๋ผ์ฐํ
ํ๋ ์์ ๊ฒ์ดํธ๋ **์กฐ์ฉํ ๋์น๊ณ ** ์ฌ์๋/์ ์ ๊ฒฝ๋ก๋ฅผ ํ๋ค.
|
|
940
|
+
# โ ์์น ์์์ ์ฌ๊ฐ๋ ์์๊ฐ ์ด๊ธ๋ ์์๋ค. ์ฌ๊ธฐ์ ๋ช
์์ ์ผ๋ก ๋งคํํ๋ค.
|
|
941
|
+
# โ
๋ฏธ์ง์ ์ฝ๋๋ **๊ฐ์ฅ ์ฌ๊ฐ**์ผ๋ก ์ ๋๋ค(fail-closed) โ ์ rc ๊ฐ ์๊ฒผ์ ๋ ์กฐ์ฉํ
|
|
942
|
+
# ํต๊ณผํ๋ ์ชฝ์ผ๋ก ๊ธฐ์ธ์ง ์๊ฒ.
|
|
943
|
+
_sev() { # ์ข
๋ฃ์ฝ๋ โ ์ฌ๊ฐ๋(ํด์๋ก ์ฌ๊ฐ). ์์น ํฌ๊ธฐ โ ์ฌ๊ฐ๋.
|
|
944
|
+
case "$1" in
|
|
945
|
+
"$RC_OK") printf '0' ;;
|
|
946
|
+
"$RC_UNVERIFIABLE") printf '1' ;;
|
|
947
|
+
"$RC_VIOLATION") printf '2' ;;
|
|
948
|
+
"$RC_HARNESS") printf '3' ;;
|
|
949
|
+
*) printf '3' ;;
|
|
950
|
+
esac
|
|
951
|
+
}
|
|
952
|
+
|
|
953
|
+
# ๐ฅ **๋ฐฐ์น๋ ยซ๊ฐ์ฅ ์ฌ๊ฐํ ๊ฒยป ํ๋๋ง ์ข
๋ฃ์ฝ๋๋ก ๋ผ ์ ์๋ค** โ ๊ทธ๋์ ์ ํ๋ ์ ๋ณด๊ฐ ์๊ธด๋ค.
|
|
954
|
+
# cross-family ์ง๋ชฉ #2: ์ฌ๊ฐ๋ ๋งคํ์ ๋ฃ์ ๋ค ใ์๋ฐ + ๋ฏธ์ธก์ ใ ๋ฐฐ์น๊ฐ `1` ๋ก ๋๊ฐ๋ฏ๋ก,
|
|
955
|
+
# `rc==3` ์ผ๋ก ยซ๋ฏธ์ธก์ ์์ยป ์ ๋ผ์ฐํ
ํ๋ ์๋น์๋ **๋ฏธ์ธก์ capfile ์ ์๋๋ค.**
|
|
956
|
+
# โ ์ข
๋ฃ์ฝ๋๋ ์ฌ๊ฐ๋๋ก ๋๊ณ , **์ ํ ์ ๋ณด๋ ์์ฝ ์ค๋ก ํ๋ฉดํ**ํ๋ค(์ผํค์ง ์๋๋ค).
|
|
957
|
+
# ํ ์ค์ด๋ฉด ์์๊ฐ grep ์ผ๋ก ์ง์ ์ ์๊ณ , ์ข
๋ฃ์ฝ๋ ๊ณ์ฝ์ ํ๋๋ก ์ ์ง๋๋ค.
|
|
800
958
|
worst=0
|
|
959
|
+
n_viol=0; n_unver=0; n_harn=0; n_ok=0
|
|
801
960
|
for c in "$@"; do
|
|
802
961
|
probe_one "$c"; rc=$?
|
|
803
|
-
|
|
962
|
+
case "$rc" in
|
|
963
|
+
"$RC_OK") n_ok=$((n_ok+1)) ;;
|
|
964
|
+
"$RC_VIOLATION") n_viol=$((n_viol+1)) ;;
|
|
965
|
+
"$RC_UNVERIFIABLE") n_unver=$((n_unver+1)) ;;
|
|
966
|
+
*) n_harn=$((n_harn+1)) ;;
|
|
967
|
+
esac
|
|
968
|
+
[ "$(_sev "$rc")" -gt "$(_sev "$worst")" ] && worst=$rc
|
|
804
969
|
done
|
|
970
|
+
if [ "$#" -gt 1 ]; then
|
|
971
|
+
echo "โโ BATCH SUMMARY: ok=$n_ok violation=$n_viol unverifiable=$n_unver harness=$n_harn (exit=$worst)"
|
|
972
|
+
fi
|
|
805
973
|
exit "$worst"
|
|
@@ -85,13 +85,77 @@ FH="${CLAUDE_PROJECT_DIR:-$(cd "$SELF_DIR/.." && pwd)}"
|
|
|
85
85
|
# โ ๏ธ ๊ฒ์ฆ๊ธฐ๋ **๋๊ตฌ**์ด๊ณ FH ๋ **๋์**์ด๋ค โ ๋ ์ถ์ ๊ฐ์ ๋ณ์๋ก ๋ฌถ์ผ๋ฉด ๊ฒฉ๋ฆฌ ํฝ์ค์ฒ์์
|
|
86
86
|
# ๋๊ตฌ๊น์ง ์์ ํธ๋ฆฌ์์ ์ฐพ๋ค๊ฐ ์ฃฝ๋๋ค(์ค์ธก). ๋๊ตฌ๋ ์ธ์ ๋ ์ด ์คํฌ๋ฆฝํธ ์์ ์๋ค.
|
|
87
87
|
CHECKER="$SELF_DIR/utterance_landing_check.sh"
|
|
88
|
+
|
|
89
|
+
# โโ ์ฐฉ์ง ์ค์ฝํ (2026-08-18, R1) โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
90
|
+
# ๊ธฐ๋ณธ ์ค์ฝํ๋ **FH ์์ ์ ๋ฌธ๋ฒ**์ด๋ค(`knowledge` ยท `CLAUDE.md` ยท gitignored `tracks/_meta`).
|
|
91
|
+
# ์์ฑ์ด ๊ฒจ๋ ๋์ ํ๋ค์ค์๋ ๊ทธ ์
์ด ์์ด์ ํ๊น์ด 0๊ฑด โ rc=10 ์ด ๋งค ๋ฐ ์ฐํ๋ค. ๊ทธ๊ฑด ์ ์งํ
|
|
92
|
+
# ๊ฐ์ด์ง๋ง(๋ฏธ์ธก์ โ 0), ๊ณ๊ธฐ๊ฐ **๊ตฌ์กฐ์ ์ผ๋ก ์ฃฝ์ ์ฑ** ๋ฐฐ์ ๋ ๊ฒ๊ณผ ๊ฐ๋ค.
|
|
93
|
+
# ๐ฅ ์ค์ฝํ๋ฅผ ยซ๋ฌ๋๊ฐ ์์ผ๋ก ๋ชฉ๋ก์ ๋ง๋ค์ด ๋๊ธฐ๋ยป ์์ผ๋ก ํ์ง ์๋๋ค โ ๊ทธ๋ฌ๋ฉด ์ ํ ํํฐ๊ฐ
|
|
94
|
+
# ๋ ๋ฒ์ด ๋๊ณ ๊ด๋ํจ์ด ๊ฐ๋ฆฌ๋ ์๊ฐ ํ์ชฝ๋ง ํต๊ณผํ๋ ์
๋ ฅ์ด ๋ฌด์ ๋๋กญ๋๋ค
|
|
95
|
+
# ([[feedback_divergent_leniency_duplicate_normalizers]]). ํํฐ๋ ์ฌ๊ธฐ ํ ๊ณณ์ ๋๊ณ
|
|
96
|
+
# **๋ฌด์์ ๋ณผ์ง๋ง** ๋ฐ์์ ์ ํ๋ค.
|
|
97
|
+
# ๊ธฐ๋ณธ๊ฐ์ ์ข
์ ๊ทธ๋๋ก โ FH ๊ฒฝ๋ก ๋ฌด๋ณ๊ฒฝ.
|
|
98
|
+
# โ ๏ธ **๋ช
๋ช
๋ ์์ฌ (cross-family/codex F4)**: ์ด ๊ฐ์ **๊ณต๋ฐฑ ๋ถ๋ฆฌ**๋ ๋ค์ค pathspec ์ด๋ค.
|
|
99
|
+
# ๋ฐ๋ผ์ **๊ฒฝ๋ก์ ๊ณต๋ฐฑ์ด ์์ผ๋ฉด ๊ฐ๋ฆฐ๋ค** โ `docs public` ์ ยซํ ๊ฒฝ๋กยป๊ฐ ์๋๋ผ ๋ ๊ฒฝ๋ก๊ฐ ๋๋ค.
|
|
100
|
+
# ๋ค์ค ๊ฒฝ๋ก ์ง์๊ณผ์ ํธ๋ ์ด๋์คํ๋ผ ์ค๋์ **๋ฌธ์ํ๋ง** ํ๊ณ ๊ธฐ๊ณ ๊ฒ์ฌ๋ ์๋ค.
|
|
101
|
+
DLC_TRACKED_PATHS="${DLC_TRACKED_PATHS:-knowledge CLAUDE.md}" # git ์ถ์ ์ถ (์ปค๋ฐ์๊ฐ)
|
|
102
|
+
DLC_IGNORED_DIR="${DLC_IGNORED_DIR-tracks/_meta}" # gitignored ์ถ (mtime). ๋น ๊ฐ = ๊ทธ ์ถ ์์
|
|
88
103
|
SECTION_RE='^## .*Immediate Application Candidates'
|
|
89
104
|
|
|
90
105
|
# ํ๋ณด ํ์์ (id, ํ๋ณํ ํฐ OR ์ ๊ท์) ์ ๋ฝ๋๋ค. ํ ํฐ ์์ผ๋ฉด id ๋ง ๋ด๊ณ ์ ๊ท์์ ๋น ๊ฐ.
|
|
91
106
|
_extract() { # $1 = digest path
|
|
92
107
|
awk -v sec="$SECTION_RE" '
|
|
108
|
+
# ํ๋ณ์ ์ถ์ถ โ ํ/๋ฌธ๋จ **๋ ๊ฒฝ๋ก๊ฐ ๊ณต์ **ํ๋ค(์ค๋ณต ์ ๊ทํ๊ธฐ ๋ฐฉ์ง).
|
|
109
|
+
function harvest(body, toks, tmp, w, t) {
|
|
110
|
+
tmp=body
|
|
111
|
+
while (match(tmp, /\[\[[^]]+\]\]/)) {
|
|
112
|
+
w=substr(tmp, RSTART+2, RLENGTH-4); tmp=substr(tmp, RSTART+RLENGTH)
|
|
113
|
+
if (length(w) >= 5) toks = (toks == "" ? w : toks "|" w)
|
|
114
|
+
}
|
|
115
|
+
tmp=body
|
|
116
|
+
while (match(tmp, /`[^`]+`/)) {
|
|
117
|
+
t=substr(tmp, RSTART+1, RLENGTH-2); tmp=substr(tmp, RSTART+RLENGTH)
|
|
118
|
+
sub(/[: ].*$/, "", t)
|
|
119
|
+
gsub(/^[[:space:]]+|[[:space:]]+$/, "", t)
|
|
120
|
+
if (length(t) < 5) continue
|
|
121
|
+
if (t ~ /[][(){}.*+?^$\\|]/) { if (t ~ /^[A-Za-z0-9_.-]+$/) { } else continue }
|
|
122
|
+
gsub(/\./, "\\.", t)
|
|
123
|
+
toks = (toks == "" ? t : toks "|" t)
|
|
124
|
+
}
|
|
125
|
+
return toks
|
|
126
|
+
}
|
|
93
127
|
$0 ~ sec { inblk=1; next }
|
|
94
|
-
inblk && /^## / { inblk=0 }
|
|
128
|
+
inblk && /^## / { if (pid != "") { print pid "\t" ptoks; pid="" } inblk=0; inpara=0 }
|
|
129
|
+
# โโ ๋ฌธ๋จ ํ์ (2026-08-18 ์ ์ค) โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
130
|
+
# ๐ฅ ์ด ๊ณ๊ธฐ๋ ํ๋ณด๋ฅผ **ํ**๋ก๋ง ์ฝ์๋ค. ์ค์ธก: ๋ค์ด์ ์คํธ 60๊ฑด ์ค ํ ํ์์ **4๊ฑด**,
|
|
131
|
+
# ๋๋จธ์ง๋ `**โ โฆ**` `**[A] โฆ**` `**1. โฆ**` `**#1 โฆ**` ๊ฐ์ **๋ฌธ๋จ ํ์**์ด๋ค.
|
|
132
|
+
# ์ฆ ๊ณ๊ธฐ๊ฐ ์ค๋ฌผ์ 6.7% ๋ง ์ฝ์ ์ ์์๊ณ , ๊ทธ๋์ ์ฒซ ์ค์ธก์ด rc=10(ยซํ๋ณด ์ ์ ๋ชป ์ฐพ์๋คยป)
|
|
133
|
+
# ์ ๋๋ค. ์ ๋๋ฌ๋ ์ด์ ๋ **ํ๋ก๋์
ํธ์ถ๋ถ๊ฐ 0** ์ด์๊ธฐ ๋๋ฌธ โ ์๋ฌด๋ ์ ๋๋ ธ๋ค.
|
|
134
|
+
# โ ๏ธ ๋จธ๋ฆฌ ํ๊ธฐ๋ ์ฌ๋ฌ ์ข
์ด๋ผ ํ ๋ชจ์์ ๋ง์ถ์ง ์๋๋ค(์ค์ธก: โ ยท [A] ยท 1. ยท #1 ยท ๊ทธ ์ธ).
|
|
135
|
+
# **`**` ๋ก ์ด๋ฆฌ๋ ์ค**์ ํญ๋ชฉ ์์์ผ๋ก ๋ณด๊ณ , ๋ค์ ํญ๋ชฉ/์ ๊น์ง๋ฅผ ๋ณธ๋ฌธ์ผ๋ก ๋ชจ์๋ค.
|
|
136
|
+
# ๐ฅ ํ๋ณ์ ์ถ์ถ์ **ํ ๊ฒฝ๋ก์ ๊ฐ์ ์ฝ๋**๋ฅผ ์ด๋ค โ ๋ ๋ฒ๋ก ๊ฐ๋ฆฌ๋ฉด ๊ด๋ํจ์ด ์ด๊ธ๋
|
|
137
|
+
# ํ์ชฝ๋ง ํต๊ณผํ๋ ์
๋ ฅ์ด ๋ฌด์ ๋๋กญ๋๋ค(divergent leniency).
|
|
138
|
+
# ํญ๋ชฉ ๋จธ๋ฆฌ **๋ค** ํ์์ ๋ค ๋ฐ๋๋ค. ์ค์ธก(60๊ฑด ํ๋ณด ์ ์ ์, ํ๋์ฉ ์ด์ด์ ํ์ธ):
|
|
139
|
+
# `**โฆ**` 74 ยท ํ `|` 28 ยท `### [M] 1.` 22 ยท **๋ฒํธ ๋ฆฌ์คํธ `1. **โฆ**`**(์ด๊ธฐ ๋ค์ด์ ์คํธ์ ์ฃผ ํ์)
|
|
140
|
+
# ๐ฅ ์ดํ์ `**` ๋ง ๋ฐ์๊ณ , ํ๊ฐ ์์ธ ์ ์์ **ํ ์์ `**` ์ค์ ๋จผ์ ์ผ์ผ** ํ ํ์
|
|
141
|
+
# UNCHECKABLE ๋ก ๋จ์ด๋จ๋ ธ๋ค(ํ๊ท ์ค์ธก). ๊ทธ๋์ **ํ ํ์ ํญ์ ํ ๊ฒฝ๋ก๊ฐ ๋จผ์ ๊ฐ์ ธ๊ฐ๋ค**.
|
|
142
|
+
inblk && (/^###+ / || /^\*\*/ || /^[0-9]+\. / || /^- \*\*/) {
|
|
143
|
+
if (pid != "") { print pid "\t" ptoks }
|
|
144
|
+
pid=$0; ptoks=""
|
|
145
|
+
sub(/^###+ /, "", pid); sub(/^[0-9]+\. /, "", pid); sub(/^- /, "", pid)
|
|
146
|
+
sub(/^\*\*/, "", pid); sub(/\*\*.*$/, "", pid)
|
|
147
|
+
gsub(/^[[:space:]]+|[[:space:]]+$/, "", pid)
|
|
148
|
+
# ๐ฅ substr ๋ก ์๋ฅด์ง ์๋๋ค โ awk ๋ ๋ก์ผ์ผ์ ๋ฐ๋ผ **๋ฐ์ดํธ** ๋จ์๋ผ ํ๊ธ/๊ธฐํธ๋ฅผ
|
|
149
|
+
# ์ค๊ฐ์์ ์ชผ๊ฐ๊ณ ๊ทธ ์ถ๋ ฅ์ด UTF-8 ๋ก ์ ์ฝํ๋ค(์ค์ธก: ์ง๊ณ ์คํฌ๋ฆฝํธ๊ฐ UnicodeDecodeError).
|
|
150
|
+
# id ๋ ํ์์ฉ์ด๋ฏ๋ก ์๋ฅด์ง ๋ง๊ณ **๊ณต๋ฐฑ ๊ธฐ์ค ์ 6๋ฑ๋ง**๋ง ์ด๋ค.
|
|
151
|
+
if (split(pid, _w, /[[:space:]]+/) > 6) {
|
|
152
|
+
pid=""; for (_i=1; _i<=6; _i++) pid = pid (_i>1 ? " " : "") _w[_i]
|
|
153
|
+
}
|
|
154
|
+
ptoks=harvest($0, ptoks)
|
|
155
|
+
inpara=1; next
|
|
156
|
+
}
|
|
157
|
+
# ํ ํ์ ์๋ ํ ๊ฒฝ๋ก๊ฐ ์ฒ๋ฆฌํ๋ค โ ์ฌ๊ธฐ์ ์ ๋จน๋๋ค(์ฐ์ ์์ ๋ช
์).
|
|
158
|
+
inblk && inpara && !/^\|/ && !/^###+ / && !/^[0-9]+\. / && !/^- \*\*/ { ptoks=harvest($0, ptoks); next }
|
|
95
159
|
inblk && /^\|/ {
|
|
96
160
|
line=$0
|
|
97
161
|
# ํค๋/๊ตฌ๋ถ์ ์ ์ธ
|
|
@@ -135,6 +199,7 @@ _extract() { # $1 = digest path
|
|
|
135
199
|
}
|
|
136
200
|
print id "\t" toks
|
|
137
201
|
}
|
|
202
|
+
END { if (pid != "") print pid "\t" ptoks }
|
|
138
203
|
' "$1"
|
|
139
204
|
}
|
|
140
205
|
|
|
@@ -143,8 +208,30 @@ do_extract() { # $1 = digest
|
|
|
143
208
|
[ -f "$d" ] || { echo "โ digest ์์: $d" >&2; return 10; }
|
|
144
209
|
# ์ปจํธ๋กค โ ์ด ๊ณ๊ธฐ๊ฐ ์ด์ ์๋์ง ์ฆ๋ช
ํ๋ค. ๋์ ํธ๋ฆฌ์ ํ์คํ ์กด์ฌํ๋ ํ ํฐ.
|
|
145
210
|
# ์ปจํธ๋กค์ด ์ฃฝ์ผ๋ฉด ์ฐฉ์ง ๊ฒ์ฆ๊ธฐ๊ฐ rc=10 ์ ๋ด๊ณ ํ๊น ๊ฒฐ๊ณผ๋ฅผ ์ธ์ํ์ง ์๋๋ค.
|
|
146
|
-
|
|
147
|
-
|
|
211
|
+
# ๐ฅ R1-b (2026-08-18) โ ์ปจํธ๋กค์ด `forge-harness`/`session` ์ผ๋ก **ํ๋์ฝ๋ฉ**์ด์๋ค.
|
|
212
|
+
# ์์ฑ์ด ๊ฒจ๋ ๋ ํฌ์๋ ๊ทธ ๋ ํ ํฐ์ด ์์ผ๋ฏ๋ก **์ปจํธ๋กค์ด ๋งค๋ฒ ์ฃฝ๊ณ ** ๊ณ๊ธฐ๋ rc=10 ๋ง ๋ธ๋ค.
|
|
213
|
+
# R1 ์ ์ธ์ ๋ฒ๊ทธ๋ฅผ ๊ณ ์ณ๋ ์ด๊ฒ ๋จ์ ์์ผ๋ฉด ๊ณ๊ธฐ๋ ์ฌ์ ํ ๊ตฌ์กฐ์ ์ผ๋ก ์ฃฝ์ ์ฑ๋ค โ ๊ทธ ์ฌ์ค์
|
|
214
|
+
# ์ด ๋ ์ธ์ด ์ก์๋ค(์๋ฆฌ๊ฐ ์ ๊ท ๊ฒฐํจ์ ์ถ์ฒ์ธ ๊ฒ๊ณผ ๊ฐ์ ์ผ๊ตด: ๋ฐ์ชฝ ์๋ฆฌ).
|
|
215
|
+
# ๊ธฐ๋ณธ๊ฐ์ **์๊ธฐ ๋ ํฌ ์ด๋ฆ**์ด๋ผ FH ์์๋ ์ข
์ ๊ณผ ๋์ผ(`forge-harness`)ํ๋ค.
|
|
216
|
+
# ๐ฅ ๋ ๊ฐ๋๋ฅผ ๊ฐ๋ผ์ผ ํ๋ค (cross-family/codex F3 ์ง๋ชฉ, ์ค์ธก์ผ๋ก **๋ ๋์ ํํ** ํ์ธ):
|
|
217
|
+
# ์ดํ์ `for _ctl in ${DLC_CONTROLS:-$(basename "$FH") session}` ์๋๋ฐ, ๋น์ธ์ฉ ๋ช
๋ น์นํ์
|
|
218
|
+
# ๋จ์ด๋ถ๋ฆฌ **์ ๊ธ๋ก๋น**์ ๋ ๋ค ํ๋ค โ ๋ ํฌ๋ช
์ด `.*` ์ธ ๋๋ ํฐ๋ฆฌ์์ ์ค์ธกํ๋ ์ปจํธ๋กค์ด
|
|
219
|
+
# `.git` ๋ฑ **4๊ฐ๋ก ๊ธ๋ก๋ธ ํ์ฅ**๋๋ค. ๊ฒ๋ค๊ฐ ์ปจํธ๋กค์ ERE ๋ก ์ฐ์ด๋ฏ๋ก ๋ ํฌ๋ช
์ ์ ๊ท์
|
|
220
|
+
# ๋ฉํ๋ฌธ์๊ฐ ์์ผ๋ฉด ยซ์๋ฌด ๋ด์ฉ์๋ ๋งค์นยปํด **๊ณ๊ธฐ ์์กด์ด ์คํ**์ด ๋๋ค.
|
|
221
|
+
# โ ์ ๋ ๊ธฐ๋ณธ๊ฐ์ **๋ฆฌํฐ๋ด๋ก ์ทจ๊ธ**(๋ฉํ๋ฌธ์ ์ด์ค์ผ์ดํ) ยท ์ฌ์ฉ์ ์ง์ ๊ฐ๋ง ์ ๊ท์์ผ๋ก ๋๋ค.
|
|
222
|
+
local _ctl _label=1
|
|
223
|
+
if [ -n "${DLC_CONTROLS:-}" ]; then
|
|
224
|
+
for _ctl in $DLC_CONTROLS; do # ๋ช
์๊ฐ์ ยซ์ ๊ท์ยป ๊ณ์ฝ โ ์๋์ ๋ถ๋ฆฌ
|
|
225
|
+
printf 'CONTROL\t%s\t์ปจํธ๋กค%s: %s\n' "$_ctl" "$_label" "$_ctl"
|
|
226
|
+
_label=$((_label+1))
|
|
227
|
+
done
|
|
228
|
+
else
|
|
229
|
+
local _repo; _repo="$(basename "$FH")"
|
|
230
|
+
# ERE ๋ฉํ๋ฌธ์ ์ด์ค์ผ์ดํ โ ์ ๋๊ฐ์ ยซ๊ทธ ๋ฌธ์์ด์ด ์ค์ ๋ก ์๋๊ฐยป ๋ฅผ ๋ฌป๋ ๊ฒ์ด์ง ํจํด์ด ์๋๋ค
|
|
231
|
+
_repo="$(printf '%s' "$_repo" | sed 's/[][\.^$*+?(){}|]/\\&/g')"
|
|
232
|
+
printf 'CONTROL\t%s\t์ปจํธ๋กค1: %s\n' "$_repo" "$_repo"
|
|
233
|
+
printf 'CONTROL\tsession\t์ปจํธ๋กค2: session\n'
|
|
234
|
+
fi
|
|
148
235
|
while IFS=$'\t' read -r id toks; do
|
|
149
236
|
[ -n "${id:-}" ] || continue
|
|
150
237
|
n=$((n+1))
|
|
@@ -168,7 +255,14 @@ do_check() {
|
|
|
168
255
|
[ -x "$CHECKER" ] || [ -f "$CHECKER" ] || {
|
|
169
256
|
echo "โ ์ฐฉ์ง ๊ฒ์ฆ๊ธฐ ๋ถ์ฌ: $CHECKER (์ด ์คํฌ๋ฆฝํธ๋ ๊ฒ์ฆ์ ์์ฒด ๊ตฌํํ์ง ์๋๋ค)" >&2; return 10; }
|
|
170
257
|
|
|
171
|
-
|
|
258
|
+
# ๐ฅ R7 (2026-08-19, **์ฒซ ์ค์ฌ์ฉ ๋ฐ๊ฒฌ**) โ `set -u` + bash 3.2 ์์ **๋น ๋ฐฐ์ด์ `${a[@]}` ๋
|
|
259
|
+
# unbound ์๋ฌ**๋ค. ๋์ ๋ ํฌ์ digest ์ดํ ์ปค๋ฐ์ด ์์ผ๋ฉด targets ๊ฐ ๋น๊ณ , ๊ทธ๋ฌ๋ฉด ์๋
|
|
260
|
+
# ํํฐ ๋ฃจํ๊ฐ ํฐ์ง๋ค. ๊ทธ ์๊ฐ ์คํฌ๋ฆฝํธ๋ ํ์ ์ ์ธ์ํ์ง ๋ชปํ ์ฑ **rc=1 ๋ก ๋๋๊ณ **,
|
|
261
|
+
# ๋ฌ๋๋ ๊ทธ 1 ์ ใSOME-UNLANDEDใ๋ก ๋ก๊ทธ์ ์ ๋๋ค โ ์ฆ **์
ธ ์๋ฌ๊ฐ ์ฐฉ์ง์จ ์๊ณ์ด์
|
|
262
|
+
# ์ค์ธก๊ฐ์ผ๋ก ๋ค์ด๊ฐ๋ค**([[feedback_not_found_is_not_zero_family]] ์ ๊ฐ์ฅ ์กฐ์ฉํ ์ผ๊ตด).
|
|
263
|
+
# ์ค์ธก: forge-wiki ๋์ ์ฒซ ๋ฐ์ด ์ ํํ ๊ทธ๋ ๊ฒ ยซSOME-UNLANDED (rc=1)ยป ์ ๋จ๊ฒผ๊ณ ๋ณธ๋ฌธ์ ์์๋ค.
|
|
264
|
+
# ์ฌ๋ฐ๋ฅธ ๊ฐ์ rc=10(ํ๊น 0๊ฑด = HARNESS-ERROR)์ด๋ค. ๋น ๋ฐฐ์ด ํ์ฅ์ ์ ๋ถ ๋ฐฉ์ดํ๋ค.
|
|
265
|
+
local -a targets=()
|
|
172
266
|
if [ "$#" -gt 0 ]; then targets=("$@")
|
|
173
267
|
else
|
|
174
268
|
# ๊ธฐ๋ณธ ์ค์ฝํ = ๊ณต๊ฐ FH ์์ฐ + tracks. **๋น๊ณต๊ฐ store ์ ์ธ**(์ด์์ ๊ฒฐ์ ).
|
|
@@ -176,7 +270,8 @@ do_check() {
|
|
|
176
270
|
# โ ๏ธ CLAUDE.md ๋ **์ ํ ํํฐ๋ฅผ ๊ฑฐ์น๋ค.** ์ดํ์ ๋ฌด์กฐ๊ฑด ์ถ๊ฐํ๊ณ , ๊ทธ๋์ ์ด ํ์ผ ํ๋๊ฐ
|
|
177
271
|
# ํํฐ๋ฅผ ์ฐํํด ์คํ ์์ฒ์ด ๋๋ค โ ์๊ฒ์ฆ์์ "M1 ์ฐฉ์ง 1ํ์ผ" ์ ๊ทธ 1ํ์ผ์ด CLAUDE.md
|
|
178
272
|
# ์๊ณ , ํ๋ณด์ ๋ฌด๊ดํ๊ฒ ์๋ ์๋ ํ ํฐ์ด์๋ค. ์์ธ ๊ฒฝ๋ก ํ๋๊ฐ ํํฐ ์ ์ฒด๋ฅผ ๋ฌด๋ ฅํํ๋ค.
|
|
179
|
-
|
|
273
|
+
case " $DLC_TRACKED_PATHS " in *" CLAUDE.md "*)
|
|
274
|
+
[ -f "$FH/CLAUDE.md" ] && [ "$FH/CLAUDE.md" -nt "$d" ] && targets+=("$FH/CLAUDE.md") ;; esac
|
|
180
275
|
# โ
**digest ๋ณด๋ค ๋์ค์ ์์ ๋ ํ์ผ๋ง** ๋ณธ๋ค. grep ์ "ํ ํฐ์ด ์๋ค" ๋ง ์ฌ๊ณ
|
|
181
276
|
# "์ด ํ๋ณด ๋๋ฌธ์ ์๊ฒผ๋ค" ๋ ๋ชป ์ฐ๋ค โ ์ด๋ฏธ ์๋ ๋ฌธ์๊ฐ ์ฐฉ์ง๋ก ์กํ๋ค(์ค์ธก: ํ๋ณด ํ๋๊ฐ
|
|
182
277
|
# 21ํ์ผ ํํธ, ์ ๋ถ ๋ฌด๊ดํ ๊ธฐ์กด ๋ฌธ์์๋ค). ์ ํ ํํฐ๊ฐ ์ธ๊ณผ๋ฅผ ์ฃผ์ง๋ ์์ง๋ง
|
|
@@ -211,11 +306,13 @@ do_check() {
|
|
|
211
306
|
[ -n "$f" ] || continue
|
|
212
307
|
case "$f" in *.md) ;; *) continue ;; esac
|
|
213
308
|
[ -f "$FH/$f" ] && targets+=("$FH/$f")
|
|
214
|
-
done < <(git -C "$FH" log --since="@$_dts" --name-only --pretty=format: --
|
|
215
|
-
|
|
216
|
-
|
|
309
|
+
done < <(git -C "$FH" log --since="@$_dts" --name-only --pretty=format: -- $DLC_TRACKED_PATHS 2>/dev/null | sort -u)
|
|
310
|
+
if [ -n "$DLC_IGNORED_DIR" ] && [ -d "$FH/$DLC_IGNORED_DIR" ]; then
|
|
311
|
+
while IFS= read -r f; do targets+=("$f"); done < <(
|
|
312
|
+
find "$FH/$DLC_IGNORED_DIR" -name '*.md' -type f -newer "$d" 2>/dev/null | head -400)
|
|
313
|
+
fi
|
|
217
314
|
# dirty tracked โ ์ปค๋ฐ ์ ๋ ์์ ๋ณธ์ git ์๊ฐ ์ฆ๊ฑฐ๊ฐ ์๋ค. ์ด๋ก์ผ๋ก ๋ง๋ค์ง ์๊ณ ์
์ ๋จ๊ธด๋ค.
|
|
218
|
-
DIRTY_TRACKED="$(git -C "$FH" diff --name-only --
|
|
315
|
+
DIRTY_TRACKED="$(git -C "$FH" diff --name-only -- $DLC_TRACKED_PATHS 2>/dev/null | grep -c '[.]md$')" || true
|
|
219
316
|
DIRTY_TRACKED="${DIRTY_TRACKED//[^0-9]/}"; DIRTY_TRACKED="${DIRTY_TRACKED:-0}"
|
|
220
317
|
fi
|
|
221
318
|
# โ
์๊ธฐ์ฐธ์กฐ ์ฐจ๋จ โ **์ด ๊ณ๊ธฐ์ ์ฒซ ์ค๋ฌผ ์คํ์์ 100% ์คํ์ ๋ธ ์์ธ**์ด๋ค.
|
|
@@ -224,7 +321,7 @@ do_check() {
|
|
|
224
321
|
local _dbase; _dbase="$(basename "$d")"
|
|
225
322
|
local -a _filtered=()
|
|
226
323
|
local _t
|
|
227
|
-
for _t in "${targets[@]}"; do
|
|
324
|
+
for _t in ${targets[@]+"${targets[@]}"}; do
|
|
228
325
|
case "$_t" in
|
|
229
326
|
*"$_dbase") continue ;; # digest ์์
|
|
230
327
|
*/logs/*) continue ;; # ๊ทธ ์์ฑ ๋ก๊ทธ
|
|
@@ -232,7 +329,7 @@ do_check() {
|
|
|
232
329
|
esac
|
|
233
330
|
_filtered+=("$_t")
|
|
234
331
|
done
|
|
235
|
-
targets=("${_filtered[@]}")
|
|
332
|
+
targets=(${_filtered[@]+"${_filtered[@]}"})
|
|
236
333
|
[ "${#targets[@]}" -gt 0 ] || { echo "โ ํ๊น 0๊ฑด" >&2; return 10; }
|
|
237
334
|
|
|
238
335
|
local probes; probes="$(mktemp -t dlc.XXXXXX)" || return 10
|
|
@@ -244,7 +341,7 @@ do_check() {
|
|
|
244
341
|
local unchk; unchk="$(grep -c '^# UNCHECKABLE' "$probes" 2>/dev/null)" || true
|
|
245
342
|
unchk="${unchk//[^0-9]/}"; unchk="${unchk:-0}"
|
|
246
343
|
echo "โโ digest ์ฐฉ์ง ๊ฒ์ฆ: $(basename "$d") โโ"
|
|
247
|
-
echo " ์ค์ฝํ:
|
|
344
|
+
echo " ์ค์ฝํ: git์ถ์ [${DLC_TRACKED_PATHS}] + ignored[${DLC_IGNORED_DIR:-์์}] (๋น๊ณต๊ฐ companion store ์ ์ธ โ '์กฐ์ง ์ ํ'๊ฐ ์๋๋ผ '๋ ํฌ ๋ด๋ถ ์ฐฉ์ง')"
|
|
248
345
|
echo " ํ๊น ํ์ผ ${#targets[@]}๊ฑด (digest ์ดํ ์์ ๋ถ๋ง) ยท ํ๋ณ๋ถ๊ฐ ํ๋ณด ${unchk}๊ฑด"
|
|
249
346
|
echo " ์ถ: git์ถ์ =์ปค๋ฐ์๊ฐ ยท gitignored=mtime ยท dirty tracked ${DIRTY_TRACKED:-0}๊ฑด=UNMEASURED"
|
|
250
347
|
echo " โ ๏ธ ์ด ๊ณ๊ธฐ๋ **์ ํ**๋ฅผ ์ฐ๋ค. ์ธ๊ณผ๊ฐ ์๋๋ค โ ํํธ๋ ์ด์ด์ ํ์ธํ๋ผ"
|
|
@@ -331,8 +428,66 @@ EOF
|
|
|
331
428
|
touch knowledge/old.md
|
|
332
429
|
printf 'forge-harness session control\n' > tracks/_meta/card.md
|
|
333
430
|
) >/dev/null 2>&1
|
|
334
|
-
|
|
431
|
+
# ์ปจํธ๋กค์ ํฝ์ค์ฒ๊ฐ ์ค์ ๋ก ๋ด๊ณ ์๋ ํ ํฐ์ผ๋ก ๊ณ ์ ํ๋ค(๋ ํฌ๋ช
์ด mktemp ๋์๋ผ์).
|
|
432
|
+
# ๐ฅ ์ด ๋ ์ธ์ ์ฃผ์ฅ์ **git/mtime ๋ ์ถ ๋ถ๋ฆฌ**์ง ์ปจํธ๋กค ์ ๋๊ฐ ์๋๋ค โ ์ถ์ ์์ง ์๋๋ค.
|
|
433
|
+
out="$( cd "$G" && CLAUDE_PROJECT_DIR="$G" DLC_CONTROLS="forge-harness session" \
|
|
434
|
+
bash "$SELF_DIR/$(basename "${BASH_SOURCE[0]}")" \
|
|
335
435
|
"$G/tracks/_meta/frontier_digest_2001_01_02.md" 2>&1 )"
|
|
436
|
+
# โโ โ
N-ctl (2026-08-18, R1-b) โ ์ปจํธ๋กค์ด **๋ ํฌ ์ด๋ฆ์ ๋ฐ๋ผ๊ฐ๋ค** โโโโโโโโโโโโ
|
|
437
|
+
# ์ดํ์ `forge-harness`/`session` ํ๋์ฝ๋ฉ์ด๋ผ **์์ฑ์ด ๊ฒจ๋ ๋ ํฌ์์ ๋งค๋ฒ ์ปจํธ๋กค ์ฌ๋ง**
|
|
438
|
+
# (= rc=10)์ด์๋ค. R1 ์ ์ธ์ ๋ฒ๊ทธ๋ฅผ ๊ณ ์ณ๋ ๊ณ๊ธฐ๋ ๊ตฌ์กฐ์ ์ผ๋ก ์ฃฝ์ ์ฑ์์ ๊ฒ์ด๋ค.
|
|
439
|
+
local out_ctl rc_ctl
|
|
440
|
+
out_ctl="$( cd "$G" && CLAUDE_PROJECT_DIR="$G" bash "$SELF_DIR/$(basename "${BASH_SOURCE[0]}")" \
|
|
441
|
+
"$G/tracks/_meta/frontier_digest_2001_01_02.md" 2>&1 )"; rc_ctl=$?
|
|
442
|
+
# ํฝ์ค์ฒ ๋ ํฌ ์ด๋ฆ(mktemp ๋์)์ ๋ณธ๋ฌธ์ ์๋ค โ ์ ๋๋ ์ปจํธ๋กค์ด ์ฃฝ์ด rc=10 ์ด ์ ์์ด๋ค.
|
|
443
|
+
# ์ด๊ฒ์ด ยซ์ ๋๊ฐ ์ค์ ๋ก ๋๋คยป์ ์ฆ๊ฑฐ๋ค(ํ๋์ฝ๋ฉ์ด๋ฉด ์ฌ๊ธฐ์ rc=1 ์ด ๋์จ๋ค).
|
|
444
|
+
_t "โ
N-ctl ์ปจํธ๋กค์ด ๋ ํฌ๋ช
์ ๋ฐ๋ผ๊ฐ๋ค(ํ๋์ฝ๋ฉ ์๋)" 10 "$rc_ctl"
|
|
445
|
+
# โโ โ
N-ctl-re (cross-family/codex F3) โ ์ ๋ ์ปจํธ๋กค์ **๋ฆฌํฐ๋ด**์ด์ง ์ ๊ท์์ด ์๋๋ค โโโโโโ
|
|
446
|
+
# ์ดํ์ `for _ctl in ${DLC_CONTROLS:-$(basename "$FH") session}` ์๋ค. ๋น์ธ์ฉ ๋ช
๋ น์นํ์ด๋ผ
|
|
447
|
+
# โ ๋ ํฌ๋ช
์ด ERE ๋ฉํ๋ฌธ์๋ฉด ยซ์๋ฌด ๋ด์ฉ์๋ ๋งค์นยปํด ๊ณ๊ธฐ ์์กด์ด **์คํ**์ด ๋๊ณ
|
|
448
|
+
# โ ์ค์ธกํ๋ ๊ธ๋ก๋น๊น์ง ํ์ ์ปจํธ๋กค์ด `.git` ๋ฑ์ผ๋ก **ํ์ฅ**๋๊ธฐ๋ ํ๋ค.
|
|
449
|
+
# ๐ฅ ํฝ์ค์ฒ๋ **ํ๋ณํ๋ ํํ**์ฌ์ผ ํ๋ค. ์ฒซ ํ๋ณธ์ ๋ ํฌ๋ช
์ `.*` ๋ก ์ก์๋๋ฐ, ๊ทธ๊ฑด ๊ธ๋ก๋น์
|
|
450
|
+
# ๊ฑธ๋ ค ์ฃฝ์ ์ปจํธ๋กค์ด ์๊ธฐ๋ ๋ฐ๋์ **๋ฒ๊ทธ ํ๋ณธ๋ rc=10** ์ ๋๋ค โ ๋๋๋ฆผ ํ๋ก๋ธ๊ฐ ๊ทธ
|
|
451
|
+
# ์ฅ์์ฑ์ ์ก์๋ค([[feedback_fixture_must_use_the_breaking_spelling]]).
|
|
452
|
+
# ๊ทธ๋์ ๋ ํฌ๋ช
์ `a.b` ๋ก ์ด๋ค: ๊ธ๋ก๋ธ๋ก๋ ์๋ฌด๊ฒ๋ ์ ๋ง์ ๊ทธ๋๋ก ๋จ๊ณ (ํ์ฅ ์์),
|
|
453
|
+
# ERE ๋ก๋ `axb` ์ ๋งค์น๋๋ค. ๋์์ `axb` ๋ง ๋๋ฉด
|
|
454
|
+
# ๋ฒ๊ทธ ํ๋ณธ โ ์ปจํธ๋กค **์์กด(์คํ)** โ rcโ 10
|
|
455
|
+
# ์๋ฆฌ ํ๋ณธ โ ๋ฆฌํฐ๋ด `a.b` ์์ โ ์ปจํธ๋กค ์ฌ๋ง โ rc=10
|
|
456
|
+
local RG; RG="$(mktemp -d -t 'dlc_re.XXXXXX')" || return 10
|
|
457
|
+
local RD="$RG/a.b"
|
|
458
|
+
(
|
|
459
|
+
mkdir -p "$RD/tracks/_meta" "$RD/knowledge" && cd "$RD" \
|
|
460
|
+
&& git init -q . && git config user.email t@t && git config user.name t
|
|
461
|
+
printf '# d\n## ๐ FH Immediate Application Candidates\n\n| # | ํฐ์ด | ๋ด์ฉ |\n|---|---|---|\n| **A1** | M | `zzz_absent_token` ํ๋ณด |\n\n## end\n' \
|
|
462
|
+
> tracks/_meta/frontier_digest_2001_01_01.md
|
|
463
|
+
touch -t 200101010000 tracks/_meta/frontier_digest_2001_01_01.md
|
|
464
|
+
# ๋ฆฌํฐ๋ด `a.b` ๋ **์๋ค**. `axb`(ERE ๋ก๋ง ๋งค์น) ์ `session` ๋ง ์๋ค.
|
|
465
|
+
printf 'axb ๊ทธ๋ฆฌ๊ณ session\n' > tracks/_meta/card.md
|
|
466
|
+
) >/dev/null 2>&1
|
|
467
|
+
local rc_re
|
|
468
|
+
( cd "$RD" && CLAUDE_PROJECT_DIR="$RD" bash "$SELF_DIR/$(basename "${BASH_SOURCE[0]}")" \
|
|
469
|
+
"$RD/tracks/_meta/frontier_digest_2001_01_01.md" ) >/dev/null 2>&1; rc_re=$?
|
|
470
|
+
_t "โ
N-ctl-re ๋ ํฌ๋ช
์ด ์ ๊ท์ ๋ฉํ๋ฌธ์์ฌ๋ ๋ฆฌํฐ๋ด๋ก ์ทจ๊ธ(์ปจํธ๋กค ์คํ ์์)" 10 "$rc_re"
|
|
471
|
+
rm -rf "$RG"
|
|
472
|
+
|
|
473
|
+
# โโ โ
N-empty (2026-08-19, R7) โ ํ๊น์ด 0๊ฑด์ด๋ฉด **rc=10** ์ด์ง rc=1 ์ด ์๋๋ค โโโโโโโโโโโโ
|
|
474
|
+
# ๐ฅ `set -u` + bash 3.2 ์์ ๋น ๋ฐฐ์ด ํ์ฅ์ด ํฐ์ง๋ฉด, ์คํฌ๋ฆฝํธ๋ ํ์ ์ ๋ชป ๋ด๊ณ **rc=1** ๋ก
|
|
475
|
+
# ๋๋๋ค. ๋ฌ๋๋ ๊ทธ 1 ์ ใSOME-UNLANDEDใ๋ก ์ ๋๋ค โ ์
ธ ์๋ฌ๊ฐ ์ฐฉ์ง์จ ์๊ณ์ด์ ์ค์ธก๊ฐ์ผ๋ก
|
|
476
|
+
# ๋ค์ด๊ฐ๋ค. ์ฒซ ์ค์ฌ์ฉ(forge-wiki ๋์)์์ ์ ํํ ๊ทธ ๋ก๊ทธ๊ฐ ๋์๊ณ ๋ณธ๋ฌธ์ ๋น์ด ์์๋ค.
|
|
477
|
+
local EG; EG="$(mktemp -d -t dlc_e.XXXXXX)" || return 10
|
|
478
|
+
(
|
|
479
|
+
mkdir -p "$EG/wiki" && cd "$EG" && git init -q . \
|
|
480
|
+
&& git config user.email t@t && git config user.name t
|
|
481
|
+
printf '# d\n## ๐ FH Immediate Application Candidates\n\n| # | ํฐ์ด | ๋ด์ฉ |\n|---|---|---|\n| **A1** | M | `zzz_tok` ํ๋ณด |\n\n## end\n' \
|
|
482
|
+
> wiki/frontier_digest_2001_01_01.md
|
|
483
|
+
) >/dev/null 2>&1
|
|
484
|
+
# digest ์ดํ ์ปค๋ฐ 0 ยท ignored ์ถ ์์ โ ํ๊น 0๊ฑด
|
|
485
|
+
local rc_e
|
|
486
|
+
( cd "$EG" && CLAUDE_PROJECT_DIR="$EG" DLC_TRACKED_PATHS="wiki" DLC_IGNORED_DIR="" \
|
|
487
|
+
DLC_CONTROLS="zzz_tok" bash "$SELF_DIR/$(basename "${BASH_SOURCE[0]}")" \
|
|
488
|
+
"$EG/wiki/frontier_digest_2001_01_01.md" ) >/dev/null 2>&1; rc_e=$?
|
|
489
|
+
_t "โ
N-empty ํ๊น 0๊ฑด์ HARNESS-ERROR(10)์ด์ง ๋ฏธ์ฐฉ์ง(1)๊ฐ ์๋๋ค" 10 "$rc_e"
|
|
490
|
+
rm -rf "$EG"
|
|
336
491
|
# โ ๏ธ **์ค ๋จ์๋ก** ๋ณธ๋ค. `case *"A1"*"๋ฏธ์ฐฉ์ง"*` ๋ ๋ง์ง๋ง ์์ฝ์ค("N๊ฑด ์ค M๊ฑด ๋ฏธ์ฐฉ์ง")๊น์ง
|
|
337
492
|
# ์ผ์ผ ์ค๋งค์นญํ๋ค โ ๋ฌธ์์ด ์์น๋ก ํ์ ํ๋ prose-grep ํจ์ ([[feedback_typed_verdict_channel]]).
|
|
338
493
|
if printf '%s\n' "$out" | grep -qE 'ํ๋ณด A1[[:space:]]+๋ฏธ์ฐฉ์ง'; then
|
|
@@ -290,6 +290,77 @@ fi
|
|
|
290
290
|
( cd "$FH" && bash scripts/branch_claim.sh reap >/dev/null 2>&1 ) || true
|
|
291
291
|
}
|
|
292
292
|
|
|
293
|
+
# โโ ๋งคํ๋ ํ๋ก์ ํธ์ capability ํ๋ฉดํ (2026-08-18) โโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
294
|
+
# WHY HERE (branch-claim ๊ณผ ๊ฐ์ ์๋ฆฌ, early exit **์**): ์ด๊ฑด Mode D ์ ์ฉ์ด ์๋๋ค.
|
|
295
|
+
# companion store ๊ฐ ์๋ ์ค์น์์๋ ํ๋ก์ ํธ๋ ๋งคํ๋๊ณ , ๊ทธ๋๋ ํ์ ํ๋ค์ค์ ์คํฌ์
|
|
296
|
+
# ์ ๋ณด์ธ๋ค. ์๋ early exit ๋ฐ์ ๋๋ฉด ๊ทธ ์ค์น์์ ํต์งธ๋ก ์ฃฝ๋๋ค โ ๋ฐ๋ก ์ branch-claim
|
|
297
|
+
# ๋ธ๋ก์ด ๊ฐ์ ์ด์ ๋ก ์ฌ๊ธฐ ์๋ค.
|
|
298
|
+
# โ ๏ธ **์ ๋ฐํ(cross-family ์ ๋ฐ)**: `tracks/` ๋ npm ์ฐ์ถ๋ฌผ์ **์ ๋ค์ด๊ฐ๋ค**(per-install ๋ฐ์ดํฐ).
|
|
299
|
+
# ๊ทธ๋ฌ๋ ยซ๊ฐ ์ค์นํยป ์๋น์์๊ฒ๋ ์ด ๋ธ๋ก์ด ์๋ฌด๊ฒ๋ ์ ์ฐ๋๋ค โ ๊ฐ์ ๊ทธ ์ฌ๋์ด ํ๋ก์ ํธ๋ฅผ
|
|
300
|
+
# **๋งคํํ ๋ค๋ถํฐ** ์๊ธด๋ค. ใ๊ณต๊ฐ ์ฌ์ฉ์์๊ฒ๋ ์ฐ๋คใ๋ ๊ทธ๋ฐ ๋ป์ด์ง ยซ์ค์น ์ฆ์ ๊ฐ์ด ์๋คยป ๊ฐ
|
|
301
|
+
# ์๋๋ค. (์ค์ธก: ํฉ ์ฐ์ถ๋ฌผ์ tracks ์์ โ ์นจ๋ฌต ยท tracks/someproject ์์ฑ ํ โ ๋ฐํ)
|
|
302
|
+
#
|
|
303
|
+
# WHY AT ALL: `CLAUDE.md ยงCross-Project Skill Bus` ๋ registry ๋ฅผ **์จ๋ณด๋ฉ Step 1-c** ์์
|
|
304
|
+
# ์ฝ๋๋ฐ, ยงActive Onboarding ์ Guards ๊ฐ ยซexplicit task-entry โ skip onboarding menuยป ๋ค.
|
|
305
|
+
# ์ฒซ ๋ฐํ๊ฐ task ๋ฉด ๋ฉ๋ด์ ํจ๊ป **๋ฐ์ดํฐ ๋ก๋๊น์ง ๊ฐ์ด ๊บผ์ง๋ค.** ๋ฉ๋ด๋ UI ๊ณ registry ๋
|
|
306
|
+
# ๋ฐ์ดํฐ์ธ๋ฐ ํ ๋จ๊ณ์ ๋ฌถ์ฌ ์์ด์ UI ๋ฅผ ๋๋ฉด ๋ฐ์ดํฐ๋ ๊บผ์ง๋ค.
|
|
307
|
+
# โ Mode D companion-store ๋ก๋๋ ์ด ๋ณ์ ์ด๋ฏธ ํ ๋ฒ ๊ณ ์ณค๋ค(ยซ์ด๊ฑด ๋ฉ๋ด๊ฐ ์๋๋ผ ๋ฐ์ดํฐ
|
|
308
|
+
# ๋ก๋๋คยป carve-out + ์ด ์คํฌ๋ฆฝํธ). **registry ์ ๊ทธ ์ฒ๋ฐฉ์ด ์ ๋ถ์๋ค** = ๋ฐ์ชฝ-ํฝ์ค
|
|
309
|
+
# ์ ํ๊ฒฝ๊ณ.
|
|
310
|
+
# ์ค์ธก(2026-08-18): `tracks/gstack` ์ด ๋งคํ๋ผ ์๊ณ SKILL.md ๊ฐ 55๊ฐ์ธ๋ฐ, ์ด์์๊ฐ ์ด๋ฆ์
|
|
311
|
+
# ๋ ๋๊น์ง ์ธ์
์ด ๊ทธ ์กด์ฌ๋ฅผ ๋ชฐ๋๋ค. CATALOGยทCLAUDE.mdยทsim-conductor ์ ์ ๋ถ ๋ฑ๋ก๋ผ ์์๋ค.
|
|
312
|
+
#
|
|
313
|
+
# ๋น์ฉ ๊ฒฝ๊ณ: ์ด๋ฆ๊ณผ ๊ฐ์๋ง. ๋ชฉ๋ก ์ ๋ ๋ก๋๋ ์ ํ๋ค(ํ ํฐ). ์ค๋ฌผ์ด ์๊ฑฐ๋ ์คํฌ์ด 0์ธ ํธ๋์
|
|
314
|
+
# ์์ ์ ์ฐ๋๋ค โ ๋งค ์ธ์
13์ค์ด ๋จ๋ฉด ๊ทธ๊ฑด ๋ฐฐ๊ฒฝ ์์์ด๊ณ ์๋ฌด๋ ์ ์ฝ๋๋ค.
|
|
315
|
+
# ๐ฅ 0 ์ ยซ์๋คยป ๋ก ๋ ๋ํ์ง ์๋๋ค: ํ๋ก์ ํธ ๋ฃจํธ๋ฅผ ๋ชป ์ฐพ์ผ๋ฉด ๊ทธ๋ ๊ฒ ์ ๊ณ , ๊ฐ์๋ฅผ 0 ์ผ๋ก
|
|
316
|
+
# ์ ์ง ์๋๋ค(๋ถ์ฌ โ 0).
|
|
317
|
+
_PROJ_ROOT="${FH_PROJECTS_ROOT:-$(dirname "$FH")}"
|
|
318
|
+
if [ -d "$FH/tracks" ]; then
|
|
319
|
+
_reg=""; _mapped=0; _resolved=0
|
|
320
|
+
for _t in "$FH"/tracks/*/; do
|
|
321
|
+
_n=$(basename "$_t")
|
|
322
|
+
case "$_n" in _*) continue ;; esac
|
|
323
|
+
[ "$_n" = "*" ] && continue
|
|
324
|
+
_mapped=$((_mapped + 1))
|
|
325
|
+
_d="$_PROJ_ROOT/$_n"
|
|
326
|
+
[ -d "$_d" ] || continue
|
|
327
|
+
_resolved=$((_resolved + 1))
|
|
328
|
+
# ๋ฌด๊ฑฐ์ด ๋๋ ํฐ๋ฆฌ๋ฅผ ์ณ๋ธ๋ค โ ๋น์ฉ ์ฃผ์ฅ์ด ยซ๋ด ๋จธ์ ์ ๋ด ํ๋ก์ ํธ ์งํฉยป ์์ ์ ์์ผ๋ฉด
|
|
329
|
+
# ์ ๋๋ค(cross-family ์ง์ ). node_modules/.venv/.git ์ด depth 3 ์์ ์์ผ๋ฉด ์ ํ์ผ๋ก ๋๋ค.
|
|
330
|
+
_sk=$(find "$_d" -maxdepth 3 \( -name node_modules -o -name .git -o -name .venv \
|
|
331
|
+
-o -name venv -o -name target -o -name dist \) -prune -o \
|
|
332
|
+
-name SKILL.md -print 2>/dev/null | wc -l | tr -d ' ')
|
|
333
|
+
[ "${_sk:-0}" -gt 0 ] || continue
|
|
334
|
+
_reg="${_reg} โธ ${_n} โ SKILL.md ${_sk}๊ฐ (${_d})
|
|
335
|
+
"
|
|
336
|
+
done
|
|
337
|
+
# ๐ฅ **๋ถ์ฌ โ 0.** ํ๋ณ์๋ ยซ๋ฃจํธ ๋๋ ํฐ๋ฆฌ๊ฐ ์๋ยป๊ฐ ์๋๋ค โ `dirname "$FH"` ๋ ๊ฑฐ์ ํญ์
|
|
338
|
+
# ์กด์ฌํด์ ๊ทธ ๋ถ๊ธฐ๋ ๋ฐํ ๋ถ๊ฐํ ์ฅ์์ด์๋ค(์ดํ ๊ฒฐํจ, ๊ฐ์ ์ปค๋ฐ์์ ์๋ ฅ ์ ๋ฐ).
|
|
339
|
+
# ์ค์ง ํ๋ณ์๋ **๋งคํ๋ ํธ๋์ด ์๋๋ฐ ํ๋๋ ์ค๋ฌผ๋ก ํด์๋์ง ์์๋ค** ์ด๊ณ , ๊ทธ๋๋ง
|
|
340
|
+
# ใ๋ชป ์๋คใ๋ฅผ ๋งํ๋ค. ์๋น์์ ๋ ํฌ๊ฐ ๋ค๋ฅธ ๊ฒฝ๋ก์ ์์ผ๋ฉด ์ ํํ ์ด ์ํ๊ฐ ๋๋ค.
|
|
341
|
+
# ๐ฅ **all-or-nothing ์ด๋ฉด ์ ๋๋ค** (cross-family ์ ๋ฐ, ์ดํ ๊ฒฐํจ): ยซ์ ๋ถ ๋ชป ์ฐพ์์ ๋๋งยป
|
|
342
|
+
# ๋งํ๋ฉด 13๊ฐ ์ค 1๊ฐ๋ง ํด์๋๊ณ 12๊ฐ๊ฐ ์์ ๋ ๊ทธ 12๊ฐ๊ฐ **์์ ํ ์นจ๋ฌต**ํ๋ค โ ์ด ๋ธ๋ก์ด
|
|
343
|
+
# ์์ ๋ ค๋ ยซ๋ถ์ฌ๋ฅผ 0์ผ๋ก ๋ ๋ยป ๋ฅผ ๋ธ๋ก ์์ ์ด ์ฌํํ๋ค. ๋ฏธํด์๊ฐ ํ๋๋ผ๋ ์์ผ๋ฉด ๋งํ๋ค.
|
|
344
|
+
_unres=$((_mapped - _resolved))
|
|
345
|
+
if [ "$_unres" -gt 0 ]; then
|
|
346
|
+
_reg="${_reg} โ ๏ธ ๋งคํ๋ ํธ๋ ${_mapped}๊ฐ ์ค ${_unres}๊ฐ๋ ยซ${_PROJ_ROOT}ยป ๋ฐ์์ ์ค๋ฌผ์ ๋ชป ์ฐพ์๋ค โ ๊ทธ ${_unres}๊ฐ๋ ยซ0ยป ์ด ์๋๋ผ **๋ฏธ์ธก์ **์ด๋ค (๊ฒฝ๋ก๊ฐ ๋ค๋ฅด๋ฉด FH_PROJECTS_ROOT).
|
|
347
|
+
"
|
|
348
|
+
fi
|
|
349
|
+
if [ -n "$_reg" ]; then
|
|
350
|
+
if [ "$_resolved" -gt 0 ]; then
|
|
351
|
+
echo "๐งฉ [cross-project skill bus] ๋งคํ๋ ํ๋ก์ ํธ์ SKILL.md ๊ฐ ์๋ค โ ํ์ผ ๊ฐ์๋ง ์ผ ๊ฒ์ด์ง ยซ์ง๊ธ ์ธ์
์์ ํธ์ถ ๊ฐ๋ฅํ๋คยป ๋ ํ์ธ์ด ์๋๋ค."
|
|
352
|
+
printf "%s" "$_reg"
|
|
353
|
+
# ๋ชฉ๋ก์ด ์ค์ ๋ก ์์ ๋๋ง ๋ธ๋ค. ๊ฐ๋ฑ(๋ชป ์ฐพ์) ์ผ์ด์ค์ ์ด ์๋ด๊ฐ ๋ถ์ผ๋ฉด ยซ์ฝ์ ๊ฒ์ด ์๋คยป ๋
|
|
354
|
+
# ์ธ์์ ์ฃผ๋๋ฐ ๋ชฉ๋ก์ ๋น์ด ์๋ค โ ์๋ ๊ฒ์ ์๋ค๊ณ ๋งํ๋ ์ชฝ์ด๋ค.
|
|
355
|
+
echo " โ ๏ธ ์ด ์ค์ ยซ์๋คยป ๋ง ๋งํ๋ค. ์ฐ๊ธฐ ์ ์ ๊ทธ์ชฝ SKILL.md ๋ฅผ ์ฝ์ด๋ผ โ ํ๋ ํ๋ค์ค ์ฉ์ด๋ฅผ"
|
|
356
|
+
echo " ์ผ๋ฐ ๊ฐ๋
์ผ๋ก ์ ๊ทํํ๋ ๊ฒ์ด ์ด ๋ ํฌ์ ์์ต ์คํจ๋ค."
|
|
357
|
+
else
|
|
358
|
+
echo "๐งฉ [cross-project skill bus] ๋งคํ์ ์๋๋ฐ ์ค๋ฌผ์ ๋ชป ์ฐพ์๋ค โ ์๋๋ **๋ฏธ์ธก์ **์ด๋ค."
|
|
359
|
+
printf "%s" "$_reg"
|
|
360
|
+
fi
|
|
361
|
+
fi
|
|
362
|
+
fi
|
|
363
|
+
|
|
293
364
|
# Non-Mode-D / no companion store โ silent no-op (this is the majority path for public users).
|
|
294
365
|
[ -d "$BE/.git" ] || exit 0
|
|
295
366
|
|
package/scripts/selfcheck.sh
CHANGED
|
@@ -703,6 +703,35 @@ else
|
|
|
703
703
|
fail=1
|
|
704
704
|
fi
|
|
705
705
|
|
|
706
|
+
# test_satellite_publish_gate_lanes โ ์์ฑ ๊ณต๊ฐํ๋ฉด ๊ฒ์ดํธ(2026-08-18, ์์ 2์ฐจ).
|
|
707
|
+
# ๐ฅ ์ด ๋ฐฐ์ ์ด ์์ด์ CI ๊ฐ `lane-runner: lane suite(s) with no runner and no declaration` ๋ก
|
|
708
|
+
# ๋นจ๊ฐฐ๋ค. ์ค์ํธ๋ฅผ ์ ์คํ๊ณ ์๋ฌด ๋ฐ์๋ ์ ๋๋ฆฐ ๊ฒ โ ๊ฒ์ฌ๊ธฐ์ ํํ๋๋ก
|
|
709
|
+
# *"A suite nothing executes is prose."* ๊ทธ ๊ฒ์ฌ๊ธฐ๊ฐ ๋ด ์ ์ค ๋ ์ธ์ ์ก์๋ค.
|
|
710
|
+
if [ ! -f scripts/test_satellite_publish_gate_lanes.sh ]; then
|
|
711
|
+
echo "FAIL test_satellite_publish_gate_lanes.sh: missing โ publish gate has no anchor"
|
|
712
|
+
fail=1
|
|
713
|
+
elif _out=$(bash scripts/test_satellite_publish_gate_lanes.sh < /dev/null 2>&1); then
|
|
714
|
+
echo "PASS test_satellite_publish_gate_lanes.sh ($(printf '%s\n' "$_out" | grep -oE '[0-9]+ passed, [0-9]+ failed' | tail -1))"
|
|
715
|
+
else
|
|
716
|
+
echo "FAIL test_satellite_publish_gate_lanes.sh: publish gate lanes failed"
|
|
717
|
+
_show_failure "$_out"
|
|
718
|
+
fail=1
|
|
719
|
+
fi
|
|
720
|
+
|
|
721
|
+
# test_evidence_root_psa_lanes โ ์ํฌํธ๋ฆฌ์์ ๊ธฐ๋ฐ์ฑ ์ค๋ฒ๋ผ์ด๋๋ฅผ ์ฐพ๋๊ฐ (R4, 2026-08-18).
|
|
722
|
+
# ๐ฅ `EVIDENCE_ROOT` ์๋ ๋ ์ธ์ด **ํ๋๋ ์์๋ค** โ ๊ทธ๋์ `tracks/` ๋ง ์ฎ๊ธฐ๊ณ gitignored
|
|
723
|
+
# ํจํด ํ์ผ์ ์ ์ฎ๊ธด ๋ฐ์ชฝ-ํฝ์ค๊ฐ ๊ทธ๋๋ก ์ถํ๋๋ค. ๋๋๋ฆผ ํ๋ก๋ธ๋ก E1 ๋ง ์ ์ ํ์ธ.
|
|
724
|
+
if [ ! -f scripts/test_evidence_root_psa_lanes.sh ]; then
|
|
725
|
+
echo "FAIL test_evidence_root_psa_lanes.sh: missing โ EVIDENCE_ROOT ๊ธฐ๋ฐ์ฑ ๊ฒฝ๋ก์ ์ต์ปค ์์"
|
|
726
|
+
fail=1
|
|
727
|
+
elif _out=$(bash scripts/test_evidence_root_psa_lanes.sh < /dev/null 2>&1); then
|
|
728
|
+
echo "PASS test_evidence_root_psa_lanes.sh ($(printf '%s\n' "$_out" | grep -oE '[0-9]+ passed, [0-9]+ failed' | tail -1))"
|
|
729
|
+
else
|
|
730
|
+
echo "FAIL test_evidence_root_psa_lanes.sh: evidence-root psa lanes failed"
|
|
731
|
+
_show_failure "$_out"
|
|
732
|
+
fail=1
|
|
733
|
+
fi
|
|
734
|
+
|
|
706
735
|
# cluster_capability_scan โ wired 2026-08-16 (์ ์ฒด์ฑ โ -(a) cluster-wizard).
|
|
707
736
|
# ์ข
๋จ ํ์ ์ค์ด `โฆ ์บ๋ฆฌ๋ธ๋ ์ด์
ํต๊ณผ/์คํจ: N PASS / M FAIL` ์ด๋ผ ์ `_subj` ๋ฃจํ์
|
|
708
737
|
# ์บ๋ฆฌ๋ธ๋ ์ด์
๊ฒ์ดํธ๋ฅผ **์ง์ง ํ์ ์ค๋ก** ๋ง์กฑํ๋ค โ ํ
์คํธ ์ผ์ด์ค ์ ๋ชฉ์ด ์๋๋ค.
|