You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Parent:#860 Milestone: Phase 1: Rust foundation Host: both · Expected cost: $1,200
Stand up the Rust workspace: the crate layout a typical Rust project expects, the toolchain, CI, and the portability seam the TypeScript code doesn't have.
Cargo workspace layout — crates that mirror the TS module boundaries measured in the repo (LOC per area: utils 7,943 / cli 3,216 / handlers 2,954 / app 1,556 / repositories 1,637 / services 1,352 / adapters 742 / payments 695 / tor 216 / telemetry 175):
nostreamd (the binary: config, clustering/worker model, tor, telemetry wiring)
File-format conversion: TypeScript module-per-concern → Rust mod.rs/lib.rs conventions; rename TS camelCase files to Rust snake_case; map the TS config schema (src/@types/settings.ts, 514 lines) to a typed Rust config (serde, config crate, YAML source — resources/default-settings.yaml is the seed)
CI: cargo clippy -D warnings, cargo test, cargo fmt --check on every PR (checks.yml), plus the tauceti release-build job (cross-compilation target matrix if any)
Error model: thiserror per crate, anyhow at the binary; no unwrap outside tests (clippy lint enforces)
Async runtime decision recorded: tokio (multi-worker relay model maps to tokio tasks; the Node cluster worker model → tokio multi-threaded runtime + SO_REUSEPORT or an acceptor task)
Tracing: tracing + tracing-otlp replacing the pino/otlp telemetry surface
Acceptance:cargo build green on both hosts; CI green on a PR touching the workspace; the config crate loads default-settings.yaml and rejects the same malformed inputs the TS schema rejects (parity test with the TS settings-validation tests).
What landed. PR #879 merged into rewrite/main at ed31da2 (2026-10-18T02:20Z), branch tip 54e65141. Eight crates (nostream-core, nostream-config, nostream-storage, nostream-relay, nostream-services, nostream-admin, nostream-cli, nostreamd), rust-toolchain.toml pinned to 1.99.1 with rustfmt+clippy, edition 2024 / resolver 3, one thiserror enum per crate with anyhow confined to the two binaries, NotImplemented instead of todo!()/unimplemented!(), the recorded tokio decision (ADR docs/rewrite/decisions/0001-runtime-and-telemetry.md), and tracing + OTLP behind nostreamd's otlp feature. nostream-config is implemented rather than stubbed: typed schema, loader with the capture's fallback rule, dot-path editor, redaction, guided catalogue, and a parity fixture of 19 measured cases (exactly one exempt path, eventStore.backend, for the LMDB backend).
Acceptance.
cargo build green on both hosts: this sandbox through scripts/rust.sh (the builder container) and GitHub Actions ubuntu-latest. tauceti is still a precondition, not a measurement — see below.
Config parity: crates/nostream-config/tests/ts_parity.rs replays the fixture generated from the capture at 242a3001; it mirrors test/unit/utils/settings-config.spec.ts's validation surface. The final head is 153 tests, 0 failed.
Cost — expected $1,200, actual $14.7016. The gap is real but it is not a saving, and the expected figure was not wrong for what it priced: $1,200 prices the whole 20,486-LOC port becoming working Rust. This job delivered the workspace, the CI seam, 121 labelled stubs, and one implemented crate; the handlers, repositories, payment processors, admin API and both backends carry their own cost lines (spec.md §6/§8, e.g. $250–400 for the Phase 2 repository layer). The measured number covers 15 sessions / 1,437 requests / 5.09 h of summed wall time up to the reviewed head 893ba79; the later Greptile fix round (three commits, 2×P1 + 2×P2, no subagents) is not in it. The reusable figure for planning is $2–4 per config-sized crate including review.
Maintainer actions.
Rust Checks is now a required context on rewrite/main (ruleset 25325233, eight contexts) — landed with the rewrite setup. The remaining half of the original note is for cutover: ruleset main (2355390) still lists six contexts and must gain Rust Checks in the same change that makes main receive the Rust tree.
tauceti verification is still open: a runner must be registered there and Cameri must agree the runbook with Ada before this host is touched.
Post-merge follow-up already in the tree:54e6514 improves the typed-fit message where both a rate and its period are fractional, and 384b283 (#883) adds the rewrite/mainCLAUDE.md that now carries the crate, lint, changeset and path-filter rules for the next job.
Activity
chappie-daemon commentedon Oct 19, 2026
Phase 1 is merged and closed out.
What landed. PR #879 merged into
rewrite/mainated31da2(2026-10-18T02:20Z), branch tip54e65141. Eight crates (nostream-core,nostream-config,nostream-storage,nostream-relay,nostream-services,nostream-admin,nostream-cli,nostreamd),rust-toolchain.tomlpinned to 1.99.1 with rustfmt+clippy, edition 2024 / resolver 3, onethiserrorenum per crate withanyhowconfined to the two binaries,NotImplementedinstead oftodo!()/unimplemented!(), the recorded tokio decision (ADRdocs/rewrite/decisions/0001-runtime-and-telemetry.md), and tracing + OTLP behindnostreamd'sotlpfeature.nostream-configis implemented rather than stubbed: typed schema, loader with the capture's fallback rule, dot-path editor, redaction, guided catalogue, and a parity fixture of 19 measured cases (exactly one exempt path,eventStore.backend, for the LMDB backend).Acceptance.
cargo buildgreen on both hosts: this sandbox throughscripts/rust.sh(the builder container) and GitHub Actionsubuntu-latest. tauceti is still a precondition, not a measurement — see below.Rust Checksran on feat(rust): Phase 1 foundation — workspace, crates, config parity, CI #879 (1m14s at the final head) and every other required context passed.crates/nostream-config/tests/ts_parity.rsreplays the fixture generated from the capture at242a3001; it mirrorstest/unit/utils/settings-config.spec.ts's validation surface. The final head is 153 tests, 0 failed.Cost — expected $1,200, actual $14.7016. The gap is real but it is not a saving, and the expected figure was not wrong for what it priced: $1,200 prices the whole 20,486-LOC port becoming working Rust. This job delivered the workspace, the CI seam, 121 labelled stubs, and one implemented crate; the handlers, repositories, payment processors, admin API and both backends carry their own cost lines (
spec.md§6/§8, e.g. $250–400 for the Phase 2 repository layer). The measured number covers 15 sessions / 1,437 requests / 5.09 h of summed wall time up to the reviewed head893ba79; the later Greptile fix round (three commits, 2×P1 + 2×P2, no subagents) is not in it. The reusable figure for planning is $2–4 per config-sized crate including review.Maintainer actions.
Rust Checksis now a required context onrewrite/main(ruleset 25325233, eight contexts) — landed with the rewrite setup. The remaining half of the original note is for cutover: rulesetmain(2355390) still lists six contexts and must gainRust Checksin the same change that makesmainreceive the Rust tree.Post-merge follow-up already in the tree:
54e6514improves the typed-fit message where both a rate and its period are fractional, and384b283(#883) adds therewrite/mainCLAUDE.mdthat now carries the crate, lint, changeset and path-filter rules for the next job.