Phase 2: fula-ingest - verified byte ingress (client-side CID, quota-gated)#75
Open
ehsan6sha wants to merge 16 commits into
Open
Phase 2: fula-ingest - verified byte ingress (client-side CID, quota-gated)#75ehsan6sha wants to merge 16 commits into
ehsan6sha wants to merge 16 commits into
Conversation
PUT /v0/block?cid=<declared>: verifies the blake3 raw-leaf CID over the body BEFORE storing (single flipped bit => 422, nothing written), then kubo block/put?cid-codec=raw&mhtype=blake3 and cross-checks kubo's key. S1 quota gate mirrors the gateway (GET /api/v1/storage with the client Bearer; INGEST_QUOTA_MODE=open matches gateway fail-open, strict denies when unverifiable); per-token 30s cache so a thousand-chunk upload makes one quota call per window. Size cap + bounded concurrency + /health + graceful shutdown. 10 Go tests (containerized run: all pass). Part of #74 (cross-repo: fula-api#31) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…, live mapping PUT I1-I10 on the test master: image build+run (strict quota vs the live webui storage API via a seeded legacy api key); valid block stored; tampered body 422 + never stored; suspended user 402 + never stored; missing token 401; bytes still ingested with the gateway container STOPPED; gateway rebuilt from the phase-2 branch flips /fula/capabilities false->true; live empty-body remote-cid mapping PUT returns ETag=cid and GET round-trips the exact ingested bytes; absent cid rejected (client-fallback contract). Part of #74 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ff, FxFiles flow, 1 GiB Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…lied) The previous commit re-encoded both files with a BOM + mojibake comments (PowerShell 5.1 round-trip). Restored from the clean parent and reapplied the scope=storage:* JWT claim via a targeted edit. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…t pins via it) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…parity) The registry pin forwards the user JWT to the pinning API, which validates sessions IT issued (/auth/google) - a minted drill token must be seeded into sessions (hashed per migration 009) for the pin to authenticate, exactly as prod tokens are. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ce matches) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… drills Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The 1 GiB upload alone runs ~2h on the contended 4-core box; the 2h fixed-expiry test token died at chunk 4019/4096 (real clients refresh). Measured insight recorded: chunked-upload throughput is metadata-commit bound (per-chunk bucket lock + tree flush) - pre-existing gateway property, unchanged by Phase 2. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Member
Author
Fidelity suite evidence (test master, real daemons)
Scale measurement worth recording: chunked-upload throughput on this path is metadata-commit-bound (each chunk's mapping/bytes PUT serializes through the per-bucket write lock + an index-tree flush; observed ~3× object amplification per chunk). This is a pre-existing property of the gateway's chunked path — Phase 2 neither worsens nor improves it (byte transport moves off the master; commit costs are identical). The plan's Phase-7 client-computed recursive root / batched commits is the designed fix. 🤖 Generated with Claude Code |
… failed test Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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.
Phase 2 — fula-ingest: verified byte ingress + e2e suites
The decentralized-upload byte path: any approved operator can run a
fula-ingestnode that accepts encrypted chunk BYTES so uploads stop depending on a single gateway, with tamper-evidence enforced server-side.What's in
docker/fula-ingest/(Go):PUT /v0/block?cid=<declared>verifies the blake3 raw-leaf CID over the body before anything touches the blockstore (one flipped bit ⇒ 422, nothing stored), then kuboblock/put?cid-codec=raw&mhtype=blake3with a cross-check of kubo's key. S1 quota gate mirrors the gateway exactly (GET {STORAGE_API_URL}/api/v1/storagewith the client's Bearer;INGEST_QUOTA_MODE=open= gateway-parity fail-open,strictdenies when unverifiable) with a 30s per-token cache (one quota call per window, not per chunk). Size cap, bounded concurrency,/health, graceful shutdown, Dockerfile.tests/e2e/phase-2/):40-ingest-drills.sh(I1–I10) +60-fidelity.sh(F1–F4).Evidence (clean Ubuntu 24.04 test master, real daemons)
/fula/capabilitiesfalse→true; live empty-body remote-cid mapping PUT ⇒ 200 withETag=<declared cid>and a byte-exact GET round-trip; absent cid ⇒ bounded 409 (client-fallback contract).Cross-repo: functionland/fula-api#31 (client routing + gateway mapping PUT; functionland/fula-api#30 lands first — the gateway image recipe).
In simple words
When your phone uploads a file today, the encrypted pieces must pass through one company server. With this, the pieces can go to any approved relay computer instead — and every piece carries a fingerprint, so a relay that corrupts even one byte gets caught and rejected instantly, and nobody can upload without an account in good standing.
Closes #74
🤖 Generated with Claude Code