Skip to content
The CNA BibleCNA 0.1.0-alpha.1 Edition

Chapter 78 Project Practice and Durable Task Tracking

CNA’s repository is rich in plans, handoffs, audits, remediation ledgers, and integration records. That abundance is valuable and dangerous: an old plan can explain why code exists while being wrong about whether it exists today. Durable practice is therefore not “trust the tracking document.” It is preserving a chain from intent to source, test, artifact, and current status.

78.1 Documents have roles, not equal authority

The root NEXT.md is a session and integration handoff. At alpha.1 it opens with the 2026-08-18 merge and compiled-effect follow-up, while thousands of lines of earlier renderer, platform, C API, glTF, and remediation history remain below it. It is operational history, not a normalized single source of current feature truth.

CHECKLIST.md defines repeatable port rules: API surface comes from XNA reference assemblies, behavior from FNA, extensions require CNAEXT, and each public member needs tests or an explicit host-dependent exception. It is a policy document; compliance still has to be checked against code and gates.

AUDIT.md is a large historical class table with a current C-ABI tracking banner above older per-class rows. It contains valuable provenance and many dated claims; current banner text does not automatically refresh older rows. Treat it as a claim corpus that must be checked against the tag, not a normalized current API inventory. The same warning applies to source-audit files generated before modularization.

78.2 Subsystem plans preserve causality

The CNA root contains 62 plan_*.md files at the alpha.1 tag, not a small fixed set. Their numbered tasks record rationale, experiments, owner decisions, defects discovered while doing the work, and follow-up boundaries. A stable identifier such as GLTF-245 or REMED-GFX-188 is useful because commits, tests, and later tasks can point back to the same decision.

A done marker is still a claim. Several audits found tasks marked complete because code existed, not because their acceptance case ran; others found plan banners saying nothing was implemented above sections describing completed phases. Before quoting a task, check its named path, test, commit, and present behavior. If any one moved, update the forward pointer rather than erasing the old identifier.

When a task expands across independent renderers or failure modes, split it. The parent becomes a tracking pointer and each child receives its own acceptance evidence. This keeps a partial fix from turning a broad row green and lets controls finish independently.

78.3 Integration records need immutable inputs

The renderer-integration campaign demonstrates a stronger form of handoff. It records every feature lane’s exact SHA, derives merge order from path interaction, preserves signed no-fast- forward merges, recomputes registry arithmetic, and names conflicts whose correct result could not be taken from either lane alone. A later reader can reconstruct which trees were combined and why the result differs from each parent.

For work of this scale, a useful checkpoint packet contains:

  • base and input SHAs, branch roles, and proof no hidden worktree state was consumed;

  • path-overlap and ordering rationale;

  • exact configure/build/test commands with renderer and host identity;

  • machine-readable results, skip counts, logs, screenshots, and generated manifests;

  • newly found defects separated from the requested change;

  • a clean-tree/diff check and a handoff naming the next bounded step.

A prose statement that “all lanes passed” cannot replace this packet, especially when one lane was only compile-checked or one renderer ran under a substitute runtime.

78.4 Executable ledgers resist prose drift

The glTF conformance work keeps known defects in both documentation and tests, then a meta-test asserts that the two sets agree. Skia validators compare parity ledgers and decisions with live interfaces and enums. Renderer identity gates compare the CMake and C++ registries. Module probes inspect link closures.

These mechanisms encode a general rule: if a plan row names a finite set that code can derive, derive and compare it. Check row uniqueness, accepted status vocabulary, set equality, path existence, and non-empty parsing. Keep negative fixtures and mutation so the validator can prove it goes red.

Executable documents can rot too. Four wired validators at the pin read paths removed by modularization. A gate that cannot find its input is not current evidence. Self-validation must include its input mapping, and a physical source move should update implementation, tests, validators, and cited docs atomically.

78.5 SemVer and phase tracking coexist

The first tagged release adds a second durable coordinate without replacing task history. Product version authority begins in the root CMake numeric version plus its prerelease field; configuration generates CNA/Version.hpp, and release preparation synchronizes Doxygen, the changelog, and the v0.1.0-alpha.1 tag. CNA::getVersionString() and the CNA_VERSION_* macros expose that product version to C++ consumers.

The experimental native C package has a separate ABI version in CNA/C/abi.h. Its package compatibility and release gate must move according to C ABI rules, not because the C++ product tag changed. A release record is therefore complete only when it names both coordinates where the C surface is in scope. Alpha.1 remains pre-1.0: SemVer identifies the snapshot and communicates prerelease status; it does not promise a stable 1.0 API.

The release checklist in docs/releasing.md treats source, changelog, generated version API, tag, and verification evidence as a coordinated operation. Phase/task identifiers remain the causal engineering ledger underneath that snapshot. A task answers why and how; the tag answers which immutable product state.

78.6 sharp-runtime’s database makes scope measurable

The sharp-runtime sibling stores coarse classifications and concrete tickets in plan.sqlite3. At pinned commit f827a6c5, the task table contains exactly 16,201 rows: 1,082 ported, 14,979 ignored, and 140 ignore; 118 rows also carry outofscope=1. The ticket table contains 2,183 work items with descriptions, acceptance criteria, priorities, estimates, status, and optional validation commands.

The denominator matters more than the apparent percentage. The database deliberately classifies vast areas of .NET that sharp-runtime will never implement. “1,082 ported” means rows with a working C++ counterpart under this schema; it is not a claim of 6.7% behavioral parity with the whole BCL. Doxygen @note Status: tags are secondary human hints and can drift from the database.

The query should travel with the number:

SELECT status, COUNT(*) FROM task GROUP BY status;
SELECT COUNT(*) FROM ticket;

This makes a future change visible and prevents an old book number from becoming an unexplained project constant.

78.7 Separate observations, inferences, and decisions

A robust task record distinguishes three things. An observation is directly reproducible: “this shader compiler path imports a missing module.” An inference connects evidence: “modularization left the workflow validator stale.” A decision sets policy: “the release gate must fail closed on a missing manifest.”

Mixing them causes plans to outlive their premises. A decision can remain valid after the cited bug moves; an observation can become false after a fix; an inference may need revisiting when a new control run appears. Marking the category makes later re-audit cheaper.

78.8 Handoff is part of implementation

An effective handoff states what is complete, what was verified, what remains, which repositories are read-only, and which actions require external approval. It includes failed approaches whose repetition would waste time and identifies known-stale documents that must not be used as status sources. It does not paste an ever-growing transcript into one file.

The final authority order is practical: current source and generated configuration; executable tests and retained artifacts; accepted integration/remediation records; then plans, audits, READMEs, and comments as context. Comments often preserve the best explanation and the worst status. Durable project practice keeps both facts visible by linking explanation to something a future maintainer can rerun.

Type at least three characters. Results are ranked by how often and where the words occur.