peertable 0.4.25 → 0.4.26

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.ja.md CHANGED
@@ -37,7 +37,7 @@ Peertable はこれを裏返す:
37
37
  | **計画** | [Lattice](https://www.npmjs.com/package/@quolu/lattice)(**任意**——下記) | タスクグラフ(依存・状態・証跡)。「今取れるタスク」は機械的に出るので、会話は判断だけに使う |
38
38
  | **成果物** | git | コード・文書・commit |
39
39
 
40
- 各メンバーには同じroom MCPクライアントが載る。Claudeはchannels、CodexとGrokは起床ブリッジで新着を受け取る。broadcastは本文(claim・試験・完了)を載せ、Codexはターン中に混ぜ、Grokはidleになってから起こす。roomの同じログとツールを使う。
40
+ 各メンバーには同じroom MCPクライアントが載る。Claudeはchannels、CodexとGrokは席の TUI へ新着を入れる。broadcastは本文(claim・試験・完了)を載せ、Codexはターン中に混ぜ、Grokはidleになってから入れる。roomの同じログとツールを使う。
41
41
 
42
42
  ### ロックなしの調整
43
43
 
@@ -93,7 +93,7 @@ claude --dangerously-load-development-channels server:room
93
93
 
94
94
  **`--mcp-config` で渡してはいけない。** channels はその経路の MCP server を解決せず、バナーに `server:room · no MCP server configured with that name` が出て**room の配達だけが黙って死ぬ**(Claude Code v2.1.226 で実測・決定44)。スキルを使えば自動で置かれ、teardown で戻る。
95
95
 
96
- Codex では、スキルが所有する room MCP block をプロジェクトの `.codex/config.toml` へ置く。`.mcp.json` だけは Codex の設定入口にならず、席固有のroom環境も同じスキル起動経路が渡す。Grok Buildはproject rootの`.mcp.json`を読み、Aitermの`grok_agent`からmodel・effort・席固有envを受け取る。CodexとGrokの新着は同じ起床ブリッジが届ける。Codexは即送信(ターン中のsteering)。Grok TUIはターン中の素送信を次のuserターンへ積むので、ブリッジはidleを待ってから送る。親は起床対象にしない——ClaudeとGrok親は`parent-watch --follow`、Codex親はpoll。
96
+ Codex では、スキルが所有する room MCP block をプロジェクトの `.codex/config.toml` へ置く。`.mcp.json` だけは Codex の設定入口にならず、席固有のroom環境も同じスキル起動経路が渡す。Grok Buildはproject rootの`.mcp.json`を読み、Aitermの`grok_agent`からmodel・effort・席固有envを受け取る。CodexとGrokの新着は同じ経路で席の TUI へ入る。Codexは即送信(ターン中のsteering)。Grok TUIはターン中の素送信を次のuserターンへ積むので、配達はidleを待ってから送る。親は通常席の TUI 配達に載せない——ClaudeとGrok親は`parent-watch --follow`、Codex親はpoll。
97
97
 
98
98
  **3. あるいはスキルに全部やらせる** — `skill/` を `~/.claude/skills/peertable` にリンクして、セッションに一言:
99
99
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "peertable",
3
- "version": "0.4.25",
3
+ "version": "0.4.26",
4
4
  "description": "A round table of peer agents. No orchestrator at the head. Turn Claude Code, Codex, and Grok sessions into a team of equal, long-lived peers.",
5
5
  "type": "module",
6
6
  "license": "MIT",
package/room/client.mjs CHANGED
@@ -13,7 +13,7 @@ import { findModelsDoc, resolveSeatIdentity } from '../skill/scripts/resolve-sea
13
13
 
14
14
  // client.mjs 側のハードコード版数。package.json の version と一致していることを
15
15
  // diagnostics の version_consistency が見る(2 つの版数源の drift 検出。決定45)
16
- const MCP_VERSION = '0.4.25'
16
+ const MCP_VERSION = '0.4.26'
17
17
  const PKG_ROOT = join(dirname(fileURLToPath(import.meta.url)), '..')
18
18
 
19
19
  const USAGE = `usage:
@@ -74,7 +74,7 @@ const mcp = new Server(
74
74
  '<channel source="room"> の通知は「新着あり」の合図であり、本文は read_unread ツールで読む。' +
75
75
  '発言は post ツールを使う。to: "all" はroom全体、メンバー名はDM、配列は複数人宛である。' +
76
76
  `次にやる仕事があるターンを終える直前に post(to: "${ME}", message: "[次の行動] ...") を1回送れ。` +
77
- 'wakeup-bridge はこの自己DMで次ターンを起こす。仕事があるのに出さないと席は止まる。' +
77
+ 'この自己DMは席の TUI へ次ターンの入力として入る。仕事があるのに出さないと席は止まる。' +
78
78
  '手番が無く待機に入るときは自己DMを出すな。親へ [待機] を一度だけ送り沈黙せよ。空の終了通知は使うな。',
79
79
  },
80
80
  )
package/skill/SKILL.md CHANGED
@@ -28,7 +28,7 @@ description: 任意プロジェクトに Peertable チーム(対等メンバ
28
28
  ## Peertableの正規席と委譲入口
29
29
 
30
30
  Peertableのメンバー席は、aiterm-mcpの外部PTYに長寿命で着席させる。新しい席は
31
- `env -u PEERTABLE_POST_TOKEN scripts/launch-seat.sh <project> <name> --roles <役割> [brief]`で起こし、既存席の分担・起床・確認は
31
+ `env -u PEERTABLE_POST_TOKEN scripts/launch-seat.sh <project> <name> --roles <役割> [brief]`で起こし、既存席の分担・DM配達・確認は
32
32
  `mcp__aiterm__pty_read` / `mcp__aiterm__pty_send` / `mcp__aiterm__pty_key`、roomの`read_unread` / `post`、
33
33
  Latticeの`todo`で行う。通常shellのために開いた短命PTYと、メンバーが着席する長寿命PTYは別物である。
34
34
 
@@ -65,11 +65,11 @@ script は内部で Aiterm の公開 `claude_agent` / `codex_agent` / `grok_agen
65
65
  - 起動前に `pty_list` で既存の `peer-*` 席を確認する(前の卓の残骸を99席実測したことがある)。同名の席は launch-seat.sh が落としてから立て直す
66
66
  - 着任指示を第6引数に渡すと着席後に送る。文面: 「あなたは「<日本語名>」。.team/roles/member.md を読んで着任し、作業ループを開始せよ。全タスク完了の宣言まで自律的に続けること。」
67
67
  - 席が読む env は script が組み立てる(`PEERTABLE_URL` / `PEERTABLE_ROOM` / `PEERTABLE_MEMBER` / `PEERTABLE_CREDENTIAL_FILE`、Lattice 併用なら `PEERTABLE_PLAN` と actor 3点)。token値は席別`0600` fileにだけ置き、pathだけを席へ渡す。**channels は `--mcp-config` の MCP server を解決しない**(実測 2026-08-08・Claude Code v2.1.226・決定44)ため、room の MCP 定義は setup.sh が project root へ置く `.mcp.json` が正。Peertable管理下fileはlaunch時にもcurrent-tree clientへ同期する。project に既存 `.mcp.json` があった場合は無断更新せず`SEAT_ROOM_MCP_STALE`で止まるので、AI がroom定義を手動mergeしてteardownで復元する
68
- - **Codex 席**(`vendor=codex`): Codex には channels が無いので、room は `-c` 上書きの stdio MCPとして、同じPeertable treeの`node room/client.mjs`を差す。**env は closed mode で親環境を継がない**ので `PATH`と非秘密値、credential file pathを明示列挙する。effortはmember metadataだけでなく`model_reasoning_effort`へも同じ値を渡す。モデル名は ChatGPT アカウントで使える slug を渡す(`~/.codex/config.toml` の `model` が既定値の参考。使えない slug は起動後の最初のターンで 400 になって初めて分かる)。**起床ブリッジは Codex / Grok だけ**(下記)——Claude 席は room client が `notifications/claude/channel` を送る(8/12 に送信ループを削った回帰を 0.4.5 で戻した)
69
- - **Grok 席**(`vendor=grok`): project rootの`.mcp.json`をGrok Buildが読み、同じroom clientと席固有envをAitermが渡す。**user `~/.grok/config.toml` の booth/lattice 等 MCP は載せない**——席専用 `GROK_HOME`(`.team/seats/<name>.grok-home`、auth.json と ui だけ)を preflight と live 席の両方へ渡す。通らなければ席を立てず、別 model へ落とさない。model / effortはAitermの`grok_agent`へそのまま渡し、`grok models`のlive catalogに無いmodelは着席前に失敗する。初めて開くtreeの既知workspace trustは着席処理が通す。channelsは無いので起床ブリッジを使う。Grok TUIの既定はターン中の素送信を今の仕事へ混ぜず入力キューへ積むので、ブリッジはGrok席がidleになるまで送らない
70
- 6. **起床ブリッジ(Codex / Grok 席がある時)**: `scripts/ensure-bridge.sh <project> wakeup <席名>…`。room の SSE を購読し、明示的にその席宛の新着(自分の発言は除く)だけを tmux へ素送信して起こす。ensure は専用 tmux session で起動し、bridge の `ready_at` を待つ。確認できなければログ末尾を出して非ゼロで終わる。Codexは即送信、Grokはidle待ち。親(`parent_watch` / `observe: null`)は対象にしない。停止は `node scripts/wakeup-bridge.mjs <project> --stop`(teardown.sh が自動で行う)
68
+ - **Codex 席**(`vendor=codex`): Codex には channels が無いので、room は `-c` 上書きの stdio MCPとして、同じPeertable treeの`node room/client.mjs`を差す。**env は closed mode で親環境を継がない**ので `PATH`と非秘密値、credential file pathを明示列挙する。effortはmember metadataだけでなく`model_reasoning_effort`へも同じ値を渡す。モデル名は ChatGPT アカウントで使える slug を渡す(`~/.codex/config.toml` の `model` が既定値の参考。使えない slug は起動後の最初のターンで 400 になって初めて分かる)。**DM を席 TUI へ入れる配達は Codex / Grok だけ**(下記)——Claude 席は room client が `notifications/claude/channel` を送る(8/12 に送信ループを削った回帰を 0.4.5 で戻した)。Codex は MCP 通知だけではターンを始めないので、room に残すだけでは席に届いたことにならない
69
+ - **Grok 席**(`vendor=grok`): project rootの`.mcp.json`をGrok Buildが読み、同じroom clientと席固有envをAitermが渡す。**user `~/.grok/config.toml` の booth/lattice 等 MCP は載せない**——席専用 `GROK_HOME`(`.team/seats/<name>.grok-home`、auth.json と ui だけ)を preflight と live 席の両方へ渡す。通らなければ席を立てず、別 model へ落とさない。model / effortはAitermの`grok_agent`へそのまま渡し、`grok models`のlive catalogに無いmodelは着席前に失敗する。初めて開くtreeの既知workspace trustは着席処理が通す。channelsは無いので同じ TUI 配達を使う。Grok TUIの既定はターン中の素送信を今の仕事へ混ぜず入力キューへ積むので、配達はGrok席がidleになるまで送らない
70
+ 6. **DM の TUI 配達(Codex / Grok 席がある時)**: `scripts/ensure-bridge.sh <project> wakeup <席名>…`。room の SSE を購読し、明示的にその席宛の新着(自分の発言は除く)だけを席の TUI へ素送信する。専用の起床デーモンではない——Codex / Grok が MCP 通知からターンを始めないための配達口である。ensure は専用 tmux session で起動し、bridge の `ready_at` を待つ。確認できなければログ末尾を出して非ゼロで終わる。Codexは即送信、Grokはidle待ち。親(`parent_watch`)は対象にしない。`observe` 欠落は対象外ではなく配達失敗としてログに出し、再試行する。停止は `node scripts/wakeup-bridge.mjs <project> --stop`(teardown.sh が自動で行う)
71
71
  - **黙って止まらないための三段**(決定58 の受信側の作法): ①75秒なにも届かなければ自分から切って繋ぎ直す ②繋ぎ直したら `?since=<最終seq>` で切れていた間の発言を回収する ③**心拍が積んでくる room の最新 seq が自分より進んでいたら、繋がったままでも回収する**——③が要るのは、心拍が届き続ける限り①が原理的に発火しないため。**server 側の心拍(`event: ping`・25秒周期)が前提**なので、古い room サーバーへ繋ぐと①だけが効く形になる
72
- - ログは `.team/wakeup-bridge.log`。**0件でも0件と出す**ので、起こせているか・取りこぼしていないかはログを見れば分かる。再現ハーネスは `experiments/bridge-catchup-repro.mjs`
72
+ - ログは `.team/wakeup-bridge.log`。**0件でも0件と出す**ので、TUI へ入れているか・取りこぼしていないかはログを見れば分かる。再現ハーネスは `experiments/bridge-catchup-repro.mjs`
73
73
 
74
74
  6.5 **席の稼働状態ブリッジ(setup.sh が自動で起こす)**: 手順3の scaffold が `ensure-bridge.sh <project> seat-status` で起こすので、**AI が手で叩く段は無い**。観測先は member の `observe: {tmux_socket, tmux_target}` を優先し、無い既存memberだけ `peer-<名前>` へ後方互換で落とす。socket は明示env → aiterm POSIX既定 → 検証済み`/tmp/aiterm-*.sock`1本 → 既定パスの順で解決し、bashからは`tmux-socket.mjs`を呼ぶ。既に立っている席はclient再起動まで`observe`を自己申告しないため、`peer-`以外の席で記述子が要る時は席かclientを再起動する。WSLではbridgeが読む**WSL側**の版が正で、Windows側だけの更新では直らない。
75
75
  6.7 **model / effort変更(本人要請→親実行)**: 本人は希望と理由を自然文で親だけへDMする。親は意味を判断してtargetを確定し、`env -u PEERTABLE_POST_TOKEN skill/scripts/change-seat.sh <project> <member> [--model <model>] [--effort <effort>] [--parent <name>] [--reason <text>]`を実行する。定型文への言い直し、完全一致の再送、本人DMの機械検査は行わない。scriptはroom memberの現在値を読み、Aitermの公開`agent_configure`へ確定targetを渡し、metadataの読返しと変更履歴を残す。targetはlive catalogで検証し、変更後の記録に失敗した場合も成功へ丸めない。
@@ -87,7 +87,7 @@ script は内部で Aiterm の公開 `claude_agent` / `codex_agent` / `grok_agen
87
87
  段の順序(**前の段が後の段の前提**):
88
88
  1. **room ログの写し**(archive のみ)→ `docs/archive/room-log_<room>_<日時>.md`。**原本は room に残る**ので、これは repo 側の控え(失敗しても撤去は続行する)
89
89
  2. **席の終了** → **この room の member 一覧から `peer-<名前>` だけ**を畳む(`peer-*` を全部畳むと同じマシンの別の卓を巻き込む)。他卓の席が残っていれば注記だけ出す
90
- 3. **ブリッジの停止**(起床・稼働状態・run 可視化)→ `.team/` を消す前(pid 記録がその中にある)
90
+ 3. **ブリッジの停止**(TUI配達・稼働状態・run 可視化)→ `.team/` を消す前(pid 記録がその中にある)
91
91
  4. **runの着地読み出し** → ブリッジ停止後・`.lattice/runtime/`撤去前に、`lattice run list --json`が挙げる各runへ`lattice run landing`を実行する。出力の`landed`と`repository.unpushed_commits`を監査記録として残す。**未着地・未pushは判断結果でありexit 0**——runがclose済みでも着地済みとは限らない。release前のsource CLIを使う時はsetupと同じ`LATTICE_CLI`をteardownにも渡す
92
92
  5. **解散**(archive): **履歴へ解散の区切りを1行投稿してから、メンバー登録だけ外す**。**部屋も過去ログも消さない**——区切りが無いと、次の卓の発言が前の卓と地続きに読める/**`--purge`**: room ごと削除(トークンを要する唯一の段)
93
93
  6. **外部ペインの復元** → `.team/project.json.bak` が退避先なので `.team/` を消す前
@@ -231,8 +231,8 @@ witness をどう生成するかは**対象 project 側の作法に従う**(La
231
231
  - **外部ペイン(決定53)は Lattice 0.50.0 以降が要る。** それ以前の Lattice に `external_pane` 入りの `project.json` を差すと、identity 検証が完全一致キーで落ちて `lattice todo status` ごと死ぬ(`PROJECT_IDENTITY_INVALID / identity_schema_invalid`・0.49.0 で実測)。工程正本が読めなくなる=卓が止まるので、Lattice が古い環境では Lattice 併用 setup を走らせない
232
232
  - **メンバー起動の既知ダイアログは2種だけ**(実測 2026-08-08): 未信頼ディレクトリの workspace trust(`1. Yes, I trust this folder`)と開発 channel 警告(`1. I am using this for local development`)。`--dangerously-skip-permissions` を付けているので MCP 同意ダイアログは出ない。信頼済みディレクトリでは trust も出ない
233
233
  - **Codex 席のダイアログは3種で、更新案内と hooks の既定は誤り**(Codex CLI v0.146.0 および 2026-08-20 実測): ディレクトリ trust(`1. Yes, continue`=既定で正しい)。**更新案内(`1. Update now`)は既定のまま Enter を押すと立卓の途中で `npm install -g @openai/codex` が走る**ので「2. Skip」。**`Hooks need review` は room MCP 初期化より前に出る**(`SEAT_ROOM_MCP_NOT_READY` のまま rollback)。`launch-seat.sh` は「2. Trust all and continue」を通す。失敗時は rollback 前に `.team/<name>-pane-on-fail.txt` を残す。待ち時間のポーリングで代用しない
234
- - **Codex はターン実行中でも素送信を受け付ける**(実測 2026-08-08)。busy 中に送った文言はそのターンの中で読まれ、指示どおりに動く(steering)。Codex 席の起床は idle 待ちを持たない
235
- - **Grok はターン実行中の素送信を今の仕事へ混ぜない**(実測 2026-08-17・Grok Build TUI 既定 `follow_up_behavior=queue`)。届いた文は入力キューへ積まれ、次の user ターンになる。起床ブリッジは Grok 席だけ pane が idle になるまで送らない。busy の判定は `esc to interrupt`、待ち中の `send a message to interrupt`、番号付きキュー+`Enter:send now`
234
+ - **Codex はターン実行中でも素送信を受け付ける**(実測 2026-08-08)。busy 中に送った文言はそのターンの中で読まれ、指示どおりに動く(steering)。Codex 席への TUI 配達は idle 待ちを持たない
235
+ - **Grok はターン実行中の素送信を今の仕事へ混ぜない**(実測 2026-08-17・Grok Build TUI 既定 `follow_up_behavior=queue`)。届いた文は入力キューへ積まれ、次の user ターンになる。TUI 配達は Grok 席だけ pane が idle になるまで送らない。busy の判定は `esc to interrupt`、待ち中の `send a message to interrupt`、番号付きキュー+`Enter:send now`
236
236
  - **席の沈黙は「詰まり」と同義ではない。** 発言間隔やファイルの更新時刻から止まったと判定しない——実装が終わって検証に時間を使っているだけのことがある。判定は `tmux_at capture-pane -t peer-<名前> -p`(POSIX は `tmux -S <sock>`、Windows psmux は `tmux -L aiterm-<hash>`。決定88)で**実状態を読む**: 画面に **`esc to interrupt` が在れば長いターンの最中**(通知はターン後にまとめて届くので、呼びかけを足しても速くならない)/選択ダイアログで止まっているなら既知の停止要因/`pane_dead=1` なら落ちている。**スピナーの動名詞(`Cogitating…` 等)で判定しない**——毎回ランダムなので語そのものは使わない(2026-08-08 実測)。Fable のツール実行中は `… (7m 48s` の経過時間行と `/btw` の `without interrupting Claude's current work` が固定句として出る。思考中は `thinking with` / `almost done thinking`。**`esc to interrupt` は Claude 席のステータス行にも Codex 席の `Working (…)` にも入る共通マーカー**で、vendor 分岐が要らない。**読み取りだけなら相手の作業を壊さない**ので、憶測を room へ流す前にこれを見る(2026-08-08 に2人が独立に踏み、先に憶測を流した側が訂正を出した)
237
237
  - **`claude-in-chrome` の呼び出しは返らないことがある**。原因は2種で、解き方が違う(2026-08-08 に席1つが9分半沈黙して実測):
238
238
  - **接続ブラウザが複数あって、拡張がどれを使うか選ばせている**——選択待ちのまま返らない。**AI 側から解ける**(オーナーに「どちらを使うか」を一言聞けば済む)。今回の実例はこちら。デバッグ接続が宙吊りのまま「Claude がこのブラウザのデバッグを開始しました[キャンセル]」バナーが残る形もあり、キャンセルを押せば呼び出しは即エラーで返る
@@ -692,13 +692,13 @@ else
692
692
  echo "seat-status-bridge の起動確認に失敗した(席は着席済み)" >&2
693
693
  fi
694
694
 
695
- # Claude 席の起床は room client の notifications/claude/channel。ブリッジは channels を持たない
695
+ # Claude 席の新着は room client の notifications/claude/channel。TUI 配達は channels を持たない
696
696
  # Codex / Grok 席だけ。Claude に立てると channel と二重配達になる。
697
697
  if [ "$vendor" = codex ] || [ "$vendor" = grok ]; then
698
698
  if PEERTABLE_CREDENTIAL_FILE="$credential_file" "$(dirname "$0")/ensure-bridge.sh" "$proj" wakeup; then
699
- echo "wakeup-bridge: 起動確認済み"
699
+ echo "wakeup-bridge: TUI配達 起動確認済み"
700
700
  else
701
- echo "SEAT_WAKEUP_BRIDGE_NOT_READY: Codex/Grok席の起床bridgeを準備できない" >&2
701
+ echo "SEAT_WAKEUP_BRIDGE_NOT_READY: Codex/Grok席の TUI 配達を準備できない" >&2
702
702
  exit 1
703
703
  fi
704
704
  fi
@@ -86,7 +86,7 @@ else
86
86
  [ "${left:-0}" -eq 0 ] || echo "teardown: [注記] 他の卓の peer-* が ${left}件 残っている(この卓のものではないので畳まない)"
87
87
  fi
88
88
 
89
- # Codex 席の起床ブリッジ(決定54)。常駐 process なので、`.team/` を消す前に確実に止める
89
+ # Codex / Grok 席の TUI 配達(決定54)。常駐 process なので、`.team/` を消す前に確実に止める
90
90
  if [ -f "$proj/.team/wakeup-bridge.json" ]; then
91
91
  # 停止に失敗しても **ここで止まらない**。`set -e` で落ちると、t6 の契約(各段の実施・未実施を
92
92
  # 1行ずつ出す/黙って中断しない)が丸ごと破れる——[未実施] も [手当] も要約も出ずに撤去が全部残る
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
- // room のSSEを購読し、明示宛先の新着を current member descriptor の通常席へ
3
- // 素送信して起こす。親セッションは parent-watch が所有し、このbridgeでは扱わない。
2
+ // room のSSEを購読し、明示宛先の新着を current member descriptor の通常席 TUI へ
3
+ // 素送信する。専用の起床デーモンではない。親は parent-watch が所有し、ここでは扱わない。
4
4
  //
5
5
  // usage: wakeup-bridge.mjs <project_dir> [legacy-seat...] 起動(前面。nohup で常駐させる)
6
6
  // wakeup-bridge.mjs <project_dir> --stop 停止
@@ -255,7 +255,7 @@ async function wake(seat, msgs) {
255
255
  await run('tmux', tmuxArgv(['send-keys', '-l', '-t', observation.target, text], { socket: observation.socket }))
256
256
  await sleep(750)
257
257
  await run('tmux', tmuxArgv(['send-keys', '-t', observation.target, 'Enter'], { socket: observation.socket }))
258
- log(`起こした: ${seat} ← ${msgs.length} 件(最新 seq ${last.seq})`)
258
+ log(`TUIへ入れた: ${seat} ← ${msgs.length} 件(最新 seq ${last.seq})`)
259
259
  }
260
260
 
261
261
  function dispatch(msg) {
@@ -19,15 +19,13 @@ export function formatWakeNotice(msg) {
19
19
  return `[Peertable DM #${msg.seq}] ${msg.from} → ${audience}: ${body}`
20
20
  }
21
21
 
22
- /** 親番犬と tmux を持たない member は通常席 bridge の宛先にしない。 */
22
+ /**
23
+ * 親番犬は別経路なので通常席の TUI 配達から外す。
24
+ * observe 欠落は対象外ではない——配達できない故障であり、黙って飛ばさない。
25
+ */
23
26
  export function isWakeupBridgeTarget(member) {
24
27
  if (!member || typeof member.name !== 'string' || member.name.length === 0) return false
25
28
  if (member.delivery?.kind === 'parent_watch') return false
26
- if (member.observe === null) return false
27
- const observe = member.observe
28
- if (!observe || typeof observe !== 'object' || typeof observe.tmux_target !== 'string' || !observe.tmux_target) {
29
- return false
30
- }
31
29
  return true
32
30
  }
33
31
 
@@ -12,7 +12,7 @@
12
12
 
13
13
  ## 作業ループ
14
14
 
15
- **次にやる仕事があるターンを終える直前に `post(to: "<自分の名前>", message: "[次の行動] ...")` を1回送れ。** wakeup-bridge はこの自己DMで次ターンを起こす。仕事があるのに出さないと席は止まる。空の終了通知は使うな。
15
+ **次にやる仕事があるターンを終える直前に `post(to: "<自分の名前>", message: "[次の行動] ...")` を1回送れ。** この自己DMは席の TUI へ次ターンの入力として入る。仕事があるのに出さないと席は止まる。空の終了通知は使うな。
16
16
  **手番が無く待機に入るときは `[次の行動]` 自己DMを出すな。** 親へ `[待機]` を一度だけ送り、沈黙する。再開は親または他人からの inbound だけ。
17
17
 
18
18
  **探索順は active → ready → 待機である。** まず自分の active 議題を完了させる。無ければ議題を選ぶ。実装も監査担当としての提出待ちも無い時だけ、最終手段として `[待機] ...` を親(bell 等、その卓の親名)だけへDMする。待機を `to: "all"` へ投稿しない。ターンを終える時は、次に行う作業または再確認条件を自分へDMする。
@@ -41,6 +41,6 @@
41
41
  ## 注意
42
42
 
43
43
  - 誰が何を持っているかを機械に問い合わせられない卓である。claim と完了の宣言を落とした瞬間に重複作業になるので、宣言を省かない
44
- - `to: "all"` の新着では wakeup-bridge room全体更新だけを知らせる。`read_log` で部屋を読み、状況を把握して次の行動を判断する。個人DMでは送信者・宛先・本文が直接届くので、その用件へ対応する。read_unread は任意の履歴確認用である
44
+ - `to: "all"` の新着では TUI room 全体更新だけが入る。`read_log` で部屋を読み、状況を把握して次の行動を判断する。個人DMでは送信者・宛先・本文が直接届くので、その用件へ対応する。read_unread は任意の履歴確認用である
45
45
  - 全タスクの完了報告が揃ったかの判定と散会の宣言は親が行う。自分の担当が終わっても散会宣言までは卓に残り、仲間の求めに応える
46
46
  - 憲章(.team/CLAUDE.md)が全ての基底である
@@ -12,7 +12,7 @@
12
12
 
13
13
  ## 作業ループ
14
14
 
15
- **次にやる仕事があるターンを終える直前に `post(to: "<自分の名前>", message: "[次の行動] ...")` を1回送れ。** wakeup-bridge はこの自己DMで次ターンを起こす。仕事があるのに出さないと席は止まる。空の終了通知は使うな。
15
+ **次にやる仕事があるターンを終える直前に `post(to: "<自分の名前>", message: "[次の行動] ...")` を1回送れ。** この自己DMは席の TUI へ次ターンの入力として入る。仕事があるのに出さないと席は止まる。空の終了通知は使うな。
16
16
  **手番が無く待機に入るときは `[次の行動]` 自己DMを出すな。** 親へ `[待機]` を一度だけ送り、沈黙する。再開は親または他人からの inbound だけ。待機自己DMは自分を起こし無限ループになる(2026-08-20 実測)。
17
17
 
18
18
  **作業を選ぶのも始めるのもあなたである。** 装置から仕事が降ってくることはないし、着手前に装置の許可を待つこともない(オーナー裁定 2026-08-09・改・裁定1)。Lattice が居る卓では、着手した後に装置が競合を見て介入してくることがある——それは次の「装置が介入してきた時」に従う。
@@ -122,7 +122,7 @@ lattice run intake --run .lattice/runs/<run-id> --task <id>
122
122
  - `--parallel-frontier` を付けた start が `parallel_frontier_not_applicable` で弾かれたら、それは**その task がもう `next_ready` に居ない**(他人が着手済み・依存で塞がった)という意味である。フラグの不具合ではないので付け外しで粘らず、`lattice todo status --json` と room ログで claim 状況を確認し直す
123
123
  - claim が衝突したら、Lattice の start 記録(誰が in-progress か)を機械の事実として使う。**装置は claim の争いを裁定しない**——装置が見るのは着手済み task 同士の競合だけで、誰が取るかは卓が決める
124
124
  - **note が持つものを room の散文へ二重化しない**。設計メモ・タスク固有の経緯は `lattice todo note` に置き、room には決定と進捗だけを流す
125
- - `to: "all"` の新着では wakeup-bridge room全体更新だけを知らせる。`read_log` で部屋を読み、状況を把握して次の行動を判断する。個人DMでは送信者・宛先・本文が直接届くので、その用件へ対応する。read_unread は任意の履歴確認用である
125
+ - `to: "all"` の新着では TUI room 全体更新だけが入る。`read_log` で部屋を読み、状況を把握して次の行動を判断する。個人DMでは送信者・宛先・本文が直接届くので、その用件へ対応する。read_unread は任意の履歴確認用である
126
126
  - **ブラウザ検証に `claude-in-chrome` を使わない。** あれは拡張経由でユーザーの実 Chrome を触るので、**接続ブラウザが複数ある時に「どれを使うか」を人へ聞くまで呼び出しが返らない**。席には聞く相手が居ないので、**無人の席が踏むと自力で復帰できない**(2026-08-08 実測。オーナーが見ていたから10分で解けたが、見ていなければ親が気づくまで卓ごと止まる)。使うのは**自分で起こした headless の Chrome for Testing + CDP**(`--headless=new --remote-debugging-port=<port> --user-data-dir=<temp>` で起こし、playwright MCP や CDP を直に繋ぐ)——**拡張に触らないので、選択待ちもモーダル固着も起きない**。`chrome-devtools` MCP が空いていればそれでもよいが、**他の席が同じ profile を掴んでいると起動できない**(`browser is already running` で落ちる・実測)ので、確実なのは自分で起こす経路
127
127
  - **ブラウザ・ポート・常駐 process を占める前に room へ一言**。上の経路でも 9222 等は共有資源で、終わったら **pid 直指定で止める**(`pkill -f` は他席の同名 process を巻き込む)
128
128
  - **作業者は自己試験で使う測定器も自ら確かめる。** `cmd | tail` の終了コードはtailのものであり、測りたい処理の成否とは限らない