Proposal: Canton Failure-Classification Engine (Canton Transaction Debugger Earlier)
Development Fund Proposal Submission
Proposal file: /proposals/canton-failure-classification-engine.md
Summary
A Canton-native failure-classification engine that turns failed or rejected Ledger API submissions into deterministic, categorized root-cause diagnoses with ranked next checks — backed by an open, community-extensible knowledge base that the ecosystem can grow, and delivered as a DPM component so it installs through the toolchain Daml teams already use.
Existing Canton tooling operates on the success path: it inspects committed transactions by update-id and streams ledger events, all of which assume a transaction exists on the ledger to examine. When a submission is rejected, no update-id is created and nothing commits, and the developer reconstructs root cause by hand from the rejection payload and error code. That is where Canton is hardest to reason about, because its most painful failures — authorization, sub-transaction privacy/visibility, package/vetting drift, contention — are often the ones that never commit.
This build starts from the failed submission rather than the successful one. It parses Canton's structured error codes and rejection payloads and classifies each failure into a named family with ranked next checks at a measured precision. Where the available signals cannot distinguish the cause, it returns insufficient signal rather than guessing — the tool is bounded honestly to what the Ledger API exposes. Anyone can extend the knowledge base by contributing a new diagnosis (a declarative rule plus test examples) through a reviewed pull request, with no engine changes required: decoder packs are published as data-only DPM components that export under a shared key with conflict-strategy: extend, so dpm discovers and concatenates canonical, experimental, and organization-private packs while the engine arbitrates between them deterministically. It builds on the existing toolchain — Ledger API rejection payloads and error codes, plus dpm's published component and export mechanisms — with no compiler dependency, no fork of any component, and no bespoke plugin registry, loader, or version-resolution machinery of its own. It complements the DPM diagnostic component family — DPM Trace (#327), DPM Debug (#494), and the Transaction Profiler (#379) — all of which operate on transactions that exist.
Total funding request: 450,000 CC across 3 milestones (~10 weeks).
Checklist
- Proposal file added under
/proposals/ - Milestones and funding amounts defined
- Acceptance criteria included
- Alignment with Canton priorities described
Notes for Reviewers
Label: daml-tooling
This is a single-objective build: a failure-classification engine plus the open, community-extensible knowledge base behind it. Community extensibility is the core of the design, per SIG feedback — contributions are declarative (no contributed code runs in the engine, and packs are data-only components), fixture-gated with an automated no-regression check, deterministically resolved, and namespaced (canonical / experimental / org-private) with governed acceptance via the SIG. Two guarantees are enforced mechanically rather than asserted: version-gating is verified in CI across a matrix of at least 3 SDK versions installed through dpm — every decoder must classify correctly inside its declared range and abstain outside it, so knowledge-base rot surfaces as a build failure — and namespace precedence is enforced against a signed canonical index, so an untrusted pack cannot outrank a reviewed decoder through extend concatenation.
Delineation against adjacent work is deliberate: PRs #327, #494, and #379 all operate on committed transactions (inspection, visual debugging, execution cost); this engine addresses submissions that never committed, where there is no transaction to inspect. The only overlap is decoding a rejection against DAR metadata. A stable integration contract — library interface plus versioned JSON diagnosis schema, with a reference adapter — is published so those components can call a measured classifier instead of each reimplementing failure heuristics.
Funding is split 50% on delivery and 50% on independently verified outcomes (measured diagnostic precision/coverage, time-to-diagnosis, and validation on real production failures), so half the total — 225,000 CC — is gated on measured ecosystem value rather than artifact delivery, with the outcome share rising across milestones.
The team (InfraSingularity) ships Daml-based projects and operates production Canton validator infrastructure as an institutional NaaS provider; the diagnosis knowledge base is seeded from real production failures. Relevant SIGs: Daml Language & Developer Tooling, Canton APIs, dApp Integration.
Unique solutions (technical detail in the proposal file):
- Failure-first diagnosis: starts from the rejected submission, not the committed transaction
- Deterministic, categorized diagnosis at a measured precision, with honest
insufficient signalwhen the signal is inadequate - Community-extensible knowledge base riding
dpm's nativeexports/extendmechanism — data-only packs, no contributed code executes, private packs via standard registry credentials, no fork required - Loophole-closed governance: fixture-gated no-regression CI, deterministic conflict resolution, signed-canonical-index namespace precedence, and version-gating verified across a ≥3-version SDK matrix
- Non-invasive integration: Ledger API and
dpm's published component mechanism only — no compiler dependency, no fork, no parallel registry - Published integration contract so the DPM diagnostic components (#327, #494, #379) consume classification rather than rebuild it
Full technical specifications and per-milestone deliverables/acceptance criteria are in the proposal file.
Champion: @v9n