From 17a9488a4aa0a3dc83be2d3360b6ffd8ffcaeb5a Mon Sep 17 00:00:00 2001 From: Hare Date: Mon, 29 Jun 2026 04:39:27 +0900 Subject: [PATCH] refactor: remove old pod crates --- Cargo.lock | 31 +---- Cargo.toml | 6 - crates/client/README.md | 2 +- crates/llm-engine/README.md | 2 +- crates/manifest/src/paths.rs | 18 +-- crates/manifest/src/scope.rs | 2 +- crates/pod-registry/Cargo.toml | 17 --- crates/pod-registry/README.md | 30 ----- crates/pod-registry/src/lib.rs | 37 ------ crates/pod-store/Cargo.toml | 15 --- crates/pod-store/README.md | 30 ----- crates/protocol/README.md | 2 +- crates/protocol/src/lib.rs | 2 +- crates/session-store/README.md | 4 +- crates/session-store/src/lib.rs | 6 + .../src/worker_metadata.rs} | 109 ++++++++--------- crates/tui/Cargo.toml | 3 +- crates/tui/README.md | 2 +- crates/tui/src/console/mod.rs | 4 +- crates/tui/src/dashboard/mod.rs | 15 +-- crates/tui/src/picker.rs | 23 ++-- crates/tui/src/worker_list.rs | 114 ++++++++++++------ crates/worker/Cargo.toml | 2 - crates/worker/README.md | 4 +- crates/worker/examples/worker_cli.rs | 2 +- crates/worker/examples/worker_protocol.rs | 2 +- crates/worker/src/controller.rs | 13 +- crates/worker/src/discovery.rs | 40 +++--- crates/worker/src/entrypoint.rs | 16 +-- crates/worker/src/ipc/event.rs | 2 +- crates/worker/src/runtime/mod.rs | 2 +- .../worker/src/runtime/worker_allocation.rs | 29 +++++ .../runtime/worker_allocation}/conflict.rs | 8 +- .../src/runtime/worker_allocation}/error.rs | 4 +- .../runtime/worker_allocation}/lifecycle.rs | 24 ++-- .../src/runtime/worker_allocation}/mutate.rs | 16 +-- .../src/runtime/worker_allocation}/table.rs | 18 +-- .../runtime/worker_allocation}/test_util.rs | 8 +- crates/worker/src/runtime_adapter.rs | 32 ++--- crates/worker/src/spawn/registry.rs | 18 +-- crates/worker/src/spawn/tool.rs | 24 ++-- crates/worker/src/ticket_event_notify.rs | 6 +- crates/worker/src/worker.rs | 42 +++---- crates/worker/tests/compact_events_test.rs | 2 +- crates/worker/tests/consolidation_test.rs | 2 +- crates/worker/tests/controller_test.rs | 2 +- crates/worker/tests/restore_test.rs | 4 +- crates/worker/tests/session_metrics_test.rs | 2 +- crates/worker/tests/spawn_worker_test.rs | 14 +-- .../tests/system_prompt_template_test.rs | 2 +- crates/worker/tests/worker_comm_tools_test.rs | 10 +- crates/worker/tests/worker_events_test.rs | 8 +- crates/yoi/Cargo.toml | 1 - crates/yoi/src/session_cli.rs | 20 +-- crates/yoi/src/worker_cleanup_cli.rs | 41 +++++-- package.nix | 2 +- 56 files changed, 415 insertions(+), 481 deletions(-) delete mode 100644 crates/pod-registry/Cargo.toml delete mode 100644 crates/pod-registry/README.md delete mode 100644 crates/pod-registry/src/lib.rs delete mode 100644 crates/pod-store/Cargo.toml delete mode 100644 crates/pod-store/README.md rename crates/{pod-store/src/lib.rs => session-store/src/worker_metadata.rs} (88%) create mode 100644 crates/worker/src/runtime/worker_allocation.rs rename crates/{pod-registry/src => worker/src/runtime/worker_allocation}/conflict.rs (97%) rename crates/{pod-registry/src => worker/src/runtime/worker_allocation}/error.rs (90%) rename crates/{pod-registry/src => worker/src/runtime/worker_allocation}/lifecycle.rs (94%) rename crates/{pod-registry/src => worker/src/runtime/worker_allocation}/mutate.rs (98%) rename crates/{pod-registry/src => worker/src/runtime/worker_allocation}/table.rs (94%) rename crates/{pod-registry/src => worker/src/runtime/worker_allocation}/test_util.rs (93%) diff --git a/Cargo.lock b/Cargo.lock index 8f9f2ccc..203bf133 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2880,31 +2880,6 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6" -[[package]] -name = "pod-registry" -version = "0.1.0" -dependencies = [ - "fs4", - "libc", - "manifest", - "serde", - "serde_json", - "session-store", - "tempfile", - "thiserror 2.0.18", -] - -[[package]] -name = "pod-store" -version = "0.1.0" -dependencies = [ - "serde", - "serde_json", - "session-store", - "tempfile", - "thiserror 2.0.18", -] - [[package]] name = "pom" version = "1.1.0" @@ -4688,11 +4663,10 @@ dependencies = [ "base64", "client", "crossterm 0.28.1", + "fs4", "llm-engine", "manifest", "minijinja", - "pod-registry", - "pod-store", "protocol", "provider", "pulldown-cmark", @@ -5910,8 +5884,6 @@ dependencies = [ "mcp", "memory", "minijinja", - "pod-registry", - "pod-store", "protocol", "provider", "reqwest", @@ -5994,7 +5966,6 @@ dependencies = [ "client", "manifest", "memory", - "pod-store", "project-record", "serde", "serde_json", diff --git a/Cargo.toml b/Cargo.toml index 51e91e5f..da9ab790 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,10 +12,8 @@ members = [ "crates/worker-runtime", "crates/plugin-pdk", "crates/yoi", - "crates/pod-store", "crates/protocol", "crates/provider", - "crates/pod-registry", "crates/session-metrics", "crates/session-analytics", "crates/lint-common", @@ -40,10 +38,8 @@ default-members = [ "crates/worker-runtime", "crates/plugin-pdk", "crates/yoi", - "crates/pod-store", "crates/protocol", "crates/provider", - "crates/pod-registry", "crates/session-metrics", "crates/session-analytics", "crates/lint-common", @@ -75,8 +71,6 @@ worker = { path = "crates/worker" } worker-runtime = { path = "crates/worker-runtime" } yoi-plugin-pdk = { path = "crates/plugin-pdk" } yoi = { path = "crates/yoi" } -pod-registry = { path = "crates/pod-registry" } -pod-store = { path = "crates/pod-store" } protocol = { path = "crates/protocol" } provider = { path = "crates/provider" } session-metrics = { path = "crates/session-metrics" } diff --git a/crates/client/README.md b/crates/client/README.md index 54526a10..4de987ef 100644 --- a/crates/client/README.md +++ b/crates/client/README.md @@ -16,7 +16,7 @@ Owns: Does not own: - product command names (`yoi`) -- Worker state authority (`worker`, `pod-store`, `session-store`) +- Worker state authority (`worker`, `session-store` worker metadata) - UI rendering (`tui`) - Engine turn semantics (`llm-engine`) diff --git a/crates/llm-engine/README.md b/crates/llm-engine/README.md index 4e842ff4..19db5846 100644 --- a/crates/llm-engine/README.md +++ b/crates/llm-engine/README.md @@ -19,7 +19,7 @@ Does not own: - Worker names, sockets, process lifecycle, or scope delegation (`worker`) - product CLI shape (`yoi`) - provider catalog and secret resolution (`provider`, `secrets`) -- durable Worker current state (`pod-store`) +- durable Worker current state (`session-store` worker metadata) ## Design notes diff --git a/crates/manifest/src/paths.rs b/crates/manifest/src/paths.rs index 188b570e..96f77cb6 100644 --- a/crates/manifest/src/paths.rs +++ b/crates/manifest/src/paths.rs @@ -88,9 +88,9 @@ pub fn sessions_dir() -> Option { sessions_dir_from_data_dir(data_dir()) } -/// `/workers.json` — machine-wide Worker allocation registry。 -pub fn pod_registry_path() -> Option { - pod_registry_path_from_runtime_dir(runtime_dir()) +/// `/workers.json` — machine-wide Worker allocation table。 +pub fn worker_allocation_path() -> Option { + worker_allocation_path_from_runtime_dir(runtime_dir()) } /// `//` — Worker ごとのランタイムディレクトリ。 @@ -104,8 +104,8 @@ pub fn worker_runtime_dir(worker_name: &str) -> Option { /// `RuntimeDir::socket_path()` で、Worker 名が分かっている外部 (TUI の /// attach フロー等) からの**予測**はこの関数で行う。両者は同じパス /// を返すことが期待される。 -pub fn pod_socket_path(worker_name: &str) -> Option { - pod_socket_path_from_runtime_dir(runtime_dir(), worker_name) +pub fn worker_socket_path(worker_name: &str) -> Option { + worker_socket_path_from_runtime_dir(runtime_dir(), worker_name) } // ---- internals -------------------------------------------------------------- @@ -183,7 +183,7 @@ fn sessions_dir_from_data_dir(data_dir: Option) -> Option { Some(data_dir?.join("sessions")) } -fn pod_registry_path_from_runtime_dir(runtime_dir: Option) -> Option { +fn worker_allocation_path_from_runtime_dir(runtime_dir: Option) -> Option { Some(runtime_dir?.join("workers.json")) } @@ -194,7 +194,7 @@ fn worker_runtime_dir_from_runtime_dir( Some(runtime_dir?.join(worker_name)) } -fn pod_socket_path_from_runtime_dir( +fn worker_socket_path_from_runtime_dir( runtime_dir: Option, worker_name: &str, ) -> Option { @@ -396,7 +396,7 @@ mod tests { PathBuf::from("/sand/sessions") ); assert_eq!( - pod_registry_path_from_runtime_dir(runtime_dir.clone()).unwrap(), + worker_allocation_path_from_runtime_dir(runtime_dir.clone()).unwrap(), PathBuf::from("/sand/run/workers.json") ); assert_eq!( @@ -404,7 +404,7 @@ mod tests { PathBuf::from("/sand/run/foo") ); assert_eq!( - pod_socket_path_from_runtime_dir(runtime_dir, "foo").unwrap(), + worker_socket_path_from_runtime_dir(runtime_dir, "foo").unwrap(), PathBuf::from("/sand/run/foo/sock") ); } diff --git a/crates/manifest/src/scope.rs b/crates/manifest/src/scope.rs index d482470c..5e01d56a 100644 --- a/crates/manifest/src/scope.rs +++ b/crates/manifest/src/scope.rs @@ -266,7 +266,7 @@ impl Scope { /// Allow rules with their targets resolved to absolute paths. /// - /// Used by the pod-registry, where every Worker's allocation + /// Used by the worker-allocation, where every Worker's allocation /// must be expressed in absolute terms so prefix comparisons are /// meaningful across processes. pub fn allow_rules(&self) -> Vec { diff --git a/crates/pod-registry/Cargo.toml b/crates/pod-registry/Cargo.toml deleted file mode 100644 index d659e626..00000000 --- a/crates/pod-registry/Cargo.toml +++ /dev/null @@ -1,17 +0,0 @@ -[package] -name = "pod-registry" -version = "0.1.0" -edition.workspace = true -license.workspace = true - -[dependencies] -fs4 = { workspace = true, features = ["sync"] } -libc = { workspace = true } -manifest = { workspace = true } -serde = { workspace = true, features = ["derive"] } -serde_json = { workspace = true } -session-store = { workspace = true } -thiserror = { workspace = true } - -[dev-dependencies] -tempfile = { workspace = true } diff --git a/crates/pod-registry/README.md b/crates/pod-registry/README.md deleted file mode 100644 index 28a81497..00000000 --- a/crates/pod-registry/README.md +++ /dev/null @@ -1,30 +0,0 @@ -# pod-registry - -## Role - -`pod-registry` is the legacy-named crate that tracks live Worker process ownership and delegated scope locks at runtime. - -## Boundaries - -Owns: - -- machine-local live Worker registration -- collision detection for running Worker names -- delegated scope lock bookkeeping -- registry cleanup hooks for stopped or unreachable children - -Does not own: - -- durable Worker metadata (`pod-store`) -- replayable session logs (`session-store`) -- socket protocol definitions (`protocol`) -- project work item state - -## Design notes - -The registry is a runtime coordination mechanism. It can help decide whether a Worker is live or colliding, but durable visibility/restoration should be backed by Worker metadata when possible. - -## See also - -- [`../../docs/design/worker-session-state.md`](../../docs/design/worker-session-state.md) -- [`../../docs/design/tool-permissions-scope.md`](../../docs/design/tool-permissions-scope.md) diff --git a/crates/pod-registry/src/lib.rs b/crates/pod-registry/src/lib.rs deleted file mode 100644 index 02514ec1..00000000 --- a/crates/pod-registry/src/lib.rs +++ /dev/null @@ -1,37 +0,0 @@ -//! Machine-wide Worker allocation registry. -//! -//! A single JSON file at `/workers.json` records every live -//! Worker's allocation (see [`manifest::paths::pod_registry_path`] for -//! how the path is resolved). File-level `flock(2)` serialises access -//! across processes so spawn sequences from unrelated Workers can't race. -//! -//! Each Worker, when starting, acquires the lock, reclaims stale entries -//! (Workers whose PID has died), checks that its requested write scope -//! does not overlap any other allocation's effective write scope, and -//! registers itself. When it exits normally, it removes its entry and -//! returns delegated scope to its `delegated_from` parent. Crash -//! recovery rides on the next Worker that opens the file — no background -//! reaper. - -mod conflict; -mod error; -mod lifecycle; -mod mutate; -mod table; - -#[cfg(test)] -mod test_util; - -pub use conflict::{ - ConflictOwner, find_conflict_owner, find_conflict_owners, is_within_effective_write, -}; -pub use error::ScopeLockError; -pub use lifecycle::{ - ScopeAllocationGuard, SegmentLockInfo, adopt_allocation, install_top_level, - install_top_level_with_deny, lookup_segment, update_segment, -}; -pub use mutate::{ - delegate_scope, reclaim_delegated_scope, reclaim_stale, reclaim_stale_with, register_worker, - register_worker_with_deny, release_worker, -}; -pub use table::{Allocation, LockFile, LockFileGuard, default_registry_path}; diff --git a/crates/pod-store/Cargo.toml b/crates/pod-store/Cargo.toml deleted file mode 100644 index 2488035d..00000000 --- a/crates/pod-store/Cargo.toml +++ /dev/null @@ -1,15 +0,0 @@ -[package] -name = "pod-store" -description = "Legacy-named durable Worker metadata/state persistence" -version = "0.1.0" -edition.workspace = true -license.workspace = true - -[dependencies] -session-store = { workspace = true } -serde = { workspace = true, features = ["derive"] } -serde_json = { workspace = true } -thiserror = { workspace = true } - -[dev-dependencies] -tempfile = { workspace = true } diff --git a/crates/pod-store/README.md b/crates/pod-store/README.md deleted file mode 100644 index 29f25ef0..00000000 --- a/crates/pod-store/README.md +++ /dev/null @@ -1,30 +0,0 @@ -# pod-store - -## Role - -`pod-store` is the legacy-named crate that owns current Worker metadata keyed by Worker name. - -## Boundaries - -Owns: - -- persisted Worker metadata files -- current active/pending session pointers -- resolved manifest snapshots for restoration -- parent-visible spawned-child metadata -- restoration labels and diagnostics derived from metadata - -Does not own: - -- replayable conversation logs (`session-store`) -- live process locks or socket reachability (`pod-registry`, `client`) -- product CLI behavior (`yoi`) -- model turn execution (`llm-engine`) - -## Design notes - -Worker metadata is intentionally thin. It should answer current-state questions without duplicating transcripts or becoming a second session log. - -## See also - -- [`../../docs/design/worker-session-state.md`](../../docs/design/worker-session-state.md) diff --git a/crates/protocol/README.md b/crates/protocol/README.md index 6222866a..f582d3d9 100644 --- a/crates/protocol/README.md +++ b/crates/protocol/README.md @@ -17,7 +17,7 @@ Does not own: - Unix socket implementation details (`client`, `worker`) - TUI rendering (`tui`) - Engine history semantics (`llm-engine`) -- durable storage (`session-store`, `pod-store`) +- durable storage (`session-store`, `session-store` worker metadata) ## Design notes diff --git a/crates/protocol/src/lib.rs b/crates/protocol/src/lib.rs index 3e3a35bf..2aaaad50 100644 --- a/crates/protocol/src/lib.rs +++ b/crates/protocol/src/lib.rs @@ -99,7 +99,7 @@ pub enum Method { /// /// Delivered as `Method::WorkerEvent` over the parent's Unix socket. The /// parent Controller always applies variant-specific side effects -/// (registry / pod-registry updates). Agent-visible variants are also +/// (registry / worker-allocation updates). Agent-visible variants are also /// queued into the notification buffer; control-plane-only variants are /// not injected into the parent's LLM context. /// diff --git a/crates/session-store/README.md b/crates/session-store/README.md index 158332c0..87f63174 100644 --- a/crates/session-store/README.md +++ b/crates/session-store/README.md @@ -15,8 +15,8 @@ Owns: Does not own: -- current Worker-name metadata (`pod-store`) -- live process/socket discovery (`pod-registry`, `client`) +- current Worker-name metadata (`session-store` worker metadata) +- live process/socket discovery (`worker-allocation`, `client`) - UI state (`tui`) - generated memory summaries (`memory`) diff --git a/crates/session-store/src/lib.rs b/crates/session-store/src/lib.rs index 2cb08968..d1fe855b 100644 --- a/crates/session-store/src/lib.rs +++ b/crates/session-store/src/lib.rs @@ -37,6 +37,7 @@ pub mod segment; pub mod segment_log; pub mod store; pub mod system_item; +pub mod worker_metadata; pub use event_trace::{TraceEntry, TracePayload}; pub use fs_store::FsStore; @@ -52,6 +53,11 @@ pub use segment::{ pub use segment_log::{LogEntry, RestoredState, SegmentOrigin, collect_state}; pub use store::{Store, StoreError}; pub use system_item::{SystemItem, SystemReminder, SystemReminderSource, render_worker_event}; +pub use worker_metadata::{ + CombinedStore, FsWorkerStore, WorkerActiveSegmentRef, WorkerMetadata, WorkerMetadataStore, + WorkerPeer, WorkerReclaimedChild, WorkerSpawnedChild, WorkerSpawnedScopeRule, WorkerStoreError, + validate_worker_name, +}; /// Session identifier — the fork-tree root. UUID v7 (time-ordered). /// diff --git a/crates/pod-store/src/lib.rs b/crates/session-store/src/worker_metadata.rs similarity index 88% rename from crates/pod-store/src/lib.rs rename to crates/session-store/src/worker_metadata.rs index 12bbf3cf..5e538d87 100644 --- a/crates/pod-store/src/lib.rs +++ b/crates/session-store/src/worker_metadata.rs @@ -12,8 +12,8 @@ //! model remain session JSONL history. Socket and callback paths are last-known //! runtime hints, not proof of liveness. +use crate::{SegmentId, SessionId}; use serde::{Deserialize, Serialize}; -use session_store::{SegmentId, SessionId}; use std::fs; use std::path::PathBuf; @@ -26,8 +26,8 @@ pub enum WorkerStoreError { #[error("serialization error: {0}")] Serde(#[from] serde_json::Error), - #[error("invalid pod name: {0}")] - InvalidPodName(String), + #[error("invalid worker name: {0}")] + InvalidWorkerName(String), } /// Active Session/Segment pointer for a Worker. @@ -284,13 +284,13 @@ impl FsWorkerStore { Ok(Self { root }) } - fn pod_dir(&self, worker_name: &str) -> Result { + fn worker_dir(&self, worker_name: &str) -> Result { validate_worker_name(worker_name)?; Ok(self.root.join(worker_name)) } fn metadata_path(&self, worker_name: &str) -> Result { - Ok(self.pod_dir(worker_name)?.join("metadata.json")) + Ok(self.worker_dir(worker_name)?.join("metadata.json")) } } @@ -364,7 +364,7 @@ pub fn validate_worker_name(worker_name: &str) -> Result<(), WorkerStoreError> { || worker_name.contains('/') || worker_name.contains('\0') { - return Err(WorkerStoreError::InvalidPodName(worker_name.to_string())); + return Err(WorkerStoreError::InvalidWorkerName(worker_name.to_string())); } Ok(()) } @@ -372,61 +372,58 @@ pub fn validate_worker_name(worker_name: &str) -> Result<(), WorkerStoreError> { /// Convenience composition for callers that want one handle carrying separate /// session-log and Worker-state roots. #[derive(Clone)] -pub struct CombinedStore { +pub struct CombinedStore { pub session_store: S, - pub pod_store: P, + pub worker_metadata_store: W, } -impl CombinedStore { - pub fn new(session_store: S, pod_store: P) -> Self { +impl CombinedStore { + pub fn new(session_store: S, worker_metadata_store: W) -> Self { Self { session_store, - pod_store, + worker_metadata_store, } } } -impl session_store::Store for CombinedStore +impl crate::Store for CombinedStore where - S: session_store::Store, - P: Send + Sync, + S: crate::Store, + W: Send + Sync, { fn append( &self, session_id: SessionId, segment_id: SegmentId, - entry: &session_store::LogEntry, - ) -> Result<(), session_store::StoreError> { + entry: &crate::LogEntry, + ) -> Result<(), crate::StoreError> { self.session_store.append(session_id, segment_id, entry) } fn read_all( &self, session_id: SessionId, segment_id: SegmentId, - ) -> Result, session_store::StoreError> { + ) -> Result, crate::StoreError> { self.session_store.read_all(session_id, segment_id) } - fn list_sessions(&self) -> Result, session_store::StoreError> { + fn list_sessions(&self) -> Result, crate::StoreError> { self.session_store.list_sessions() } - fn list_segments( - &self, - session_id: SessionId, - ) -> Result, session_store::StoreError> { + fn list_segments(&self, session_id: SessionId) -> Result, crate::StoreError> { self.session_store.list_segments(session_id) } fn lookup_session_of( &self, segment_id: SegmentId, - ) -> Result, session_store::StoreError> { + ) -> Result, crate::StoreError> { self.session_store.lookup_session_of(segment_id) } fn create_segment( &self, session_id: SessionId, segment_id: SegmentId, - entries: &[session_store::LogEntry], - ) -> Result<(), session_store::StoreError> { + entries: &[crate::LogEntry], + ) -> Result<(), crate::StoreError> { self.session_store .create_segment(session_id, segment_id, entries) } @@ -434,7 +431,7 @@ where &self, session_id: SessionId, segment_id: SegmentId, - ) -> Result { + ) -> Result { self.session_store.exists(session_id, segment_id) } fn truncate( @@ -442,7 +439,7 @@ where session_id: SessionId, segment_id: SegmentId, entries_len: usize, - ) -> Result<(), session_store::StoreError> { + ) -> Result<(), crate::StoreError> { self.session_store .truncate(session_id, segment_id, entries_len) } @@ -450,39 +447,39 @@ where &self, session_id: SessionId, segment_id: SegmentId, - ) -> Result { + ) -> Result { self.session_store.read_entry_count(session_id, segment_id) } fn append_trace( &self, session_id: SessionId, segment_id: SegmentId, - entry: &session_store::TraceEntry, - ) -> Result<(), session_store::StoreError> { + entry: &crate::TraceEntry, + ) -> Result<(), crate::StoreError> { self.session_store .append_trace(session_id, segment_id, entry) } } -impl WorkerMetadataStore for CombinedStore +impl WorkerMetadataStore for CombinedStore where S: Send + Sync, - P: WorkerMetadataStore, + W: WorkerMetadataStore, { fn write(&self, metadata: &WorkerMetadata) -> Result<(), WorkerStoreError> { - self.pod_store.write(metadata) + self.worker_metadata_store.write(metadata) } fn read_by_name(&self, worker_name: &str) -> Result, WorkerStoreError> { - self.pod_store.read_by_name(worker_name) + self.worker_metadata_store.read_by_name(worker_name) } fn list_names(&self) -> Result, WorkerStoreError> { - self.pod_store.list_names() + self.worker_metadata_store.list_names() } fn root_dir(&self) -> Option { - self.pod_store.root_dir() + self.worker_metadata_store.root_dir() } fn delete_by_name(&self, worker_name: &str) -> Result<(), WorkerStoreError> { - self.pod_store.delete_by_name(worker_name) + self.worker_metadata_store.delete_by_name(worker_name) } } @@ -491,15 +488,15 @@ mod tests { use super::*; #[test] - fn pod_metadata_manifest_snapshot_roundtrips() { + fn worker_metadata_manifest_snapshot_roundtrips() { let mut metadata = WorkerMetadata::new( - "profile-pod", + "profile-worker", Some(WorkerActiveSegmentRef::pending_segment( - session_store::new_session_id(), + crate::new_session_id(), )), ); metadata.resolved_manifest_snapshot = Some(serde_json::json!({ - "pod": { "name": "profile-pod" }, + "worker": { "name": "profile-worker" }, "profile": { "source": { "kind": "path", "path": "/profiles/coder.lua" } } })); @@ -510,22 +507,22 @@ mod tests { } #[test] - fn fs_store_writes_under_pod_state_root_only() { + fn fs_store_writes_under_worker_state_root_only() { let tmp = tempfile::TempDir::new().unwrap(); let session_root = tmp.path().join("sessions"); - let pod_root = tmp.path().join("workers"); + let worker_root = tmp.path().join("workers"); fs::create_dir_all(&session_root).unwrap(); - let store = FsWorkerStore::new(&pod_root).unwrap(); + let store = FsWorkerStore::new(&worker_root).unwrap(); store .write(&WorkerMetadata::new( "agent", Some(WorkerActiveSegmentRef::pending_segment( - session_store::new_session_id(), + crate::new_session_id(), )), )) .unwrap(); - assert!(pod_root.join("agent/metadata.json").exists()); + assert!(worker_root.join("agent/metadata.json").exists()); assert!(!session_root.join("workers/agent/metadata.json").exists()); } @@ -540,16 +537,16 @@ mod tests { scope_delegated: vec![], callback_address: std::path::Path::new("/tmp/parent.sock").into(), }); - metadata.resolved_manifest_snapshot = Some(serde_json::json!({"pod":{"name":"agent"}})); + metadata.resolved_manifest_snapshot = Some(serde_json::json!({"worker":{"name":"agent"}})); store.write(&metadata).unwrap(); - let snapshot = serde_json::json!({"pod":{"name":"updated"}}); + let snapshot = serde_json::json!({"worker":{"name":"updated"}}); store .set_active( "agent", Some(WorkerActiveSegmentRef::active_segment( - session_store::new_session_id(), - session_store::new_segment_id(), + crate::new_session_id(), + crate::new_segment_id(), )), Some(snapshot.clone()), ) @@ -564,10 +561,10 @@ mod tests { let tmp = tempfile::TempDir::new().unwrap(); let store = FsWorkerStore::new(tmp.path()).unwrap(); let active = WorkerActiveSegmentRef::active_segment( - session_store::new_session_id(), - session_store::new_segment_id(), + crate::new_session_id(), + crate::new_segment_id(), ); - let snapshot = serde_json::json!({"pod":{"name":"agent"}}); + let snapshot = serde_json::json!({"worker":{"name":"agent"}}); store .set_active("agent", Some(active.clone()), Some(snapshot.clone())) .unwrap(); @@ -592,10 +589,10 @@ mod tests { let tmp = tempfile::TempDir::new().unwrap(); let store = FsWorkerStore::new(tmp.path()).unwrap(); let active = WorkerActiveSegmentRef::active_segment( - session_store::new_session_id(), - session_store::new_segment_id(), + crate::new_session_id(), + crate::new_segment_id(), ); - let snapshot = serde_json::json!({"pod":{"name":"agent"}}); + let snapshot = serde_json::json!({"worker":{"name":"agent"}}); store .set_active("agent", Some(active.clone()), Some(snapshot.clone())) .unwrap(); diff --git a/crates/tui/Cargo.toml b/crates/tui/Cargo.toml index 1389200f..7af42fd1 100644 --- a/crates/tui/Cargo.toml +++ b/crates/tui/Cargo.toml @@ -22,8 +22,7 @@ toml = { workspace = true } manifest = { workspace = true } secrets = { workspace = true } session-store = { workspace = true } -pod-store = { workspace = true } -pod-registry = { workspace = true } +fs4 = { workspace = true } provider = { workspace = true } ticket = { workspace = true } serde = { workspace = true, features = ["derive"] } diff --git a/crates/tui/README.md b/crates/tui/README.md index 6d50a42a..9b70d54d 100644 --- a/crates/tui/README.md +++ b/crates/tui/README.md @@ -16,7 +16,7 @@ Owns: Does not own: - durable transcript authority (`session-store`) -- Worker current state (`pod-store`) +- Worker current state (`session-store` worker metadata) - Worker lifecycle policy (`worker`) - product CLI ownership (`yoi`) diff --git a/crates/tui/src/console/mod.rs b/crates/tui/src/console/mod.rs index a8a9516d..e447a80f 100644 --- a/crates/tui/src/console/mod.rs +++ b/crates/tui/src/console/mod.rs @@ -132,7 +132,7 @@ fn resolve_socket(worker_name: &str, override_path: Option) -> PathBuf if let Some(p) = override_path { return p; } - manifest::paths::pod_socket_path(worker_name).unwrap_or_else(|| { + manifest::paths::worker_socket_path(worker_name).unwrap_or_else(|| { PathBuf::from("/tmp") .join("yoi") .join(worker_name) @@ -317,7 +317,7 @@ async fn connect_live_pod( if !allow_registry_fallback { return None; } - let registry_socket = picker::live_socket_for_pod(worker_name)?; + let registry_socket = picker::live_socket_for_worker(worker_name)?; if registry_socket == preferred_socket { return None; } diff --git a/crates/tui/src/dashboard/mod.rs b/crates/tui/src/dashboard/mod.rs index 1b46d84b..3426cb5a 100644 --- a/crates/tui/src/dashboard/mod.rs +++ b/crates/tui/src/dashboard/mod.rs @@ -19,7 +19,6 @@ use crossterm::event::{ Event as TermEvent, KeyCode, KeyEvent, KeyModifiers, MouseButton, MouseEvent, MouseEventKind, poll, read, }; -use pod_store::FsWorkerStore; use protocol::stream::{JsonLineReader, JsonLineWriter}; use protocol::{ErrorCode, Event, Method, Segment, WorkerStatus}; use ratatui::Frame; @@ -31,6 +30,7 @@ use ratatui::text::{Line, Span}; use ratatui::widgets::{Block, Borders, Clear, Paragraph, Widget, Wrap}; use serde::Serialize; use session_store::FsStore; +use session_store::FsWorkerStore; use ticket::config::{GitBranchName, TicketConfig, TicketOrchestrationConfig}; use ticket::{ LocalTicketBackend, MarkdownText, TicketBackend, TicketIdOrSlug, TicketStateChange, @@ -46,7 +46,7 @@ use crate::role_session_registry::{ }; use crate::worker_list::{ StoredMetadataState, WorkerList, WorkerListEntry, WorkerVisibilitySource, - read_reachable_live_pod_infos, read_stored_worker_infos, + read_reachable_live_worker_infos, read_stored_worker_infos, }; #[cfg(not(feature = "e2e-test"))] use crate::workspace_panel::build_workspace_panel; @@ -522,9 +522,9 @@ fn default_store_dir() -> Result { }) } -fn default_pod_store_dir() -> Result { +fn default_worker_metadata_dir() -> Result { manifest::paths::data_dir() - .map(|dir| dir.join("pods")) + .map(|dir| dir.join("workers")) .ok_or_else(|| { DashboardError::Io(io::Error::new( io::ErrorKind::NotFound, @@ -3423,9 +3423,10 @@ async fn load_worker_list( ) -> Result { let store_dir = default_store_dir()?; let store = FsStore::new(&store_dir)?; - let pod_store = FsWorkerStore::new(default_pod_store_dir()?).map_err(io::Error::other)?; - let stored = read_stored_worker_infos(&store, &pod_store)?; - let live = read_reachable_live_pod_infos(&store) + let worker_metadata_store = + FsWorkerStore::new(default_worker_metadata_dir()?).map_err(io::Error::other)?; + let stored = read_stored_worker_infos(&store, &worker_metadata_store)?; + let live = read_reachable_live_worker_infos(&store) .await .unwrap_or_default(); Ok(WorkerList::from_workspace_sources( diff --git a/crates/tui/src/picker.rs b/crates/tui/src/picker.rs index 5dd428c1..14c6d638 100644 --- a/crates/tui/src/picker.rs +++ b/crates/tui/src/picker.rs @@ -1,7 +1,7 @@ //! Inline-viewport "pick a Worker to attach or restore" UX. //! //! Reads live Worker allocations from the runtime registry and stopped Worker state -//! from the pod-store name-keyed metadata. Picking a live row attaches to +//! from the session-store worker metadata name-keyed metadata. Picking a live row attaches to //! its socket; picking a stopped row restores via the Worker runtime command. use std::io; @@ -9,7 +9,6 @@ use std::path::PathBuf; use std::time::Duration; use crossterm::event::{self, Event as TermEvent, KeyCode, KeyEventKind, KeyModifiers}; -use pod_store::FsWorkerStore; use ratatui::Terminal; use ratatui::backend::CrosstermBackend; use ratatui::layout::{Constraint, Layout}; @@ -18,11 +17,12 @@ use ratatui::text::{Line, Span}; use ratatui::widgets::Paragraph; use ratatui::{Frame, TerminalOptions, Viewport}; use session_store::FsStore; +use session_store::FsWorkerStore; use crate::worker_list::{ LiveWorkerInfo, StoredMetadataState, StoredWorkerInfo, WorkerList, WorkerListEntry, - WorkerVisibilitySource, live_socket_for_pod as worker_list_live_socket_for_pod, - read_reachable_live_pod_infos, read_stored_worker_infos, + WorkerVisibilitySource, live_socket_for_worker as worker_list_live_socket_for_worker, + read_reachable_live_worker_infos, read_stored_worker_infos, }; const MAX_ROWS: usize = 10; @@ -156,9 +156,10 @@ fn list_for_options( pub async fn run(options: PickerOptions) -> Result { let store_dir = default_store_dir()?; let store = FsStore::new(&store_dir)?; - let pod_store = FsWorkerStore::new(default_pod_store_dir()?).map_err(io::Error::other)?; - let stored_workers = read_stored_worker_infos(&store, &pod_store)?; - let live_workers = read_reachable_live_pod_infos(&store) + let worker_metadata_store = + FsWorkerStore::new(default_worker_metadata_dir()?).map_err(io::Error::other)?; + let stored_workers = read_stored_worker_infos(&store, &worker_metadata_store)?; + let live_workers = read_reachable_live_worker_infos(&store) .await .unwrap_or_default(); let mut list = list_for_options(&options, stored_workers, live_workers); @@ -223,9 +224,9 @@ fn default_store_dir() -> Result { }) } -fn default_pod_store_dir() -> Result { +fn default_worker_metadata_dir() -> Result { manifest::paths::data_dir() - .map(|dir| dir.join("pods")) + .map(|dir| dir.join("workers")) .ok_or_else(|| { PickerError::Io(io::Error::new( io::ErrorKind::NotFound, @@ -235,8 +236,8 @@ fn default_pod_store_dir() -> Result { }) } -pub(crate) fn live_socket_for_pod(worker_name: &str) -> Option { - worker_list_live_socket_for_pod(worker_name) +pub(crate) fn live_socket_for_worker(worker_name: &str) -> Option { + worker_list_live_socket_for_worker(worker_name) } fn make_inline_terminal() -> io::Result>> { diff --git a/crates/tui/src/worker_list.rs b/crates/tui/src/worker_list.rs index 79fdd673..14a96d49 100644 --- a/crates/tui/src/worker_list.rs +++ b/crates/tui/src/worker_list.rs @@ -1,13 +1,15 @@ use std::collections::{BTreeMap, BTreeSet}; -use std::io; +use std::fs::File; +use std::io::{self, Read}; use std::path::{Path, PathBuf}; use std::time::Duration; use client::WorkerClient; -use pod_registry::{LockFileGuard, default_registry_path}; -use pod_store::{WorkerActiveSegmentRef, WorkerMetadata, WorkerMetadataStore}; +use manifest::paths; use protocol::{Event, WorkerStatus}; +use serde::Deserialize; use session_store::{FsStore, SegmentId, SessionId}; +use session_store::{WorkerActiveSegmentRef, WorkerMetadata, WorkerMetadataStore}; #[derive(Debug, Clone)] pub(crate) struct WorkerList { @@ -314,11 +316,14 @@ pub(crate) enum WorkerEntryDiagnosticKind { pub(crate) fn read_stored_worker_infos( store: &FsStore, - pod_store: &impl WorkerMetadataStore, + worker_metadata_store: &impl WorkerMetadataStore, ) -> Result, io::Error> { let mut records = Vec::new(); - for worker_name in pod_store.list_names().map_err(io::Error::other)? { - let info = match pod_store.read_by_name(&worker_name) { + for worker_name in worker_metadata_store + .list_names() + .map_err(io::Error::other)? + { + let info = match worker_metadata_store.read_by_name(&worker_name) { Ok(Some(metadata)) => stored_info_from_metadata(store, worker_name, metadata), Ok(None) => corrupt_stored_info( worker_name, @@ -331,16 +336,24 @@ pub(crate) fn read_stored_worker_infos( Ok(records) } -pub(crate) fn read_live_pod_infos() -> Result, io::Error> { - let path = default_registry_path()?; - let guard = LockFileGuard::open(&path)?; - Ok(guard - .data() +pub(crate) fn read_live_worker_infos() -> Result, io::Error> { + let path = paths::worker_allocation_path().ok_or_else(|| { + io::Error::new( + io::ErrorKind::NotFound, + "could not resolve worker allocation path", + ) + })?; + let table = match read_worker_allocation_table(&path) { + Ok(table) => table, + Err(err) if err.kind() == io::ErrorKind::NotFound => return Ok(Vec::new()), + Err(err) => return Err(err), + }; + Ok(table .allocations - .iter() + .into_iter() .map(|allocation| LiveWorkerInfo { - worker_name: allocation.worker_name.clone(), - socket_path: allocation.socket.clone(), + worker_name: allocation.worker_name, + socket_path: allocation.socket, status: None, reachable: false, segment_id: allocation.segment_id, @@ -349,20 +362,49 @@ pub(crate) fn read_live_pod_infos() -> Result, io::Error> { .collect()) } -pub(crate) async fn read_reachable_live_pod_infos( - store: &FsStore, -) -> Result, io::Error> { - let records = read_live_pod_infos()?; - probe_reachable_live_pod_infos(store, records).await +fn read_worker_allocation_table(path: &Path) -> Result { + let mut file = File::open(path)?; + fs4::fs_std::FileExt::lock_shared(&file)?; + let mut contents = String::new(); + let read_result = file.read_to_string(&mut contents); + let unlock_result = fs4::fs_std::FileExt::unlock(&file); + read_result?; + unlock_result?; + + if contents.trim().is_empty() { + return Ok(WorkerAllocationTable::default()); + } + serde_json::from_str(&contents).map_err(io::Error::other) } -async fn probe_reachable_live_pod_infos( +#[derive(Debug, Default, Deserialize)] +struct WorkerAllocationTable { + #[serde(default)] + allocations: Vec, +} + +#[derive(Debug, Deserialize)] +struct WorkerAllocationRecord { + worker_name: String, + socket: PathBuf, + #[serde(default)] + segment_id: Option, +} + +pub(crate) async fn read_reachable_live_worker_infos( + store: &FsStore, +) -> Result, io::Error> { + let records = read_live_worker_infos()?; + probe_reachable_live_worker_infos(store, records).await +} + +async fn probe_reachable_live_worker_infos( _store: &FsStore, records: Vec, ) -> Result, io::Error> { let mut handles = Vec::with_capacity(records.len()); for record in records { - handles.push(tokio::spawn(probe_live_pod_info(record))); + handles.push(tokio::spawn(probe_live_worker_info(record))); } let mut reachable = Vec::with_capacity(handles.len()); @@ -378,15 +420,15 @@ async fn probe_reachable_live_pod_infos( Ok(reachable) } -async fn probe_live_pod_info(mut record: LiveWorkerInfo) -> Result { +async fn probe_live_worker_info(mut record: LiveWorkerInfo) -> Result { let status = probe_live_status(&record.socket_path).await?; record.reachable = true; record.status = status; Ok(record) } -pub(crate) fn live_socket_for_pod(worker_name: &str) -> Option { - read_live_pod_infos() +pub(crate) fn live_socket_for_worker(worker_name: &str) -> Option { + read_live_worker_infos() .ok()? .into_iter() .find(|worker| worker.worker_name == worker_name) @@ -560,10 +602,10 @@ mod tests { use std::sync::Arc; use llm_engine::llm_client::types::RequestConfig; - use pod_store::FsWorkerStore; - use pod_store::{WorkerActiveSegmentRef, WorkerMetadataStore}; use protocol::stream::JsonLineWriter; + use session_store::FsWorkerStore; use session_store::{LogEntry, Store, new_segment_id, new_session_id}; + use session_store::{WorkerActiveSegmentRef, WorkerMetadataStore}; use tempfile::tempdir; use tokio::net::UnixListener; use tokio::sync::Barrier; @@ -877,7 +919,7 @@ mod tests { let records = tokio::time::timeout( LIVE_STATUS_PROBE_TIMEOUT * 3, - probe_reachable_live_pod_infos(&store, records), + probe_reachable_live_worker_infos(&store, records), ) .await .expect("status probes should complete") @@ -907,7 +949,7 @@ mod tests { std::future::pending::<()>().await; }); - let records = probe_reachable_live_pod_infos( + let records = probe_reachable_live_worker_infos( &store, vec![live_probe_record("silent", socket_path.clone())], ) @@ -985,12 +1027,12 @@ mod tests { fn read_stored_worker_infos_reports_corrupt_metadata() { let dir = tempdir().unwrap(); let store = FsStore::new(dir.path()).unwrap(); - let pod_store = FsWorkerStore::new(dir.path().join("pods")).unwrap(); - let pod_dir = dir.path().join("pods").join("broken"); - std::fs::create_dir_all(&pod_dir).unwrap(); - std::fs::write(pod_dir.join("metadata.json"), "{not-json").unwrap(); + let worker_metadata_store = FsWorkerStore::new(dir.path().join("workers")).unwrap(); + let worker_metadata_dir = dir.path().join("workers").join("broken"); + std::fs::create_dir_all(&worker_metadata_dir).unwrap(); + std::fs::write(worker_metadata_dir.join("metadata.json"), "{not-json").unwrap(); - let records = read_stored_worker_infos(&store, &pod_store).unwrap(); + let records = read_stored_worker_infos(&store, &worker_metadata_store).unwrap(); assert_eq!(records.len(), 1); assert_eq!(records[0].worker_name, "broken"); assert!(matches!( @@ -1003,10 +1045,10 @@ mod tests { fn read_stored_worker_infos_reads_metadata() { let dir = tempdir().unwrap(); let store = FsStore::new(dir.path()).unwrap(); - let pod_store = FsWorkerStore::new(dir.path().join("pods")).unwrap(); + let worker_metadata_store = FsWorkerStore::new(dir.path().join("workers")).unwrap(); let session_id = new_session_id(); let segment_id = new_segment_id(); - pod_store + worker_metadata_store .write(&WorkerMetadata::new( "agent", Some(WorkerActiveSegmentRef::active_segment( @@ -1015,7 +1057,7 @@ mod tests { )) .unwrap(); - let records = read_stored_worker_infos(&store, &pod_store).unwrap(); + let records = read_stored_worker_infos(&store, &worker_metadata_store).unwrap(); assert_eq!(records.len(), 1); assert_eq!(records[0].worker_name, "agent"); assert_eq!(records[0].metadata_state, StoredMetadataState::Present); diff --git a/crates/worker/Cargo.toml b/crates/worker/Cargo.toml index 5b065cc3..d7a11e5f 100644 --- a/crates/worker/Cargo.toml +++ b/crates/worker/Cargo.toml @@ -14,13 +14,11 @@ async-trait = { workspace = true } clap = { version = "4.6.0", features = ["derive"] } llm-engine = { workspace = true } session-store = { workspace = true } -pod-store = { workspace = true } manifest = { workspace = true } mcp = { workspace = true } protocol = { workspace = true } provider = { workspace = true } client = { workspace = true } -pod-registry = { workspace = true } worker-runtime = { workspace = true, features = ["ws-server"], optional = true } serde = { workspace = true, features = ["derive"] } serde_json = { workspace = true } diff --git a/crates/worker/README.md b/crates/worker/README.md index e9b29efe..aee91b83 100644 --- a/crates/worker/README.md +++ b/crates/worker/README.md @@ -10,7 +10,7 @@ Owns: - Worker lifecycle and socket protocol serving - Engine construction around a resolved Manifest -- session-store and pod-store coordination +- session-store and session-store worker metadata coordination - built-in tool registration under scope/policy - spawned-child orchestration hooks @@ -19,7 +19,7 @@ Does not own: - provider-specific wire formats (`provider` / `llm-engine` clients) - product CLI parsing (`yoi`) - TUI display authority (`tui`) -- current-state storage schema outside Worker metadata (`pod-store`) +- current-state storage schema outside Worker metadata (`session-store` worker metadata) ## Design notes diff --git a/crates/worker/examples/worker_cli.rs b/crates/worker/examples/worker_cli.rs index 624bde39..d7e26f0c 100644 --- a/crates/worker/examples/worker_cli.rs +++ b/crates/worker/examples/worker_cli.rs @@ -11,8 +11,8 @@ //! cargo run -p worker --example worker_cli //! ``` -use pod_store::{CombinedStore, FsWorkerStore}; use session_store::FsStore; +use session_store::{CombinedStore, FsWorkerStore}; use worker::{Worker, WorkerManifest, WorkerRunResult}; fn manifest_toml(pwd: &std::path::Path) -> String { diff --git a/crates/worker/examples/worker_protocol.rs b/crates/worker/examples/worker_protocol.rs index 25372dac..fc54a1d0 100644 --- a/crates/worker/examples/worker_protocol.rs +++ b/crates/worker/examples/worker_protocol.rs @@ -5,8 +5,8 @@ //! cargo run -p worker --example worker_protocol //! ``` -use pod_store::{CombinedStore, FsWorkerStore}; use session_store::FsStore; +use session_store::{CombinedStore, FsWorkerStore}; use worker::{Event, Method, WorkerController}; fn manifest_toml(pwd: &std::path::Path) -> String { diff --git a/crates/worker/src/controller.rs b/crates/worker/src/controller.rs index ebcc455e..5a98ee54 100644 --- a/crates/worker/src/controller.rs +++ b/crates/worker/src/controller.rs @@ -5,8 +5,8 @@ use std::sync::atomic::Ordering; use llm_engine::EngineError; use llm_engine::llm_client::client::LlmClient; use manifest::TicketFeatureAccessConfig; -use pod_store::WorkerMetadataStore; use session_store::Store; +use session_store::WorkerMetadataStore; use ticket::LocalTicketBackend; use ticket::config::TicketConfig; use tokio::sync::{broadcast, mpsc, oneshot}; @@ -608,7 +608,7 @@ where let spawner_name = worker.manifest().worker.name.clone(); let spawner_manifest = worker.manifest().clone(); let prompts = worker.prompts().clone(); - let pod_store = worker.store().clone(); + let worker_metadata_store = worker.store().clone(); let self_parent_socket = worker.callback_socket().cloned(); // The Worker's SharedScope (already augmented with the bash-output @@ -724,8 +724,13 @@ where worker.register_tool(send_to_worker_tool(spawned_registry.clone())); worker.register_tool(read_worker_output_tool(spawned_registry.clone())); worker.register_tool(stop_worker_tool(spawned_registry.clone())); - let discovery = - WorkerDiscovery::new(pod_store, spawner_name, runtime_base, cwd, spawned_registry); + let discovery = WorkerDiscovery::new( + worker_metadata_store, + spawner_name, + runtime_base, + cwd, + spawned_registry, + ); worker.register_tool(list_workers_tool(discovery.clone())); worker.register_tool(restore_worker_tool(discovery.clone())); worker.register_tool(send_to_peer_worker_tool(discovery)); diff --git a/crates/worker/src/discovery.rs b/crates/worker/src/discovery.rs index 518525b4..ad182f72 100644 --- a/crates/worker/src/discovery.rs +++ b/crates/worker/src/discovery.rs @@ -18,19 +18,19 @@ use async_trait::async_trait; use client::WorkerRuntimeCommand; use llm_engine::tool::{Tool, ToolDefinition, ToolError, ToolMeta, ToolOutput}; use manifest::{Permission, ScopeRule}; -use pod_store::{ - WorkerActiveSegmentRef, WorkerMetadata, WorkerMetadataStore, validate_worker_name, -}; use protocol::stream::JsonLineReader; use protocol::{Event, Method, WorkerStatus}; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; use session_store::{SegmentId, SessionId}; +use session_store::{ + WorkerActiveSegmentRef, WorkerMetadata, WorkerMetadataStore, validate_worker_name, +}; use tokio::net::UnixStream; use tokio::process::Command; use crate::runtime::dir::SpawnedWorkerRecord; -use crate::runtime::pod_registry; +use crate::runtime::worker_allocation; use crate::spawn::comm_tools::connect_and_send; use crate::spawn::registry::SpawnedWorkerRegistry; @@ -705,9 +705,9 @@ pub enum WorkerDiscoveryError { #[error("session store error: {0}")] Store(#[from] session_store::StoreError), #[error("worker store error: {0}")] - WorkerStore(#[from] pod_store::WorkerStoreError), + WorkerStore(#[from] session_store::WorkerStoreError), #[error("scope lock error: {0}")] - ScopeLock(#[from] pod_registry::ScopeLockError), + ScopeLock(#[from] worker_allocation::ScopeLockError), #[error("failed to launch restore process: {0}")] RestoreSpawn(io::Error), #[error("failed to launch restore runtime command `{command}`: {source}")] @@ -748,7 +748,7 @@ impl VisibilitySet { } } -fn comm_info_from_spawned_child(child: &pod_store::WorkerSpawnedChild) -> CommRegistryInfo { +fn comm_info_from_spawned_child(child: &session_store::WorkerSpawnedChild) -> CommRegistryInfo { let scope_delegated = child .scope_delegated .iter() @@ -773,7 +773,7 @@ fn comm_info_from_spawned_child(child: &pod_store::WorkerSpawnedChild) -> CommRe } async fn summarize_spawned_children( - children: &[pod_store::WorkerSpawnedChild], + children: &[session_store::WorkerSpawnedChild], ) -> SpawnedChildrenSummary { let mut summary = SpawnedChildrenSummary { count: children.len(), @@ -832,8 +832,8 @@ async fn probe_socket(socket_path: &Path) -> LiveInfo { fn lookup_segment_lock( segment_id: SegmentId, -) -> Result, pod_registry::ScopeLockError> { - pod_registry::lookup_segment(segment_id) +) -> Result, worker_allocation::ScopeLockError> { + worker_allocation::lookup_segment(segment_id) } #[derive(Debug, Deserialize, JsonSchema)] @@ -1061,9 +1061,11 @@ mod tests { use std::sync::Mutex; use manifest::{Permission, ScopeRule}; - use pod_store::{FsWorkerStore, WorkerSpawnedChild, WorkerSpawnedScopeRule, WorkerStoreError}; use protocol::stream::JsonLineWriter; use protocol::{Alert, AlertLevel, AlertSource}; + use session_store::{ + FsWorkerStore, WorkerSpawnedChild, WorkerSpawnedScopeRule, WorkerStoreError, + }; use session_store::{new_segment_id, new_session_id}; use tempfile::TempDir; use tokio::net::UnixListener; @@ -1143,7 +1145,7 @@ mod tests { child("child-pending", &pending_socket), ], reclaimed_children: Vec::new(), - peers: vec![pod_store::WorkerPeer { + peers: vec![session_store::WorkerPeer { worker_name: "peer".into(), }], resolved_manifest_snapshot: None, @@ -1209,7 +1211,7 @@ mod tests { workspace_root: None, spawned_children: Vec::new(), reclaimed_children: Vec::new(), - peers: vec![pod_store::WorkerPeer { + peers: vec![session_store::WorkerPeer { worker_name: "parent".into(), }], resolved_manifest_snapshot: None, @@ -1317,7 +1319,7 @@ mod tests { assert!(matches!(restore_plan, RestorePlan::Restore { .. })); let lock_socket = runtime_base.join("lock-owner.sock"); - let _guard = pod_registry::install_top_level( + let _guard = worker_allocation::install_top_level( "lock-owner".into(), std::process::id(), lock_socket.clone(), @@ -1415,7 +1417,7 @@ mod tests { workspace_root: None, spawned_children: Vec::new(), reclaimed_children: Vec::new(), - peers: vec![pod_store::WorkerPeer { + peers: vec![session_store::WorkerPeer { worker_name: "target".into(), }], resolved_manifest_snapshot: None, @@ -1455,7 +1457,7 @@ mod tests { workspace_root: None, spawned_children: Vec::new(), reclaimed_children: Vec::new(), - peers: vec![pod_store::WorkerPeer { + peers: vec![session_store::WorkerPeer { worker_name: "target".into(), }], resolved_manifest_snapshot: None, @@ -1468,7 +1470,7 @@ mod tests { workspace_root: None, spawned_children: Vec::new(), reclaimed_children: Vec::new(), - peers: vec![pod_store::WorkerPeer { + peers: vec![session_store::WorkerPeer { worker_name: "source".into(), }], resolved_manifest_snapshot: None, @@ -1573,7 +1575,7 @@ mod tests { workspace_root: None, spawned_children: Vec::new(), reclaimed_children: Vec::new(), - peers: vec![pod_store::WorkerPeer { + peers: vec![session_store::WorkerPeer { worker_name: "target".into(), }], resolved_manifest_snapshot: None, @@ -1586,7 +1588,7 @@ mod tests { workspace_root: None, spawned_children: Vec::new(), reclaimed_children: Vec::new(), - peers: vec![pod_store::WorkerPeer { + peers: vec![session_store::WorkerPeer { worker_name: "source".into(), }], resolved_manifest_snapshot: None, diff --git a/crates/worker/src/entrypoint.rs b/crates/worker/src/entrypoint.rs index 1ea6f81c..981726cd 100644 --- a/crates/worker/src/entrypoint.rs +++ b/crates/worker/src/entrypoint.rs @@ -9,7 +9,7 @@ use manifest::{ WorkerManifest, WorkerManifestConfig, paths, plugin::{PluginDiscoveryOptions, resolve_plugin_config_for_startup}, }; -use pod_store::{CombinedStore, FsWorkerStore, WorkerMetadataStore}; +use session_store::{CombinedStore, FsWorkerStore, WorkerMetadataStore}; use session_store::{FsStore, SegmentId, Store}; use ticket::config::TicketRole; @@ -85,7 +85,7 @@ struct Cli { /// Restore a Worker from an existing session. The Worker re-uses the /// given session id and appends new turns to the same jsonl; - /// concurrent writers are prevented by the pod-registry. + /// concurrent writers are prevented by the worker-allocation. /// Mutually exclusive with `--adopt` (spawned children always start /// fresh). #[arg(long, value_name = "UUID", conflicts_with_all = ["adopt"])] @@ -484,21 +484,21 @@ async fn run_cli_inner(cli: Cli) -> ExitCode { return ExitCode::FAILURE; } }; - let pod_store_dir = match paths::data_dir() { - Some(data_dir) => data_dir.join("pods"), + let worker_metadata_dir = match paths::data_dir() { + Some(data_dir) => data_dir.join("workers"), None => store_dir .parent() - .map(|parent| parent.join("pods")) + .map(|parent| parent.join("workers")) .unwrap_or_else(|| PathBuf::from("workers")), }; - let pod_store = match FsWorkerStore::new(&pod_store_dir) { + let worker_metadata_store = match FsWorkerStore::new(&worker_metadata_dir) { Ok(s) => s, Err(e) => { - eprintln!("error: failed to initialize worker store at {pod_store_dir:?}: {e}"); + eprintln!("error: failed to initialize worker store at {worker_metadata_dir:?}: {e}"); return ExitCode::FAILURE; } }; - let store = CombinedStore::new(session_store, pod_store); + let store = CombinedStore::new(session_store, worker_metadata_store); let mut worker = if cli.adopt { let callback = match cli.callback.clone() { diff --git a/crates/worker/src/ipc/event.rs b/crates/worker/src/ipc/event.rs index ab66be6a..0c8349cf 100644 --- a/crates/worker/src/ipc/event.rs +++ b/crates/worker/src/ipc/event.rs @@ -10,7 +10,7 @@ //! parent's notification buffer. Control-plane-only variants may still have //! a renderer for diagnostics, but receive-side classification keeps them //! out of LLM history/context. -//! - **Apply side effects** on the parent (registry / pod-registry +//! - **Apply side effects** on the parent (registry / worker-allocation //! updates) so that the receive path is idempotent and tolerant of //! out-of-order delivery. //! diff --git a/crates/worker/src/runtime/mod.rs b/crates/worker/src/runtime/mod.rs index e5cf84a8..efd47105 100644 --- a/crates/worker/src/runtime/mod.rs +++ b/crates/worker/src/runtime/mod.rs @@ -1,2 +1,2 @@ pub mod dir; -pub use ::pod_registry; +pub mod worker_allocation; diff --git a/crates/worker/src/runtime/worker_allocation.rs b/crates/worker/src/runtime/worker_allocation.rs new file mode 100644 index 00000000..53694e52 --- /dev/null +++ b/crates/worker/src/runtime/worker_allocation.rs @@ -0,0 +1,29 @@ +//! Process-local Worker allocation table used only for scope ownership checks. +//! +//! This module is intentionally not a runtime identity store. Runtime Worker +//! identity, creation and durable persistence remain owned by worker-runtime +//! fs-store plus its execution backend mapping; this table coordinates +//! in-process scope delegation while a Worker is running. + +mod conflict; +mod error; +mod lifecycle; +mod mutate; +mod table; + +#[cfg(test)] +mod test_util; + +pub use conflict::{ + ConflictOwner, find_conflict_owner, find_conflict_owners, is_within_effective_write, +}; +pub use error::ScopeLockError; +pub use lifecycle::{ + ScopeAllocationGuard, SegmentLockInfo, adopt_allocation, install_top_level, + install_top_level_with_deny, lookup_segment, update_segment, +}; +pub use mutate::{ + delegate_scope, reclaim_delegated_scope, reclaim_stale, reclaim_stale_with, register_worker, + register_worker_with_deny, release_worker, +}; +pub use table::{Allocation, LockFile, LockFileGuard, default_allocation_path}; diff --git a/crates/pod-registry/src/conflict.rs b/crates/worker/src/runtime/worker_allocation/conflict.rs similarity index 97% rename from crates/pod-registry/src/conflict.rs rename to crates/worker/src/runtime/worker_allocation/conflict.rs index 9c36dd76..686b993c 100644 --- a/crates/pod-registry/src/conflict.rs +++ b/crates/worker/src/runtime/worker_allocation/conflict.rs @@ -6,7 +6,7 @@ use manifest::{Permission, ScopeRule}; -use crate::table::{Allocation, LockFile}; +use super::table::{Allocation, LockFile}; /// Whether `a` and `b` claim any overlapping concrete path. /// @@ -156,9 +156,11 @@ fn find_conflict_in_subtree( #[cfg(test)] mod tests { + use super::super::test_util::*; + use super::super::{ + ScopeLockError, delegate_scope, register_worker, register_worker_with_deny, + }; use super::*; - use crate::test_util::*; - use crate::{ScopeLockError, delegate_scope, register_pod, register_worker_with_deny}; use tempfile::TempDir; #[test] diff --git a/crates/pod-registry/src/error.rs b/crates/worker/src/runtime/worker_allocation/error.rs similarity index 90% rename from crates/pod-registry/src/error.rs rename to crates/worker/src/runtime/worker_allocation/error.rs index 1ba43f3b..8e3da1aa 100644 --- a/crates/pod-registry/src/error.rs +++ b/crates/worker/src/runtime/worker_allocation/error.rs @@ -1,4 +1,4 @@ -//! Error type for mutating pod-registry operations. +//! Error type for mutating pod-worker allocation operations. use std::io; use std::path::PathBuf; @@ -6,7 +6,7 @@ use std::path::PathBuf; use manifest::{ScopeError, ScopeRule}; use session_store::SegmentId; -/// Errors raised by the mutating pod-registry operations. +/// Errors raised by the mutating pod-worker allocation operations. #[derive(Debug, thiserror::Error)] pub enum ScopeLockError { #[error("I/O error on workers.json: {0}")] diff --git a/crates/pod-registry/src/lifecycle.rs b/crates/worker/src/runtime/worker_allocation/lifecycle.rs similarity index 94% rename from crates/pod-registry/src/lifecycle.rs rename to crates/worker/src/runtime/worker_allocation/lifecycle.rs index 59d1a747..e86f4b83 100644 --- a/crates/pod-registry/src/lifecycle.rs +++ b/crates/worker/src/runtime/worker_allocation/lifecycle.rs @@ -1,5 +1,5 @@ //! Owned-allocation guards and the high-level entry points that open -//! the default registry path, mutate it, and return a guard that cleans +//! the default worker allocation path, mutate it, and return a guard that cleans //! up on drop. use std::path::{Path, PathBuf}; @@ -7,9 +7,9 @@ use std::path::{Path, PathBuf}; use manifest::ScopeRule; use session_store::SegmentId; -use crate::error::ScopeLockError; -use crate::mutate::release_worker; -use crate::table::{LockFileGuard, default_registry_path}; +use super::error::ScopeLockError; +use super::mutate::release_worker; +use super::table::{LockFileGuard, default_allocation_path}; /// Owned allocation: on drop, opens the lock file and releases this /// Worker's entry. The guard keeps only the name + lock-file path; it @@ -68,9 +68,9 @@ pub fn install_top_level_with_deny( scope_deny: Vec, segment_id: SegmentId, ) -> Result { - let lock_path = default_registry_path()?; + let lock_path = default_allocation_path()?; let mut guard = LockFileGuard::open(&lock_path)?; - crate::mutate::register_worker_with_deny( + super::mutate::register_worker_with_deny( &mut guard, worker_name.clone(), pid, @@ -99,7 +99,7 @@ pub fn adopt_allocation( new_pid: u32, segment_id: SegmentId, ) -> Result { - let lock_path = default_registry_path()?; + let lock_path = default_allocation_path()?; let mut guard = LockFileGuard::open(&lock_path)?; let alloc = guard .data_mut() @@ -134,7 +134,7 @@ pub fn adopt_allocation( /// guard, so the segment_id collision check is atomic with the /// rewrite. pub fn update_segment(worker_name: &str, new_segment_id: SegmentId) -> Result<(), ScopeLockError> { - let lock_path = default_registry_path()?; + let lock_path = default_allocation_path()?; let mut guard = LockFileGuard::open(&lock_path)?; if let Some(other) = guard.data().find_by_segment(new_segment_id) { if other.worker_name != worker_name { @@ -169,9 +169,9 @@ pub struct SegmentLockInfo { /// Used by `Worker::restore_from_manifest` to refuse a resume that would /// race a live writer on the same source session. pub fn lookup_segment(segment_id: SegmentId) -> Result, ScopeLockError> { - let lock_path = default_registry_path()?; + let lock_path = default_allocation_path()?; let mut guard = LockFileGuard::open(&lock_path)?; - crate::mutate::reclaim_stale(&mut guard); + super::mutate::reclaim_stale(&mut guard); Ok(guard .data() .find_by_segment(segment_id) @@ -184,9 +184,9 @@ pub fn lookup_segment(segment_id: SegmentId) -> Result, #[cfg(test)] mod tests { + use super::super::table::Allocation; + use super::super::test_util::*; use super::*; - use crate::table::Allocation; - use crate::test_util::*; use tempfile::TempDir; /// Mimic what the spawner does before the child comes up: push an diff --git a/crates/pod-registry/src/mutate.rs b/crates/worker/src/runtime/worker_allocation/mutate.rs similarity index 98% rename from crates/pod-registry/src/mutate.rs rename to crates/worker/src/runtime/worker_allocation/mutate.rs index 10a518b8..846adca9 100644 --- a/crates/pod-registry/src/mutate.rs +++ b/crates/worker/src/runtime/worker_allocation/mutate.rs @@ -1,5 +1,5 @@ //! Mutating operations over the allocation table. All of these expect -//! the caller to hold a [`LockFileGuard`] for the registry's lock file. +//! the caller to hold a [`LockFileGuard`] for the worker allocation's lock file. use std::io; use std::path::PathBuf; @@ -7,9 +7,9 @@ use std::path::PathBuf; use manifest::{DelegationScope, Permission, ScopeRule}; use session_store::SegmentId; -use crate::conflict::{find_conflict_owner, find_conflict_owners}; -use crate::error::ScopeLockError; -use crate::table::{Allocation, LockFileGuard}; +use super::conflict::{find_conflict_owner, find_conflict_owners}; +use super::error::ScopeLockError; +use super::table::{Allocation, LockFileGuard}; /// Register a top-level Worker (started directly by a human, no /// delegation parent). Reclaims stale entries before checking @@ -46,7 +46,7 @@ pub fn register_worker( /// competitor.rule), not relational — it does not verify that the /// competitor actually descends from this Worker's prior delegations. /// In practice this is safe because the canonical restore caller derives -/// `scope_deny` from outstanding `pod-store` child delegations, so any +/// `scope_deny` from outstanding child worker metadata delegations, so any /// covered competitor is expected to be a descendant of the original /// allocation. Direct callers must uphold the same invariant. pub fn register_worker_with_deny( @@ -79,7 +79,7 @@ pub fn register_worker_with_deny( scope_deny .iter() .filter(|r| r.permission == Permission::Write) - .any(|deny| crate::conflict::covers_fully(deny, &owner.rule)) + .any(|deny| super::conflict::covers_fully(deny, &owner.rule)) }); if all_denied { continue; @@ -286,9 +286,9 @@ fn pid_alive(pid: u32) -> bool { #[cfg(test)] mod tests { + use super::super::is_within_effective_write; + use super::super::test_util::*; use super::*; - use crate::is_within_effective_write; - use crate::test_util::*; use tempfile::TempDir; #[test] diff --git a/crates/pod-registry/src/table.rs b/crates/worker/src/runtime/worker_allocation/table.rs similarity index 94% rename from crates/pod-registry/src/table.rs rename to crates/worker/src/runtime/worker_allocation/table.rs index 6bb85bc0..3056074f 100644 --- a/crates/pod-registry/src/table.rs +++ b/crates/worker/src/runtime/worker_allocation/table.rs @@ -49,7 +49,7 @@ pub struct Allocation { /// a top-level Worker started directly by a human. pub delegated_from: Option, /// Segment ID this Worker is currently writing to. `None` means this - /// is a pre-reservation made by a spawner via [`crate::delegate_scope`] + /// is a pre-reservation made by a spawner via [`super::super::delegate_scope`] /// before the child has come up; the child fills it in at /// [`crate::adopt_allocation`] time. #[serde(default)] @@ -79,11 +79,11 @@ impl LockFile { } /// Default on-disk path: `/workers.json` resolved via -/// [`manifest::paths::pod_registry_path`]. Tests should point this +/// [`manifest::paths::worker_allocation_path`]. Tests should point this /// elsewhere by setting `YOI_HOME` or `YOI_RUNTIME_DIR` to a /// tempdir. -pub fn default_registry_path() -> io::Result { - paths::pod_registry_path().ok_or_else(|| { +pub fn default_allocation_path() -> io::Result { + paths::worker_allocation_path().ok_or_else(|| { io::Error::new( io::ErrorKind::NotFound, "could not resolve workers.json path (no YOI_HOME / \ @@ -137,7 +137,7 @@ impl LockFileGuard { return Err(io::Error::new( io::ErrorKind::TimedOut, format!( - "timed out waiting for pod registry lock `{}`", + "timed out waiting for worker allocation lock `{}`", path.display() ), )); @@ -149,7 +149,7 @@ impl LockFileGuard { return Err(io::Error::new( io::ErrorKind::TimedOut, format!( - "timed out waiting for pod registry lock `{}`", + "timed out waiting for worker allocation lock `{}`", path.display() ), )); @@ -211,9 +211,9 @@ impl Drop for LockFileGuard { #[cfg(test)] mod tests { + use super::super::register_worker; + use super::super::test_util::*; use super::*; - use crate::register_pod; - use crate::test_util::*; use tempfile::TempDir; #[test] @@ -277,7 +277,7 @@ mod tests { sid(), ) .unwrap(); - crate::delegate_scope( + super::super::delegate_scope( &mut g, "parent", "child".into(), diff --git a/crates/pod-registry/src/test_util.rs b/crates/worker/src/runtime/worker_allocation/test_util.rs similarity index 93% rename from crates/pod-registry/src/test_util.rs rename to crates/worker/src/runtime/worker_allocation/test_util.rs index 2ec9dbcf..d307933c 100644 --- a/crates/pod-registry/src/test_util.rs +++ b/crates/worker/src/runtime/worker_allocation/test_util.rs @@ -1,6 +1,6 @@ -//! Shared test helpers for the pod-registry crate. +//! Shared test helpers for the pod-worker allocation crate. //! -//! Visible to all `#[cfg(test)]` modules under `crate::test_util::*`. +//! Visible to all `#[cfg(test)]` modules under `super::test_util::*`. use std::path::{Path, PathBuf}; use std::sync::{LazyLock, Mutex, MutexGuard}; @@ -8,7 +8,7 @@ use std::sync::{LazyLock, Mutex, MutexGuard}; use manifest::{DelegationScope, Permission, ScopeConfig, ScopeRule}; use session_store::SegmentId; -use crate::table::LockFileGuard; +use super::table::LockFileGuard; pub(crate) fn sid() -> SegmentId { session_store::new_segment_id() @@ -17,7 +17,7 @@ pub(crate) fn sid() -> SegmentId { /// Serialises tests that mutate runtime-dir env vars. The test /// harness runs tests on multiple threads inside a single process, /// so env-var writes from one test would otherwise leak into a -/// parallel test's `default_registry_path()` lookup. +/// parallel test's `default_allocation_path()` lookup. pub(crate) static ENV_LOCK: LazyLock> = LazyLock::new(|| Mutex::new(())); /// Sandbox `YOI_RUNTIME_DIR` to a tempdir for the duration of diff --git a/crates/worker/src/runtime_adapter.rs b/crates/worker/src/runtime_adapter.rs index 22854447..93581d52 100644 --- a/crates/worker/src/runtime_adapter.rs +++ b/crates/worker/src/runtime_adapter.rs @@ -16,9 +16,9 @@ use std::time::Duration; use async_trait::async_trait; use manifest::paths; -use pod_store::{CombinedStore, FsWorkerStore}; use protocol::{Method, Segment, WorkerStatus}; use session_store::FsStore; +use session_store::{CombinedStore, FsWorkerStore}; use tokio::runtime::Runtime; use tokio::sync::broadcast; use worker_runtime::execution::{ @@ -49,7 +49,7 @@ pub struct ProfileRuntimeWorkerFactory { workspace_root: PathBuf, cwd: PathBuf, store_dir: Option, - pod_store_dir: Option, + worker_metadata_dir: Option, profile: Option, runtime_base_dir: Option, } @@ -61,7 +61,7 @@ impl ProfileRuntimeWorkerFactory { cwd: workspace_root.clone(), workspace_root, store_dir: None, - pod_store_dir: None, + worker_metadata_dir: None, profile: None, runtime_base_dir: None, } @@ -77,8 +77,8 @@ impl ProfileRuntimeWorkerFactory { self } - pub fn with_pod_store_dir(mut self, pod_store_dir: impl Into) -> Self { - self.pod_store_dir = Some(pod_store_dir.into()); + pub fn with_worker_metadata_dir(mut self, worker_metadata_dir: impl Into) -> Self { + self.worker_metadata_dir = Some(worker_metadata_dir.into()); self } @@ -104,11 +104,11 @@ impl ProfileRuntimeWorkerFactory { }) } - fn pod_store_dir(&self, store_dir: &std::path::Path) -> PathBuf { - self.pod_store_dir + fn worker_metadata_dir(&self, store_dir: &std::path::Path) -> PathBuf { + self.worker_metadata_dir .clone() - .or_else(|| paths::data_dir().map(|data_dir| data_dir.join("pods"))) - .or_else(|| store_dir.parent().map(|parent| parent.join("pods"))) + .or_else(|| paths::data_dir().map(|data_dir| data_dir.join("workers"))) + .or_else(|| store_dir.parent().map(|parent| parent.join("workers"))) .unwrap_or_else(|| PathBuf::from("workers")) } @@ -174,14 +174,14 @@ impl RuntimeWorkerFactory for ProfileRuntimeWorkerFactory { store_dir.display() ) })?; - let pod_store_dir = self.pod_store_dir(&store_dir); - let pod_store = FsWorkerStore::new(&pod_store_dir).map_err(|err| { + let worker_metadata_dir = self.worker_metadata_dir(&store_dir); + let worker_metadata_store = FsWorkerStore::new(&worker_metadata_dir).map_err(|err| { format!( "failed to initialize worker metadata store at {}: {err}", - pod_store_dir.display() + worker_metadata_dir.display() ) })?; - let store = CombinedStore::new(session_store, pod_store); + let store = CombinedStore::new(session_store, worker_metadata_store); let worker = Worker::from_manifest_with_context( manifest, @@ -558,7 +558,7 @@ mod tests { runtime_base: PathBuf, cwd: PathBuf, store_dir: PathBuf, - pod_store_dir: PathBuf, + worker_metadata_dir: PathBuf, } #[async_trait] @@ -588,7 +588,7 @@ mod tests { .map_err(|err| err.to_string())?; let store = CombinedStore::new( FsStore::new(&self.store_dir).map_err(|err| err.to_string())?, - FsWorkerStore::new(&self.pod_store_dir).map_err(|err| err.to_string())?, + FsWorkerStore::new(&self.worker_metadata_dir).map_err(|err| err.to_string())?, ); let scope = Scope::writable(&self.cwd).map_err(|err| err.to_string())?; let worker = Worker::new( @@ -662,7 +662,7 @@ mod tests { runtime_base: runtime_base.path().to_path_buf(), cwd: cwd.path().to_path_buf(), store_dir: store.path().join("sessions"), - pod_store_dir: store.path().join("pods"), + worker_metadata_dir: store.path().join("workers"), }; let backend = WorkerRuntimeExecutionBackend::new(factory).unwrap(); let runtime = EmbeddedRuntime::with_execution_backend( diff --git a/crates/worker/src/spawn/registry.rs b/crates/worker/src/spawn/registry.rs index d4241296..3081f6d4 100644 --- a/crates/worker/src/spawn/registry.rs +++ b/crates/worker/src/spawn/registry.rs @@ -21,7 +21,7 @@ use std::sync::Arc; use std::time::Duration; use manifest::{Permission, ScopeRule, SharedScope}; -use pod_store::{ +use session_store::{ WorkerMetadataStore, WorkerReclaimedChild, WorkerSpawnedChild, WorkerSpawnedScopeRule, WorkerStoreError, }; @@ -30,7 +30,7 @@ use tokio::sync::Mutex; use tracing::warn; use crate::runtime::dir::{RuntimeDir, SpawnedWorkerRecord}; -use crate::runtime::pod_registry; +use crate::runtime::worker_allocation; type RegistryStateWriter = Arc io::Result<()> + Send + Sync>; type RegistryReclaimWriter = Arc io::Result<()> + Send + Sync>; @@ -339,11 +339,11 @@ fn reclaim_record( .cloned() .collect::>(); - let lock_path = pod_registry::default_registry_path() + let lock_path = worker_allocation::default_allocation_path() .map_err(|err| io::Error::new(io::ErrorKind::Other, err))?; - let mut guard = pod_registry::LockFileGuard::open(&lock_path) + let mut guard = worker_allocation::LockFileGuard::open(&lock_path) .map_err(|err| io::Error::new(io::ErrorKind::Other, err))?; - pod_registry::reclaim_delegated_scope( + worker_allocation::reclaim_delegated_scope( &mut guard, parent_name, &record.worker_name, @@ -361,12 +361,12 @@ fn reclaim_record( } fn release_child_allocation(worker_name: &str) -> io::Result<()> { - let lock_path = pod_registry::default_registry_path() + let lock_path = worker_allocation::default_allocation_path() .map_err(|err| io::Error::new(io::ErrorKind::Other, err))?; - let mut guard = pod_registry::LockFileGuard::open(&lock_path) + let mut guard = worker_allocation::LockFileGuard::open(&lock_path) .map_err(|err| io::Error::new(io::ErrorKind::Other, err))?; - match pod_registry::release_worker(&mut guard, worker_name) { - Ok(()) | Err(pod_registry::ScopeLockError::UnknownWorker(_)) => Ok(()), + match worker_allocation::release_worker(&mut guard, worker_name) { + Ok(()) | Err(worker_allocation::ScopeLockError::UnknownWorker(_)) => Ok(()), Err(err) => Err(io::Error::new(io::ErrorKind::Other, err)), } } diff --git a/crates/worker/src/spawn/tool.rs b/crates/worker/src/spawn/tool.rs index f4dba933..a6794241 100644 --- a/crates/worker/src/spawn/tool.rs +++ b/crates/worker/src/spawn/tool.rs @@ -1,9 +1,9 @@ //! `SpawnWorker` tool — launch a new Worker process as a child of this one. //! -//! Wires pod-registry delegation, child manifest-config construction, subprocess +//! Wires worker-allocation delegation, child manifest-config construction, subprocess //! launch, and socket handoff into a single `Tool` implementation. When //! the LLM calls `SpawnWorker`, a fresh Worker runtime command is exec'd in its own -//! process group, the pod-registry is updated atomically, and the child's +//! process group, the worker-allocation is updated atomically, and the child's //! first turn is kicked off by handing its socket a `Method::Run`. use std::path::{Path, PathBuf}; @@ -29,7 +29,7 @@ use tokio::time::sleep; use crate::ipc::event; use crate::prompt::catalog::PromptCatalog; use crate::runtime::dir::SpawnedWorkerRecord; -use crate::runtime::pod_registry::{self, LockFileGuard, ScopeLockError}; +use crate::runtime::worker_allocation::{self, LockFileGuard, ScopeLockError}; use crate::spawn::comm_tools::{SendRunError, send_run_and_confirm}; use crate::spawn::registry::SpawnedWorkerRegistry; use protocol::WorkerEvent; @@ -216,7 +216,7 @@ fn parse_spawn_profile_selector(raw: Option<&str>) -> Result ToolError { } } -fn pod_registry_err_to_tool(e: ScopeLockError) -> ToolError { +fn worker_allocation_err_to_tool(e: ScopeLockError) -> ToolError { match e { ScopeLockError::NotSubset { .. } | ScopeLockError::WriteConflict { .. } diff --git a/crates/worker/src/ticket_event_notify.rs b/crates/worker/src/ticket_event_notify.rs index a32dc881..bb719d29 100644 --- a/crates/worker/src/ticket_event_notify.rs +++ b/crates/worker/src/ticket_event_notify.rs @@ -10,7 +10,7 @@ use tracing::{debug, warn}; use crate::discovery::{WeakNotifyDelivery, WorkerDiscovery}; use crate::hook::{Hook, HookPostToolAction, PostToolCall, ToolResultSummary}; use crate::prompt::catalog::{PromptCatalog, WorkerPrompt}; -use pod_store::WorkerMetadataStore; +use session_store::WorkerMetadataStore; const MAX_TITLE_CHARS: usize = 96; const MAX_SUMMARY_CHARS: usize = 160; @@ -251,11 +251,11 @@ mod tests { use crate::runtime::dir::RuntimeDir; use crate::spawn::registry::SpawnedWorkerRegistry; use llm_engine::tool::ToolOutput; - use pod_store::FsWorkerStore; - use pod_store::WorkerMetadata; use protocol::stream::{JsonLineReader, JsonLineWriter}; use protocol::{Event, Method}; use serde_json::json; + use session_store::FsWorkerStore; + use session_store::WorkerMetadata; use std::sync::Arc; use tempfile::tempdir; use ticket::NewTicket; diff --git a/crates/worker/src/worker.rs b/crates/worker/src/worker.rs index f994e527..1673c621 100644 --- a/crates/worker/src/worker.rs +++ b/crates/worker/src/worker.rs @@ -10,13 +10,13 @@ use llm_engine::llm_client::client::LlmClient; use llm_engine::llm_client::types::Role; use llm_engine::state::Mutable; use llm_engine::{Engine, EngineError, EngineResult, ToolOutputLimits, UsageRecord}; -use pod_store::{ - WorkerActiveSegmentRef, WorkerMetadata, WorkerMetadataStore, WorkerReclaimedChild, - WorkerSpawnedChild, WorkerSpawnedScopeRule, WorkerStoreError, -}; use session_store::{ LogEntry, SegmentId, SessionId, Store, StoreError, SystemItem, segment_log, to_logged, }; +use session_store::{ + WorkerActiveSegmentRef, WorkerMetadata, WorkerMetadataStore, WorkerReclaimedChild, + WorkerSpawnedChild, WorkerSpawnedScopeRule, WorkerStoreError, +}; use tracing::{info, warn}; use crate::segment_log_sink::SegmentLogSink; @@ -44,7 +44,7 @@ use crate::prompt::catalog::{CatalogError, PromptCatalog}; use crate::prompt::loader::PromptLoader; use crate::prompt::system::{SystemPromptContext, SystemPromptError, SystemPromptTemplate}; use crate::runtime::dir; -use crate::runtime::pod_registry::{self, ScopeAllocationGuard, ScopeLockError}; +use crate::runtime::worker_allocation::{self, ScopeAllocationGuard, ScopeLockError}; use crate::workflow::WorkflowResolveError; #[cfg(test)] use async_trait::async_trait; @@ -795,7 +795,7 @@ impl Worker { /// Strip `revoke` rules from the Worker's runtime scope by adding /// matching deny rules. A `Permission::Write` revoke caps effective - /// access at `Read` (mirroring the pod-registry `effective_write` + /// access at `Read` (mirroring the worker-allocation `effective_write` /// semantics — Write is the only permission tracked across Workers). /// A `Permission::Read` revoke removes access entirely. pub fn revoke_scope_rules( @@ -2086,7 +2086,7 @@ impl Worker { self.segment_state.set_entries_written(1); self.sink.reset_with_initial(entry); if self.scope_allocation.is_some() { - pod_registry::update_segment(&self.manifest.worker.name, fork_segment_id)?; + worker_allocation::update_segment(&self.manifest.worker.name, fork_segment_id)?; } self.write_worker_metadata_active(SegmentLocation { session_id: loc.session_id, @@ -2795,7 +2795,7 @@ impl Worker { // when no allocation is installed (e.g. compact under // `Worker::new` in tests). if self.scope_allocation.is_some() { - pod_registry::update_segment(&self.manifest.worker.name, new_segment_id)?; + worker_allocation::update_segment(&self.manifest.worker.name, new_segment_id)?; } self.write_worker_metadata_active(SegmentLocation { session_id: old_loc.session_id, @@ -3847,19 +3847,19 @@ where // Segment creation is deferred to the first run (see // `ensure_segment_head`) so the SegmentStart entry can capture // the rendered system prompt, not the raw template source. The - // session_id + segment_id are allocated here so the pod-registry + // session_id + segment_id are allocated here so the worker-allocation // registration can record them from the start. let session_id = session_store::new_session_id(); let segment_id = session_store::new_segment_id(); - // Register this Worker in the machine-wide pod-registry + // Register this Worker in the machine-wide worker-allocation // before building anything else, so a spawn that conflicts on // scope fails fast. let socket_path = dir::default_base() .map_err(ScopeLockError::from)? .join(&manifest.worker.name) .join("sock"); - let scope_allocation = pod_registry::install_top_level( + let scope_allocation = worker_allocation::install_top_level( manifest.worker.name.clone(), std::process::id(), socket_path, @@ -3927,7 +3927,7 @@ where /// /// Behaves like [`Worker::from_manifest`] but claims the scope /// allocation that the spawner pre-registered via - /// [`pod_registry::delegate_scope`], rather than installing a new + /// [`worker_allocation::delegate_scope`], rather than installing a new /// top-level entry. `callback_socket` carries the spawner's /// Unix-socket path so the spawned Worker can send `Method::Notify` /// back to the spawner. @@ -3971,7 +3971,7 @@ where // fresh Session rather than joining the spawner's. let session_id = session_store::new_session_id(); let segment_id = session_store::new_segment_id(); - let scope_allocation = pod_registry::adopt_allocation( + let scope_allocation = worker_allocation::adopt_allocation( manifest.worker.name.clone(), std::process::id(), segment_id, @@ -4104,9 +4104,9 @@ where /// reuses the same `segment_id` so subsequent turns append to the /// source jsonl as a continuation of the same conversation. /// - /// Concurrent writers are prevented by the pod-registry: + /// Concurrent writers are prevented by the worker-allocation: /// the registration carries `segment_id`, and this constructor - /// refuses to start when `pod_registry::lookup_segment` already finds + /// refuses to start when `worker_allocation::lookup_segment` already finds /// a live Worker writing to `segment_id`. So there is no need to fork — /// resume is "the same session, a different process owning it". /// @@ -4173,7 +4173,7 @@ where .map_err(ScopeLockError::from)? .join(&manifest.worker.name) .join("sock"); - let scope_allocation = pod_registry::install_top_level_with_deny( + let scope_allocation = worker_allocation::install_top_level_with_deny( manifest.worker.name.clone(), std::process::id(), socket_path, @@ -4291,10 +4291,10 @@ where let delegated_scope = spawned_child_scope_rules(&child); if !delegated_scope.is_empty() { let lock_path = - pod_registry::default_registry_path().map_err(ScopeLockError::from)?; - let mut guard = - pod_registry::LockFileGuard::open(&lock_path).map_err(ScopeLockError::from)?; - pod_registry::reclaim_delegated_scope( + worker_allocation::default_allocation_path().map_err(ScopeLockError::from)?; + let mut guard = worker_allocation::LockFileGuard::open(&lock_path) + .map_err(ScopeLockError::from)?; + worker_allocation::reclaim_delegated_scope( &mut guard, &worker_name, &child.worker_name, @@ -5300,7 +5300,7 @@ mod worker_metadata_restore_manifest_tests { #[test] fn metadata_writer_persists_workspace_root_through_store_update() { let temp = tempfile::tempdir().unwrap(); - let store = pod_store::FsWorkerStore::new(temp.path().join("pods")).unwrap(); + let store = session_store::FsWorkerStore::new(temp.path().join("workers")).unwrap(); let workspace_root = temp.path().join("workspace-root"); std::fs::create_dir_all(&workspace_root).unwrap(); let writer = worker_metadata_writer_for_store(&store); diff --git a/crates/worker/tests/compact_events_test.rs b/crates/worker/tests/compact_events_test.rs index 0a4b690f..ab6d1fba 100644 --- a/crates/worker/tests/compact_events_test.rs +++ b/crates/worker/tests/compact_events_test.rs @@ -16,8 +16,8 @@ use llm_engine::Engine; use llm_engine::llm_client::event::{Event as LlmEvent, ResponseStatus, StatusEvent}; use llm_engine::llm_client::types::Item; use llm_engine::llm_client::{ClientError, LlmClient, Request}; -use pod_store::{CombinedStore, FsWorkerStore, WorkerMetadataStore}; use protocol::{Event, Method, RunResult}; +use session_store::{CombinedStore, FsWorkerStore, WorkerMetadataStore}; use session_store::{FsStore, LogEntry, Store}; use tokio::sync::broadcast; diff --git a/crates/worker/tests/consolidation_test.rs b/crates/worker/tests/consolidation_test.rs index 7d9b4073..4b68c64e 100644 --- a/crates/worker/tests/consolidation_test.rs +++ b/crates/worker/tests/consolidation_test.rs @@ -26,8 +26,8 @@ use llm_engine::llm_client::{ClientError, LlmClient, Request}; use memory::WorkspaceLayout; use memory::extract::{ExtractedPayload, write_staging}; use memory::schema::SourceRef; -use pod_store::{CombinedStore, FsWorkerStore}; use session_store::FsStore; +use session_store::{CombinedStore, FsWorkerStore}; type TestStore = CombinedStore; use tokio::sync::broadcast; diff --git a/crates/worker/tests/controller_test.rs b/crates/worker/tests/controller_test.rs index 777e87a9..097967e2 100644 --- a/crates/worker/tests/controller_test.rs +++ b/crates/worker/tests/controller_test.rs @@ -9,7 +9,7 @@ use llm_engine::llm_client::event::{ErrorEvent, Event as LlmEvent, ResponseStatu use llm_engine::llm_client::types::Item; use llm_engine::llm_client::{ClientError, LlmClient, Request}; use llm_engine::tool::{Tool, ToolDefinition, ToolError, ToolMeta, ToolOutput}; -use pod_store::{CombinedStore, FsWorkerStore}; +use session_store::{CombinedStore, FsWorkerStore}; use session_store::{FsStore, LogEntry}; use worker::{Event, Method, Worker, WorkerController, WorkerHandle, WorkerManifest, WorkerStatus}; diff --git a/crates/worker/tests/restore_test.rs b/crates/worker/tests/restore_test.rs index 022dea2e..d898fa99 100644 --- a/crates/worker/tests/restore_test.rs +++ b/crates/worker/tests/restore_test.rs @@ -2,12 +2,12 @@ //! validation paths. //! //! These cases all return before `prepare_worker_common` runs, so they -//! do not need a real LLM client or pod-registry environment — only the +//! do not need a real LLM client or worker-allocation environment — only the //! session store needs to be present. use std::sync::{LazyLock, Mutex}; -use pod_store::{ +use session_store::{ CombinedStore, FsWorkerStore, WorkerActiveSegmentRef, WorkerMetadata, WorkerMetadataStore, }; use session_store::{FsStore, StoreError}; diff --git a/crates/worker/tests/session_metrics_test.rs b/crates/worker/tests/session_metrics_test.rs index 3b342e28..d932a1a2 100644 --- a/crates/worker/tests/session_metrics_test.rs +++ b/crates/worker/tests/session_metrics_test.rs @@ -25,8 +25,8 @@ use llm_engine::Engine; use llm_engine::llm_client::event::{Event as LlmEvent, ResponseStatus, StatusEvent, UsageEvent}; use llm_engine::llm_client::{ClientError, LlmClient, Request}; use llm_engine::tool::{Tool, ToolDefinition, ToolError, ToolMeta, ToolOutput}; -use pod_store::{CombinedStore, FsWorkerStore}; use session_metrics::{DOMAIN, Metric, metrics_from_extensions}; +use session_store::{CombinedStore, FsWorkerStore}; use session_store::{FsStore, LogEntry, SegmentId, SessionId, Store, StoreError, TraceEntry}; use worker::{Worker, WorkerManifest}; diff --git a/crates/worker/tests/spawn_worker_test.rs b/crates/worker/tests/spawn_worker_test.rs index 7d2a45a2..1f080f2d 100644 --- a/crates/worker/tests/spawn_worker_test.rs +++ b/crates/worker/tests/spawn_worker_test.rs @@ -1,6 +1,6 @@ //! Integration tests for the `SpawnWorker` tool. //! -//! These tests exercise the tool's pod-registry delegation, subprocess +//! These tests exercise the tool's worker-allocation delegation, subprocess //! launch, socket handoff, and `spawned_workers.json` write through an injected //! typed runtime command. The mock command exits immediately while a //! test-owned Unix listener pre-binds the predicted socket path, so the tool @@ -22,7 +22,7 @@ use std::sync::Arc; use tempfile::TempDir; use tokio::net::UnixListener; use worker::runtime::dir::{RuntimeDir, SpawnedWorkerRecord}; -use worker::runtime::pod_registry::{self, LockFileGuard}; +use worker::runtime::worker_allocation::{self, LockFileGuard}; use worker::spawn::registry::SpawnedWorkerRegistry; use worker::spawn::tool::spawn_worker_tool_with_runtime_command; @@ -67,7 +67,7 @@ async fn setup_spawner( .unwrap(); let spawner_socket = spawner_rd.socket_path(); - let _guard = pod_registry::install_top_level( + let _guard = worker_allocation::install_top_level( spawner_name.into(), std::process::id(), spawner_socket.clone(), @@ -450,8 +450,8 @@ async fn spawn_worker_delegates_scope_and_sends_run() { other => panic!("expected Run, got {other:?}"), } - // Verify pod_registry has the child allocation under `root`. - let lock_path = pod_registry::default_registry_path().unwrap(); + // Verify worker_allocation has the child allocation under `root`. + let lock_path = worker_allocation::default_allocation_path().unwrap(); let guard = LockFileGuard::open(&lock_path).unwrap(); let child = guard .data() @@ -651,7 +651,7 @@ async fn spawn_worker_rejects_scope_outside_spawner() { } // The spawner's allocation is unchanged; no "child" appeared. - let lock_path = pod_registry::default_registry_path().unwrap(); + let lock_path = worker_allocation::default_allocation_path().unwrap(); let guard = LockFileGuard::open(&lock_path).unwrap(); assert!(guard.data().find("child").is_none()); @@ -724,7 +724,7 @@ async fn spawn_worker_rolls_back_reservation_when_socket_never_appears() { } // Rollback assertion: the reserved "ghost" allocation is gone. - let lock_path = pod_registry::default_registry_path().unwrap(); + let lock_path = worker_allocation::default_allocation_path().unwrap(); let guard = LockFileGuard::open(&lock_path).unwrap(); assert!( guard.data().find("ghost").is_none(), diff --git a/crates/worker/tests/system_prompt_template_test.rs b/crates/worker/tests/system_prompt_template_test.rs index 60cad880..f4422a88 100644 --- a/crates/worker/tests/system_prompt_template_test.rs +++ b/crates/worker/tests/system_prompt_template_test.rs @@ -8,7 +8,7 @@ use futures::Stream; use llm_engine::Engine; use llm_engine::llm_client::event::{Event as LlmEvent, ResponseStatus, StatusEvent}; use llm_engine::llm_client::{ClientError, LlmClient, Request}; -use pod_store::{CombinedStore, FsWorkerStore}; +use session_store::{CombinedStore, FsWorkerStore}; use session_store::{FsStore, LogEntry, Store}; use worker::{PromptLoader, SystemPromptTemplate, Worker, WorkerError}; diff --git a/crates/worker/tests/worker_comm_tools_test.rs b/crates/worker/tests/worker_comm_tools_test.rs index abb73987..91a04544 100644 --- a/crates/worker/tests/worker_comm_tools_test.rs +++ b/crates/worker/tests/worker_comm_tools_test.rs @@ -14,17 +14,17 @@ use std::sync::{Arc, LazyLock, Mutex}; use llm_engine::llm_client::types::{ContentPart, Item, Role}; use llm_engine::tool::ToolOutput; use manifest::{Permission, Scope, ScopeRule, SharedScope}; -use pod_store::{CombinedStore, FsWorkerStore, WorkerMetadataStore}; use protocol::stream::{JsonLineReader, JsonLineWriter}; use protocol::{ErrorCode, Event, Greeting, Method}; use serde_json::json; use session_store::FsStore; +use session_store::{CombinedStore, FsWorkerStore, WorkerMetadataStore}; use tempfile::TempDir; use tokio::net::UnixListener; use tokio::sync::mpsc; use tokio::task::JoinHandle; use worker::runtime::dir::{RuntimeDir, SpawnedWorkerRecord}; -use worker::runtime::pod_registry::{self, LockFileGuard}; +use worker::runtime::worker_allocation::{self, LockFileGuard}; use worker::spawn::comm_tools::{read_worker_output_tool, send_to_worker_tool, stop_worker_tool}; use worker::spawn::registry::SpawnedWorkerRegistry; @@ -416,7 +416,7 @@ async fn stop_worker_sends_shutdown_and_releases_scope() { permission: Permission::Write, recursive: true, }; - pod_registry::register_worker_with_deny( + worker_allocation::register_worker_with_deny( &mut g, "spawner".into(), std::process::id(), @@ -426,7 +426,7 @@ async fn stop_worker_sends_shutdown_and_releases_scope() { session_store::new_segment_id(), ) .unwrap(); - pod_registry::register_worker( + worker_allocation::register_worker( &mut g, "child".into(), std::process::id(), @@ -663,7 +663,7 @@ async fn load_from_worker_state_reclaims_missing_child_scope_and_records_history { let mut g = LockFileGuard::open(&runtime_tmp.path().join("workers.json")).unwrap(); - pod_registry::register_worker_with_deny( + worker_allocation::register_worker_with_deny( &mut g, "spawner".into(), std::process::id(), diff --git a/crates/worker/tests/worker_events_test.rs b/crates/worker/tests/worker_events_test.rs index 512b6715..5860dc45 100644 --- a/crates/worker/tests/worker_events_test.rs +++ b/crates/worker/tests/worker_events_test.rs @@ -15,7 +15,7 @@ use tempfile::TempDir; use tokio::net::UnixListener; use worker::ipc::event::{apply_event_side_effects, fire_and_forget, render_event}; use worker::runtime::dir::{RuntimeDir, SpawnedWorkerRecord}; -use worker::runtime::pod_registry::{self, LockFileGuard}; +use worker::runtime::worker_allocation::{self, LockFileGuard}; use worker::spawn::registry::SpawnedWorkerRegistry; /// Serialises tests that mutate `YOI_RUNTIME_DIR`. @@ -62,7 +62,7 @@ impl Drop for EnvGuard { } } -/// Point `YOI_RUNTIME_DIR` at `dir`. The pod-registry then lives at +/// Point `YOI_RUNTIME_DIR` at `dir`. The worker-allocation then lives at /// `/workers.json` and Worker runtime sub-dirs at `/{worker_name}/`. fn set_runtime_dir(dir: &std::path::Path) { unsafe { @@ -380,7 +380,7 @@ async fn shutdown_releases_scope_allocation_when_present() { // Install a top-level allocation for "kid" so ShutDown has // something to release. - let guard = pod_registry::install_top_level( + let guard = worker_allocation::install_top_level( "kid".into(), std::process::id(), "/tmp/kid.sock".into(), @@ -412,7 +412,7 @@ async fn shutdown_releases_scope_allocation_when_present() { ) .await; - // Allocation is gone from the pod-registry. + // Allocation is gone from the worker-allocation. let g = LockFileGuard::open(&lock_path).unwrap(); assert!( g.data().find("kid").is_none(), diff --git a/crates/yoi/Cargo.toml b/crates/yoi/Cargo.toml index db129448..075ac71a 100644 --- a/crates/yoi/Cargo.toml +++ b/crates/yoi/Cargo.toml @@ -15,7 +15,6 @@ client = { workspace = true } memory = { workspace = true } manifest = { workspace = true } worker = { workspace = true } -pod-store = { workspace = true } session-store = { workspace = true } session-analytics = { workspace = true } ticket = { workspace = true } diff --git a/crates/yoi/src/session_cli.rs b/crates/yoi/src/session_cli.rs index 1430d769..9c1798ce 100644 --- a/crates/yoi/src/session_cli.rs +++ b/crates/yoi/src/session_cli.rs @@ -4,8 +4,8 @@ use std::path::PathBuf; use std::time::{Duration, SystemTime}; use manifest::paths; -use pod_store::{FsWorkerStore, WorkerMetadataStore}; use session_store::{FsStore, SessionId, Store}; +use session_store::{FsWorkerStore, WorkerMetadataStore}; use crate::worker_cleanup_cli::parse_duration; @@ -203,8 +203,8 @@ pub fn run_prune_with_roots( )); } let session_store = FsStore::new(data_dir.join("sessions")).map_err(to_error)?; - let pod_store = FsWorkerStore::new(data_dir.join("pods")).map_err(to_error)?; - let referenced_sessions = referenced_sessions(&pod_store)?; + let worker_metadata_store = FsWorkerStore::new(data_dir.join("workers")).map_err(to_error)?; + let referenced_sessions = referenced_sessions(&worker_metadata_store)?; let cutoff = options .older_than .map(|older_than| { @@ -315,10 +315,12 @@ pub fn run_prune_with_roots( }) } -fn referenced_sessions(pod_store: &FsWorkerStore) -> Result, SessionCliError> { +fn referenced_sessions( + worker_metadata_store: &FsWorkerStore, +) -> Result, SessionCliError> { let mut sessions = BTreeSet::new(); - for name in pod_store.list_names().map_err(to_error)? { - let metadata = pod_store + for name in worker_metadata_store.list_names().map_err(to_error)? { + let metadata = worker_metadata_store .read_by_name(&name) .map_err(to_error)? .ok_or_else(|| { @@ -358,8 +360,8 @@ pub fn help_text() -> &'static str { #[cfg(test)] mod tests { use super::*; - use pod_store::{WorkerActiveSegmentRef, WorkerMetadata}; use session_store::{Store, new_segment_id, new_session_id}; + use session_store::{WorkerActiveSegmentRef, WorkerMetadata}; use std::io::Write; #[test] @@ -441,7 +443,7 @@ mod tests { let tmp = tempfile::TempDir::new().unwrap(); let data_dir = tmp.path().join("data"); let session_store = FsStore::new(data_dir.join("sessions")).unwrap(); - let pod_store = FsWorkerStore::new(data_dir.join("pods")).unwrap(); + let worker_metadata_store = FsWorkerStore::new(data_dir.join("workers")).unwrap(); let referenced_session = new_session_id(); let referenced_segment = new_segment_id(); let orphan_session = new_session_id(); @@ -452,7 +454,7 @@ mod tests { session_store .create_segment(orphan_session, orphan_segment, &[]) .unwrap(); - pod_store + worker_metadata_store .write(&WorkerMetadata::new( "agent", Some(WorkerActiveSegmentRef::active_segment( diff --git a/crates/yoi/src/worker_cleanup_cli.rs b/crates/yoi/src/worker_cleanup_cli.rs index 77b6c12f..8e5a2c30 100644 --- a/crates/yoi/src/worker_cleanup_cli.rs +++ b/crates/yoi/src/worker_cleanup_cli.rs @@ -4,7 +4,7 @@ use std::path::{Path, PathBuf}; use std::time::{Duration, SystemTime}; use manifest::paths; -use pod_store::{FsWorkerStore, WorkerMetadata, WorkerMetadataStore, validate_worker_name}; +use session_store::{FsWorkerStore, WorkerMetadata, WorkerMetadataStore, validate_worker_name}; const MAX_REPORT_ITEMS: usize = 50; @@ -234,7 +234,7 @@ async fn run_delete( data_dir: PathBuf, runtime_dir: PathBuf, ) -> Result { - let store = FsWorkerStore::new(data_dir.join("pods")).map_err(to_error)?; + let store = FsWorkerStore::new(data_dir.join("workers")).map_err(to_error)?; let metadata = store.read_by_name(&options.name).map_err(to_error)?; let Some(metadata) = metadata else { return Ok(WorkerCleanupCliOutput { @@ -290,7 +290,7 @@ async fn run_prune( data_dir: PathBuf, runtime_dir: PathBuf, ) -> Result { - let store = FsWorkerStore::new(data_dir.join("pods")).map_err(to_error)?; + let store = FsWorkerStore::new(data_dir.join("workers")).map_err(to_error)?; let names = store.list_names().map_err(to_error)?; let cutoff = SystemTime::now() .checked_sub(options.older_than) @@ -498,7 +498,7 @@ fn prune_help_text() -> &'static str { #[cfg(test)] mod tests { use super::*; - use pod_store::WorkerActiveSegmentRef; + use session_store::WorkerActiveSegmentRef; use session_store::{Store, new_segment_id, new_session_id}; fn string_args(args: &[&str]) -> Vec { @@ -543,14 +543,14 @@ mod tests { let tmp = tempfile::TempDir::new().unwrap(); let data_dir = tmp.path().join("data"); let runtime_dir = tmp.path().join("run"); - let pod_store = FsWorkerStore::new(data_dir.join("pods")).unwrap(); + let worker_metadata_store = FsWorkerStore::new(data_dir.join("workers")).unwrap(); let session_store = session_store::FsStore::new(data_dir.join("sessions")).unwrap(); let session_id = new_session_id(); let segment_id = new_segment_id(); session_store .create_segment(session_id, segment_id, &[]) .unwrap(); - pod_store + worker_metadata_store .write(&WorkerMetadata::new( "agent", Some(WorkerActiveSegmentRef::active_segment( @@ -573,7 +573,12 @@ mod tests { assert_eq!(output.status, WorkerCleanupCliStatus::Success); assert!(output.stdout.contains("deleted: worker metadata")); - assert!(pod_store.read_by_name("agent").unwrap().is_none()); + assert!( + worker_metadata_store + .read_by_name("agent") + .unwrap() + .is_none() + ); assert!(session_store.exists(session_id, segment_id).unwrap()); } @@ -582,8 +587,8 @@ mod tests { let tmp = tempfile::TempDir::new().unwrap(); let data_dir = tmp.path().join("data"); let runtime_dir = tmp.path().join("run"); - let pod_store = FsWorkerStore::new(data_dir.join("pods")).unwrap(); - pod_store + let worker_metadata_store = FsWorkerStore::new(data_dir.join("workers")).unwrap(); + worker_metadata_store .write(&WorkerMetadata::new("agent", None)) .unwrap(); @@ -601,7 +606,12 @@ mod tests { assert_eq!(output.status, WorkerCleanupCliStatus::Success); assert!(output.stdout.contains("mode: dry-run")); - assert!(pod_store.read_by_name("agent").unwrap().is_some()); + assert!( + worker_metadata_store + .read_by_name("agent") + .unwrap() + .is_some() + ); } #[cfg(unix)] @@ -612,8 +622,8 @@ mod tests { let tmp = tempfile::TempDir::new().unwrap(); let data_dir = tmp.path().join("data"); let runtime_dir = tmp.path().join("run"); - let pod_store = FsWorkerStore::new(data_dir.join("pods")).unwrap(); - pod_store + let worker_metadata_store = FsWorkerStore::new(data_dir.join("workers")).unwrap(); + worker_metadata_store .write(&WorkerMetadata::new("agent", None)) .unwrap(); std::fs::create_dir_all(runtime_dir.join("agent")).unwrap(); @@ -634,6 +644,11 @@ mod tests { drop(listener); assert_eq!(output.status, WorkerCleanupCliStatus::Failure); assert!(output.stdout.contains("status: refused")); - assert!(pod_store.read_by_name("agent").unwrap().is_some()); + assert!( + worker_metadata_store + .read_by_name("agent") + .unwrap() + .is_some() + ); } } diff --git a/package.nix b/package.nix index 8e206b0c..6a2dd7b1 100644 --- a/package.nix +++ b/package.nix @@ -43,7 +43,7 @@ rustPlatform.buildRustPackage rec { filter = sourceFilter; }; - cargoHash = "sha256-9F60cIVhRTct8sK11xoqOVA4rLd5Ba76Vi7+Y2NFrRo="; + cargoHash = "sha256-9e99NfbErWlmyZqXd7d5UaJ88gx6ENbHOubqYtnjXVg="; depsExtraArgs = { # Older fetchCargoVendor utilities used crates.io's API download endpoint,