# ADR-0003: Crucible binary contract: standalone shims, fail-closed scaffold, no committed binaries - **Status:** Accepted - **Date:** 2026-06-11 - **Migrated from:** `sow-docs` `07-decisions-log.md` entry **D19**, on the retirement of `sow-docs`. Content is the original decision, unchanged. - **Decision:** Phase 5 builds `migration/sow-tools` (Crucible, D11) as a multi-binary Go scaffold: - One `crucible` dispatcher plus standalone `crucible-{depot,hak,module,topdata,wiki}` binaries sharing one registry (`internal/dispatch`). The dispatcher is for humans/CI; the **standalone shims are canonical for consumers** so wrapper scripts resolve a single-token command and `"$builder" args` quoting stays correct. - Consumer resolution order: explicit env override (`$SOW_MODULE_BUILD`/`$SOW_TOPDATA_BUILD`/`$CRUCIBLE`) → `crucible-` → legacy `sow--build`. CI runs inside the pinned `crucible:` image. - Every builder is **unwired** in the scaffold and fails closed (exit 70); it never fakes an artifact. The `internal/` logic is migrated from `gitea/sow-tools` by the operator at cutover (hard rule: no source transplant by tooling). - **Binaries are never committed** — they are CI artifacts / image layers. Retires the committed `nwn-tool` / `tools/sow-toolkit`. - Builders take `NWN_ROOT` only via explicit env/flag; no `$HOME` defaulting. - **Rationale:** Locks the command surface, container, and CI shape so migrated logic drops into a stable frame; aligns the three artifact repos onto one Crucible contract while keeping back-compat with the pre-D11 skeletons. - **Image name:** `registry.westgate.pw/deployment/crucible:` (the bare `crucible:` is the local/dev tag).