⚠️ Status correction (2026-08-11, docs-maintainer)
Items ① (hooks_add session-local write target) and ③ (external
monitoring doc) have both landed since filing (#4230, #4241, #4247,
#4220) — the "①は完了ではありません" open-TODO note in the thread is
now false.
Still open: item ② (parent observing a child's hook events) —
HookBus.subscribe() still has only the same 2 call sites the issue
measured. This is now the issue's sole remaining scope.
The body below is preserved as filed. Read the section above as current
state, and treat anything below that it doesn't mention as still accurate.
[architect] — owner との設計議論(2026-08-11)の記録と実行計画。私は実装を持ちません。
出発点 — owner の観察
hooks 以外は能動的動作なので見えていても使わなければ影響ないが、hooks は受動的なので、
他の人による登録で自身に直接影響を受けるのが良くない。
∴ hook は reyn で唯一 reactive な角であり、**「他人の登録が自分に効く」**が構造的な懸念。
⚪ owner の設計上の好み(同日): 決定論と ReAct。∴ reactive を広げるより、決定論側に寄せる方が
既存の重心とも合う。
結論 3 点(いずれも★新機構ゼロ)
① hook handler をセッションローカルに
hooks_add(LLM op)の書き込み先を session 層に固定する。
現在 named agent → .reyn/agents/<name>/hooks.yaml
default agent → ★.reyn/config/hooks.yaml(GLOBAL)= 全 agent・全セッションで発火
後 ★常に <session state dir>/hooks.yaml
⚪ operator の面は維持(reyn.yaml の hooks: / .reyn/config/hooks.yaml の直接編集)—
fs_watch は operator が「監視を宣言し、反応も宣言する」設計(#2608 H4)なので、
operator 層を閉じると consumer を失う。
② 親が子のイベントを観測する — 非ブロックで橋渡し
既存パターン SpawnBridge(present / ask_user)— 子の sink を★親のものに差し替える
spawn サイトは presentation_consumer + intervention_bridge を★必須 kwarg で取る
(inspect.signature で pin、#2708 P3-item3)
追加 spawn 時に★子の HookBus を subscribe し、親の bus へ再 publish
🔴 必ず非ブロックにすること(owner 要件)。⚪ HookBus は元から非ブロック
(publish never blocks the publisher、購読者ごとの bounded queue)∴ 性質は既に正しい。
⚠️ dispatcher を繋いではいけない — あちらは await 経路で、子の発行が親の hook 実行を待つ。
③ 外部セッションによる監視・改善 — pull(差分ゼロ)
owner の用例: task 完了を監視 → 監査イベントを分析 → プロンプト / pipeline を外部セッションが改善。
cron.jobs ★既存(scheduled message dispatch → 改善役 agent を定期起床)
.reyn/events/ ★既存(project 単位・agent 別・既定 read ゾーン内)
完了の記録 ★既存(turn_settled / session_completed / pipeline_step_completed /
chain_timeout / task_settle_undelivered ほか)
⚪ pull は「被監視側が何もしない」 ∴ owner が閉じたい向きを一度も使わない。
∴ ①でセッションローカルに寄せても、監視は何も失わない。
差分(実測)
① コード: _hooks_yaml_path 1 関数 doc: #2088 docstring のみ(hooks.md は★既に正しい)
★読む側は完成済み(session.py:4529「the 4th, most-specific layer」)
test: test_2088_hooks_add_scope_aware.py が書き換わる(挙動変更ゆえ想定内)
② コード: subscribe 1 本 + spawn の必須 kwarg 2→3(★全 spawn サイト 3 箇所が触られる)
doc: 🔴 0059 §3.3 の「session isolation is ★structural, not a runtime check」を更新
— ★明示的な設計変更。黙って緩めないこと
③ コード: ★ゼロ doc: 新規 how-to(監視エージェントの作り方)
進め方
1. ① ★単独で完結。②③に依存しない。差分最小。先に入れて受動性の穴を閉じる
2. ③ ★コード変更ゼロ。doc のみ ∴ ①と並行可
3. ② ★最後。①③が入ってから
理由: ②は 0059 の設計変更を含み、①③が先に入っていれば
「観測のために危険な向きを開ける必要が無い」ことが★実証済みの状態で議論できる
🔴 着手前に測ること(②のスコープを左右する)
親の bus を★読む主体が現在いません。 HookBus.subscribe() の既存呼び出しは
composer.py / composed_consumer.py の 2 箇所(Composer 機構)のみ。
∴ 子のイベントを親の bus に流しても、親に受け皿が無ければ誰も見ません。
②の差分が「subscribe 1 本」で済むか、「観測面の新設」まで要るかは、ここで決まります。
私は測っていません。
範囲
測ったもの: hooks_add の書き込み先分岐、session 層 hook の読み取り経路、
HookBus の非ブロック性と API、ingress の外部イベント 2 経路(bounded queue / fire_and_forget)、
HookDispatcher の await 性、SpawnBridge の sink 差し替え、cron / .reyn/events / 完了 kind の存在。
測っていないもの: 親側の bus 受け皿(上記)、.reyn/events のリアルタイム追従手段、
BridgeToParent がイベントを運べる型か。
⚠️ owner の記憶が私の測定を 2 度上回りました(#2072 cross-session push の存在、
sync/async がイベント種別で決まること)。∴ 本 issue も、関連する過去議論を私が
取りこぼしている可能性が残ります。
Items ① (hooks_add session-local write target) and ③ (external
monitoring doc) have both landed since filing (#4230, #4241, #4247,
#4220) — the "①は完了ではありません" open-TODO note in the thread is
now false.
Still open: item ② (parent observing a child's hook events) —
HookBus.subscribe()still has only the same 2 call sites the issuemeasured. This is now the issue's sole remaining scope.
The body below is preserved as filed. Read the section above as current
state, and treat anything below that it doesn't mention as still accurate.
[architect] — owner との設計議論(2026-08-11)の記録と実行計画。私は実装を持ちません。
出発点 — owner の観察
∴ hook は reyn で唯一 reactive な角であり、**「他人の登録が自分に効く」**が構造的な懸念。
⚪ owner の設計上の好み(同日): 決定論と ReAct。∴ reactive を広げるより、決定論側に寄せる方が
既存の重心とも合う。
結論 3 点(いずれも★新機構ゼロ)
① hook handler をセッションローカルに
hooks_add(LLM op)の書き込み先を session 層に固定する。⚪ operator の面は維持(
reyn.yamlのhooks:/.reyn/config/hooks.yamlの直接編集)—fs_watchは operator が「監視を宣言し、反応も宣言する」設計(#2608 H4)なので、operator 層を閉じると consumer を失う。
② 親が子のイベントを観測する — 非ブロックで橋渡し
🔴 必ず非ブロックにすること(owner 要件)。⚪ HookBus は元から非ブロック
⚠️ dispatcher を繋いではいけない — あちらは await 経路で、子の発行が親の hook 実行を待つ。
(
publish never blocks the publisher、購読者ごとの bounded queue)∴ 性質は既に正しい。③ 外部セッションによる監視・改善 — pull(差分ゼロ)
owner の用例: task 完了を監視 → 監査イベントを分析 → プロンプト / pipeline を外部セッションが改善。
⚪ pull は「被監視側が何もしない」 ∴ owner が閉じたい向きを一度も使わない。
∴ ①でセッションローカルに寄せても、監視は何も失わない。
差分(実測)
進め方
🔴 着手前に測ること(②のスコープを左右する)
親の bus を★読む主体が現在いません。
HookBus.subscribe()の既存呼び出しはcomposer.py/composed_consumer.pyの 2 箇所(Composer 機構)のみ。∴ 子のイベントを親の bus に流しても、親に受け皿が無ければ誰も見ません。
②の差分が「subscribe 1 本」で済むか、「観測面の新設」まで要るかは、ここで決まります。
私は測っていません。
範囲
測ったもの:
hooks_addの書き込み先分岐、session 層 hook の読み取り経路、HookBusの非ブロック性と API、ingress の外部イベント 2 経路(bounded queue / fire_and_forget)、HookDispatcherの await 性、SpawnBridge の sink 差し替え、cron/.reyn/events/ 完了 kind の存在。測っていないもの: 親側の bus 受け皿(上記)、
.reyn/eventsのリアルタイム追従手段、BridgeToParentがイベントを運べる型か。sync/async がイベント種別で決まること)。∴ 本 issue も、関連する過去議論を私が
取りこぼしている可能性が残ります。