From ebf50baa94f76bb000f70f63e133c7883729de5c Mon Sep 17 00:00:00 2001 From: Hare Date: Fri, 26 Jun 2026 00:25:03 +0900 Subject: [PATCH] fix: align worker rename followups --- KNOWN_ISSUES.md | 6 ++--- crates/client/src/spawn.rs | 8 +++--- crates/pod-store/README.md | 8 +++--- crates/protocol/src/lib.rs | 6 ++--- docs/design/worker-session-state.md | 2 +- .../prompts/common/worker-orchestration.md | 2 +- .../panel/orchestrator_idle_queue_notice.md | 2 +- resources/prompts/role/intake.md | 2 +- resources/prompts/role/orchestrator.md | 2 +- .../workflows/ticket-orchestrator-routing.md | 2 +- web/workspace/src/lib/generated/protocol.ts | 26 +++++++++---------- 11 files changed, 33 insertions(+), 33 deletions(-) diff --git a/KNOWN_ISSUES.md b/KNOWN_ISSUES.md index 516701b1..346a58e3 100644 --- a/KNOWN_ISSUES.md +++ b/KNOWN_ISSUES.md @@ -2,7 +2,7 @@ Ticket を切るほどではないが、次に近所を触るときに合わせて拾いたい小粒な所見の置き場。 -- `crates/worker/src/controller.rs:1269-1278` — `worker_error_code` で `PodError::WorkflowResolve(_) => InvalidRequest` が post-commit な resolve エラー (`KnowledgeNotFound` 等) にも適用される。意味論的には妥当方向だが、resolve 系のエラー粒度を分けたくなったタイミングで再評価。 +- `crates/worker/src/controller.rs:1453-1461` — `worker_error_code` で `WorkerError::WorkflowResolve(_) => InvalidRequest` が post-commit な resolve エラー (`KnowledgeNotFound` 等) にも適用される。意味論的には妥当方向だが、resolve 系のエラー粒度を分けたくなったタイミングで再評価。 - `crates/session-store/src/fs_store.rs:200-210` — `FsStore::read_entry_count` が `fs::read_to_string` で全文ロードしてから行数カウントするため O(n)。`ensure_head_or_fork` は run-start でしか呼ばれず現状は許容範囲だが、長期セッションが普通になった時点で `\n` バイト数の cheap count か末尾 seek に置き換える。 -- `crates/session-store/src/segment.rs:143-172` `ensure_head_or_fork` (free fn, test 専用・本番 caller ゼロ) と `crates/worker/src/pod.rs:1941-2006` `Pod::ensure_segment_head` (本番 inline) に live auto-fork の検知 + forked_from 記録が二重実装されている。entry-hash-abolish 以前からの重複で、両方独立にテスト済みだが drift 必至。session-store 側を本番から呼ぶ形に寄せるか free fn を畳むかは要設計判断。Pod state / fork 周辺を次に触るときに統合を検討。 -- `crates/worker/src/pod.rs:4100-4147` / `crates/worker/src/spawn/registry.rs:84-174` — restore 時の spawned child prune/reclaim が Pod restore path と spawned registry load path の両方に残っている。現状は安全側の重複チェックだが、Pod state / spawned registry 周辺を次に触るときに責務境界を再整理。 +- `crates/session-store/src/segment.rs:143-172` `ensure_head_or_fork` (free fn, test 専用・本番 caller ゼロ) と `crates/worker/src/worker.rs:2032` `Worker::ensure_segment_head` (本番 inline) に live auto-fork の検知 + forked_from 記録が二重実装されている。entry-hash-abolish 以前からの重複で、両方独立にテスト済みだが drift 必至。session-store 側を本番から呼ぶ形に寄せるか free fn を畳むかは要設計判断。Worker state / fork 周辺を次に触るときに統合を検討。 +- `crates/worker/src/worker.rs` / `crates/worker/src/spawn/registry.rs:84-174` — restore 時の spawned child prune/reclaim が Worker restore path と spawned registry load path の両方に残っている。現状は安全側の重複チェックだが、Worker state / spawned registry 周辺を次に触るときに責務境界を再整理。 diff --git a/crates/client/src/spawn.rs b/crates/client/src/spawn.rs index 9db90dd0..d8ccb647 100644 --- a/crates/client/src/spawn.rs +++ b/crates/client/src/spawn.rs @@ -78,7 +78,7 @@ pub enum SpawnError { Io(io::Error), /// runtime ディレクトリが解決できなかった (環境変数未設定等)。 RuntimeDirUnavailable, - PodLaunchFailed { + WorkerLaunchFailed { command: WorkerRuntimeCommand, source: io::Error, }, @@ -96,7 +96,7 @@ impl std::fmt::Display for SpawnError { f, "could not resolve runtime directory (set YOI_HOME, YOI_RUNTIME_DIR, XDG_RUNTIME_DIR, or HOME)" ), - Self::PodLaunchFailed { command, source } => write!( + Self::WorkerLaunchFailed { command, source } => write!( f, "failed to launch worker runtime command `{command}`: {source}" ), @@ -119,7 +119,7 @@ impl std::fmt::Display for SpawnError { impl std::error::Error for SpawnError { fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { match self { - Self::Io(error) | Self::PodLaunchFailed { source: error, .. } => Some(error), + Self::Io(error) | Self::WorkerLaunchFailed { source: error, .. } => Some(error), Self::RuntimeDirUnavailable | Self::WorkerExitedEarly { .. } | Self::Timeout => None, } } @@ -197,7 +197,7 @@ where } let mut child = command .spawn() - .map_err(|source| SpawnError::PodLaunchFailed { + .map_err(|source| SpawnError::WorkerLaunchFailed { command: config.runtime_command.clone(), source, })?; diff --git a/crates/pod-store/README.md b/crates/pod-store/README.md index 4718033e..29f25ef0 100644 --- a/crates/pod-store/README.md +++ b/crates/pod-store/README.md @@ -2,13 +2,13 @@ ## Role -`pod-store` owns current Pod metadata keyed by Pod name. +`pod-store` is the legacy-named crate that owns current Worker metadata keyed by Worker name. ## Boundaries Owns: -- persisted Pod metadata files +- persisted Worker metadata files - current active/pending session pointers - resolved manifest snapshots for restoration - parent-visible spawned-child metadata @@ -23,8 +23,8 @@ Does not own: ## Design notes -Pod metadata is intentionally thin. It should answer current-state questions without duplicating transcripts or becoming a second session log. +Worker metadata is intentionally thin. It should answer current-state questions without duplicating transcripts or becoming a second session log. ## See also -- [`../../docs/design/pod-session-state.md`](../../docs/design/pod-session-state.md) +- [`../../docs/design/worker-session-state.md`](../../docs/design/worker-session-state.md) diff --git a/crates/protocol/src/lib.rs b/crates/protocol/src/lib.rs index 10a293dc..63c85760 100644 --- a/crates/protocol/src/lib.rs +++ b/crates/protocol/src/lib.rs @@ -1658,7 +1658,7 @@ mod tests { } #[test] - fn pod_discovery_methods_roundtrip() { + fn worker_discovery_methods_roundtrip() { let methods = [ Method::ListWorkers, Method::RestoreWorker { @@ -1681,7 +1681,7 @@ mod tests { } #[test] - fn pod_discovery_events_roundtrip() { + fn worker_discovery_events_roundtrip() { let events = [ Event::WorkersListed { workers: serde_json::json!([{ "worker_name": "child" }]), @@ -1698,7 +1698,7 @@ mod tests { let decoded: Event = serde_json::from_str(&json).unwrap(); match (decoded, event) { (Event::WorkersListed { workers }, Event::WorkersListed { workers: expected }) => { - assert_eq!(pods, expected) + assert_eq!(workers, expected) } (Event::WorkerRestored { result }, Event::WorkerRestored { result: expected }) => { assert_eq!(result, expected) diff --git a/docs/design/worker-session-state.md b/docs/design/worker-session-state.md index 15f07887..b92e0811 100644 --- a/docs/design/worker-session-state.md +++ b/docs/design/worker-session-state.md @@ -36,7 +36,7 @@ Delegated write scope is a capability loan. Stopping, shutting down, or pruning Peer visibility is also Worker metadata, but it is distinct from spawned-child delegation. A TUI user can run `:peer ` while attached to an idle Worker to register reciprocal peer metadata with another existing Worker. This is a metadata-level registration, not live target-controller consent. -A peer relationship only makes the Workers mutually visible through `ListWorkers` with visibility source `peer`. It does not grant filesystem scope, create a child output cursor, make either Worker the other's parent, or imply child completion notifications. Peer messages use `SendToPeerPod`, which delivers a labeled notification into the target Worker's normal durable notification/history path. `SendToPeerPod` requires the peer to be live and fails clearly for non-live peers rather than auto-restoring them. +A peer relationship only makes the Workers mutually visible through `ListWorkers` with visibility source `peer`. It does not grant filesystem scope, create a child output cursor, make either Worker the other's parent, or imply child completion notifications. Peer messages use `SendToPeerWorker`, which delivers a labeled notification into the target Worker's normal durable notification/history path. `SendToPeerWorker` requires the peer to be live and fails clearly for non-live peers rather than auto-restoring them. ## Notifications are not authority diff --git a/resources/prompts/common/worker-orchestration.md b/resources/prompts/common/worker-orchestration.md index 8f5b50af..5f92d2f5 100644 --- a/resources/prompts/common/worker-orchestration.md +++ b/resources/prompts/common/worker-orchestration.md @@ -7,6 +7,6 @@ The parent does not need to keep a turn open or call tools solely to wait for a Before treating delegated work as complete, read the child output and inspect concrete evidence such as worktree state, diff, and test results. Notifications are hints, not proof of completion. -Peer Pods made visible by reciprocal metadata registration are not spawned children. Use peer messaging only as explicit communication; it does not grant scope, produce a child output cursor, imply parent ownership, or create child completion notifications. Peer sends require a live peer and do not auto-restore stopped peers. +Peer Workers made visible by reciprocal metadata registration are not spawned children. Use peer messaging only as explicit communication; it does not grant scope, produce a child output cursor, imply parent ownership, or create child completion notifications. Peer sends require a live peer and do not auto-restore stopped peers. This guidance is not scheduler or auto-maintain authorization. Do not start workflows, merge or clean up work, close tickets, or bypass user/workflow authorization solely because Worker tools or notifications exist. diff --git a/resources/prompts/panel/orchestrator_idle_queue_notice.md b/resources/prompts/panel/orchestrator_idle_queue_notice.md index f50e2961..3574523a 100644 --- a/resources/prompts/panel/orchestrator_idle_queue_notice.md +++ b/resources/prompts/panel/orchestrator_idle_queue_notice.md @@ -20,5 +20,5 @@ Queued Tickets retained in the session work set but currently waiting: Additional queued Tickets omitted from this bounded notice: {{ omitted_ticket_count }} {% endif -%} -Preserve the existing human gate, dependency/conflict/capacity/dirty-workspace checks, and duplicate-start checks using actual Ticket state, role/session claims, visible Pods, and worktrees. +Preserve the existing human gate, dependency/conflict/capacity/dirty-workspace checks, and duplicate-start checks using actual Ticket state, role/session claims, visible Workers, and worktrees. diff --git a/resources/prompts/role/intake.md b/resources/prompts/role/intake.md index d5ef72e7..f5707a58 100644 --- a/resources/prompts/role/intake.md +++ b/resources/prompts/role/intake.md @@ -6,6 +6,6 @@ In drafts and Ticket bodies, separate user claims/request snapshot, confirmed fa Create or update Tickets only after user agreement or an explicit user instruction to record the agreed draft. Durable Ticket item/thread/resolution text should follow the configured worker language unless a Ticket-specific record language instruction is supplied by the host/environment. -Intake is not a scheduler. Do not spawn coder/reviewer/read-only investigation helper Pods, create implementation worktrees, route implementation/review, merge, close, or perform implementation side effects; leave those to the user/Orchestrator queue flow. +Intake is not a scheduler. Do not spawn coder/reviewer/read-only investigation helper Workers, create implementation worktrees, route implementation/review, merge, close, or perform implementation side effects; leave those to the user/Orchestrator queue flow. When a workflow is invoked, follow that workflow as the procedural authority. Do not infer requirements from a Ticket id or title alone; read the relevant Ticket record before updating it. diff --git a/resources/prompts/role/orchestrator.md b/resources/prompts/role/orchestrator.md index 3858cf69..44e458ef 100644 --- a/resources/prompts/role/orchestrator.md +++ b/resources/prompts/role/orchestrator.md @@ -1,6 +1,6 @@ You are the Ticket Orchestrator role. -Keep durable orchestration behavior here and treat the first committed user message as concrete Ticket/action context only. Use typed Ticket tools and current repository state as authority. Record `inprogress` before implementation side effects, route concrete work to sibling Coder/Reviewer Pods when appropriate, and stop for human authority when merge/closure is not explicitly delegated. +Keep durable orchestration behavior here and treat the first committed user message as concrete Ticket/action context only. Use typed Ticket tools and current repository state as authority. Record `inprogress` before implementation side effects, route concrete work to sibling Coder/Reviewer Workers when appropriate, and stop for human authority when merge/closure is not explicitly delegated. Workspace roots, cwd, profile selector, workflow selector, and launch-prompt configuration are control-plane/environment facts rather than user instructions. If the launch input names explicit Git/worktree operation targets, use those paths only for that operation and do not substitute heuristic roots. diff --git a/resources/workflows/ticket-orchestrator-routing.md b/resources/workflows/ticket-orchestrator-routing.md index 9e351b66..02983f2c 100644 --- a/resources/workflows/ticket-orchestrator-routing.md +++ b/resources/workflows/ticket-orchestrator-routing.md @@ -10,7 +10,7 @@ requires: [workflow-resource-boundary] 1. Ticket body/thread/artifacts/resolution 状態を読み、current state と blocking relation を確認する。queued Ticket は実装 side effect 前に `inprogress` を記録する。 2. 不足情報が具体的にある場合は planning return とし、何が足りないかを Ticket thread に残す。risk flag は context lookup・review focus・invariant・escalation として扱い、自動 stop gate にしない。 3. 実装に進む場合は Orchestrator workspace/orchestration HEAD を基準にし、launch input の explicit Git/worktree operation target だけを使う。role workspace/cwd は環境情報であり、original/root workspace を読み書き・検証・cleanup・git 操作対象にしない。 -4. child implementation worktree は recorded implementation worktree root 配下に作成し、implementation branch は Orchestrator workspace current HEAD / orchestration branch HEAD から切る。Coder/Reviewer は sibling Pods として route し、Ticket intent・binding decisions・validation/report expectations を concrete handoff として渡す。 +4. child implementation worktree は recorded implementation worktree root 配下に作成し、implementation branch は Orchestrator workspace current HEAD / orchestration branch HEAD から切る。Coder/Reviewer は sibling Workers として route し、Ticket intent・binding decisions・validation/report expectations を concrete handoff として渡す。 5. Reviewer が request-changes した場合は、scope 内で Coder に修正を戻すか、Orchestrator が blocked/escalation を記録する。approve evidence が揃うまで merge-ready とみなさない。 6. merge completion authority が無い場合は、Ticket/branch/commit identity、intent/invariant check、implementation summary、coder/reviewer evidence、blocker resolution、validation、risks、dirty state、decision needs を含む merge-ready dossier で停止する。 7. 明示 authority と clean reviewer evidence がある場合のみ、merge target workspace への統合、validation、Ticket close/completion processing、関連 Worker 停止、scope reclamation、worktree/branch cleanup、evidence reporting を進める。 diff --git a/web/workspace/src/lib/generated/protocol.ts b/web/workspace/src/lib/generated/protocol.ts index 18bc080b..7f99a2f8 100644 --- a/web/workspace/src/lib/generated/protocol.ts +++ b/web/workspace/src/lib/generated/protocol.ts @@ -4,15 +4,15 @@ export type AlertLevel = "warn" | "error"; -export type AlertSource = "pod" | "worker" | "compactor" | "agents_md"; +export type AlertSource = "worker" | "engine" | "compactor" | "agents_md"; export type CompletionKind = "file" | "knowledge" | "workflow"; -export type PodStatus = "idle" | "running" | "paused"; +export type WorkerStatus = "idle" | "running" | "paused"; export type TurnResult = "finished" | "paused"; -export type InvokeKind = "user_send" | "notify" | "pod_event" | "system_reminder" | "wakeup"; +export type InvokeKind = "user_send" | "notify" | "worker_event" | "system_reminder" | "wakeup"; export type RunResult = "finished" | "paused" | "limit_reached" | "rolled_back"; @@ -53,9 +53,9 @@ export type InFlightBlock = { "kind": "text", text: string, finished?: boolean, export type InFlightSnapshot = { blocks?: Array, }; -export type Greeting = { pod_name: string, cwd: string, provider: string, model: string, scope_summary: string, tools: Array, +export type Greeting = { worker_name: string, cwd: string, provider: string, model: string, scope_summary: string, tools: Array, /** - * Model context window in tokens. Always filled by the Pod greeting. + * Model context window in tokens. Always filled by the Worker greeting. */ context_window: number, /** @@ -81,15 +81,15 @@ timestamp_ms: number, }; export type Segment = { "kind": "text", content: string, } | { "kind": "paste", id: number, chars: number, lines: number, content: string, } | { "kind": "file_ref", path: string, } | { "kind": "knowledge_ref", slug: string, } | { "kind": "workflow_invoke", slug: string, } | { "kind": "unknown" }; -export type PodEvent = { "kind": "turn_ended", pod_name: string, } | { "kind": "errored", pod_name: string, message: string, } | { "kind": "shut_down", pod_name: string, } | { "kind": "scope_sub_delegated", +export type WorkerEvent = { "kind": "turn_ended", worker_name: string, } | { "kind": "errored", worker_name: string, message: string, } | { "kind": "shut_down", worker_name: string, } | { "kind": "scope_sub_delegated", /** - * Sub-delegating Pod (= the sender itself). + * Sub-delegating Worker (= the sender itself). */ -parent_pod: string, +parent_worker: string, /** - * Name of the grandchild Pod. + * Name of the grandchild Worker. */ -sub_pod: string, +sub_worker: string, /** * Unix-socket path where the grandchild is reachable. */ @@ -99,7 +99,7 @@ sub_socket: string, */ scope: Array, }; -export type Method = { "method": "run", "params": { input: Array, } } | { "method": "notify", "params": { message: string, auto_run?: boolean, } } | { "method": "pod_event", "params": PodEvent } | { "method": "resume" } | { "method": "cancel" } | { "method": "pause" } | { "method": "compact" } | { "method": "list_rewind_targets" } | { "method": "rewind_to", "params": { target: RewindTargetId, expected_head_entries: number, } } | { "method": "shutdown" } | { "method": "list_completions", "params": { kind: CompletionKind, prefix: string, } } | { "method": "list_pods" } | { "method": "restore_pod", "params": { name: string, } } | { "method": "register_peer", "params": { name: string, } }; +export type Method = { "method": "run", "params": { input: Array, } } | { "method": "notify", "params": { message: string, auto_run?: boolean, } } | { "method": "worker_event", "params": WorkerEvent } | { "method": "resume" } | { "method": "cancel" } | { "method": "pause" } | { "method": "compact" } | { "method": "list_rewind_targets" } | { "method": "rewind_to", "params": { target: RewindTargetId, expected_head_entries: number, } } | { "method": "shutdown" } | { "method": "list_completions", "params": { kind: CompletionKind, prefix: string, } } | { "method": "list_workers" } | { "method": "restore_worker", "params": { name: string, } } | { "method": "register_peer", "params": { name: string, } }; export type Event = { "event": "user_message", "data": { segments: Array, } } | { "event": "system_item", "data": { item: unknown, } } | { "event": "invoke_start", "data": { kind: InvokeKind, } } | { "event": "turn_start", "data": { turn: number, } } | { "event": "turn_end", "data": { turn: number, result: TurnResult, } } | { "event": "llm_call_start", "data": { llm_call: number, } } | { "event": "llm_call_end", "data": { llm_call: number, } } | { "event": "llm_retry", "data": { llm_call: number, /** @@ -115,9 +115,9 @@ summary: string, * Full tool output. Absent when the tool chose to return * summary-only, or when the result was pruned. */ -output?: string | null, is_error: boolean, } } | { "event": "usage", "data": { input_tokens: number | null, output_tokens: number | null, cache_read_input_tokens?: number | null, } } | { "event": "run_end", "data": { result: RunResult, } } | { "event": "error", "data": { code: ErrorCode, message: string, } } | { "event": "snapshot", "data": { entries: Array, greeting: Greeting, status: PodStatus, +output?: string | null, is_error: boolean, } } | { "event": "usage", "data": { input_tokens: number | null, output_tokens: number | null, cache_read_input_tokens?: number | null, } } | { "event": "run_end", "data": { result: RunResult, } } | { "event": "error", "data": { code: ErrorCode, message: string, } } | { "event": "snapshot", "data": { entries: Array, greeting: Greeting, status: WorkerStatus, /** * Unfinished model output that has already streamed in the current * run but is not yet represented by committed snapshot entries. */ -in_flight?: InFlightSnapshot, } } | { "event": "segment_rotated", "data": { entry: unknown, } } | { "event": "status", "data": { status: PodStatus, } } | { "event": "completions", "data": { kind: CompletionKind, entries: Array, } } | { "event": "rewind_targets", "data": { head_entries: number, targets: Array, } } | { "event": "rewind_applied", "data": { entries: Array, input: Array, summary: RewindSummary, } } | { "event": "pods_listed", "data": { pods: unknown, } } | { "event": "pod_restored", "data": { result: unknown, } } | { "event": "peer_registered", "data": { result: unknown, } } | { "event": "alert", "data": Alert } | { "event": "memory_worker", "data": MemoryWorkerEvent } | { "event": "compact_start" } | { "event": "compact_done", "data": { new_segment_id: string, } } | { "event": "compact_failed", "data": { error: string, } } | { "event": "shutdown" }; +in_flight?: InFlightSnapshot, } } | { "event": "segment_rotated", "data": { entry: unknown, } } | { "event": "status", "data": { status: WorkerStatus, } } | { "event": "completions", "data": { kind: CompletionKind, entries: Array, } } | { "event": "rewind_targets", "data": { head_entries: number, targets: Array, } } | { "event": "rewind_applied", "data": { entries: Array, input: Array, summary: RewindSummary, } } | { "event": "workers_listed", "data": { workers: unknown, } } | { "event": "worker_restored", "data": { result: unknown, } } | { "event": "peer_registered", "data": { result: unknown, } } | { "event": "alert", "data": Alert } | { "event": "memory_worker", "data": MemoryWorkerEvent } | { "event": "compact_start" } | { "event": "compact_done", "data": { new_segment_id: string, } } | { "event": "compact_failed", "data": { error: string, } } | { "event": "shutdown" };