crucible depot: Increment 1 core (status/push/verify/get/pull + local/cdn/bunny backends) (#30)
Implements Increment 1 of `docs/superpowers/specs/2026-07-04-crucible-depot-core-design.md`: a new stdlib-only `internal/depot` package wired into the dispatcher. - `crucible depot status|push|verify|get|pull` with backends `local`/`cdn`/`bunny`; exit contract `0` clean / `1` drift / `2` unconfirmed-only / `64` usage / `70` internal. - Presence is always probed against the real target (IPv4 1-byte range GET; HEAD is banned with a regression-tripwire test). `unconfirmed` is a distinct state, never collapsed into `missing`. - No prompting anywhere: missing `BUNNY_STORAGE_*` env fails closed (read path included), enforced by a no-stdin test. - Uploads: probe-then-PUT with `Checksum: <UPPER-sha>`; read/write key split (`BUNNY_STORAGE_READ_PASSWORD` falls back to `BUNNY_STORAGE_PASSWORD`). - Field-driven fix included: per-probe transient retry (curl `--retry 2` equivalent) — without it a real 1490-blob CDN sweep reported 1222 false-unconfirmed; with it, 1490/1490 present in 74s, exit 0. - Registry: depot `Wired: true`, joins the interactive menu; stale "(SeaweedFS)" wording removed. Tests: unit + httptest fake-Bunny (probe sequence, Checksum header, key split, 428 throttling → exit 2) + local→bunny integration (drift → push → clean → idempotent no-second-PUT; incremental pull). `make check` green. **Merge ordering:** this merges FIRST; the companion `sow-assets-manifest#crucible-depot-cutover` PR needs its flake input bumped to include this. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Reviewed-on: #30 Reviewed-by: xtul <mpiasecki720@protonmail.com> Co-authored-by: vickydotbat <vickydotbat@tutamail.com> Co-committed-by: vickydotbat <vickydotbat@tutamail.com>
This commit was merged in pull request #30.
This commit is contained in:
@@ -5,8 +5,10 @@
|
||||
// Cutover state (Phase 5 → 6): the internal pipeline/topdata/erf/wiki
|
||||
// packages migrated from gitea/sow-tools now live in this tree, so wired
|
||||
// builders delegate to internal/app's legacy command surface (mapped per
|
||||
// docs/command-surface.md). A builder with no migrated logic yet (depot) keeps
|
||||
// the Wired=false fail-closed path: exit 70, never a faked artifact.
|
||||
// docs/command-surface.md). depot is wired but bypasses that legacy surface
|
||||
// entirely, delegating straight to internal/depot.Run. A builder with no
|
||||
// migrated logic yet keeps the Wired=false fail-closed path: exit 70, never a
|
||||
// faked artifact.
|
||||
package dispatch
|
||||
|
||||
import (
|
||||
@@ -16,6 +18,7 @@ import (
|
||||
|
||||
"git.westgate.pw/ShadowsOverWestgate/sow-tools/internal/app"
|
||||
"git.westgate.pw/ShadowsOverWestgate/sow-tools/internal/buildinfo"
|
||||
"git.westgate.pw/ShadowsOverWestgate/sow-tools/internal/depot"
|
||||
"git.westgate.pw/ShadowsOverWestgate/sow-tools/internal/menu"
|
||||
)
|
||||
|
||||
@@ -90,8 +93,15 @@ var Registry = []Builder{
|
||||
{
|
||||
Name: "depot",
|
||||
Bin: "crucible-depot",
|
||||
Summary: "verify/move content-addressed depot blobs (SeaweedFS)",
|
||||
Wired: false, // no migrated logic yet; fails closed (exit 70)
|
||||
Summary: "content-addressed asset depot (local/cdn/bunny)",
|
||||
Commands: []Command{
|
||||
{Name: "status", Summary: "report referenced-vs-present drift against a backend", Usage: "crucible depot status [--manifests DIR] [--source DIR] --target bunny|cdn|local"},
|
||||
{Name: "push", Summary: "upload referenced-but-absent blobs from a local depot", Usage: "crucible depot push [--manifests DIR] --source DIR --target bunny"},
|
||||
{Name: "verify", Summary: "existence sweep plus sampled download re-hash", Usage: "crucible depot verify [--manifests DIR] --target bunny|cdn [--sample N]"},
|
||||
{Name: "get", Summary: "fetch one blob with sha re-verify", Usage: "crucible depot get <sha> <dest> --target cdn|bunny|local"},
|
||||
{Name: "pull", Summary: "incremental verified pull of every referenced blob", Usage: "crucible depot pull [--manifests DIR] --dest DIR --target cdn|bunny"},
|
||||
},
|
||||
Wired: true,
|
||||
},
|
||||
{
|
||||
Name: "hak",
|
||||
@@ -365,6 +375,12 @@ func runBuilder(name string, args []string, out, errw io.Writer) int {
|
||||
return exitOK
|
||||
}
|
||||
}
|
||||
if b.Name == "depot" && b.Wired {
|
||||
// depot parses its own subcommand (status/push/verify/get/pull) and
|
||||
// has its own richer exit contract (0/1/2/64/70), so it bypasses the
|
||||
// b.Commands/delegateLegacy routing entirely.
|
||||
return depot.Run(args, out, errw, os.Getenv)
|
||||
}
|
||||
if !b.Wired {
|
||||
// No migrated logic yet (depot): fail closed, never fake an artifact.
|
||||
fmt.Fprintf(errw, unwiredMsg, b.Name, b.Bin)
|
||||
|
||||
Reference in New Issue
Block a user