# Crucible Command Surface Cleanup Design **Date:** 2026-06-25 **Status:** Approved **Scope:** `sow-tools`, with the two active `sow-assets-manifest` call sites updated in lockstep ## Problem Crucible exposes migrated `nwn-tool` implementation names directly. Several public commands repeat their builder name (`topdata build-topdata`, `wiki build-wiki`), the interactive menu repeats builder-level descriptions instead of explaining each action, and selected commands only prompt for unexplained "extra args". The registry also exposes a migrated music-conversion subsystem that is not part of the current project workflow. Live HAK builds explicitly bypass it with `--skip-music`; authored `.bmu` files are already packed as ordinary assets. ## Decisions ### Canonical command names The visible command surface is: | Builder | Visible commands | | --- | --- | | `hak` | `build`, `manifest` | | `module` | `build`, `extract`, `validate`, `compare`, `manifest` | | `topdata` | `validate`, `build`, `package`, `compare`, `convert` | | `wiki` | `build`, `deploy` | The dispatcher translates these names to the existing `internal/app` implementation commands. The app implementation names do not need to be renamed. ### Hidden compatibility aliases Existing long names remain callable indefinitely but are omitted from the interactive menu and routine builder help: - `hak build-haks` - `hak apply-hak-manifest` - `module build-module` - `module apply-hak-manifest` - `topdata validate-topdata` - `topdata build-topdata` - `topdata build-top-package` - `topdata compare-topdata` - `topdata convert-topdata` - `wiki build-wiki` - `wiki deploy-wiki` Aliases preserve their existing implementation target. In particular, `module build-module` continues to run the module-only implementation; it must not silently become the broader `module build`. ### Registry model `internal/dispatch.Registry` remains the single source of truth. Each wired builder owns command records containing: - visible command name; - action-oriented summary; - underlying `internal/app` command; - command usage and option guidance; - hidden compatibility aliases, where applicable. Execution, menu items, and builder help are generated from these records. Unknown commands continue to fail with exit `64`. ### Interactive behavior The main menu: - lists only visible commands; - aligns the description column from the longest visible label; - shows a distinct description for every command. After selection, it prints the selected command's usage and available options, then prompts: ```text arguments (press Enter to use defaults): ``` Arguments continue to use shell-like whitespace splitting, matching current behavior. Quoted argument parsing is out of scope. `crucible --help` prints the same command-specific guidance, returns success, and performs no project loading or build work. ### Remove the unused music pipeline The music conversion subsystem is deleted rather than hidden: - remove the `music` app and dispatcher commands; - remove `internal/music` and `internal/pipeline/music.go`; - remove music config, effective config, validation, environment overrides, and project accessors; - remove HAK music preparation, conversion, credits, generated-manifest result fields, `--skip-music`, and `--music-dataset`; - remove ffmpeg/ffprobe runtime and development dependencies; - remove music-pipeline documentation and wrapper wording. `.bmu` remains a supported ordinary asset extension and continues through the same content-addressed HAK packing path as other authored files. Actual game content, category names, or prose that happens to use the word "music" is not part of this deletion. The default asset-extension list drops conversion-only `.mp3` and `.ogg`. `.wav` remains because it is an NWN resource type independent of the deleted conversion pipeline. Because `sow-assets-manifest` currently passes `--skip-music`, its `scripts/pack-haks.sh` and `scripts/build-local-haks.sh` call sites are updated in the same change before verification. ## Error handling - Canonical and hidden alias lookup is deterministic within one builder. - Registry tests reject duplicate visible names or aliases. - Command help never delegates to `internal/app`. - Removed music commands and flags fail as unknown usage. - Existing project files containing a top-level `music:` configuration become invalid under strict YAML decoding. No active consumer configuration contains that field. ## Testing Tests assert public contracts rather than exact incidental formatting: - visible command names and hidden alias translation; - preservation of the distinct `module build-module` target; - hidden aliases absent from menu and normal help; - command-specific help exits successfully without project setup; - menu columns align and selected-command guidance is displayed; - `.bmu` remains accepted as an asset; - `.mp3`/`.ogg` are no longer default packable assets; - HAK builds no longer expose or execute music preparation; - ffmpeg is absent from package/image definitions; - both consumer scripts no longer pass `--skip-music`. Final verification is `nix develop --command make check`, `make build`, `make smoke`, focused consumer tests, and repository-wide searches for deleted pipeline identifiers.