@tyhld/conductor 0.12.85 → 0.12.87
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/README.md +11 -1
- package/dist/autoupdate.js +643 -0
- package/dist/cli.js +7 -1
- package/dist/headless.js +157 -10
- package/dist/relay.js +196 -0
- package/dist/selfcheck.js +94 -10
- package/package.json +3 -1
- package/sales-template/install.sh +22 -2
- package/sales-template/setup.sh +201 -0
- package/scripts/autoupdate-install.sh +285 -0
- package/scripts/conductor-run.sh +3 -1
- package/scripts/dist-source.sh +161 -12
- package/scripts/hooks/policy.py +84 -2
- package/scripts/hooks/skill_sync_notify.py +19 -1
- package/scripts/hooks/test_policy.py +64 -0
- package/scripts/hooks/test_skill_sync_notify.py +26 -0
- package/scripts/tyhld-autoupdate.sh +61 -0
- package/scripts/update-guard.sh +29 -7
- package/skills/conductor-craftsman/SKILL.md +13 -5
- package/systemd/build-runner-install.sh +1 -1
- package/systemd/ear-install.sh +1 -1
- package/systemd/guard-sync-install.sh +1 -1
- package/systemd/tyhld-autoupdate-boot.service +27 -0
- package/systemd/tyhld-autoupdate.service +24 -0
- package/systemd/tyhld-autoupdate.timer +20 -0
- package/systemd/tyhld-selfcheck.service +1 -1
- package/systemd/tyhld-selfcheck.timer +1 -1
|
@@ -110,6 +110,11 @@ REINSTALL = ('npm install -g @tyhld/conductor '
|
|
|
110
110
|
RESYNC = 'APPLY=1 bash "$(npm root -g)/@tyhld/conductor/scripts/update-guard.sh"'
|
|
111
111
|
|
|
112
112
|
|
|
113
|
+
def autoupdate_enabled():
|
|
114
|
+
"""自動更新が入っている PC か(自社PCの鍵 ~/.tyhld/bin/autoupdate/enabled・便 29babc5d)。"""
|
|
115
|
+
return os.path.isfile(os.path.join(os.path.expanduser('~'), '.tyhld', 'bin', 'autoupdate', 'enabled'))
|
|
116
|
+
|
|
117
|
+
|
|
113
118
|
def recovery_steps(reason):
|
|
114
119
|
"""うまくいかなかった理由に【合った】手順を返す(便 675e2d05)。
|
|
115
120
|
|
|
@@ -118,7 +123,20 @@ def recovery_steps(reason):
|
|
|
118
123
|
(入っている版と公開の版が違う)のときにこれを打っても、配り元の確認でまた弾かれる=
|
|
119
124
|
同じ失敗を繰り返すだけで直らない。先に入れ直しが要る。
|
|
120
125
|
"""
|
|
121
|
-
if reason in ('
|
|
126
|
+
if reason in ('flagged-bad', 'flagged-suspect'):
|
|
127
|
+
# ★管制で不具合・疑いの印が付いた版(便 29babc5d)。入れ直しても同じ版なら直らない。
|
|
128
|
+
if autoupdate_enabled():
|
|
129
|
+
return ['再開のしかた: この PC は自動更新が入っています。管制が直した版を決めれば、'
|
|
130
|
+
'次の自動更新で入れ替わります(人の操作は要りません)。']
|
|
131
|
+
return ['再開のしかた: この版には管制で不具合の印が付いています。CC1 に知らせてください'
|
|
132
|
+
f'(直した版が公開されたら {REINSTALL})。']
|
|
133
|
+
if reason in ('unpublished', 'deprecated', 'version-drift', 'not-installed', 'incomplete'):
|
|
134
|
+
# ★自動更新が入っている PC は、更新係が管制の決めた版へそろえる(便 29babc5d)。
|
|
135
|
+
# 人が npm で入れると段階配布の順番が崩れるので、入れ直しを促さない。
|
|
136
|
+
# ★not-installed・incomplete は配布物そのものが無い=更新係も動けないので、自動更新の有無によらず入れ直す。
|
|
137
|
+
if autoupdate_enabled() and reason in ('unpublished', 'deprecated', 'version-drift'):
|
|
138
|
+
return ['再開のしかた: この PC は自動更新が入っています。次の自動更新(管制が決めた版を、'
|
|
139
|
+
'作業中の便が終わってから入れます)でそろいます。管制の「PCの状態」で確かめてください。']
|
|
122
140
|
return [f'再開のしかた: この PC で次の順に打ってください。① {REINSTALL}',
|
|
123
141
|
f' ② {RESYNC}']
|
|
124
142
|
if reason == 'no-npm':
|
|
@@ -1912,6 +1912,70 @@ finally:
|
|
|
1912
1912
|
else:
|
|
1913
1913
|
os.environ['CONDUCTOR_WORK_DIR'] = _wd_env2
|
|
1914
1914
|
|
|
1915
|
+
# ─────────────────────────────────────────────────────────────────────────────
|
|
1916
|
+
# 検索の「探す言葉」の中の削除命令(便 915694ac・えふさん確定 2026-10-02)
|
|
1917
|
+
#
|
|
1918
|
+
# 【実物】職人が鉄則や台本を調べるとき、探す言葉に「rm -rf .git」のような字が入る。
|
|
1919
|
+
# 番人はそれを削除命令として読み、調べる作業を毎回止めていた。
|
|
1920
|
+
# 【直し】探すだけの道具(grep 系・rg 系・git grep)の【引用符の中】に在る字は、
|
|
1921
|
+
# 削除命令として数えない。囲みの外に在る字は1件も免じない。
|
|
1922
|
+
# ★安全は1件も緩めない=下の「止まり続ける形」をすべて固定する。
|
|
1923
|
+
# ─────────────────────────────────────────────────────────────────────────────
|
|
1924
|
+
print('\n=== 探す言葉の中の削除命令は、削除命令として読まない ===')
|
|
1925
|
+
_SEARCH_OK = [
|
|
1926
|
+
"grep -rn 'rm ' skills docs",
|
|
1927
|
+
'grep -rn "rm -rf" skills',
|
|
1928
|
+
"grep -n 'rm -rf .git' skills/conductor-craftsman/SKILL.md",
|
|
1929
|
+
"grep -rn 'rm -r /tmp/claude-1000/sagyou' skills",
|
|
1930
|
+
"grep -rln 'rm -r ~' docs",
|
|
1931
|
+
'grep -rn "rm -rf $HOME" docs',
|
|
1932
|
+
"git grep -n 'rm -rf .git' -- skills docs",
|
|
1933
|
+
"rg -n 'rm -rf /' docs",
|
|
1934
|
+
"rg 'rm -rf .tyhld' skills",
|
|
1935
|
+
"grep -rn '-f なしの rm -r' skills",
|
|
1936
|
+
]
|
|
1937
|
+
for _c in _SEARCH_OK:
|
|
1938
|
+
check(f'探す言葉: {_c}', policy.decide_bash(_c)['decision'], policy.ALLOW)
|
|
1939
|
+
|
|
1940
|
+
print('\n=== 探す言葉に見せても、本当に消す形は止まり続ける ===')
|
|
1941
|
+
# ★この一覧はえふさん確定(2026-10-02)の「今までどおり止まること」の全件。
|
|
1942
|
+
_STILL_DENY = [
|
|
1943
|
+
# 包みの中(bash -c・sh -c・eval)
|
|
1944
|
+
"bash -c 'rm -rf .git'",
|
|
1945
|
+
'sh -c "rm -rf .git"',
|
|
1946
|
+
"eval 'rm -rf .git'",
|
|
1947
|
+
'bash -c "grep -rn \'x\' docs; rm -rf .git"',
|
|
1948
|
+
# 命令の置き換え($( ) と ` `)
|
|
1949
|
+
'$(rm -rf .git)',
|
|
1950
|
+
'echo $(rm -rf .git)',
|
|
1951
|
+
'X=$(rm -rf .git)',
|
|
1952
|
+
'`rm -rf .git`',
|
|
1953
|
+
'echo `rm -rf .git`',
|
|
1954
|
+
'$(rm -r ~)',
|
|
1955
|
+
# ; && | で続けた後ろ
|
|
1956
|
+
'echo x; rm -rf .git',
|
|
1957
|
+
"grep -rn 'x' docs && rm -rf .git",
|
|
1958
|
+
"grep -rn 'x' docs | rm -rf .git",
|
|
1959
|
+
"grep -rn 'rm -rf' docs; rm -r .tyhld",
|
|
1960
|
+
# 探す命令に見せかけて後ろで消す形
|
|
1961
|
+
"grep -rn 'rm -rf .git' docs; rm -rf .git",
|
|
1962
|
+
"grep -rn 'rm -rf' skills && rm -r ~",
|
|
1963
|
+
# xargs・find の -exec(消す先が字面に出る形)
|
|
1964
|
+
'xargs rm -rf .git',
|
|
1965
|
+
"find . -name '*.tmp' -exec rm -rf .git {} +",
|
|
1966
|
+
'find docs -type f -exec rm -r {} +',
|
|
1967
|
+
# 変数・* を含む再帰削除(今までどおり)
|
|
1968
|
+
'rm -rf $DIR/x',
|
|
1969
|
+
'rm -rf build/*',
|
|
1970
|
+
]
|
|
1971
|
+
for _c in _STILL_DENY:
|
|
1972
|
+
check(f'止まり続ける: {_c}', policy.decide_bash(_c)['decision'], policy.DENY)
|
|
1973
|
+
|
|
1974
|
+
print('\n=== -f なしの実在パスの削除は今までどおり通る ===')
|
|
1975
|
+
for _c in ['rm -r /tmp/claude-1000/sagyou', 'rm /tmp/claude-1000/a.html',
|
|
1976
|
+
'rm -rf node_modules', 'rm -rf dist']:
|
|
1977
|
+
check(f'通る: {_c}', policy.decide_bash(_c)['decision'], policy.ALLOW)
|
|
1978
|
+
|
|
1915
1979
|
# ─────────────────────────────────────────────────────────────────────────────
|
|
1916
1980
|
print('\n' + '=' * 72)
|
|
1917
1981
|
if failures:
|
|
@@ -322,6 +322,32 @@ with tempfile.TemporaryDirectory() as tmp:
|
|
|
322
322
|
check_true(f'{label}: 入っている配布物の台本を打たせる', 'npm root -g' in b)
|
|
323
323
|
check(f'{label}: 作業ツリーへ cd させない', 'cd ~/projects' in b, False)
|
|
324
324
|
|
|
325
|
+
# ★便 29babc5d: 番人を配る条件が「公開されている正規の版で、管制で不具合の印が無い版」になった。
|
|
326
|
+
unpub = body_for('unpublished')
|
|
327
|
+
check_true('公開npmに無い版: 入れ直しから案内する', '① npm install -g @tyhld/conductor' in unpub)
|
|
328
|
+
check_true('使わないでの印: 入れ直しから案内する', '① npm install -g' in body_for('deprecated'))
|
|
329
|
+
bad = body_for('flagged-bad')
|
|
330
|
+
check_true('管制で不具合の印: CC1 に知らせる', 'CC1 に知らせて' in bad)
|
|
331
|
+
check('管制で不具合の印: 配り直しだけを促さない(同じ版なら直らない)', '② APPLY=1 bash' in bad, False)
|
|
332
|
+
|
|
333
|
+
# ★自動更新が入っている PC(鍵 ~/.tyhld/bin/autoupdate/enabled)は、人に npm で入れさせない
|
|
334
|
+
# (更新係が管制の決めた版へそろえる。人が入れると段階配布の順番が崩れる)。
|
|
335
|
+
old_home = os.environ.get('HOME')
|
|
336
|
+
os.environ['HOME'] = tmp
|
|
337
|
+
try:
|
|
338
|
+
os.makedirs(os.path.join(tmp, '.tyhld', 'bin', 'autoupdate'), exist_ok=True)
|
|
339
|
+
write(os.path.join(tmp, '.tyhld', 'bin', 'autoupdate'), 'enabled', 'x\n')
|
|
340
|
+
auto = body_for('unpublished')
|
|
341
|
+
check_true('自動更新の PC: 次の自動更新でそろうと書く', '次の自動更新' in auto)
|
|
342
|
+
check('自動更新の PC: npm で入れさせない', 'npm install -g' in auto, False)
|
|
343
|
+
check_true('自動更新の PC・不具合の印: 人の操作は要らないと書く', '人の操作は要りません' in body_for('flagged-suspect'))
|
|
344
|
+
check_true('自動更新の PC でも、配布物が無いときは入れ直す', 'npm install -g' in body_for('not-installed'))
|
|
345
|
+
finally:
|
|
346
|
+
if old_home is None:
|
|
347
|
+
os.environ.pop('HOME', None)
|
|
348
|
+
else:
|
|
349
|
+
os.environ['HOME'] = old_home
|
|
350
|
+
|
|
325
351
|
# ── ★札の覚え書き(壊れていても・書けなくても止まらない)──────────────────
|
|
326
352
|
print('\n【★札の覚え書き】')
|
|
327
353
|
with tempfile.TemporaryDirectory() as tmp:
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# tyhld-autoupdate — 自社PCの更新係を1回流す入口(便 29babc5d・設計 3ed9e2b2 の A3)。
|
|
3
|
+
#
|
|
4
|
+
# 【置き場】~/.tyhld/bin/tyhld-autoupdate(★職人は書けない場所)。隣に dist-source.sh が要る
|
|
5
|
+
# (常駐の入口 conductor-run と同じ置き場・同じ探し方)。置くのは自社PCの導入台本
|
|
6
|
+
# scripts/autoupdate-install.sh だけ。★お客さまの機の導入台本(sales-template/install.sh・setup.sh)は置かない。
|
|
7
|
+
#
|
|
8
|
+
# 【使い方】systemd から呼ぶ(人が打つ物ではない)。
|
|
9
|
+
# tyhld-autoupdate-boot.service … ~/.tyhld/bin/tyhld-autoupdate --boot(起動時に1回・常駐より先)
|
|
10
|
+
# tyhld-autoupdate.service … ~/.tyhld/bin/tyhld-autoupdate(タイマーから数分ごと。聞きに行くのは管制が返す間隔ごと)
|
|
11
|
+
# 終了コード: 0=いつも(更新しなかった・失敗した も 0。理由は journal と控えに残る)/2=使い方の誤り/
|
|
12
|
+
# 78=動かす采配くんが見つからない
|
|
13
|
+
#
|
|
14
|
+
# 【決め】
|
|
15
|
+
# ・鍵(~/.tyhld/bin/autoupdate/enabled)が無い機では、何も読まずに終わる(お客さまの機で動かない)。
|
|
16
|
+
# ・同時に2つ動かさない(起動時の1回とタイマーが重なっても、後の方は何もせず終わる)。
|
|
17
|
+
# ・動かすのは常駐と同じ「公開済みの配布物」(作業ツリーは動かさない=dist_runtime_resolve)。
|
|
18
|
+
# ・接続設定は systemd が EnvironmentFile で渡す。無いときだけ ~/.conductor.env から
|
|
19
|
+
# CONDUCTOR_URL・CONDUCTOR_TOKEN・CONDUCTOR_MACHINE の3つを読む(★値は画面に出さない)。
|
|
20
|
+
set -u
|
|
21
|
+
|
|
22
|
+
KEY="${HOME:-}/.tyhld/bin/autoupdate/enabled"
|
|
23
|
+
if [[ ! -f "$KEY" ]]; then
|
|
24
|
+
echo "[tyhld-autoupdate] 自動更新の鍵がありません($KEY)。この機では何もしません。"
|
|
25
|
+
exit 0
|
|
26
|
+
fi
|
|
27
|
+
|
|
28
|
+
HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
29
|
+
. "$HERE/dist-source.sh"
|
|
30
|
+
|
|
31
|
+
if ! dist_runtime_resolve; then
|
|
32
|
+
echo "[tyhld-autoupdate] 流せません: 動かす采配くんを確かめられません(${DIST_REASON})。" >&2
|
|
33
|
+
echo "[tyhld-autoupdate] 人の手番: npm install -g @tyhld/conductor --@tyhld:registry=https://registry.npmjs.org" >&2
|
|
34
|
+
exit 78
|
|
35
|
+
fi
|
|
36
|
+
|
|
37
|
+
ENV_FILE="${HOME:-}/.conductor.env"
|
|
38
|
+
if [[ ( -z "${CONDUCTOR_URL:-}" || -z "${CONDUCTOR_TOKEN:-}" ) && -r "$ENV_FILE" ]]; then
|
|
39
|
+
while IFS= read -r line || [[ -n "$line" ]]; do
|
|
40
|
+
line="${line#export }"
|
|
41
|
+
case "$line" in
|
|
42
|
+
CONDUCTOR_URL=*|CONDUCTOR_TOKEN=*|CONDUCTOR_MACHINE=*)
|
|
43
|
+
key="${line%%=*}"; val="${line#*=}"
|
|
44
|
+
val="${val%\"}"; val="${val#\"}"; val="${val%\'}"; val="${val#\'}"
|
|
45
|
+
[[ -n "${!key:-}" ]] || export "$key=$val"
|
|
46
|
+
;;
|
|
47
|
+
esac
|
|
48
|
+
done < "$ENV_FILE"
|
|
49
|
+
fi
|
|
50
|
+
|
|
51
|
+
# ★同時に2つ動かさない(flock が無い機では、そのまま1つとして動かす)。
|
|
52
|
+
LOCK="${HOME:-}/.tyhld/bin/autoupdate/lock"
|
|
53
|
+
if command -v flock >/dev/null 2>&1; then
|
|
54
|
+
exec 9>"$LOCK" || exit 0
|
|
55
|
+
if ! flock -n 9; then
|
|
56
|
+
echo "[tyhld-autoupdate] ほかの更新係が動いているので、今回は何もしません。"
|
|
57
|
+
exit 0
|
|
58
|
+
fi
|
|
59
|
+
fi
|
|
60
|
+
|
|
61
|
+
"$DIST_NODE" "$DIST_ROOT/dist/cli.js" autoupdate "$@"
|
package/scripts/update-guard.sh
CHANGED
|
@@ -80,7 +80,7 @@ info() { echo "[update-guard] $*"; }
|
|
|
80
80
|
warn() { echo "[update-guard] 注意: $*" >&2; }
|
|
81
81
|
fail() { echo "[update-guard] エラー: $*" >&2; exit 1; }
|
|
82
82
|
|
|
83
|
-
# >>> preflight >>> ★この印の間が正本。install.sh
|
|
83
|
+
# >>> preflight >>> ★この印の間が正本。install.sh・update-guard.sh・setup.sh の3つで1文字も違わないことをテストが固定する。
|
|
84
84
|
# ═════════════════════════════════════════════════════════════════════════════
|
|
85
85
|
# 先頭の確かめ(職人が始まるのに要る物・便 ff8f4be9)
|
|
86
86
|
#
|
|
@@ -125,6 +125,14 @@ preflight_ver_lt() {
|
|
|
125
125
|
return 1
|
|
126
126
|
}
|
|
127
127
|
|
|
128
|
+
# ホームの外の置き場(★src/headless.ts の CLAUDE_SYSTEM_BIN_DIRS と同じ・テストで一致を固定)。
|
|
129
|
+
# ★検査だけが作り物のフォルダに差し替える(CONDUCTOR_PREFLIGHT_SYSTEM_DIRS)。
|
|
130
|
+
# HOME を隔離してもここは絶対パスなので、機体に claude が在ると検査が機体に依って落ちる
|
|
131
|
+
# (実測 2026-10-02 メインPC: /usr/bin/claude = 2.1.86)。中継の側は便 ff8f4be9 で
|
|
132
|
+
# 同じ差し替え(resolveClaudeBin(systemDirs))を入れてある。作りをそろえる。
|
|
133
|
+
# ★差し替えても安全は変わらない(探す場所が変わるだけ・見つからなければ need では止まる)。
|
|
134
|
+
PREFLIGHT_SYSTEM_BIN_DIRS="${CONDUCTOR_PREFLIGHT_SYSTEM_DIRS-/usr/local/bin:/usr/bin}"
|
|
135
|
+
|
|
128
136
|
# 中継と同じ候補を同じ順で出す(1行に1つ)。
|
|
129
137
|
preflight_claude_candidates() {
|
|
130
138
|
if [[ -n "${CONDUCTOR_CLAUDE_BIN:-}" ]]; then
|
|
@@ -133,6 +141,7 @@ preflight_claude_candidates() {
|
|
|
133
141
|
fi
|
|
134
142
|
local d
|
|
135
143
|
local -a nv=()
|
|
144
|
+
local -a sysdirs=()
|
|
136
145
|
for d in "$HOME/.nvm/versions/node"/v*; do
|
|
137
146
|
[[ -d "$d" ]] && nv+=("${d##*/}")
|
|
138
147
|
done
|
|
@@ -142,7 +151,12 @@ preflight_claude_candidates() {
|
|
|
142
151
|
printf '%s\n' "$HOME/.nvm/versions/node/$d/bin/claude"
|
|
143
152
|
done < <(printf '%s\n' "${nv[@]}" | sort -t. -k1.2,1nr -k2,2nr -k3,3nr)
|
|
144
153
|
fi
|
|
145
|
-
printf '%s\n' "$HOME/.local/bin/claude" "$HOME/.claude/local/claude"
|
|
154
|
+
printf '%s\n' "$HOME/.local/bin/claude" "$HOME/.claude/local/claude"
|
|
155
|
+
IFS=':' read -r -a sysdirs <<< "$PREFLIGHT_SYSTEM_BIN_DIRS"
|
|
156
|
+
for d in ${sysdirs[@]+"${sysdirs[@]}"}; do
|
|
157
|
+
[[ -n "$d" ]] && printf '%s\n' "$d/claude"
|
|
158
|
+
done
|
|
159
|
+
return 0
|
|
146
160
|
}
|
|
147
161
|
|
|
148
162
|
# その claude の入れ方に合う更新の1行(src/headless.ts の claudeUpdateHint と同じ見分け方)。
|
|
@@ -308,8 +322,10 @@ fi
|
|
|
308
322
|
# 「止まる」を採ると、今までどおり打ったのに何も起きない形になり、手順を覚え直すことになる。
|
|
309
323
|
#
|
|
310
324
|
# 【正規版でないときは黙って進まない】
|
|
311
|
-
# 入っていない/版が読めない/公開 npm に聞けない/版が公開 npm
|
|
312
|
-
#
|
|
325
|
+
# 入っていない/版が読めない/公開 npm に聞けない/版が公開 npm に無い・使わないでの印がある/
|
|
326
|
+
# 管制で不具合(bad)・疑い(suspect)の印がある のどれでも、★1バイトも配らずに終わる。
|
|
327
|
+
# ★公開の最新より古くても、公開 npm に在る正規の版で印が無ければ配る(便 29babc5d・段階配布のため・
|
|
328
|
+
# えふさん確定 2026-10-02 夜)。管制に届かないときは「印が無い」として配る(配らないほうが危ない)。失敗は控えに残し、便 29612ff1 で作った知らせ方(確認カード)に載せる。
|
|
313
329
|
. "$SCRIPT_DIR/dist-source.sh"
|
|
314
330
|
|
|
315
331
|
DIST_STATE="$GUARD_HOME/dist-source.state" # 最後に【確かめられた】配り元
|
|
@@ -349,9 +365,10 @@ if ! dist_source_resolve; then
|
|
|
349
365
|
no-version) warn " 入っている配布物の版が読めません。" ;;
|
|
350
366
|
no-npm) warn " 公開 npm に問い合わせる npm が見つかりません(配布物を動かす node の隣にも、PATH にもありません)。" ;;
|
|
351
367
|
unverifiable) warn " 公開 npm への問い合わせに失敗しました(npm: ${DIST_NPM:-不明}。回線・取得先・npm の不調のどれか)。" ;;
|
|
352
|
-
|
|
368
|
+
unpublished) warn " 入っている版 ${DIST_VERSION} は公開 npm にありません(正規の版ではありません。公開の最新は ${DIST_PUBLISHED})。" ;;
|
|
369
|
+
deprecated) warn " 入っている版 ${DIST_VERSION} には、公開 npm で「使わないで」の印が付いています(${DIST_DEPRECATED})。" ;;
|
|
353
370
|
esac
|
|
354
|
-
warn "
|
|
371
|
+
while IFS= read -r l; do warn " $l"; done < <(dist_human_step "$DIST_REASON")
|
|
355
372
|
dist_record failed "$DIST_REASON"
|
|
356
373
|
dist_notify
|
|
357
374
|
exit 0
|
|
@@ -363,7 +380,12 @@ if ! dist_source_complete "$DIST_ROOT"; then
|
|
|
363
380
|
dist_notify
|
|
364
381
|
exit 0
|
|
365
382
|
fi
|
|
366
|
-
|
|
383
|
+
if [[ "$DIST_VERSION" == "$DIST_PUBLISHED" ]]; then
|
|
384
|
+
info " 配り元: $DIST_ROOT(版 $DIST_VERSION =公開 npm のいまの版・管制の印 ${DIST_CENTRAL_FLAG:-unknown})"
|
|
385
|
+
else
|
|
386
|
+
# ★段階配布のあいだ、後続の機は公開の最新より古い正規の版で動く(便 29babc5d・えふさん確定 2026-10-02 夜)。
|
|
387
|
+
info " 配り元: $DIST_ROOT(版 $DIST_VERSION =公開 npm に在る正規の版・公開の最新は $DIST_PUBLISHED・管制の印 ${DIST_CENTRAL_FLAG:-unknown})"
|
|
388
|
+
fi
|
|
367
389
|
if [[ "$DIST_ROOT" != "$REPO_ROOT" ]]; then
|
|
368
390
|
info " ★この台本の置き場($REPO_ROOT)からは配りません。"
|
|
369
391
|
fi
|
|
@@ -109,7 +109,7 @@ description: 采配くんの便(プロンプト末尾に CONDUCTOR_JOB:<id>
|
|
|
109
109
|
- ① **起動は必ず `chromium_sandbox=False`**(`--no-sandbox`)。付けないと起動できない。
|
|
110
110
|
- ② **道具は共有の場所を使う。自分でダウンロードしない。** python は `$HOME/.tyhld/pw-venv/bin/python`、`PLAYWRIGHT_BROWSERS_PATH` は `$HOME/.tyhld/pw-browsers`。**無ければそこで止めて「人の手番=`APPLY=1 bash scripts/pw-browser-install.sh`」と報告する。** `playwright install` も `pip install playwright` も職人は実行しない(毎便まるごとダウンロードが走り、便が遅くなる。通信自体は鉄則12のとおり許可済みだが、取りに行かないのが本筋=ADR-010)。
|
|
111
111
|
- ③ **localhost の画面検品は proxy を指定しない。** プロキシ `localhost:3128` はサンドボックスの中にしか居ないので、外部URLへ出るときだけ Playwright の proxy オプションへ明示指定する(環境変数は拾われない)。`ECONNREFUSED` なら回避せず**未実施として報告**する。
|
|
112
|
-
- ④ 検品用の使い捨て画面(確認だけのHTML/スクリプト)は**リポジトリの中に作らない。置き場は `/tmp/claude-1000/`**(鉄則13
|
|
112
|
+
- ④ 検品用の使い捨て画面(確認だけのHTML/スクリプト)は**リポジトリの中に作らない。置き場は `/tmp/claude-1000/`**(鉄則13)。リポジトリの中に作ってしまったものはコミット前に削除する。**自分で作った物に限り、`-f` を付けない `rm -r` と実在のパスの名指しで消し、消した物を報告に書く**(鉄則13)。★止められたら別の消し方を探さず報告する。
|
|
113
113
|
9. **pnpm は取りに行かない・版を指定しない(ADR-015)** — ★`npx --yes pnpm@10 …` と打たない(毎回ダウンロードが走る)。`pnpm` とだけ打てば、そのリポジトリの `packageManager` の版が corepack で自動的に使われる。
|
|
114
114
|
- ★**必ずリポジトリの中で打つ。** 版の指定はディレクトリごとに効くので、リポジトリの外(ホーム等)から `--filter` で呼ぶと既定の新しい版が動き `ERR_PNPM_UNSUPPORTED_ENGINE` で弾かれる(実測)。
|
|
115
115
|
- `pnpm` が見つからない/版が合わないときは、回避せず**人の手番=`corepack enable`** と報告する。`npm i -g pnpm` は打たない(corepack と衝突する)。
|
|
@@ -120,10 +120,17 @@ description: 采配くんの便(プロンプト末尾に CONDUCTOR_JOB:<id>
|
|
|
120
120
|
- **電話は自由。** 外への通信(npm / GitHub / API / ドキュメント取得など)は許可済みなので、`Network request outside of sandbox` は出ない。**通信のために止まらない・人を待たない**。最後まで自走して完了まで行く。
|
|
121
121
|
- **金庫は禁止。** 秘密の持ち出し(`curl -d @.env` / `cp .env` / `tar ~/.ssh` / `base64 .env` / `echo $DATABASE_URL` など)は**番人が今までどおり止める**。通信が自由になったこととは**別の仕組み**なので、「通信が許可されたから秘密も送れる」は成り立たない。本番DB・secret・`.env`・`hooks`・`.tyhld`・`.ssh` への書き込み禁止もそのまま。
|
|
122
122
|
- **それでも塞がれたら回避しない。** `curl: (56) CONNECT tunnel failed, response 403` のように通信が塞がれたときは、**意図的に閉じてある接続先**(例: 本番DBへの直結)か、設定がその機体にまだ届いていないかのどちらか。**別経路を探さず、そこで止めて報告する**(人の手番=`APPLY=1 bash scripts/update-guard.sh` → 職人を再起動)。
|
|
123
|
-
13. **使い捨てファイルはリポジトリの中に作らない(えふさん決定 2026-09-03
|
|
124
|
-
- **実機検品・検証用の使い捨てファイル(HTML・画像・ログ等)は、リポジトリの中に作らない。`/tmp/claude-1000/`
|
|
125
|
-
-
|
|
126
|
-
|
|
123
|
+
13. **使い捨てファイルはリポジトリの中に作らない(えふさん決定 2026-09-03/えふさん確定 2026-10-02・判断6 で後片付けの形を改めた)**
|
|
124
|
+
- **実機検品・検証用の使い捨てファイル(HTML・画像・ログ等)は、リポジトリの中に作らない。`/tmp/claude-1000/` に置く。**
|
|
125
|
+
- **リポジトリの中(直下を含む)に作ってしまったときの後片付け(えふさん確定 2026-10-02・判断6)。自分で作った物に限り、`-f` を付けない `rm -r` と実在のパスの名指しで消し、消した物を報告に書く。**
|
|
126
|
+
- 通る例: `rm -r ./_layout-check.html` / `rm -r node_modules/.tmp-作業名`(★実在のパスを名指し・`-f` を付けない)
|
|
127
|
+
- ★**はじめから在った物には触らない。** 自分が作った物かどうか分からなければ消さず、報告に「残骸あり・場所」と書く。
|
|
128
|
+
- ★**`.git`・`.claude/hooks`・`.tyhld` は、相対パスでも削除禁止**(番人が止める。緩めない)。
|
|
129
|
+
- ★**`-f` 付きの再帰削除(`rm -rf` 等)・変数や `*` を含む形は止まる**(禁止の一覧と番人)。
|
|
130
|
+
- ★**止められたら別の消し方(`find -delete`・`python -c` 等)を探さず、消せなかった場所を報告に書く**(鉄則4)。
|
|
131
|
+
- **なぜ(置き場の話)。** 実機 2026-09-03: ai-saku の画面便(PR#258・PR#269)で、検品用の使い捨てページ `_layout-check.html` をリポジトリ直下に作り、`rm -rf` で消そうとして止められ、人が2回消した。**禁止の一覧と番人の制限は正しい(緩めない)。悪いのは置き場。**
|
|
132
|
+
- **なぜ(後片付けの話を改めた理由)。** 旧い文言は「リポジトリ直下は番人が `rm` を止めるので自分で消さず報告」だった。実測(便 fb248f6e)では、`-f` を付けない `rm -r` と実在のパスの名指しなら、リポジトリ直下の自分の作業ファイルも通る。止まるのは `-f` 付きと変数・`*` 入りだけ。**止まらない形を「止まる」と書いていると、職人が自分の残骸を残したまま便を終える**ので、実物に合わせた(番人・禁止の一覧は1行も変えていない)。
|
|
133
|
+
- 置き場を `/tmp/claude-1000/` にすれば、止められることも、残骸がコミットに混ざることも起きない(根治=鉄則10)。Playwright の検品ページも同じ(鉄則8-④)。
|
|
127
134
|
14. **`.env` 類(`.env`・`.env.local`・`.env.example` などの雛形も含む)は職人が書き換えない(えふさん確定 2026-09-18・便 3d11f913)**
|
|
128
135
|
- **番人は `.env` 本体も `.env.example` などの雛形も、書き込みを止める**(Write/Edit の設定 deny と、Bash の `echo`/`tee`/`sed -i`/`cp`/`mv` などを、経路を問わず同じ結果にそろえた)。読み込みは今までどおり(雛形は読める・本物は読めない)。
|
|
129
136
|
- **なぜ。** 雛形(`.env.example`)は普通は秘密値を置かないが、「exampleだから常に安全」と番人へ例外を作ると、将来誤って実値が書かれたときの穴になる(利便性より安全側・えふさん確定)。
|
|
@@ -155,6 +162,7 @@ description: 采配くんの便(プロンプト末尾に CONDUCTOR_JOB:<id>
|
|
|
155
162
|
- **`-f` 付き、または中身が変わる場所を指す再帰の `rm`**(`rm -rf`・`rm -fr`・`rm -r -f`・`rm -R`・`rm --recursive`/`rm -r "$DIR/x"`・`rm -r build/*` のように変数や `*` を含む)→ 止まる。`-f` 付きは配布している禁止の一覧(現場の `.claude/settings.json` の deny)で**必ず**止まる(番人より先に効く=消す先が作業ファイルでも通らない・便 fb248f6e)。変数・`*` は番人が止める。**`-f` を付けず、消す先を実在のパスで名指しする**(`/tmp/claude-1000/` の下・鉄則13)。★止められたら**別の消し方を探さず**(`find -delete`・`python -c` 等に回らない)、消せなかった場所を報告に書く(鉄則4)。
|
|
156
163
|
- 通る例: `rm -r /tmp/claude-1000/作業名` / `rm -r node_modules/.tmp-作業名`(★`-f` を付けない・自分で作った物だけ)
|
|
157
164
|
- 止まる例: `rm -rf /tmp/claude-1000/作業名`(禁止の一覧)/ `rm -r "$DIR/x"`・`rm -r build/*`(番人)/ `rm -r .git`・`rm -r .claude/hooks`・`rm -r .tyhld`(番人=相対パスでも消せない)
|
|
165
|
+
- ★**探すだけの道具の「探す言葉」に `rm …` と書いても、もう止まらない**(便 915694ac で直した)。鉄則や台本を調べるときの `grep -rn 'rm -rf .git' skills`・`git grep -n 'rm -r' -- skills`・`rg 'rm -rf /' docs` は通る。★囲みの外に書いた `rm` は今までどおり測るので、`grep -rn 'x' docs; rm -rf .git` のように**後ろで消す形は止まる**。
|
|
158
166
|
- **作業場所が変数のままの `git push`**(`git -C "$DIR" push`・行き先のブランチを確かめられない形)→ 止まる。**リポの中で、ブランチを名指しして** `git push -u origin <作業ブランチ名>`。
|
|
159
167
|
|
|
160
168
|
## 便の終え方
|
|
@@ -102,7 +102,7 @@ else
|
|
|
102
102
|
# 入口の一式を写す元=公開済みの正規版(作業ツリーからは写さない・便 4061dd71 と同じ判定)。
|
|
103
103
|
if ! dist_source_for_setup "$(cd "$SCRIPT_DIR/.." && pwd)"; then
|
|
104
104
|
die "司令塔を動かす采配くんを確かめられません(${DIST_REASON})。
|
|
105
|
-
|
|
105
|
+
$(dist_human_step "$DIST_REASON" | sed 's/^/ /')"
|
|
106
106
|
fi
|
|
107
107
|
if ! dist_runtime_bundle_install "$DIST_ROOT"; then
|
|
108
108
|
die "司令塔の入口を置けませんでした: $DIST_RUNTIME_BIN_DIR"
|
package/systemd/ear-install.sh
CHANGED
|
@@ -85,7 +85,7 @@ else
|
|
|
85
85
|
# 入口の一式を写す元=公開済みの正規版(作業ツリーからは写さない・便 4061dd71 と同じ判定)。
|
|
86
86
|
if ! dist_source_for_setup "$(cd "$SCRIPT_DIR/.." && pwd)"; then
|
|
87
87
|
skip "耳を動かす采配くんを確かめられません(${DIST_REASON})。
|
|
88
|
-
|
|
88
|
+
$(dist_human_step "$DIST_REASON" | sed 's/^/ /')"
|
|
89
89
|
fi
|
|
90
90
|
if ! dist_runtime_bundle_install "$DIST_ROOT"; then
|
|
91
91
|
skip "耳の入口を置けませんでした: $DIST_RUNTIME_BIN_DIR"
|
|
@@ -66,7 +66,7 @@ done
|
|
|
66
66
|
. "$SCRIPT_DIR/../scripts/dist-source.sh"
|
|
67
67
|
if ! dist_source_for_setup "$REPO_ROOT"; then
|
|
68
68
|
warn "配り元を確かめられません(${DIST_REASON})。自動同期タイマーは設置しません。"
|
|
69
|
-
warn "
|
|
69
|
+
while IFS= read -r l; do warn " $l"; done < <(dist_human_step "$DIST_REASON")
|
|
70
70
|
exit 0
|
|
71
71
|
fi
|
|
72
72
|
if [[ "$DIST_ROOT" != "$REPO_ROOT" ]]; then
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# tyhld-autoupdate-boot.service — 起動時に1回だけ、更新係を流す(便 29babc5d・設計 3ed9e2b2 の A3)。
|
|
2
|
+
#
|
|
3
|
+
# 【何をするか】~/.tyhld/bin/tyhld-autoupdate --boot を1回。管制に目標の版を聞き、違えば入れ替える。
|
|
4
|
+
# 起動直後は便が0なので、更新は「電源を入れた直後」にほぼ済む(設計 1/4)。
|
|
5
|
+
# 自己診断は、常駐が起きてからタイマーの回(tyhld-autoupdate.service)が行う。
|
|
6
|
+
#
|
|
7
|
+
# 【順番】常駐(conductor@*・耳・司令塔)は、この1回が終わってから起きる。
|
|
8
|
+
# ★順番は常駐の側の drop-in(conductor@.service.d/10-tyhld-autoupdate.conf の After=)で決める。
|
|
9
|
+
# 置くのは scripts/autoupdate-install.sh(自社PCだけ)。お客さまの機の常駐には何も足さない。
|
|
10
|
+
# ★この1回が失敗しても常駐は起きる(After= だけで Requires= は付けない)。
|
|
11
|
+
#
|
|
12
|
+
# 【★自社PCだけ】置いて有効にするのは scripts/autoupdate-install.sh(人の窓で1回)だけ。
|
|
13
|
+
|
|
14
|
+
[Unit]
|
|
15
|
+
Description=tyhld: auto-update check at boot (before the relays start)
|
|
16
|
+
After=network-online.target
|
|
17
|
+
Wants=network-online.target
|
|
18
|
+
|
|
19
|
+
[Service]
|
|
20
|
+
Type=oneshot
|
|
21
|
+
EnvironmentFile=-%h/.conductor.env
|
|
22
|
+
ExecStart=/bin/bash %h/.tyhld/bin/tyhld-autoupdate --boot
|
|
23
|
+
# 入れ替え(npm・公式の導入台本)の上限。常駐をいつまでも待たせない。
|
|
24
|
+
TimeoutStartSec=20min
|
|
25
|
+
|
|
26
|
+
[Install]
|
|
27
|
+
WantedBy=default.target
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# tyhld-autoupdate.service — 更新係を1回流す(便 29babc5d・設計 3ed9e2b2 の A3)。
|
|
2
|
+
#
|
|
3
|
+
# 【何をするか】~/.tyhld/bin/tyhld-autoupdate を1回(中身は src/autoupdate.ts)。
|
|
4
|
+
# ・管制が返す checkAgainMin の時刻が来た回だけ、管制に目標の版を聞く(それ以外の回はすぐ終わる)
|
|
5
|
+
# ・全現場が空きのときだけ入れ替える → 常駐を起こし直す → 自己診断 → 結果を管制へ
|
|
6
|
+
# ・自己診断が FAIL なら、この機だけ前の版へ戻す
|
|
7
|
+
# ★sudo を使わない。番人・禁止の一覧・囲い・通信の許可には触らない。
|
|
8
|
+
#
|
|
9
|
+
# 【★自社PCだけ】置いて有効にするのは scripts/autoupdate-install.sh(人の窓で1回)だけ。
|
|
10
|
+
# 鍵(~/.tyhld/bin/autoupdate/enabled)が無ければ、この係は何もしない。
|
|
11
|
+
# .timer から数分ごとに呼ばれる(tyhld-autoupdate.timer)。
|
|
12
|
+
|
|
13
|
+
[Unit]
|
|
14
|
+
Description=tyhld: auto-update (conductor / Claude Code, staged by the central)
|
|
15
|
+
After=network-online.target
|
|
16
|
+
Wants=network-online.target
|
|
17
|
+
|
|
18
|
+
[Service]
|
|
19
|
+
Type=oneshot
|
|
20
|
+
EnvironmentFile=-%h/.conductor.env
|
|
21
|
+
ExecStart=/bin/bash %h/.tyhld/bin/tyhld-autoupdate
|
|
22
|
+
# 入れ替え+自己診断(小さな試験の3分を含む)+戻すときの分。
|
|
23
|
+
TimeoutStartSec=60min
|
|
24
|
+
Nice=10
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# tyhld-autoupdate.timer — 更新係を数分ごとに起こす(便 29babc5d・設計 3ed9e2b2 の A3)。
|
|
2
|
+
#
|
|
3
|
+
# - OnBootSec=4min … 起動時の1回(tyhld-autoupdate-boot)と常駐が起きた後に、1回目
|
|
4
|
+
# (起動時に入れ替えた機は、ここで自己診断を行う)
|
|
5
|
+
# - OnUnitActiveSec=5min … 以後5分ごとに起きる。★管制へ聞きに行くのは、管制が返した
|
|
6
|
+
# checkAgainMin(いまは15分)が来た回だけ(間隔は更新係が決め打ちしない)
|
|
7
|
+
# - Persistent=false … 取りこぼしの追い実行はしない(起動時の1回が在る)
|
|
8
|
+
#
|
|
9
|
+
# ★自社PCだけ。有効にするのは scripts/autoupdate-install.sh(お客さまの機には入れない)。
|
|
10
|
+
|
|
11
|
+
[Unit]
|
|
12
|
+
Description=tyhld: auto-update check
|
|
13
|
+
|
|
14
|
+
[Timer]
|
|
15
|
+
OnBootSec=4min
|
|
16
|
+
OnUnitActiveSec=5min
|
|
17
|
+
AccuracySec=30s
|
|
18
|
+
|
|
19
|
+
[Install]
|
|
20
|
+
WantedBy=timers.target
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
# ・副作用なし(commit・push・PR・合流・配備・公開をしない)。結果は手元の控えと管制へ。
|
|
6
6
|
# ・正常時は何も知らせない(知らせるかどうかは管制が決める)。
|
|
7
7
|
#
|
|
8
|
-
# 【★自社PCだけ】置いて有効にするのは自社PC
|
|
8
|
+
# 【★自社PCだけ】置いて有効にするのは自社PCの導入台本 scripts/autoupdate-install.sh(人の窓で1回)。
|
|
9
9
|
# sales-template/install.sh・setup.sh はこのタイマーを置かない(お客さまの機には入れない)。
|
|
10
10
|
# .timer から毎日1回呼ばれる(tyhld-selfcheck.timer)。
|
|
11
11
|
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
# - RandomizedDelaySec … 複数の機が同じ時刻に Claude を呼ばないよう30分ばらす。
|
|
6
6
|
# ★管制は「26時間来ない機」を🟡にする想定(設計 3ed9e2b2 の 2/4)。
|
|
7
7
|
#
|
|
8
|
-
# ★自社PCだけ。有効にするのは自社PC
|
|
8
|
+
# ★自社PCだけ。有効にするのは自社PCの導入台本 scripts/autoupdate-install.sh(お客さまの機には入れない)。
|
|
9
9
|
|
|
10
10
|
[Unit]
|
|
11
11
|
Description=tyhld: daily self-check
|