decrating: Phase 1 — scaffold ops/ and runtime/ layer dirs#49
Conversation
Adds two of the five layered architecture directories per docs/decrating-plan.md §4. Each folder gets a CLAUDE.md describing its single responsibility and import rules, plus an empty mod.rs stub. Layer rules (enforced by .github/workflows/architecture-guard.yml): - ops (layer 1, bottom) — I/O primitives, may import nothing above - runtime (layer 2) — pure-data runtime context, may import ops - state (layer 3) — persistence, may import runtime/ops [deferred] - plan (layer 4) — planning algorithms [deferred] - engine (layer 5, top) — orchestration [deferred] The state/, plan/, and engine/ directories are deferred because each name collides with an existing flat module file (state.rs, plan.rs, engine.rs) and Rust cannot disambiguate <name>.rs from <name>/mod.rs simultaneously. Those three layer directories will be created in their respective Phase 2 absorption PRs (where the flat file is deleted in the same commit, removing the conflict atomically).
|
Warning You have reached your daily quota limit. Please wait up to 24 hours and I will start processing your requests again! |
|
Warning Rate limit exceeded
Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 14 minutes and 37 seconds. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Run ID: 📒 Files selected for processing (4)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Move shipper-lock crate (2059 LOC) into crates/shipper/src/ops/lock/
as a crate-private module. Delete the stale 337-LOC duplicate at
crates/shipper/src/lock.rs and the 1-LOC pub-use shim at lock_micro.rs.
Remove shipper-lock from workspace members and from shipper's deps.
Drop the micro-lock feature flag (shipper, shipper-cli) and strip it
from the CI/CircleCI feature-matrix arrays.
The public surface at shipper::lock is preserved via
`pub use crate::ops::lock;` in lib.rs so that shipper-cli and
integration-test callers of shipper::lock::{LockFile, LockInfo,
lock_path, LOCK_FILE, is_locked, read_lock_info} continue to work
unchanged. The ops/ scaffold from PR #49 gets its first inhabitant:
ops/mod.rs now declares `pub mod lock;`.
Files kept flat: everything lives in ops/lock/mod.rs (core is ~270
non-test LOC — well under the 500-LOC guideline; the remainder is the
test suite which per instructions stays inline).
Tests preserved inline:
- 127 lock tests (ops::lock::{tests, snapshot_tests, edge_case_tests,
hardened_tests, proptest_edge_cases, hardened_proptests,
lock_edge_case_tests, tests::proptests}).
- 25 insta snapshot files moved under ops/lock/snapshots/ and renamed
from `shipper_lock__*` to `shipper__ops__lock__*` to match the new
crate + module path. Internal `source:` headers rewritten to
`crates/shipper/src/ops/lock/mod.rs`. No snapshot content changes.
insta yaml feature added to shipper's dev-dependencies (shipper-lock
previously pulled it in via `insta = { workspace = true }`; shipper
only had `insta = "1.46.3"`).
Per docs/decrating-plan.md §6 Phase 2.
…-invariants-2026-05-22 merge: backfill shipper review-invariant sync
Summary
Phase 1 of the decrating plan (per `docs/decrating-plan.md`). Lays down two of the five layered-architecture directories inside `crates/shipper/src/`:
Each folder gets a `CLAUDE.md` describing its single responsibility, allowed imports, and what lives there, plus an empty `mod.rs` stub.
Why only 2 of 5 layers
The other three layer dirs (`state/`, `plan/`, `engine/`) each collide with an existing flat module file (`state.rs`, `plan.rs`, `engine.rs`). Rust cannot resolve `pub mod state;` when both `state.rs` and `state/mod.rs` exist. Those three layer directories are deferred to their respective Phase 2 absorption PRs, where the flat file is deleted in the same commit — eliminating the conflict atomically.
This is also why Phase 2 absorptions for those three layers must come BEFORE absorptions targeting their layer (e.g., `auth → ops/auth/` is independent of state.rs/plan.rs/engine.rs and can land first; but `store → state/store/` requires the `state/` dir to exist, which requires `state.rs` to be deleted in the SAME PR via the absorption move).
Architecture-guard CI
The `architecture-guard` workflow added in PR #48 already handles missing layer dirs gracefully (`if [ ! -d ... ]; then exit 0`). With this PR, the guard becomes meaningful for `ops/` and `runtime/` immediately.
Test plan
Stacking
This PR is independent of #48 (plan doc + CI workflow) and can merge in either order. Phase 2 absorption PRs will branch off main after this lands.