Phase 5: scaffold Crucible (sow-tools) — dispatcher + builder shims, container, PR-first CI, fail-closed (D11, D19).

This commit is contained in:
2026-06-11 20:36:13 +02:00
parent ff264f0d7c
commit 97f8427c4b
154 changed files with 948 additions and 76902 deletions
+48
View File
@@ -0,0 +1,48 @@
# Migrating from `nwn-tool` to Crucible (operator cutover)
The legacy toolchain lives at `gitea/sow-tools` as a single `nwn-tool` binary
(entry `cmd/nwn-tool`, logic under `internal/`). This repo is the Crucible
rewrite. Per the migration hard rules, the `internal/` source is **not**
transplanted automatically — the operator migrates it. This is the checklist.
## Why a clean scaffold first
- The hard rules forbid copying old-repo source into the migration tree
(`build from scratch; reference, don't transplant`).
- The downstream skeletons (`sow-module`, `sow-topdata`) already fail closed
until they can resolve a Crucible binary; the scaffold satisfies that contract
without faking artifacts.
- The scaffold pins the **shape** (module path, dispatcher, multi-binary layout,
container, CI) so the migrated logic drops into a stable frame.
## Cutover steps
1. **Move the internal packages.** Bring `internal/{app,pipeline,project,erf,
gff,topdata,music,changelog,validator}` from `gitea/sow-tools` into this repo.
Re-home `internal/app` command wiring behind `internal/dispatch` instead of
the old flag parser in `cmd/nwn-tool`.
2. **Restore dependencies.** Add `golang.org/x/text` and `gopkg.in/yaml.v3` back
to `go.mod`; commit the resulting `go.sum`. (`docker/Dockerfile` already
tolerates an absent `go.sum` for the scaffold; it will be present after this.)
3. **Wire each builder.** In `internal/dispatch`, register a handler per builder
and remove it from the unwired fail-closed path. Map the legacy commands per
[`command-surface.md`](command-surface.md).
4. **Kill the home-dir / `NWN_ROOT` defaulting.** Honor only explicit
env/flag roots per [`consumer-contract.md`](consumer-contract.md).
5. **Drop the committed binary.** Delete `nwn-tool` / `tools/sow-toolkit` from
the source tree; `.gitignore` already excludes them. Binaries become CI
artifacts and image layers only.
6. **Carry the determinism test.** Port
`TestBuildNativeKeepsGeneratedIDsStableAcrossRepeatedBuilds` and keep it green.
7. **Runtime base for music.** If music conversion is wired, switch the final
Docker stage from `distroless/static` to a debian-slim base that includes
`ffmpeg`.
8. **Update `make smoke`.** Once a builder is wired, change the smoke
expectation for it from exit `70` to a real success path.
## Wrapper contract carried over
Consumer repos keep the `SCRIPT_WRAPPER_CONTRACT` resolution behavior, now
pointed at Crucible binaries — see [`consumer-contract.md`](consumer-contract.md).
The old `SOW_TOOLS_DEV_BINARY` dev override maps to `$CRUCIBLE` /
`$SOW_MODULE_BUILD` / `$SOW_TOPDATA_BUILD`.