The Architecture of a Plan: Deconstructing Phase 5 of the Cuzk Proving Engine
"Now I have a complete understanding of the codebase. Let me plan Phase 5 systematically."
This single sentence, which opens message [msg 1359] in the cuzk development conversation, marks a critical inflection point. After dozens of messages spanning four phases of optimization—each characterized by rigorous empirical methodology, hard-won performance gains, and the disciplined rejection of plausible-but-wrong hypotheses—the assistant transitions from investigation to construction. The message that follows is not code, not a bug fix, not a benchmark result. It is a plan: a structured decomposition of the next major architectural intervention into the cuzk proving engine, encoded as a prioritized todo list with four waves of implementation.
Context: The Phase 4 Post-Mortem
To understand why this message was written, one must understand what preceded it. Phase 4 of the cuzk project had been a grueling, data-driven optimization campaign targeting the synthesis hot paths and GPU wrapper overhead for 32 GiB PoRep C2 proofs. The results were mixed and instructive. Two optimizations had proven themselves on real hardware: Boolean::add_to_lc reduced synthesis time by 8.3% (from 55.4s to 50.9s) by eliminating temporary allocations in circuit gadgets, and async deallocation of large C++/Rust vectors cut GPU wrapper time from 36s to 26.2s by moving ~167 GB of synchronous destructor overhead onto detached threads. The net improvement was 13.4%—respectable, but far short of the 2–3x target that had motivated the phase.
Equally important were the hypotheses that Phase 4 had disproven. SmallVec caused an 8.5% IPC regression on Zen4 and was rejected. cudaHostRegister added 5.7s of mlock overhead and was reverted. Vec pre-allocation (capacity hints) showed zero measurable impact, confirming that allocation costs were already amortized during parallel computation. A detailed perf profile had revealed the uncomfortable truth: the synthesis bottleneck (~50.8s) was now purely computational—field arithmetic and linear combination construction—not memory-bound. There were no more low-effort optimizations left to harvest.
This was the landscape at the end of Phase 4. The assistant had squeezed the lemon dry. The only remaining path to the 2–3x target was architectural: replace the entire circuit synthesis approach with something fundamentally faster. That something was the Pre-Compiled Constraint Evaluator (PCE).
The Message: A Systematic Plan
Message [msg 1359] is the first message of Phase 5. It opens with the assistant declaring that it has "a complete understanding of the codebase" and intends to "plan Phase 5 systematically." What follows is a todowrite block containing a JSON array of tasks organized into four waves:
- Wave 1: Core CSR Infrastructure — Create the
cuzk-pcecrate withRecordingCSand CSR matrix types; implementRecordingCSthat captures R1CS constraints directly into CSR format; implement a row-parallel, multi-threaded CSR sparse MatVec evaluator. - Wave 2: Specialized MatVec — Implement coefficient witness fast-paths and boolean witness fast-paths for the matrix-vector multiply.
- Wave 3: Pre-Computed Split MSM Topology — Pre-compute the MSM topology from the compiled circuit structure.
- Wave 4: SnarkPack Pipeline — Integrate the PCE into the SnarkPack aggregation pipeline. The message is a pure planning artifact. It contains no code changes, no file edits, no bash commands. It is the assistant saying: before I write a single line of code, let me decompose this problem into independently implementable, testable waves.
Why This Message Matters
This message is significant precisely because it is not dramatic. It does not contain a breakthrough insight or a clever optimization. It is a methodological commitment. The assistant is choosing to plan before building, to decompose before implementing, to sequence before executing.
The reasoning visible in the opening line—"Now I have a complete understanding of the codebase"—reveals the assistant's epistemic state. It has spent the preceding messages (see [msg 1354] through [msg 1358]) exhaustively exploring the cuzk workspace structure, the bellperson fork's prover pipeline, the WitnessCS/KeypairAssembly mechanisms, the density tracking flow, and the existing benchmark infrastructure. It has read pipeline.rs, supraseal.rs, mod.rs, generator.rs, witness_cs.rs, and the Cargo.toml files for both cuzk-core and cuzk-bench. Only after this thorough reconnaissance does it produce the plan.
Assumptions Embedded in the Plan
The plan rests on several key assumptions, some explicit and some implicit:
The PCE will be faster than synthesis. This is the foundational bet of Phase 5. The assumption is that replacing the bellperson::synthesize_circuits_batch() function—which walks the circuit graph, evaluates gadgets, and constructs linear combinations one constraint at a time—with a sparse matrix-vector multiply (a = A·w, b = B·w, c = C·w) will be significantly faster because the matrix structure is pre-computed and the evaluation is embarrassingly parallel across rows.
The circuit structure is stable across proofs. The PCE approach only works if the R1CS constraint matrix (the A, B, C matrices) is identical for every proof of the same circuit type. For Filecoin PoRep circuits, this is true: the circuit topology is fixed; only the private witness inputs change between proofs. This assumption is well-founded based on the Phase 4 analysis of the circuit structure.
CSR format is the right sparse representation. The plan specifies Compressed Sparse Row (CSR) format for the matrices. This is a standard choice for row-parallel matrix-vector products, and the plan explicitly calls out "row-parallel, multi-threaded" evaluation. The assumption is that the row-wise parallelism of CSR maps naturally onto the multi-core CPU architecture of the target hardware (AMD Zen4).
RecordingCS can capture constraints directly into CSR. The plan proposes a RecordingCS type that implements the ConstraintSystem interface and captures R1CS constraints directly into CSR format during a single synthesis run, avoiding the CSC-to-CSR transpose that would be required if using the existing KeypairAssembly format. This is a clever architectural insight: rather than generating constraints in column-major order (as KeypairAssembly does) and then transposing, RecordingCS can record them in row-major order from the start.
Input Knowledge Required
To fully understand this message, a reader would need:
- Knowledge of R1CS and Groth16. The plan references R1CS constraints, CSR sparse matrices, matrix-vector products (MatVec), and MSM (multi-scalar multiplication). These are concepts from the zero-knowledge proof literature.
- Knowledge of the cuzk project's architecture. The plan builds on the pipelined proving engine established in Phases 1–3, the batch collector from Phase 3, and the synthesis hot paths analyzed in Phase 4.
- Knowledge of the bellperson fork. The plan references
ProvingAssignment,KeypairAssembly,WitnessCS, and theConstraintSystemtrait—all components of the bellperson library that the cuzk project has forked and modified. - Knowledge of the Phase 4 results. The plan is a direct response to the Phase 4 conclusion that synthesis is now purely computational and needs architectural replacement.
Output Knowledge Created
This message creates several forms of knowledge:
A sequenced implementation roadmap. The four waves provide a clear dependency order: Wave 1 (core infrastructure) must precede Wave 2 (specialized fast-paths), which must precede Wave 3 (MSM topology), which must precede Wave 4 (SnarkPack integration). This sequencing minimizes blocking dependencies and allows each wave to be tested independently.
A priority classification. Each task is tagged with a priority (high, medium) and a status (pending). The high-priority tasks are all in Wave 1, establishing the foundation.
An implicit architecture document. The structure of the plan—separating core CSR types from specialized evaluation from MSM topology from pipeline integration—reveals the assistant's architectural vision for how the PCE will be organized as a software system.
The Thinking Process
The thinking process visible in this message is one of decomposition under uncertainty. The assistant knows the destination (replace synthesis with MatVec) but must chart the path. The four waves represent a risk-management strategy: implement the core first, validate it, then add optimizations, then integrate more deeply.
The choice of four waves is itself a design decision. Why not three? Why not five? The answer lies in the natural seams of the problem: the core data structures (Wave 1), the computational kernels (Wave 2), the proof-system-specific topology (Wave 3), and the pipeline integration (Wave 4). Each wave produces a testable artifact.
The message also reveals a commitment to incremental validation. The plan includes building a cuzk-bench extract-pce command in Wave 1 to extract and validate the circuit, ensuring that the CSR matrices are correct before proceeding to the specialized evaluation kernels. This reflects the empirical discipline carried over from Phase 4.
Conclusion
Message [msg 1359] is the quiet before the storm of Phase 5 implementation. It is a planning document that encodes weeks of investigation, the hard lessons of Phase 4, and a clear architectural vision for how to break through the performance ceiling that incremental optimization could not crack. The message itself is simple—a todo list with four waves—but the reasoning behind it is anything but. It represents the transition from understanding the problem to executing the solution, and the systematic decomposition of that solution into independently verifiable steps.