The Documentation Pivot: Why Reading Before Writing Matters in Complex Software Integration

In the midst of a sprawling, multi-week engineering effort to integrate a custom GPU-resident SNARK proving engine into the Filecoin Curio storage provider, there comes a moment that appears, on its surface, almost trivial. The assistant types seven words: "Now let me update the project documentation:" followed by a single read tool call targeting the file /home/theuser/curio/cuzk-project.md. This is message [msg 3468] in the conversation, and it represents the precise inflection point where implementation work yields to knowledge preservation.

To understand why this message matters, one must appreciate the journey that led to it. The preceding twenty messages form a dense chain of software engineering: updating Go type definitions to report zero GPU and minimal RAM when a remote proving daemon is active ([msg 3454]), adding backpressure checks to task acceptance logic ([msg 3455]), fixing variable scoping bugs introduced during refactoring ([msg 3457]), wiring a new gRPC client into three separate task constructor call sites (<msg id=3459-3463>), and finally verifying every modified package with go vet (<msg id=3465-3467>). Each of these steps was a deliberate, focused intervention in the Curio codebase — editing, compiling, fixing, verifying. The assistant was operating in what might be called "implementation mode," where the primary goal is to make the code correct and the build clean.

Then comes message [msg 3468]. The code changes are done. The TODO list shows three items completed and one remaining: "Update cuzk-project.md with Curio integration phase." The assistant does not immediately reach for an edit tool. It does not assume it knows the file's current state. Instead, it reads.

The Deliberate Choice to Read First

This single read call embodies a principle that distinguishes careful engineering from hasty patching: you cannot edit what you do not understand. The file cuzk-project.md is not a trivial README. It is a 1,984-line architectural design document that has been built incrementally over the course of the entire project, spanning phases from initial scaffolding through pipelined synthesis, cross-sector batching, pre-compiled constraint evaluation, and the recently completed Phase 12 split API with memory backpressure. The document contains timelines, benchmark results, stopping-points tables, file reference sections, configuration examples, and detailed design rationales for each phase.

The assistant's choice to read before writing reveals several assumptions. First, that the document has a specific structure that must be respected — inserting new content requires knowing where Phase 12 ends, where the timeline lives, where the stopping-points table is, and where the file reference section resides. Second, that the document may have been modified since the assistant last saw it (perhaps by the user or by parallel work). Third, that the most efficient path to a correct edit is to load the full document into context and plan the changes holistically, rather than making piecemeal edits and discovering structural conflicts later.

This "read first" pattern is visible throughout the session. Earlier, when the assistant needed to understand the PoRep and Snap task patterns before modifying PSProve, it read those files in parallel (<msg id=3449-3451>). When it needed to understand the CuzkConfig structure, it read the config types file ([msg 3452]). When it needed to fix a variable scoping bug, it re-read the function to see the full context ([msg 3456]). Reading is not overhead — it is the foundation of correct editing.

What the Assistant Needed to Know

To make sense of this message, an observer needs significant context about the cuzk project itself. The cuzk proving engine is a persistent GPU-resident SNARK prover for Filecoin's Proof-of-Replication (PoRep) protocol, designed to replace the existing ephemeral process-per-proof architecture. It maintains GPU state across proof requests, pipelines CPU synthesis with GPU computation, and manages memory through careful backpressure mechanisms. The project has been developed over twelve prior phases, each documented in the cuzk-project.md file.

The observer also needs to understand Curio's architecture: it is a Go-based storage provider that orchestrates sealing, proving, and repair tasks through a harmonydb-backed task engine. Three task types — PoRep C2 (seal.NewPoRepTask), SnapDeals Prove (snap.NewProveTask), and PSProve (proofshare.NewTaskProvideSnark) — each generate Groth16 proofs that can be offloaded to the cuzk daemon when configured.

The assistant had just finished wiring all three task types to use the cuzk client, passing it as a constructor parameter from the central addSealingTasks function in cmd/curio/tasks/tasks.go. The code integration was functionally complete. What remained was ensuring the architectural documentation reflected this new capability — Phase 13: Curio Integration.

The Output Knowledge Created

By reading the full document, the assistant gained the structural knowledge needed to make precise edits. The subsequent messages show this knowledge being applied: a grep for "Phase 12" to find the timeline location ([msg 3472]), targeted reads of specific sections to understand where Phase 12's description ends and what comes after (<msg id=3475-3476>), and finally a series of edits that add the Phase 13 timeline entry, stopping-points table row, full design section, and file reference updates (<msg id=3474-3480>).

The output knowledge created by this message is not merely the content of the file, but the structural map of the document — where each section lives, how phases are ordered, what conventions the document uses for formatting timelines and tables, and where new content can be inserted without disrupting existing references. This is knowledge that cannot be inferred from the TODO item alone; it requires direct observation of the artifact.

The Thinking Process Behind the Transition

The assistant's reasoning at this point is implicit but discernible. Having completed all code changes and verified them with go vet, the natural next step is documentation. But the assistant does not treat documentation as an afterthought or a quick copy-edit task. The sequence of actions reveals a deliberate methodology:

  1. Read the full document to understand its current state and structure.
  2. Locate the relevant sections using grep and targeted reads.
  3. Plan the edits by understanding what content needs to be added and where.
  4. Execute the edits in a logical order: timeline first, then stopping-points table, then full design section, then file references.
  5. Verify the result by confirming the edits are consistent with the document's conventions. This is the same methodology the assistant applied to the code changes — read first, understand the structure, make targeted edits, verify. The consistency of this approach across both code and documentation domains is a hallmark of systematic engineering.

Why This Message Matters

In the grand narrative of the cuzk integration, message [msg 3468] is the moment the project shifts from "does it work?" to "will others understand it?" The code changes, however elegant, are useless if the architectural rationale is not documented. The Phase 12 split API with its memory backpressure mechanisms, channel capacity auto-scaling, and permit-through-send semantics — all of these are invisible to a future developer reading the code. The documentation in cuzk-project.md is what makes the architecture intelligible.

The message also represents a commitment to upstream simplicity. As the chunk summary notes, the team chose to vendor forked Rust crates directly inside the Curio repository rather than pushing branches to external repos. This "vendor-in-repo" approach minimizes external dependencies and CI complexity. But it also means that the documentation becomes the primary reference for understanding how these vendored crates fit together. The cuzk-project.md file, with its file reference tables and phase-by-phase design rationales, serves as the map that makes the vendored code navigable.

The Broader Pattern

This message exemplifies a pattern that recurs throughout the entire opencode session: the alternation between implementation and documentation, between making and explaining. The assistant does not batch all documentation at the end; instead, it documents each phase as it is completed, keeping the design document synchronized with the codebase. This is the practice of a mature engineering organization, where documentation is not a separate deliverable but an integral part of the development workflow.

The read tool call in message [msg 3468] is, in itself, unremarkable. It is the context that gives it meaning — the twenty messages of code changes that precede it, the ten messages of documentation edits that follow it, and the 1,984-line document that bridges the two. It is the pivot point where implementation ends and understanding begins.