Add the ingot system + forge-mode e2e validation#10
Merged
Conversation
frrist
marked this pull request as ready for review
July 13, 2026 21:24
Run ingot as a first-class smelt system and validate it live against the real stack (sprue + piri + indexing-service + postgres). systems/ingot/: compose.yml (ingot daemon ghcr.io/fil-forge/ingot:main + postgres:16-alpine; forge mode; goose migrations at startup on a fresh DB) and config/config.yaml (S3 IAM, Postgres DSN, sprue/indexer endpoints, mounted space key). INGOT_IMAGE overrides the image; documented in .env alongside the other services. pkg/stack: IngotEndpoint(), Exec/Logs support; pkg/workspace registers ingot for SMELT_WORKSPACE=1 local-source rebuilds; pkg/generate adds the ingot agent key. github.com/fil-forge/ingot is pinned in go.mod (v0.0.0, ingot's release tag at current main), so the e2e tests' ingot/testing import compiles from a plain checkout — the parent go.work is only needed to rebuild ingot from local source. Forge e2e tests (tests/e2e/ingot_*.go): - TestIngotNativeProvision: ingot self-provisions its space (guppy-free: ingot login + space generate --provision-to), then runs the versity Smoke suite over forge mode. - TestIngotVersityConformance: the gate — runs the same group universe as ingot's own smoke_test.go partition (Smoke + CopyObject + DeleteObjects) plus Multipart against an in-process baseline and forge, asserting exact two-sided per-case parity: forge-only failures are regressions, forge-only passes are build divergences (mirroring the suite's "unexpectedly passed; promote it" ratchet) — both fail by name. The load-sensitive CompleteMultipartUpload_racey_success is logged, never gated. Last run vs published images: forge 158/262 vs baseline 157/262. - TestIngotForgeReadAfterEviction: the appliance read tier — PUT, wipe /data/spool, GET re-fetches the body from piri via LocalLocator + /content/retrieve (512 KiB round-tripped). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This was referenced Jul 13, 2026
frrist
added a commit
that referenced
this pull request
Jul 14, 2026
…now (#18) Stacked on #17 (which stacks on #10). **Hold merge until the ingot-side e2e PR is green** — this is the final step of the test-dependency inversion. - Deletes `tests/e2e/ingot_{versity,native,eviction}_test.go` — ported to ingot `testing/forge_*_test.go`, where the conformance baseline and the binary under test are the same commit by construction. - The upload/retrieve smoke now asserts ingot boots to **healthy** in every storage permutation — smelt keeps guarding the *system definition* (topology, config, keys), the ingot repo owns *behavior*. - `go.mod` drops the `fil-forge/ingot` and `versity/versitygw` pins — smelt no longer depends on any service repo. - Docs: DEVELOPING.md gains a "Service repos own their e2e tests (smelt as SDK)" section (the pattern for piri/sprue/etc. teams, with a one-e2e-run-per-host caveat for `CleanupLeaked`); CLAUDE.md's stale "no CI" section now describes the actual workflows. Verified: `go vet -tags e2e ./...`, live `TestUploadAndRetrieve/default` (ingot health guard exercised, PASS 78s). 🤖 Generated with [Claude Code](https://claude.com/claude-code)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Add the ingot system + forge-mode e2e validation
Runs ingot — the S3 gateway over Forge — as a first-class smelt system and validates it live against the real stack (sprue + piri + indexing-service + postgres).
All upstream dependencies have landed:
fil-forge/ingotPR #9 is merged andghcr.io/fil-forge/ingot:main/:main-devare published by ingot's container workflow. The e2e suite below passes against the published images with no workspace setup.What this adds
systems/ingot/—compose.yml(ingot daemonghcr.io/fil-forge/ingot:main+postgres:16-alpine; forge mode; goose migrations at startup on a fresh DB) andconfig/config.yaml(S3 IAM, Postgres DSN, sprue/indexer endpoints, mounted space key).INGOT_IMAGEoverrides the image (documented in.envalongside the other services).pkg/stacksupport —IngotEndpoint(),Exec(ctx, "ingot", …),Logs(ctx, "ingot");pkg/workspaceregisters ingot;pkg/generateadds the ingot agent key.github.com/fil-forge/ingotpinned ingo.mod(v0.0.0, ingot's release tag at current main) — the e2e tests importingot/testingand now compile from a plain checkout; the parentgo.workis only needed to rebuild ingot from local source viaSMELT_WORKSPACE=1.Forge e2e tests (
tests/e2e/ingot_*.go)TestIngotNativeProvisioningot login+space generate --provision-to), then runs the versity Smoke suite over forge modeTestIngotVersityConformancesmoke_test.gopartition (Smoke + CopyObject + DeleteObjects) plus Multipart against an in-process baseline and forge, and asserts exact two-sided per-case parity: forge-only failures are regressions, forge-only passes are build divergences (mirroring the suite's "unexpectedly passed; promote it" ratchet) — both fail by name; out-of-scope cases self-calibrate out, and the one load-sensitive case (CompleteMultipartUpload_racey_success) is logged, not gated. Last run vs published images: forge 158/262 vs in-process baseline 157/262 — parity modulo that one timing caseTestIngotForgeReadAfterEviction/data/spool, GET re-fetches the body from piri viaLocalLocator+/content/retrieve(512 KiB round-tripped)These caught a real forge bug during development (a re-PUT 500 from re-adding an already-stored blob), fixed in ingot PR #9.
How to run
Scope note
The branch is a single commit rebased onto current
main(including the attested-signatures ucantone bump from #7 — the sprueuse_path_stylefix and themultikeyport ofpkg/stack/proofs.golanded there independently, so this PR inherits rather than duplicates them). Reviewers should focus onsystems/ingot/**andtests/e2e/ingot_*.go.🤖 Generated with Claude Code