fix: align worker rename followups
This commit is contained in:
parent
6c59fe927b
commit
ebf50baa94
|
|
@ -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 周辺を次に触るときに責務境界を再整理。
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
})?;
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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 <worker-name>` 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
|
||||
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
</system-reminder>
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
||||
|
|
|
|||
|
|
@ -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 を進める。
|
||||
|
|
|
|||
|
|
@ -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<InFlightBlock>, };
|
||||
|
||||
export type Greeting = { pod_name: string, cwd: string, provider: string, model: string, scope_summary: string, tools: Array<string>,
|
||||
export type Greeting = { worker_name: string, cwd: string, provider: string, model: string, scope_summary: string, tools: Array<string>,
|
||||
/**
|
||||
* 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<ScopeRule>, };
|
||||
|
||||
export type Method = { "method": "run", "params": { input: Array<Segment>, } } | { "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<Segment>, } } | { "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<Segment>, } } | { "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<unknown>, 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<unknown>, 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<CompletionEntry>, } } | { "event": "rewind_targets", "data": { head_entries: number, targets: Array<RewindTarget>, } } | { "event": "rewind_applied", "data": { entries: Array<unknown>, input: Array<Segment>, 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<CompletionEntry>, } } | { "event": "rewind_targets", "data": { head_entries: number, targets: Array<RewindTarget>, } } | { "event": "rewind_applied", "data": { entries: Array<unknown>, input: Array<Segment>, 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" };
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user