@tyhld/conductor 0.12.20 → 0.12.22

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tyhld/conductor",
3
- "version": "0.12.20",
3
+ "version": "0.12.22",
4
4
  "description": "采配くん管制の見守りアプリ(conductor-agent)。各PCで常駐し、中央(devlog-tracker)へ定期的に生存報告(heartbeat)を送る常駐CLI。",
5
5
  "type": "module",
6
6
  "bin": {
@@ -131,6 +131,69 @@ branch protection は「CI が通っていない物を main に入れない」
131
131
  ★**止める側(deny)は変えていません**。危険と抜け道の判定は、今までどおり機械的な区切り(`split_segments`)で見ます
132
132
  (引用符の中まで見る方が、止める側としては広いため)。7日分の記録では、DENY の件数は前後で同じ(1,559件)でした。
133
133
 
134
+ ## 1-4. ★残る抜け道を塞ぐ(便 c05796ec=便2.5・DENY を強める)
135
+
136
+ | 抜け道 | 止める形(`policy.py`) |
137
+ | --- | --- |
138
+ | 番人の設定への書き込み | `~/.claude/settings.json`・`settings.local.json`(と各現場の `.claude/settings*.json`)・`~/.tyhld/hooks` 配下・`~/.codex/hooks.json`・`~/.codex/config.toml`・`~/.config/systemd` 配下へ、**手段を問わず**書く形。リダイレクト(`>` `>>` `>\|` `&>`)・`tee`・`cp`・`install`・`ln`・`rsync`・`mv`(動かす元も先も)・`dd of=`・`sed -i`・`perl -pi`・`touch`・`rm`・`chmod` ほか・`systemctl --user enable/edit …`・置き場ごとの `rm -rf ~/.claude`・`mv ~/.tyhld/hooks …`・`python3 -c` / `node -e` / `python3 - <<EOF` で開いて書く形(`_guard_write_scan`・`guard_config_reason`)。書き込みの道具(Write)も同じ一覧で守る |
139
+ | 秘密のファイルの読み取り(動詞が千切れる形) | `grep -n "x\|y" .env`・`rg "a;b" .env.local` など、引用符の中の `\|` `;` `&` で機械的な区切りが動詞を千切る形。★機械的な区切りに**本物の区切りを足して**測り直す(`_real_segments`)。探す道具(`rg`・`ag`・`ack`・`ugrep` …)も読む道具に数える |
140
+ | API で main の先端を書き換える | `git/refs/heads/<保護>` の PATCH・POST・PUT・DELETE、`git/refs` の POST(`ref` が保護・確かめられない)、`contents` の PUT・DELETE(`branch` が保護・**書いていない=既定のブランチ**・確かめられない)、GraphQL の `createCommitOnBranch`・`updateRefs`(保護・確かめられない)・`updateRef`(先が確かめられない)。`gh api`・`curl` の両方(`_main_tip_write`) |
141
+
142
+ ★**読むだけは止めません**(`cat`・`grep`・`diff`・`jq`・外へ写す `cp ~/.claude/settings.json /tmp/…`)。
143
+ ★**書き込む先だけを見ます**。報告・コミットの説明・PR の本文に同じ場所の名前が書いてあるだけ、引用符の中の `>` は止めません。
144
+ ★使い捨ての作業場(`/tmp` の下)に作った同じ名前は、Write と同じく通します。同じコマンドの中で決めた変数(`P=/tmp/x; … > $P/.claude/settings.json`)は解いてから測り、解けない変数は守る側で測ります。
145
+ ★`git/commits`・`git/trees` を作るだけでは main は変わりません。「作って先端を差し替える一連の形」は、先端を差し替える一手で止まります。
146
+ ★作業ブランチへの書き込み(`contents` の `branch=feat/…`・`git/refs/heads/feat/…`)は通します。
147
+ ★止める側を減らす変更はしていません。7日分の記録では、ALLOW から DENY へ7件移り、DENY から他へ移ったもの・関門の数の変化は0件でした。
148
+
149
+ ## 1-5. ★番人の設定を弱める道を「手段を問わず」塞ぎ切る(便 0f92a767=便2.6)
150
+
151
+ 便2.5 は「見つかった書き方」を塞ぐ便でした。便2.6 は、**別の書き込み手段・別のシェルの書き方に置き換えても
152
+ 同じことができない**ところまで塞ぎます。目的は、職人から**番人・guard・hook・管理設定そのものを弱める変更を
153
+ できないようにする**ことです(えふさん確定 2026-09-18)。
154
+
155
+ **守る場所は1か所の一覧(`policy.GUARD_PLACES`)だけ**を見ます(場所を2か所に書かない)。
156
+
157
+ | 種類 | 場所 |
158
+ | --- | --- |
159
+ | `site-file` | どの `.claude` フォルダでも `settings…` で始まるファイル(ホームと各現場の `settings.json`・`settings.local.json`) |
160
+ | `home-tree` | `~/.claude/skills`・`~/.tyhld/hooks`・`~/.tyhld/bin`・`~/.config/systemd`(中身ぜんぶ) |
161
+ | `home-agent` | ホーム直下の隠しフォルダの `hooks.json`・`config.toml`(`~/.codex` の2つを含む・道具名を持たない一般形・ADR-022) |
162
+ | `abs-tree` | 管理設定 `/etc/claude-code` 配下・`/Library/Application Support/ClaudeCode` 配下 |
163
+
164
+ **書き込みの手段は、道具の名前ではなく「書き込む行為」でそろえます**(`_guard_write_segment`)。
165
+ リダイレクト(`>` `>>` `>\|` `<>`・裸の `>file`・`:` `printf`・`$(…)` を先にした形)・`tee`・`sponge`・
166
+ `cp`・`install`・`rsync`・`ln`・`ditto`・`mv`(元も先も)・`sed -i`・`perl -i`・`ruby -i`・`awk -i inplace`・
167
+ `awk '…>"file"'`・`truncate`・`dd of=`・`chmod`・`chown`・`chattr`・`setfacl`・`rm`・`shred`・`touch`・
168
+ エディタ(`ed`・`ex`・`vim`・`nano`・`emacs` …)で開いて保存・`patch`・`git checkout`/`restore`/`clone`/`apply`/
169
+ `worktree`・`yq -i`・`curl -o`/`wget -O`/`-P`・アーカイブの展開(`tar`・`unzip`・`7z`・`cpio` …)・
170
+ 圧縮を解く(`gunzip` …)・`claude config set/add/remove`・`mount --bind`・`systemctl --user enable/edit/mask`・
171
+ `python3`/`node`/`ruby`/`perl` でファイルを開いて書く形。**どれも一覧の場所へ向かえば DENY**。
172
+
173
+ **包みは剥がしてから見ます**(`_unwrap`・`_guard_write_scan`)。`bash -c`・`sh -c`・`eval`・`<<<`・ヒアドキュメント・
174
+ `$(…)`・`` `…` ``・`env`・`sudo`・`nohup`・`time`・`timeout`・`nice`・`xargs`・`find -exec`・`command`・`exec`・
175
+ `busybox`・サブシェルの `( … )`・`for f in 場所; do … "$f"`・`\cp` の `\`・先に決めた変数(`P=~/.claude; … $P/…`・
176
+ `export`)・`~`・`$HOME`・`${HOME}`・相対の道・波括弧 `{a,b}`・`*`。**解けない変数は後ろの字面で照らし、
177
+ 確かめられないものは守る側に倒します。**
178
+
179
+ ★**読むだけは通します**(`cat`・`less`・`grep`・`rg`・`diff`・`jq`・`ls`・`stat`・`git status`・外へ写す `cp`)。
180
+ 通常開発・作業ブランチ・正規 merge も通します。使い捨ての作業場(`/tmp` の下)の同じ名前も通します。
181
+ 報告・コミットの説明に場所の名前が書いてあるだけ、引用符の中の `>` も止めません。
182
+
183
+ ### ★塞いだ/塞いでいない(便2.6・正直な記載)
184
+
185
+ | 書き方 | 扱い | 理由 |
186
+ | --- | --- | --- |
187
+ | 上に挙げた手段(リダイレクト・道具・包み・展開・プログラム) | 塞いだ | `_guard_write_scan` が一覧の場所へ向かう書き込みとして拾う |
188
+ | `mount --bind` / `umount` で一覧の場所を覆う | 塞いだ | 設定を丸ごと差し替える形なので `mount`/`umount` の引数を見る |
189
+ | 台本の**ファイル**の中の書き込み(`bash scripts/x.sh`・`node x.mjs`) | 塞いでいない | コマンドの字面に書き込み先が出ない。台本を開いて推し量ると、例を含む試験のファイルまで止まる(便2.5 と同じ限界) |
190
+ | 未知の道具に場所を渡す形(`mytool --write <場所>`・`ansible -m copy -a dest=<場所>`) | 塞いでいない | 道具ごとに「どの引数が書き込み先か」が違う。名指しで足すと際限がなく、普通の作業が止まる |
191
+ | コンパイル済みプログラム・`$(cat ファイル)` で場所を作る形・機体の外で定義した環境変数だけの場所 | 塞いでいない | 番人からは書き込み先が見えない(中身を実行しないと分からない) |
192
+ | 別の機械への書き込み(`scp x host:<場所>`・`rsync a host:…`) | 範囲外 | この機体の番人の設定ではない |
193
+
194
+ ★塞いでいないものの最後の砦は **OS の層(サンドボックス)** です。ここは「字面で見える書き込み」を
195
+ 広く塞ぐ層で、字面から見えない道(台本・未知の道具・別プロセス)は設計上の限界として残ります。
196
+
134
197
  ## 2. ファイルの役割
135
198
 
136
199
  | ファイル | 役割 |
@@ -144,6 +207,8 @@ branch protection は「CI が通っていない物を main に入れない」
144
207
  | `test_policy.py` | 単体テスト(297件)。`python3 scripts/hooks/test_policy.py` |
145
208
  | `test_bypass_deny.py` | 抜け道の `deny` と、止めてはいけない操作の試験(便 fc22bc34)。`python3 scripts/hooks/test_bypass_deny.py` |
146
209
  | `test_gate_real_commands.py` | 関門の当てどころの回帰試験(誤読の実例81件の形・本物の反映・止めてはいけない関門・便 ad6b5db9) |
210
+ | `test_deny_remaining_routes.py` | 残る抜け道(番人の設定への書き込み・千切れた動詞での秘密の読み取り・API での main の書き換え)の `deny` と、止めてはいけない操作の試験(便 c05796ec) |
211
+ | `test_guard_config_all_routes.py` | 番人の設定を弱める道を「手段を問わず」塞ぐ試験(書き込みの手段ごと・包みを剥がす・止めてはいけないもの・便 0f92a767) |
147
212
  | (`../check_permission_rules.py`) | 現場の許可設定に残った「番人と食い違う行」を洗い出す検査(読むだけ・ADR-009) |
148
213
  | `test_hook_datalink.py` | 連絡線の単体テスト。`python3 scripts/hooks/test_hook_datalink.py` |
149
214
  | `settings.sample.json` | フック登録の見本(★人間が `~/.claude/settings.json` へ反映する) |
@@ -423,6 +488,11 @@ Claude Code 側のフック打ち切り(`timeout: 600`)と同時に終わる
423
488
  未知の道具に秘密を渡す形(`mytool .env`)は素通りします。
424
489
  ここを「引数に字面があれば止める」まで広げると、コミットメッセージや説明文に `.env` と
425
490
  書いただけで止まってしまい(実際に止まりました)、日常の作業が回らなくなるためです。
491
+ - 番人の設定への書き込み(便 c05796ec)は、コマンドの字面で見える書き込みだけを止めます。
492
+ 台本の**ファイル**(`bash scripts/x.sh`・`node x.mjs`)の中の書き込みは見ません。
493
+ プログラムの中は「場所が書く呼び出しと同じ文に在る」か「場所を入れた変数を書く文で使う」形だけを拾います。
494
+ - API での main の書き換えは、`--input <ファイル>` や GraphQL の `-F query=@<ファイル>` の中身を見ません。
495
+ `contents`・`git/refs` の POST は、本文が見えないときは止めます(確かめられない側)。GraphQL は見えないと通ります。
426
496
  - Stop フックは**問いかけの形(`〜ですか` / `?`)で書かれた発言だけ**を取り次ぎます(ADR-008)。
427
497
  「許可が下りず進めません。」のような平叙文の相談は**取り次ぎません**。誤発火で全現場が止まる方が
428
498
  重いので、意図してこちらへ倒しています。職人が「〜してよいですか」と書き直せば出ます。