Files
zosstorage/docs/DEV_WORKFLOW.md
Jan De Landtsheer 507bc172c2 feat: first-draft preview-capable zosstorage
- CLI: add topology selection (-t/--topology), preview flags (--show/--report), and removable policy override (--allow-removable) (src/cli/args.rs)
- Config: built-in sensible defaults; deterministic overlays for logging, fstab, removable, topology (src/config/loader.rs)
- Device: discovery via /proc + /sys with include/exclude regex and removable policy (src/device/discovery.rs)
- Idempotency: detection via blkid; safe emptiness checks (src/idempotency/mod.rs)
- Partition: topology-driven planning (Single, DualIndependent, BtrfsRaid1, SsdHddBcachefs) (src/partition/plan.rs)
- FS: planning + creation (mkfs.vfat, mkfs.btrfs, bcachefs format) and UUID capture via blkid (src/fs/plan.rs)
- Orchestrator: pre-flight with preview JSON (disks, partition_plan, filesystems_planned, mount scheme). Skips emptiness in preview; supports stdout+file (src/orchestrator/run.rs)
- Util/Logging/Types/Errors: process execution, tracing, shared types (src/util/mod.rs, src/logging/mod.rs, src/types.rs, src/errors.rs)
- Docs: add README with exhaustive usage and preview JSON shape (README.md)

Builds and unit tests pass: discovery, util, idempotency helpers, and fs parser tests.
2025-09-29 11:37:07 +02:00

