diff --git a/README.md b/README.md
index 1f84a3e..130ac2b 100644
--- a/README.md
+++ b/README.md
@@ -24,10 +24,10 @@ Key modules
- [src/mount/ops.rs](src/mount/ops.rs)
Features at a glance
-- Topology-driven planning with built-in defaults: BtrfsSingle, BcachefsSingle, DualIndependent, Bcachefs2Copy, BtrfsRaid1, SsdHddBcachefs
-- Non-destructive preview: --show/--report outputs JSON summary (disks, partition plan, filesystems, planned mountpoints)
+- Topology auto-selection with built-in defaults; optional kernel cmdline override via `zosstorage.topology=` (see ADR-0002)
+- Non-destructive preview: `--show`/`--report` outputs JSON summary (disks, partition plan, filesystems, planned mountpoints)
- Safe discovery: excludes removable media by default (USB sticks) unless explicitly allowed
-- Config-optional: the tool runs without any YAML; sensible defaults are always present and may be overridden/merged by config
+- No external YAML configuration; defaults-only per ADR-0002 (sane built-ins, topology may be overridden by kernel cmdline)
Requirements
- Linux with /proc and /sys mounted (initramfs friendly)
@@ -45,8 +45,6 @@ Install and build
Binary is target/release/zosstorage.
CLI usage
-- Topology selection (config optional):
- -t, --topology btrfs-single|bcachefs-single|dual-independent|bcachefs-2copy|btrfs-raid1|ssd-hdd-bcachefs
- Preview (non-destructive):
--show Print JSON summary to stdout
--report PATH Write JSON summary to a file
@@ -56,22 +54,30 @@ CLI usage
-l, --log-level LEVEL error|warn|info|debug (default: info)
-L, --log-to-file Also write logs to /run/zosstorage/zosstorage.log
- Other:
- -c, --config PATH Merge a YAML config file (overrides defaults)
-s, --fstab Enable writing /etc/fstab entries (when mounts are applied)
-a, --apply Perform partitioning, filesystem creation, and mounts (destructive)
-f, --force Present but not implemented (returns an error)
+Deprecated (ignored with warning; see ADR-0002)
+ -t, --topology VALUE Ignored; use kernel cmdline `zosstorage.topology=` instead
+ -c, --config PATH Ignored; external YAML configuration is not used at runtime
+
Examples
-- Single disk plan with debug logs:
- sudo ./zosstorage --show -t btrfs-single -l debug
-- RAID1 btrfs across two disks; print and write summary:
- sudo ./zosstorage --show --report /run/zosstorage/plan.json -t btrfs-raid1 -l debug -L
-- SSD+HDD bcachefs plan, include removable devices (for lab cases):
- sudo ./zosstorage --show -t ssd-hdd-bcachefs --allow-removable -l debug
+- Single disk plan with debug logs (defaults to btrfs_single automatically):
+ sudo ./zosstorage --show -l debug
+- Two-disk plan (defaults to dual_independent automatically), write summary:
+ sudo ./zosstorage --show --report /run/zosstorage/plan.json -l debug -L
+- Include removable devices for lab scenarios:
+ sudo ./zosstorage --show --allow-removable -l debug
- Quiet plan to file:
- sudo ./zosstorage --report /run/zosstorage/plan.json -t dual-independent
-- Apply single-disk btrfs (DESTRUCTIVE; wipes target disk):
- sudo ./zosstorage --apply -t btrfs-single
+ sudo ./zosstorage --report /run/zosstorage/plan.json
+- Apply single-disk plan (DESTRUCTIVE; wipes target disk; defaults select topology automatically):
+ sudo ./zosstorage --apply
+
+Kernel cmdline override (at boot)
+- To force a topology, pass one of:
+ zosstorage.topology=btrfs-single | bcachefs-single | dual-independent | btrfs-raid1 | ssd-hdd-bcachefs | bcachefs-2copy
+- The override affects only topology; all other settings use sane built-in defaults.
Preview JSON shape (examples)
1) Already provisioned (idempotency success):
diff --git a/docs/Callgraph.svg b/docs/Callgraph.svg
new file mode 100644
index 0000000..ca0f970
--- /dev/null
+++ b/docs/Callgraph.svg
@@ -0,0 +1,1716 @@
+
+
\ No newline at end of file
diff --git a/docs/FUNCTION_LIST.md b/docs/FUNCTION_LIST.md
new file mode 100644
index 0000000..7fbf082
--- /dev/null
+++ b/docs/FUNCTION_LIST.md
@@ -0,0 +1,294 @@
+# Function Reference - Call Graph Analysis
+
+> This documentation is automatically derived from [`Callgraph.svg`](Callgraph.svg) and provides a comprehensive overview of all functions in the zosstorage project, organized by module.
+
+## Table of Contents
+
+- [Main Entry Points](#main-entry-points)
+- [CLI & Configuration](#cli--configuration)
+- [Orchestration](#orchestration)
+- [Device Discovery](#device-discovery)
+- [Partition Management](#partition-management)
+- [Filesystem Operations](#filesystem-operations)
+- [Mount Operations](#mount-operations)
+- [Idempotency & State](#idempotency--state)
+- [Reporting](#reporting)
+- [Utilities](#utilities)
+- [Logging](#logging)
+- [Type Definitions](#type-definitions)
+
+---
+
+## Main Entry Points
+
+### [`src/main.rs`](../src/main.rs)
+
+| Function | Purpose |
+|----------|---------|
+| `main()` | Application entry point; initializes the program and handles top-level errors |
+| `real_main()` | Core application logic; orchestrates the main workflow after initialization |
+
+---
+
+## CLI & Configuration
+
+### [`src/cli/args.rs`](../src/cli/args.rs)
+
+**Structs:** `Cli`, `LogLevelArg` (enum)
+
+| Function | Purpose |
+|----------|---------|
+| `from_args()` | Parses command-line arguments and returns a `Cli` configuration object |
+
+### [`src/config/loader.rs`](../src/config/loader.rs)
+
+| Function | Purpose |
+|----------|---------|
+| `load_and_merge()` | Loads configuration from multiple sources and merges them into a unified config |
+| `validate()` | Validates the merged configuration for correctness and completeness |
+| `to_value()` | Converts configuration structures to internal value representation |
+| `merge_value()` | Recursively merges configuration values, handling conflicts appropriately |
+| `cli_overlay_value()` | Overlays CLI-provided values onto existing configuration |
+| `kernel_cmdline_topology()` | Extracts topology information from kernel command line parameters |
+| `parse_topology_token()` | Parses individual topology tokens from kernel cmdline |
+| `default_config()` | Generates default configuration values when no config file is present |
+
+---
+
+## Orchestration
+
+### [`src/orchestrator/run.rs`](../src/orchestrator/run.rs)
+
+**Structs:** `Context`
+
+| Function | Purpose |
+|----------|---------|
+| `Context::new()` | Creates a new orchestration context with default settings |
+| `Context::with_show()` | Builder method to enable show/dry-run mode |
+| `Context::with_apply()` | Builder method to enable apply mode (actual execution) |
+| `Context::with_report_path()` | Builder method to set the report output path |
+| `Context::with_mount_existing()` | Builder method to configure mounting of existing filesystems |
+| `Context::with_report_current()` | Builder method to enable reporting of current system state |
+| `Context::with_topology_from_cli()` | Builder method to set topology from CLI arguments |
+| `Context::with_topology_from_cmdline()` | Builder method to set topology from kernel cmdline |
+| `run()` | Main orchestration function; coordinates all storage operations |
+| `build_device_filter()` | Constructs device filter based on configuration and user input |
+| `enforce_empty_disks()` | Validates that target disks are empty before proceeding |
+| `role_str()` | Converts partition role enum to human-readable string |
+| `build_summary_json()` | Builds a JSON summary of operations performed |
+
+---
+
+## Device Discovery
+
+### [`src/device/discovery.rs`](../src/device/discovery.rs)
+
+**Structs:** `Disk`, `DeviceFilter`, `SysProvider`
+**Traits:** `DeviceProvider`
+
+| Function | Purpose |
+|----------|---------|
+| `DeviceFilter::matches()` | Checks if a device matches the configured filter criteria |
+| `SysProvider::new()` | Creates a new sysfs-based device provider |
+| `SysProvider::list_block_devices()` | Lists all block devices found via sysfs |
+| `SysProvider::probe_properties()` | Probes detailed properties of a specific device |
+| `discover()` | Entry point for device discovery using default provider |
+| `discover_with_provider()` | Device discovery with custom provider (for testing/flexibility) |
+| `is_ignored_name()` | Checks if device name should be ignored (loop, ram, etc.) |
+| `sys_block_path()` | Constructs sysfs path for a given block device |
+| `base_name()` | Extracts base device name from path |
+| `is_removable_sysfs()` | Checks if device is removable via sysfs |
+| `is_partition_sysfs()` | Checks if device is a partition via sysfs |
+| `read_disk_size_bytes()` | Reads disk size in bytes from sysfs |
+| `read_rotational()` | Determines if disk is rotational (HDD) or not (SSD) |
+| `read_model_serial()` | Reads device model and serial number |
+| `read_optional_string()` | Utility to safely read optional string values from sysfs |
+
+---
+
+## Partition Management
+
+### [`src/partition/plan.rs`](../src/partition/plan.rs)
+
+**Structs:** `PartitionSpec`, `DiskPlan`, `PartitionPlan`, `PartitionResult`
+**Enums:** `PartRole`
+
+| Function | Purpose |
+|----------|---------|
+| `plan_partitions()` | Creates partition plans for all target disks based on topology |
+| `apply_partitions()` | Executes partition plans using sgdisk tool |
+| `type_code()` | Returns GPT partition type code for a given partition role |
+| `part_dev_path()` | Constructs device path for a partition (e.g., /dev/sda1) |
+| `sector_size_bytes()` | Reads logical sector size of disk |
+| `parse_sgdisk_info()` | Parses output from sgdisk to extract partition information |
+
+---
+
+## Filesystem Operations
+
+### [`src/fs/plan.rs`](../src/fs/plan.rs)
+
+**Structs:** `FsSpec`, `FsPlan`, `FsResult`
+**Enums:** `FsKind`
+
+| Function | Purpose |
+|----------|---------|
+| `plan_filesystems()` | Plans filesystem creation for all partitions |
+| `make_filesystems()` | Creates filesystems according to plan (mkfs.* tools) |
+| `capture_uuid()` | Captures UUID of newly created filesystem |
+| `parse_blkid_export()` | Parses blkid export format to extract filesystem metadata |
+| `probe_existing_filesystems()` | Detects existing filesystems on partitions |
+
+---
+
+## Mount Operations
+
+### [`src/mount/ops.rs`](../src/mount/ops.rs)
+
+**Structs:** `PlannedMount`, `PlannedSubvolMount`, `MountPlan`, `MountResult`
+
+| Function | Purpose |
+|----------|---------|
+| `fstype_str()` | Converts FsKind enum to mount filesystem type string |
+| `plan_mounts()` | Creates mount plans for all filesystems |
+| `apply_mounts()` | Executes mount operations and creates mount points |
+| `maybe_write_fstab()` | Conditionally writes /etc/fstab entries for persistent mounts |
+
+---
+
+## Idempotency & State
+
+### [`src/idempotency/mod.rs`](../src/idempotency/mod.rs)
+
+| Function | Purpose |
+|----------|---------|
+| `detect_existing_state()` | Detects existing partitions and filesystems to avoid destructive operations |
+| `is_empty_disk()` | Checks if a disk has no partition table or filesystems |
+| `parse_blkid_export()` | Parses blkid output to identify existing filesystems |
+| `read_proc_partitions_names()` | Reads partition names from /proc/partitions |
+| `base_name()` | Extracts base name from device path |
+| `is_partition_of()` | Checks if one device is a partition of another |
+
+---
+
+## Reporting
+
+### [`src/report/state.rs`](../src/report/state.rs)
+
+**Structs:** `StateReport`
+
+| Function | Purpose |
+|----------|---------|
+| `build_report()` | Builds comprehensive state report of operations performed |
+| `write_report()` | Writes report to specified output path (JSON format) |
+
+---
+
+## Utilities
+
+### [`src/util/mod.rs`](../src/util/mod.rs)
+
+**Structs:** `CmdOutput`
+
+| Function | Purpose |
+|----------|---------|
+| `which_tool()` | Locates external tool in PATH (sgdisk, mkfs.*, etc.) |
+| `run_cmd()` | Executes shell command and returns exit status |
+| `run_cmd_capture()` | Executes command and captures stdout/stderr |
+| `udev_settle()` | Waits for udev to process device events |
+| `is_efi_boot()` | Detects if system booted in EFI mode |
+
+---
+
+## Logging
+
+### [`src/logging/mod.rs`](../src/logging/mod.rs)
+
+**Structs:** `LogOptions`
+
+| Function | Purpose |
+|----------|---------|
+| `LogOptions::from_cli()` | Creates logging configuration from CLI arguments |
+| `level_from_str()` | Converts string to log level enum |
+| `init_logging()` | Initializes logging subsystem with configured options |
+
+---
+
+## Type Definitions
+
+### [`src/types.rs`](../src/types.rs)
+
+**Core Configuration Structures:**
+
+- `Config` - Top-level configuration structure
+- `LoggingConfig` - Logging configuration
+- `DeviceSelection` - Device selection criteria
+- `Topology` - Storage topology definition (enum)
+- `Partitioning` - Partition layout specification
+- `BiosBootSpec`, `EspSpec`, `DataSpec`, `CacheSpec` - Partition type specifications
+- `FsOptions`, `BtrfsOptions`, `BcachefsOptions`, `VfatOptions` - Filesystem options
+- `MountScheme`, `MountSchemeKind` - Mount configuration
+- `ReportOptions` - Report generation configuration
+
+### [`src/errors.rs`](../src/errors.rs)
+
+**Error Types:**
+
+- `Error` - Main error enum for all error conditions
+- `Result` - Type alias for `std::result::Result`
+
+---
+
+## Call Graph Relationships
+
+### Main Execution Flow
+
+```
+main() → real_main() → orchestrator::run()
+ ↓
+ ├─→ cli::from_args()
+ ├─→ config::load_and_merge()
+ ├─→ logging::init_logging()
+ ├─→ device::discover()
+ ├─→ partition::plan_partitions()
+ ├─→ partition::apply_partitions()
+ ├─→ fs::plan_filesystems()
+ ├─→ fs::make_filesystems()
+ ├─→ mount::plan_mounts()
+ ├─→ mount::apply_mounts()
+ └─→ report::build_report() / write_report()
+```
+
+### Key Dependencies
+
+- **Orchestrator** (`run()`) calls: All major subsystems
+- **Device Discovery** uses: Utilities for system probing
+- **Partition/FS/Mount** operations use: Utilities for command execution
+- **All operations** call: `util::run_cmd()` or `util::run_cmd_capture()`
+- **Idempotency checks** called by: Orchestrator before destructive operations
+
+---
+
+## Function Count Summary
+
+- **Main Entry**: 2 functions
+- **CLI & Config**: 9 functions
+- **Orchestration**: 13 functions
+- **Device Discovery**: 14 functions
+- **Partition Management**: 6 functions
+- **Filesystem Operations**: 5 functions
+- **Mount Operations**: 4 functions
+- **Idempotency**: 6 functions
+- **Reporting**: 2 functions
+- **Utilities**: 6 functions
+- **Logging**: 3 functions
+
+**Total: 70 documented functions** across 15 source files
+
+---
+
+## References
+
+- Original call graph visualization: [`docs/Callgraph.svg`](Callgraph.svg)
+- Architecture documentation: [`docs/ARCHITECTURE.md`](ARCHITECTURE.md)
+- API documentation: [`docs/API.md`](API.md)
\ No newline at end of file
diff --git a/docs/SCHEMA.md b/docs/SCHEMA.md
index 94bcff1..05be410 100644
--- a/docs/SCHEMA.md
+++ b/docs/SCHEMA.md
@@ -1,27 +1,16 @@
-# zosstorage Configuration Schema
+# zosstorage Configuration (Deprecated schema)
-This document defines the YAML configuration for the initramfs-only disk provisioning utility and the exact precedence rules between configuration sources. It complements [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md).
+This schema document is deprecated per [docs/adr/0002-defaults-only-no-external-config.md](docs/adr/0002-defaults-only-no-external-config.md). Runtime now uses defaults-only with a single optional kernel cmdline override. The YAML configuration file is not read at boot.
-Canonical paths and keys
-- Kernel cmdline key: zosstorage.config=
-- Default config file path: /etc/zosstorage/config.yaml
-- JSON state report path: /run/zosstorage/state.json
-- Optional log file path: /run/zosstorage/zosstorage.log
-- fstab generation: disabled by default
-- Reserved filesystem labels: ZOSBOOT (ESP), ZOSDATA (all data filesystems)
-- GPT partition names: zosboot, zosdata, zoscache
+Active behavior (ADR-0002)
+- Defaults-only: all settings are defined in code. No /etc/zosstorage/config.yaml is read.
+- Optional kernel cmdline override: `zosstorage.topology=VALUE` can override only the topology. Legacy alias `zosstorage.topo=` is accepted.
+- CLI: `--config` and `--topology` are deprecated and ignored (warnings emitted). Operational flags remain (`--apply`, `--show`, `--report`, `--fstab`, logging).
+- Report path: `/run/zosstorage/state.json`. Optional log file: `/run/zosstorage/zosstorage.log`.
+- Reserved labels: `ZOSBOOT` (ESP), `ZOSDATA` (data). GPT names: `zosboot`, `zosdata`, `zoscache`.
-Precedence and merge strategy
-1. Start from built-in defaults documented here.
-2. Merge in the on-disk config file if present at /etc/zosstorage/config.yaml.
-3. Merge CLI flags next; these override file values.
-4. Merge kernel cmdline last; zosstorage.config= overrides CLI and file.
-5. No interactive prompts are permitted.
-
-The kernel cmdline key zosstorage.config= accepts:
-- A path to a YAML file inside the initramfs root (preferred).
-- A file: absolute path (e.g., file:/run/config/zos.yaml).
-- A data: URL containing base64 YAML (optional extension).
+Historical reference (original YAML-based schema, no longer used at runtime)
+The remainder of this document preserves the previous YAML schema for archival purposes only.
Top-level YAML structure
diff --git a/docs/adr/0002-defaults-only-no-external-config.md b/docs/adr/0002-defaults-only-no-external-config.md
new file mode 100644
index 0000000..a93f654
--- /dev/null
+++ b/docs/adr/0002-defaults-only-no-external-config.md
@@ -0,0 +1,109 @@
+# ADR 0002: Defaults-Only Configuration; Remove External YAML Config
+
+Status
+- Accepted
+- Date: 2025-10-06
+
+Context
+- Running from initramfs at first boot provides no reliable access to an on-disk configuration file (e.g., /etc/zosstorage/config.yaml). An external file cannot be assumed to exist or be mounted.
+- The previous design added precedence and merge complexity across file, CLI, and kernel cmdline as documented in [docs/SCHEMA.md](../SCHEMA.md) and implemented via [fn load_and_merge()](../../src/config/loader.rs:1), increasing maintenance burden and risks of drift.
+- YAML introduces misconfiguration risk in early boot, adds I/O, and complicates idempotency guarantees without meaningful benefits for the intended minimal-first initializer.
+- The desired model is to ship with sane built-in defaults, selected automatically from detected hardware topology; optional kernel cmdline may override only the topology choice for VM/lab scenarios.
+
+Decision
+- Remove all dependency on an on-disk configuration file:
+ - Do not read /etc/zosstorage/config.yaml or any file-based config.
+ - Deprecate and ignore repository-local config files for runtime (e.g., config/zosstorage.yaml). The example file [config/zosstorage.example.yaml](../../config/zosstorage.example.yaml) remains as historical reference only and may be removed later.
+- Deprecate the --config CLI flag in [struct Cli](../../src/cli/args.rs:1). If present, emit a deprecation warning and ignore it.
+- Retain operational CLI flags and logging controls for usability:
+ - --apply, --show, --report PATH, --fstab, --log-level LEVEL, --log-to-file
+- Replace the prior file/CLI/kernel precedence with a defaults-only policy plus a single optional kernel cmdline override:
+ - Recognized key: zosstorage.topology=VALUE
+ - The key may override only the topology selection; all other settings use built-in defaults.
+- Topology defaults and override policy:
+ - 1 eligible disk:
+ - Default: btrfs_single
+ - Allowed cmdline overrides: btrfs_single, bcachefs_single
+ - 2 eligible disks:
+ - Default: dual_independent
+ - Allowed cmdline overrides: dual_independent, ssd_hdd_bcachefs, btrfs_raid1, bcachefs_2copy
+ - >2 eligible disks:
+ - Default: btrfs_raid1
+ - Allowed cmdline overrides: btrfs_raid1, bcachefs_2copy
+- Accept both snake_case and hyphenated forms for VALUE; normalize to [enum Topology](../../src/types.rs:1):
+ - btrfs_single | btrfs-single
+ - bcachefs_single | bcachefs-single
+ - dual_independent | dual-independent
+ - ssd_hdd_bcachefs | ssd-hdd-bcachefs
+ - btrfs_raid1 | btrfs-raid1
+ - bcachefs_2copy | bcachefs-2copy
+- Kernel cmdline parsing beyond topology is deferred; future extensions for VM workflows may be proposed separately.
+
+Rationale
+- Eliminates unreachable configuration paths at first boot and simplifies the mental model.
+- Reduces maintenance overhead by removing schema and precedence logic.
+- Minimizes early-boot I/O and failure modes while preserving a targeted override for lab/VMs.
+- Keeps the tool safe-by-default and fully idempotent without depending on external files.
+
+Consequences
+- Documentation:
+ - Mark [docs/SCHEMA.md](../SCHEMA.md) as deprecated for runtime behavior; retain only as historical reference.
+ - Update [docs/ARCHITECTURE.md](../ARCHITECTURE.md) and [docs/SPECS.md](../SPECS.md) to reflect defaults-only configuration.
+ - Update [docs/API.md](../API.md) and [docs/API-SKELETONS.md](../API-SKELETONS.md) where they reference file-based config.
+- CLI:
+ - [struct Cli](../../src/cli/args.rs:1) keeps operational flags; --config becomes a no-op with a deprecation warning.
+- Code:
+ - Replace [fn load_and_merge()](../../src/config/loader.rs:1) with a minimal loader that:
+ - Builds a [struct Config](../../src/types.rs:1) entirely from baked-in defaults.
+ - Reads /proc/cmdline to optionally parse zosstorage.topology and normalize to [enum Topology](../../src/types.rs:1).
+ - Removes YAML parsing, file reads, and merge logic.
+- Tests:
+ - Remove tests that depend on external YAML; add tests for cmdline override normalization and disk-count defaults.
+
+Defaults (authoritative)
+- Partitioning:
+ - GPT only, 1 MiB alignment, BIOS boot 1 MiB first unless UEFI detected via [fn is_efi_boot()](../../src/util/mod.rs:1).
+ - ESP 512 MiB labeled ZOSBOOT (GPT name: zosboot), data uses GPT name zosdata.
+- Filesystems:
+ - ESP: vfat labeled ZOSBOOT
+ - Data: label ZOSDATA
+ - Backend per topology (btrfs for btrfs_*; bcachefs for ssd_hdd_bcachefs and bcachefs_2copy)
+- Mount scheme:
+ - Root-mount all data filesystems under /var/mounts/{UUID}; final subvolume/subdir mounts from the primary data FS to /var/cache/{system,etc,modules,vm-meta}; fstab remains optional.
+- Idempotency:
+ - Unchanged: already-provisioned signals exit success-without-changes via [fn detect_existing_state()](../../src/idempotency/mod.rs:1).
+
+Implementation Plan
+1) Introduce a minimal defaults loader in [src/config/loader.rs](../../src/config/loader.rs:1):
+ - new internal fn parse_topology_from_cmdline() -> Option
+ - new internal fn normalize_topology(s: &str) -> Option
+ - refactor load to construct Config from constants + optional topology override
+2) CLI:
+ - Emit deprecation warning when --config is provided; ignore its value.
+3) Docs:
+ - Add deprecation banner to [docs/SCHEMA.md](../SCHEMA.md).
+ - Adjust [README.md](../../README.md) to describe defaults and the zosstorage.topology override.
+4) Tests:
+ - Add unit tests for normalization and disk-count policy; remove YAML-based tests.
+
+Backward Compatibility
+- External YAML configuration is no longer supported at runtime.
+- Kernel cmdline key zosstorage.config= is removed. Only zosstorage.topology remains recognized.
+- The JSON report, labels, GPT names, and mount behavior remain unchanged.
+
+Security and Safety
+- By eliminating external configuration input, we reduce attack surface and misconfiguration risk in early boot.
+- The emptiness and idempotency checks continue to gate destructive operations.
+
+Open Items
+- Decide whether to accept additional synonyms (e.g., “bcachefs-raid1”) and map them to existing [enum Topology](../../src/types.rs:1) variants; default is to reject unknown values with a clear error.
+- Potential future kernel cmdline keys (e.g., logging level) may be explored via a separate ADR.
+
+Links
+- Architecture: [docs/ARCHITECTURE.md](../ARCHITECTURE.md)
+- API Index: [docs/API-SKELETONS.md](../API-SKELETONS.md)
+- Specs: [docs/SPECS.md](../SPECS.md)
+- CLI: [src/cli/args.rs](../../src/cli/args.rs)
+- Config loader: [src/config/loader.rs](../../src/config/loader.rs)
+- Types: [src/types.rs](../../src/types.rs)
+- Util: [src/util/mod.rs](../../src/util/mod.rs)
\ No newline at end of file
diff --git a/docs/adr/callgraph.html b/docs/adr/callgraph.html
new file mode 100644
index 0000000..9754ddc
--- /dev/null
+++ b/docs/adr/callgraph.html
@@ -0,0 +1,2932 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/cli/args.rs b/src/cli/args.rs
index 82889ac..12a8649 100644
--- a/src/cli/args.rs
+++ b/src/cli/args.rs
@@ -58,8 +58,8 @@ impl std::fmt::Display for LogLevelArg {
#[derive(Debug, Parser)]
#[command(name = "zosstorage", disable_help_subcommand = true)]
pub struct Cli {
- /// Path to YAML configuration (mirrors kernel cmdline key 'zosstorage.config=')
- #[arg(short = 'c', long = "config")]
+ /// DEPRECATED: external YAML configuration is not used at runtime (ADR-0002). Ignored with a warning.
+ #[arg(short = 'c', long = "config", hide = true)]
pub config: Option,
/// Log level: error, warn, info, debug
@@ -74,7 +74,7 @@ pub struct Cli {
#[arg(short = 's', long = "fstab", default_value_t = false)]
pub fstab: bool,
- /// Select topology (overrides config topology)
+ /// Select topology (CLI has precedence over kernel cmdline)
#[arg(short = 't', long = "topology", value_enum)]
pub topology: Option,
@@ -82,8 +82,7 @@ pub struct Cli {
#[arg(short = 'f', long = "force")]
pub force: bool,
- /// Allow removable devices (e.g., USB sticks) to be considered during discovery
- /// Overrides config.device_selection.allow_removable when provided
+ /// Include removable devices (e.g., USB sticks) during discovery (default: false)
#[arg(long = "allow-removable", default_value_t = false)]
pub allow_removable: bool,
@@ -100,7 +99,7 @@ pub struct Cli {
#[arg(long = "show", default_value_t = false)]
pub show: bool,
- /// Write detection/planning JSON report to the given path (overrides config.report.path)
+ /// Write detection/planning JSON report to the given path
#[arg(long = "report")]
pub report: Option,
diff --git a/src/config/loader.rs b/src/config/loader.rs
index 17c596a..3168da2 100644
--- a/src/config/loader.rs
+++ b/src/config/loader.rs
@@ -1,11 +1,12 @@
//! Configuration loading, merging, and validation (loader).
//!
-//! Precedence (highest to lowest):
-//! - CLI flags (and optional `--config PATH` when provided)
-//! - Kernel cmdline key `zosstorage.topo=`
-//! - Built-in defaults
-//!
-//! See [docs/SCHEMA.md](../../docs/SCHEMA.md) for the schema details.
+//// Precedence and policy (ADR-0002):
+//// - Built-in sane defaults for all settings.
+//// - Kernel cmdline key `zosstorage.topology=` (legacy alias `zosstorage.topo=`) may override topology only.
+//// - CLI flags control operational toggles only (logging, fstab, allow-removable).
+//// - `--config` and `--topology` are deprecated and ignored (warnings emitted).
+////
+//// Note: [docs/SCHEMA.md](../../docs/SCHEMA.md) is deprecated for runtime configuration; defaults are code-defined.
//
// REGION: API
// api: config::load_and_merge(cli: &crate::cli::Cli) -> crate::Result
@@ -40,23 +41,21 @@
// REGION: TODO-END
use std::fs;
-use std::path::Path;
use crate::{cli::Cli, Error, Result};
use crate::types::*;
use serde_json::{Map, Value, json};
-use base64::Engine as _;
+use tracing::warn;
-//// Load defaults, merge optional CLI --config, overlay CLI flags (highest precedence),
-//// then consider kernel cmdline topology only if CLI omitted it.
+//// Build configuration from built-in defaults and minimal operational CLI overlays.
/// Returns a validated Config on success.
///
-/// Behavior:
-/// - Starts from built-in defaults (documented in docs/SCHEMA.md)
-/// - Skips implicit /etc reads in initramfs
-/// - If CLI --config is provided, merge that (overrides defaults)
-/// - If kernel cmdline provides `zosstorage.topo=...` and CLI did NOT specify `--topology`, apply it
-/// - Returns Error::Unimplemented when --force is used
+/// Behavior (ADR-0002):
+/// - Start from built-in defaults (code-defined).
+/// - Ignore on-disk YAML and `--config` (deprecated); emit a warning if provided.
+/// - CLI `--topology` is supported and has precedence when provided.
+/// - If CLI does not provide topology, apply kernel cmdline `zosstorage.topology=` (or legacy `zosstorage.topo=`).
+/// - Returns Error::Unimplemented when --force is used.
pub fn load_and_merge(cli: &Cli) -> Result {
if cli.force {
return Err(Error::Unimplemented("--force flag is not implemented"));
@@ -68,17 +67,17 @@ pub fn load_and_merge(cli: &Cli) -> Result {
// 2) (initramfs) Skipped reading default on-disk config to avoid dependency on /etc.
// If a config is needed, pass it via --config PATH or kernel cmdline `zosstorage.config=...`.
- // 3) Merge CLI referenced config (if any)
- if let Some(cfg_path) = &cli.config {
- let v = load_yaml_value(cfg_path)?;
- merge_value(&mut merged, v);
+ // 3) Deprecated config file flag: warn and ignore
+ if cli.config.is_some() {
+ warn!("--config is deprecated and ignored (ADR-0002: defaults-only)");
}
+ // (no file merge)
// 4) Overlay CLI flags (non-path flags)
let cli_overlay = cli_overlay_value(cli);
merge_value(&mut merged, cli_overlay);
- // 5) Kernel cmdline topology (only if CLI did not specify topology), e.g., `zosstorage.topo=dual-independent`
+ // 5) Kernel cmdline topology override only when CLI did not provide topology
if cli.topology.is_none() {
if let Some(topo) = kernel_cmdline_topology() {
merge_value(&mut merged, json!({"topology": topo.to_string()}));
@@ -204,14 +203,6 @@ fn to_value(t: T) -> Result {
serde_json::to_value(t).map_err(|e| Error::Other(e.into()))
}
-fn load_yaml_value(path: &str) -> Result {
- let s = fs::read_to_string(path)
- .map_err(|e| Error::Config(format!("failed to read config file {}: {}", path, e)))?;
- // Load as generic serde_json::Value for merging flexibility
- let v: serde_json::Value = serde_yaml::from_str(&s)
- .map_err(|e| Error::Config(format!("failed to parse YAML {}: {}", path, e)))?;
- Ok(v)
-}
/// Merge b into a in-place:
/// - Objects are merged key-by-key (recursively)
@@ -259,7 +250,7 @@ fn cli_overlay_value(cli: &Cli) -> Value {
root.insert("device_selection".into(), Value::Object(device_selection));
}
- // topology override via --topology (avoid moving out of borrowed field)
+ // topology override via --topology (takes precedence over kernel cmdline)
if let Some(t) = cli.topology.as_ref() {
root.insert("topology".into(), Value::String(t.to_string()));
}
@@ -267,63 +258,18 @@ fn cli_overlay_value(cli: &Cli) -> Value {
Value::Object(root)
}
-enum KernelConfigSource {
- Path(String),
- /// Raw YAML from a data: URL payload after decoding (if base64-encoded).
- Data(String),
-}
-
-/// Resolve a config from kernel cmdline key `zosstorage.config=`.
-/// Supports:
-/// - absolute paths (e.g., /run/zos.yaml)
-/// - file:/absolute/path
-/// - data:application/x-yaml;base64,BASE64CONTENT
-/// Returns Ok(None) when key absent.
-fn kernel_cmdline_config_source() -> Result