f7d69cde50
Two parallel scratch experiments under server/examples/ exploring the
typed Rust state machine that should replace huskies's current
stringly-typed CRDT representation (story 520).
- pipeline_state_sketch_bare.rs — hand-rolled, plain enums + match
- pipeline_state_sketch_statig.rs — using the statig crate
Both sketches:
- Define the same Stage enum (Backlog, Coding, Qa, Merge, Done, Archived)
- Define ArchiveReason (subsumes refactor 436's blocked/merge_failure/review_hold)
- Define ExecutionState (per-node, separate from synced Stage) — bare only
- Define PipelineEvent and the valid transitions
- Make bug 519 unrepresentable: Stage::Merge requires NonZeroU32 commits_ahead
- Make bug 502 unrepresentable: Coder agents can't be assigned to Merge state
- Have happy-path tests, retry-loop tests, and invalid-transition tests
Differences:
- Bare uses pure pattern matching, no framework. ~720 lines.
- Statig uses #[state_machine] proc macro and gets free hierarchical
states via the `active` superstate that factors out the cross-cutting
Block / ReviewHold / Abandon / Supersede transitions across the four
active stages. ~440 lines, 11 passing tests.
Run with:
cargo run --example pipeline_state_sketch_bare -p huskies
cargo run --example pipeline_state_sketch_statig -p huskies
cargo test --example pipeline_state_sketch_bare -p huskies
cargo test --example pipeline_state_sketch_statig -p huskies
Adds statig 0.3 as a dev-dependency in server/Cargo.toml. Cargo.lock
updated to include statig + statig-macro and their transitive deps.
Not wired into the main codebase. Once we agree on which version to
adopt, story 520 promotes the chosen sketch into a real
server/src/pipeline_state.rs module.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
60 lines
2.0 KiB
TOML
60 lines
2.0 KiB
TOML
[package]
|
|
name = "huskies"
|
|
version = "0.9.0"
|
|
edition = "2024"
|
|
build = "build.rs"
|
|
|
|
[dependencies]
|
|
async-stream = { workspace = true }
|
|
async-trait = { workspace = true }
|
|
bytes = { workspace = true }
|
|
chrono = { workspace = true, features = ["serde"] }
|
|
chrono-tz = { workspace = true }
|
|
eventsource-stream = { workspace = true }
|
|
futures = { workspace = true }
|
|
homedir = { workspace = true }
|
|
ignore = { workspace = true }
|
|
mime_guess = { workspace = true }
|
|
notify = { workspace = true }
|
|
poem = { workspace = true, features = ["websocket"] }
|
|
poem-openapi = { workspace = true, features = ["swagger-ui"] }
|
|
portable-pty = { workspace = true }
|
|
reqwest = { workspace = true, features = ["json", "stream", "form"] }
|
|
rust-embed = { workspace = true }
|
|
serde = { workspace = true, features = ["derive"] }
|
|
serde_json = { workspace = true }
|
|
serde_urlencoded = { workspace = true }
|
|
sha2 = { workspace = true }
|
|
serde_yaml = { workspace = true }
|
|
strip-ansi-escapes = { workspace = true }
|
|
tokio = { workspace = true, features = ["rt-multi-thread", "macros", "sync", "process"] }
|
|
toml = { workspace = true }
|
|
uuid = { workspace = true, features = ["v4", "serde"] }
|
|
walkdir = { workspace = true }
|
|
matrix-sdk = { workspace = true }
|
|
pulldown-cmark = { workspace = true }
|
|
regex = { workspace = true }
|
|
tokio-tungstenite = { workspace = true }
|
|
|
|
# Force bundled SQLite so static musl builds don't need a system libsqlite3
|
|
libsqlite3-sys = { version = "0.35.0", features = ["bundled"] }
|
|
sqlx = { workspace = true }
|
|
wait-timeout = "0.2.1"
|
|
bft-json-crdt = { path = "../crates/bft-json-crdt", default-features = false, features = ["bft"] }
|
|
fastcrypto = "0.1.8"
|
|
indexmap = { version = "2.2.6", features = ["serde"] }
|
|
|
|
[target.'cfg(unix)'.dependencies]
|
|
libc = { workspace = true }
|
|
|
|
[lints.rust.unexpected_cfgs]
|
|
level = "warn"
|
|
check-cfg = ["cfg(feature, values(\"logging-base\"))"]
|
|
|
|
[dev-dependencies]
|
|
tempfile = { workspace = true }
|
|
mockito = "1"
|
|
filetime = { workspace = true }
|
|
# For the pipeline_state_sketch_statig example only.
|
|
statig = "0.3"
|