The Final Commit: Upstreaming the cuzk Proving Engine into Curio
In the closing moments of a marathon coding session spanning dozens of rounds and multiple phases of optimization, the assistant issued a single summary message ([msg 3573]) that crystallized weeks of work into a commit-ready changelist. This message, the last in a 34-segment conversation, is not a tool call, a code edit, or a debugging session — it is a declaration of completion. It lists 37 files, +5038 lines added and 49 removed, spanning build system changes, vendored Rust crates, Go integration code, and documentation. But beneath this terse summary lies a dense web of architectural decisions, trade-offs, and engineering judgment that deserves careful examination.
What the Message Actually Says
The assistant writes a structured summary organized into four categories: Build system, Vendored Rust forks, Go integration, and Documentation. Each section enumerates the files changed and the rationale behind them. The message opens with "Everything is done" — a confident assertion that the integration is complete — and closes with verification results: make cuzk builds from clean in 1 minute 51 seconds, go vet passes on all modified packages, and CI remains unaffected because cuzk is opt-in.
The full text of the message reads:
Everything is done. Here's a summary of all changes, staged and ready for commit:
>
## Summary — 37 files, +5038/-49 lines
>
### Build system -.gitignore: Added/cuzkso the built binary isn't tracked -Makefile: Addedmake cuzktarget (cargo build with nvcc/cargo pre-checks),install-cuzk/uninstall-cuzktargets,cargo cleaninmake clean. Intentionally not inBINSorBUILD_DEPSso CI (no CUDA) is unaffected.
>
### Vendored Rust forks (complete crates forcargo build) -extern/bellpepper-core/— 13 new files:Cargo.toml,src/,benches/, licenses. Previously only 3 modified source files were tracked. -extern/supraseal-c2/— 8 new files:Cargo.toml,build.rs,Cargo.lock,cuda/groth16_split_msm.cu,tests/. Previously only 4 CUDA/Rust source files were tracked. -extern/bellperson/andextern/cuzk/were already fully tracked.
>
### Go integration (Curio side) -lib/cuzk/(new):client.go,proving.pb.go,proving_grpc.pb.go— gRPC client wrapper -lib/ffi/cuzk_funcs.go(new):PoRepSnarkCuzk,ProveUpdateCuzkmethods on SealCalls -deps/config/types.go:CuzkConfigstruct + defaults -cmd/curio/tasks/tasks.go: Createscuzk.Clientfrom config, passes to 3 task constructors -tasks/seal/task_porep.go: cuzk branch in Do/CanAccept/TypeDetails -tasks/snap/task_prove.go: Same pattern -tasks/proofshare/task_prove.go: Same pattern, threaded through computeProof/computePoRep/computeSnap
>
### Documentation -documentation/en/experimental-features/cuzk-proving-daemon.md(new): Full guide — what it is, requirements, building, daemon config, Curio config, deployment patterns, monitoring, troubleshooting -documentation/en/SUMMARY.md: Added entry -documentation/en/experimental-features/README.md: Added content-ref -cuzk-project.md: Added Phase 13 documentation
>
### Verified -make cuzkbuilds from clean cargo state (1m51s) -go vetpasses on all modified packages -make buildall/make build/ CI are unaffected (cuzk is opt-in)
This is not merely a status report. It is a carefully crafted commit message-in-waiting, designed to serve as the permanent record of what was done and why.## The Context: What Led to This Message
To understand why this message exists, one must understand the journey that preceded it. The cuzk proving engine was not built in a vacuum — it emerged from a deep investigation into the SUPRASEAL_C2 Groth16 proof generation pipeline for Filecoin PoRep (see [chunk 0.0]). That investigation had mapped a ~200 GiB peak memory footprint, identified nine structural bottlenecks, and produced three optimization proposals: Sequential Partition Synthesis to reduce peak memory, a Persistent Prover Daemon to eliminate SRS loading overhead, and Cross-Sector Batching for throughput. Over the subsequent segments (29 through 34), the team had implemented and benchmarked these proposals, iterating through memory-bandwidth interventions, split API designs, memory backpressure mechanisms, and low-memory benchmark sweeps.
By the time we reach [msg 3573], the heavy lifting of implementation is complete. The code works. The benchmarks are in. What remains is the unglamorous but essential work of upstreaming — taking code that was developed in a working branch and making it fit for consumption by the broader project. This means ensuring a clean clone builds, that CI pipelines don't break, that documentation exists, and that the commit history tells a coherent story.
The Vendoring Decision: A Study in Pragmatism
One of the most consequential decisions reflected in this message is how the Rust crate dependencies are managed. The assistant chose to vendor the forked Rust crates directly inside the Curio repository — extern/bellpepper-core/ and extern/supraseal-c2/ are now complete crate directories with Cargo.toml, src/, build.rs, licenses, and all supporting files. Previously, only a handful of modified source files had been tracked, which meant a fresh clone could not build these dependencies.
This decision (Option B in the team's earlier analysis) rejects the alternative of pushing branches to external repositories and pulling them via git dependencies. The reasoning is subtle but important. External branches create a coordination problem: the Curio repository becomes dependent on the availability and correctness of a remote branch that may be deleted, rebased, or diverge. They also complicate CI, which would need network access to fetch those branches. By vendoring, the team ensures that git clone of the Curio repository alone is sufficient to build everything. The build is self-contained and reproducible — a property that matters enormously for production deployments where network access may be restricted and reproducibility is paramount.
The trade-off is repository bloat: 13 new files for bellpepper-core and 8 for supraseal-c2. But the assistant judged this acceptable, and the numbers confirm it — the total addition of 5,038 lines across 37 files is modest for a project of this scale.
Build System Architecture: Opt-In by Design
The Makefile changes reveal a careful architectural sensibility. The cuzk targets are deliberately excluded from BINS and BUILD_DEPS, the standard variables that control what gets built by make build and make buildall. This means that a developer running the default build target will not attempt to compile cuzk. Why? Because cuzk requires CUDA (nvcc) and the Rust toolchain with specific crate dependencies. CI environments — especially those running in containers or on CPU-only instances — almost certainly lack CUDA. If cuzk were part of the default build, every CI run would fail with cryptic toolchain errors.
Instead, the assistant created a dedicated make cuzk target with pre-flight checks for cargo and nvcc. The install-cuzk and uninstall-cuzk targets handle deployment. This is a textbook example of defensive build engineering: the default path must never break, and optional components must be explicitly requested. The .gitignore addition of /cuzk (the built binary) further reinforces this — the binary is an artifact of a local build, not something that belongs in version control.
The assistant also added cargo clean to make clean, ensuring that the 12.5 GiB of build artifacts (as seen in [msg 3548]) can be reclaimed with a single command. This attention to the developer experience — making it easy to clean up — suggests a team that expects others to build this code frequently.## The Go Integration: Wiring a Distributed Proving System
The Go-side changes are where the cuzk proving engine becomes real for Curio operators. The integration follows a clean pattern: configuration is defined in deps/config/types.go as a CuzkConfig struct with sensible defaults; the config is consumed in cmd/curio/tasks/tasks.go to create a cuzk.Client; and that client is threaded into three task constructors — PoRep sealing (tasks/seal/task_porep.go), SnapDeals proving (tasks/snap/task_prove.go), and proofshare market tasks (tasks/proofshare/task_prove.go).
Each of these three task types follows the same pattern: a cuzk branch in their Do, CanAccept, and TypeDetails methods. This branching is significant because it means the existing monolithic proving path (which runs SUPRASEAL_C2 directly in-process) remains untouched. Operators can choose which tasks route through the cuzk daemon and which use the traditional path, enabling a gradual migration. This is not just a technical decision — it is a deployment strategy. Storage providers with existing workloads can enable cuzk for a subset of tasks, validate correctness and performance, and then expand coverage without downtime.
The gRPC client wrapper in lib/cuzk/ (client.go, proving.pb.go, proving_grpc.pb.go) abstracts the network communication. The daemon can listen on either a TCP socket (0.0.0.0:9820) or a Unix domain socket (unix:///run/curio/cuzk.sock), with the UDS option providing lower latency and stronger security guarantees for same-host deployments. The lib/ffi/cuzk_funcs.go file exposes PoRepSnarkCuzk and ProveUpdateCuzk methods on the SealCalls struct, bridging the gap between Curio's existing FFI-based proving API and the new gRPC-based one.
Documentation as a Deliverable
The assistant did not stop at code. A new documentation page, cuzk-proving-daemon.md, was added to the experimental-features section of the GitBook-style documentation. At 253 lines, it covers the full lifecycle: what the feature is, hardware requirements (CUDA-capable GPU, sufficient RAM for SRS loading), how to build it, daemon configuration, Curio-side configuration, deployment patterns (same-host vs. dedicated proving node), monitoring advice, and troubleshooting steps.
This documentation is not an afterthought — it is a first-class deliverable of the integration. The assistant studied existing experimental feature docs (like gpu-over-provisioning.md and Snark-Market.md at <msg id=3556-3557>) to match the style, tone, and structure. The SUMMARY.md was updated to include the new page, and the experimental-features README.md gained a content-reference link. This ensures the documentation is discoverable through the normal navigation flow.
The inclusion of cuzk-project.md — the internal architecture document — in the commit is notable. This file, which had accumulated Phase 13 documentation describing the pipelining, memory management, and CPU-locking architecture, is now part of the permanent record. It serves as a design rationale document for future maintainers who need to understand why the system was built this way.
Verification: Trust but Validate
The message closes with verification results. A clean build from scratch completed in 1 minute 51 seconds (<msg id=3549-3550>). go vet passed on all modified packages (<msg id=3551-3552>). The default build targets are unaffected. These are not throwaway checks — they are the minimum bar for a mergeable commit. The assistant could have simply asserted that the code works, but instead it ran the actual commands and reported the results. This transparency builds trust and gives reviewers confidence that the integration is sound.
The verification also catches a subtle issue: the LSP error in ffi-direct.go (at [msg 3559]) is explicitly noted as pre-existing and unrelated. This is a small but important gesture — it prevents a reviewer from flagging a spurious error that was introduced by someone else's code.
Assumptions and Their Implications
Every engineering decision rests on assumptions, and this message is no exception. The vendoring approach assumes that the forked crates (bellpepper-core, supraseal-c2) will not need frequent updates from upstream. If upstream releases critical bug fixes or performance improvements, the vendored copies will need manual synchronization — a process that is error-prone and easy to neglect. The team implicitly judged that the forks are stable enough that this risk is acceptable.
The opt-in build system assumes that CI environments will never need to build cuzk. This is reasonable for the current CI configuration, but if the project later adds GPU-equipped CI runners for integration testing, the Makefile targets would need re-examination. The exclusion from BINS and BUILD_DEPS is a strong architectural statement that would need to be deliberately reversed.
The documentation assumes that operators will read and follow the guide. In practice, documentation is often the weakest link in complex deployments. The assistant mitigated this by making the configuration self-documenting (the cuzk.example.toml file has inline comments explaining every field) and by providing sensible defaults that work for most deployments.
What This Message Achieves
This message is the culmination of a multi-phase engineering effort. It transforms a collection of working code, benchmarks, and prototypes into a production-ready integration that can be committed, reviewed, and deployed. The 37 files and 5,038 lines represent not just code, but decisions about build architecture, dependency management, deployment strategy, and developer experience.
The message itself is a model of technical communication. It is structured, specific, and grounded in verifiable facts. It explains not just what was done, but why — the rationale for vendoring, for opt-in builds, for the branching pattern in task handlers. It anticipates reviewer questions and answers them before they are asked. And it closes with evidence that the integration works, giving reviewers confidence to merge.
In the broader arc of the conversation, this message marks the transition from development to integration. The proving engine exists, it works, and now it is part of Curio. The next steps — deployment, monitoring, and iteration — belong to the operators who will run it in production.