Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Appendix: Workspace Scaffold

This is the whole of panoptes-control at a glance — every file, what creates it, and which dependencies each crate pulls in. The verified reference workspace (38 tests, clippy clean) lives at github.com/tbar4/panoptes_control. Use this page as the map when a build chapter says "add a crate" and you want to see where it sits.

The annotated tree

Each file is tagged with the chapter that creates it.

panoptes_control/
├── Cargo.toml                         # workspace manifest — Part I (Phase 0)
├── crates/
│   ├── control-core/                  # the seams: everything depends on this
│   │   ├── Cargo.toml
│   │   └── src/
│   │       ├── lib.rs                 # module wiring + re-exports
│   │       ├── ids.rs                 # RunId/JobId newtypes        — Part II · build-domain
│   │       ├── domain.rs              # Run, Job, EvalJob, …        — Part II · build-domain
│   │       ├── error.rs               # ControlError + is_retryable — Part II · build-seam
│   │       ├── worker.rs              # WorkerHandle trait (the seam)— Part II · build-seam
│   │       ├── proto.rs               # Message wire enum           — Part II · build-seam
│   │       └── codec.rs               # MessageStream framed codec  — Part VIII · build-codec
│   ├── control-eval/                  # the eval workload + file contract
│   │   ├── Cargo.toml
│   │   └── src/
│   │       ├── lib.rs
│   │       ├── client.rs              # ModelClient + HttpModelClient — Part III · build-eval
│   │       ├── eval.rs                # run_eval                      — Part III · build-eval
│   │       └── contract.rs            # manifest + JSONL records      — Part III · build-contract
│   ├── control-store/                 # sqlx / SQLite persistence
│   │   ├── Cargo.toml
│   │   ├── migrations/
│   │   │   └── 0001_init.sql          # runs + jobs tables          — Part IV · build-store
│   │   └── src/
│   │       └── lib.rs                 # Store: claim, record, usage — Part IV · build-store/build-claim
│   ├── panoptes-control/              # the coordinator binary (lib + main)
│   │   ├── Cargo.toml
│   │   └── src/
│   │       ├── lib.rs                 # axum API + telemetry + /stats — Part V · build-api, Part VII
│   │       ├── worker.rs              # LocalWorker                   — Part VI · build-scheduler
│   │       ├── scheduler.rs           # Scheduler, plan_jobs, retry   — Part VI · build-scheduler
│   │       ├── remote.rs              # RemoteWorker, SharedPool, actor— Part VIII · build-remote
│   │       ├── main.rs                # serve + shutdown + worker port — Part VI/VIII · build-runloop
│   │       └── tests/
│   │           └── distributed.rs     # kill-a-worker capstone         — Part VIII · build-capstone
│   └── panoptes-worker/               # the networked worker binary
│       ├── Cargo.toml
│       └── src/
│           ├── lib.rs                 # run_session / serve_worker     — Part VIII · build-remote
│           └── main.rs                # clap + reconnect loop          — Part VIII · build-remote

The workspace manifest

Dependencies are declared once in [workspace.dependencies] and each crate opts in with { workspace = true }. One version, chosen once, for the whole tree.

[workspace]
resolver = "2"
members = ["crates/control-core", "crates/control-eval", "crates/control-store", "crates/panoptes-control", "crates/panoptes-worker"]

[workspace.dependencies]
serde = { version = "1", features = ["derive"] }   # derive-based (de)serialization
serde_json = "1"                                     # JSON on the wire and in JSONL logs
chrono = { version = "0.4", features = ["serde"] }   # timestamps on runs
uuid = { version = "1", features = ["v4", "serde"] } # RunId/JobId inner type
thiserror = "2"                                       # the ControlError enum
anyhow = "1"                                          # binaries' top-level errors
async-trait = "0.1"                                   # async methods in WorkerHandle/ModelClient
tokio = { version = "1", features = ["full"] }        # the async runtime
tokio-util = { version = "0.7", features = ["codec"] }# LengthDelimitedCodec framing
futures = "0.3"                                        # buffer_unordered, Sink/Stream ext
axum = "0.7"                                           # the coordinator HTTP API
tower = "0.5"                                          # service middleware plumbing
tower-http = { version = "0.6", features = ["trace"] }# request tracing layer
sqlx = { version = "0.8", features = ["runtime-tokio", "sqlite", "macros", "migrate", "chrono", "uuid"] } # persistence
clap = { version = "4", features = ["derive"] }        # the binaries' CLIs
reqwest = { version = "0.12", features = ["json"] }    # HttpModelClient's HTTP calls
tracing = "0.1"                                         # spans + events
tracing-subscriber = { version = "0.3", features = ["env-filter", "json"] } # subscriber
bytes = "1"                                             # frame buffers
# dev
wiremock = "0.6"                                        # mock the model API in tests
pretty_assertions = "1"                                # readable assert_eq diffs

Per-crate dependency matrix

Which crate pulls what. core = control-core. Everything points at control-core; only the two binaries name concrete transports.

CrateWorkspace deps
control-coreserde, serde_json, chrono, uuid, thiserror, async-trait, tokio, tokio-util, futures, bytes
control-evalcontrol-core, serde, serde_json, async-trait, reqwest, tokio · dev: wiremock, pretty_assertions, tokio
control-storecontrol-core, sqlx, serde, serde_json, chrono, uuid, tokio · dev: pretty_assertions
panoptes-controlcontrol-core, control-eval, control-store, axum, tower, tower-http, tracing, tracing-subscriber, serde, serde_json, chrono, uuid, tokio, futures, async-trait, clap, anyhow · dev: wiremock, reqwest, pretty_assertions
panoptes-workercontrol-core, control-eval, tokio, clap, anyhow, tracing, tracing-subscriber · dev: async-trait, pretty_assertions

Expected test progression

Each part adds tests. When you finish a part, cargo test across the workspace should reach the running total below.

PartCrate(s) touchedAddsWorkspace total
II — Corecontrol-coreids, domain, error, worker, proto12
III — Evalcontrol-evalclient, eval, contract17
IV — Persistencecontrol-storestore CRUD, claim, record, idempotency22
V — Servicepanoptes-controlAPI handlers (spawn on port 0)26
VI — Schedulerpanoptes-controlplan/retry/tick, LocalWorker30
VII — Telemetrypanoptes-control, control-store/stats + usage_by_model33
VIII — Clustercontrol-core, control-store, panoptes-control, panoptes-workercodec, remote, heartbeat, worker, capstone38

Note: exact per-crate counts — control-core 12, control-eval 5, control-store 5, panoptes-control 15 (14 unit + 1 integration), panoptes-worker 1 — sum to 38. The table's "workspace total" column tracks the cumulative figure as you build each arc in order.