123 lines
6.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Modular Development Workflow and Traceability
Goal
- Enable incremental implementation without re-reading the entire codebase each time.
- Make module changes discoverable via grep and predictable locations.
- Keep a single source of truth for the API surface, invariants, and extension points.
Core Principles
1) Contract-first per module
- API signatures and responsibilities are documented in [docs/API-SKELETONS.md](docs/API-SKELETONS.md) and mirrored by crate modules:
- [src/types.rs](src/types.rs)
- [fn load_and_merge()](src/config/loader.rs:1), [fn validate()](src/config/loader.rs:1)
- [fn from_args()](src/cli/args.rs:1)
- [struct LogOptions](src/logging/mod.rs:1), [fn init_logging()](src/logging/mod.rs:1)
- [fn discover()](src/device/discovery.rs:1)
- [fn plan_partitions()](src/partition/plan.rs:1), [fn apply_partitions()](src/partition/plan.rs:1)
- [fn plan_filesystems()](src/fs/plan.rs:1), [fn make_filesystems()](src/fs/plan.rs:1)
- [fn plan_mounts()](src/mount/ops.rs:1), [fn apply_mounts()](src/mount/ops.rs:1), [fn maybe_write_fstab()](src/mount/ops.rs:1)
- [const REPORT_VERSION](src/report/state.rs:1), [fn build_report()](src/report/state.rs:1), [fn write_report()](src/report/state.rs:1)
- [struct Context](src/orchestrator/run.rs:1), [fn run()](src/orchestrator/run.rs:1)
- [fn detect_existing_state()](src/idempotency/mod.rs:1), [fn is_empty_disk()](src/idempotency/mod.rs:1)
- [struct CmdOutput](src/util/mod.rs:1), [fn which_tool()](src/util/mod.rs:1), [fn run_cmd()](src/util/mod.rs:1), [fn run_cmd_capture()](src/util/mod.rs:1), [fn udev_settle()](src/util/mod.rs:1)
2) Grep-able region markers in code
- Every module contains the following optional annotated regions:
- // REGION: API
- // REGION: EXTENSION_POINTS
- // REGION: SAFETY
- // REGION: ERROR_MAPPING
- // REGION: TODO
- Example snippet to add near top of a module:
// REGION: API
// api: device::discover(filter: &DeviceFilter) -> Result<Vec<Disk>>
// api: device::DeviceProvider
// REGION: API-END
- These must be kept concise, one-liners per function/trait/struct; they act as a quick index for search.
3) Stable identifiers for cross-references
- Use short identifiers in comments to reference public items:
- api: module::item
- ext: module::hook_or_trait
- safety: module::invariant_name
- errmap: module::error_path
- This allows quick discovery via regex: grep -R "api: device::" src/
4) Single source of truth for API surface
- Keep high-level API in [docs/API-SKELETONS.md](docs/API-SKELETONS.md) as canonical index. After adding/removing a public function or type, update this file.
- Add a short note in [docs/SPECS.md](docs/SPECS.md) if behavior or invariants change.
5) Architectural decisions recorded as ADRs
- Use docs/adr/NNNN-title.md to document decisions (context, decision, consequences).
- Start with [docs/adr/0001-modular-workflow.md](docs/adr/0001-modular-workflow.md) (added alongside this doc).
- Link ADRs from [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) when they supersede or refine prior guidance.
6) Module ownership and boundaries
- Add a “Module Responsibilities” section in each modules header doc comment summarizing scope and non-goals.
- Example references:
- [src/device/discovery.rs](src/device/discovery.rs)
- [src/partition/plan.rs](src/partition/plan.rs)
- [src/fs/plan.rs](src/fs/plan.rs)
- [src/mount/ops.rs](src/mount/ops.rs)
- [src/report/state.rs](src/report/state.rs)
7) Invariants and safety notes
- For code that must uphold safety or idempotency invariants, annotate with:
// SAFETY: explanation
// IDEMPOTENCY: explanation
- Example locations:
- [fn apply_partitions()](src/partition/plan.rs:1) must enforce empty-disks rule when configured.
- [fn make_filesystems()](src/fs/plan.rs:1) must not run if partitioning failed.
8) Error mapping consistency
- Centralize conversions to [enum Error](src/errors.rs:1). When calling external tools, wrap failures into Error::Tool with stderr captured.
- Annotate mapping areas with:
// ERROR: mapping external failure to Error::Tool
9) Module-local CHANGELOG entries
- Keep a single CHANGELOG in the repo root, plus module-local “Changes” sections appended on each module top comment (short bullets).
- Cross-link to the ADR when relevant.
10) Task-level breadcrumbs
- For multi-step features, add a short progress marker at top of relevant modules:
// TODO(KILO): feature-X step 2/4 parsing args done; next implement validation
- Summary of active tasks can also live in docs/SPECS.md under “In-Progress Work”.
11) Example configs and fixtures
- Keep comprehensive examples in:
- [config/zosstorage.example.yaml](config/zosstorage.example.yaml)
- Add minimal example variants if needed for tests (future):
- examples/config/minimal.yaml
- examples/config/dual-btrfs.yaml
- examples/config/ssd-hdd-bcachefs.yaml
12) “Golden paths” for resuming work
- If resuming work later:
- Read module headers for responsibilities
- Grep for REGION markers: API / TODO / SAFETY / ERROR_MAPPING
- Check [docs/API-SKELETONS.md](docs/API-SKELETONS.md) for contract changes
- Check latest ADRs in docs/adr/
- Check [docs/SPECS.md](docs/SPECS.md) and the “In-Progress Work” section (if used)
Checklist for adding a new feature
- Update contracts:
- Add or modify function/type signatures in code and reflect in [docs/API-SKELETONS.md](docs/API-SKELETONS.md)
- Add REGION: API one-liners for the new items
- Update invariants:
- Add REGION: SAFETY notes if needed
- Update specs:
- Document behavior in [docs/SPECS.md](docs/SPECS.md)
- If it is a long-term decision, add an ADR under docs/adr/
- Add examples if config or output formats change
- Update [config/zosstorage.example.yaml](config/zosstorage.example.yaml) or add a new example file
- Keep error mapping and logging consistent:
- Ensure any external tool calls map errors to [enum Error](src/errors.rs:1)
- Run cargo build and update any broken references
Optional automation (future)
- A simple “index check” script (cargo xtask) could validate:
- All public items referenced under REGION: API appear in [docs/API-SKELETONS.md](docs/API-SKELETONS.md)
- No broken module references
- REGION markers are well-formed
By following these conventions, changes stay localized and discoverable. A contributor (human or assistant) can quickly locate relevant areas by scanning module headers, REGION markers, and the centralized API/docs without re-reading the entire tree.