Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

ADR-0009: Adopt VectorCraft’s conventions; improve the ones that drift

Status: Accepted · 2026-10-08

Context

StitchCraft lives next to VectorCraft and may one day be embedded in it. Contributors who know one codebase should feel at home in the other, and an upstream PR is easier when our code already follows their rules. We audited VectorCraft (main at 89ea46c) for patterns worth following and checked whether each one is actually enforced.

Audit

#VectorCraft patternEvidenceVerdictStitchCraft
1Never crash: unwrap, expect, panic!, todo!, unimplemented!, unreachable! denied workspace-wide; documented alternativesCargo.toml [workspace.lints.clippy]; docs/development.md “Robustness”AdoptSame lints, plus indexing_slicing denied in parsers and dbg_macro
2Panic guard at every entry pointvectorcraft_engine::guardAdaptLibraries never need it; the CLI wraps main and writes a bug-report bundle; the wasm plug-in cannot catch panics, so the lints are absolute
3Everything is a command in a declarative registry reachable from UI, control channel and MCPcrates/engine/src/cmd/*, cmd! macroAdopt the idea, improve the dataEverything user-visible is registered (parameters, diagnostics, profiles, formats, CLI commands); parameters are typed schemas that generate docs, where VectorCraft documents command parameters as free-form strings
4Layering enforced by cargo xtask layers with an append-only table and a unit-tested rule enginextask/src/layers.rsAdoptSame model in xtask/src/layers.rs
5One local gate, cargo xtask ci, with a step summaryxtask/src/main.rs (cmd_ci)Adopt and extendSame command — and the same gates run on every pull request in GitHub Actions. VectorCraft’s workflows run the test suite on a pull request only when it changes Cargo manifests or FreeBSD packaging (freebsd.yml), relying on contributors running the gate locally; for external contributions we want required checks
6AGENTS.md as the contract for contributors and agentsAGENTS.mdAdopt, keep DRYCLAUDE.md is a pointer to AGENTS.md. VectorCraft keeps two copies that have drifted: CLAUDE.md (63 lines) lacks AGENTS.md’s (81 lines) contributor-credits section
7Clean-room rules with an automated checkAGENTS.md says cargo xtask cleanroom runs in cargo xtask ciAdopt and implementAt 89ea46c there is no cleanroom subcommand in xtask/src/main.rs and cmd_ci does not run one — documentation and code drifted. Our cargo xtask cleanroom exists, runs in CI, and cargo xtask docs --check fails when docs mention a subcommand that does not exist
8Asset attribution enforced (ASSETS.md, checked by VectorCraft’s xtask assets step)xtask/src/assets.rsAdoptEvery committed image, font or fixture has a provenance row; generated images are attributed to their shot declaration
9Untrusted input is fuzzed with property testsengine/tests/import_fuzz.rs, format/tests/prop_format.rsAdopt and extendProperty tests on every parser, plus coverage-guided cargo-fuzz nightly with a persisted corpus
10cargo xtask wasm keeps crates building for the webxtask/src/main.rs (cmd_wasm)AdoptSame, for L0–L3 and the plug-in
11Shared corpora pinned by commit and SHA-256, never committedAGENTS.md, craftrules standards/test-corpora.mdAdoptcargo xtask corpus
12Honest ROADMAP.md, updated in the same PR as the workROADMAP.md, AGENTS.mdAdoptROADMAP.md status table + plan; the PR template asks for the update
13One task id per commit (M2.1: pen tool)AGENTS.mdAdoptOne roadmap step per PR, id in the title
14PR template checklist.github/pull_request_template.mdAdopt and automateMost checklist items are CI checks; the template keeps the human ones
15Rich doc comments on fields and modulese.g. crates/doc/src/node.rsAdopt and enforcemissing_docs denied in library crates
16Dependencies explained in Cargo.toml commentse.g. the wasmi features commentAdoptSame, plus cargo-deny
17Headless UI tests that assert on what a frame showscrates/ui-egui/src/panels/transparency.rs testsAdopt (phase 3 panels)Same style for any panel we contribute
18Very large modulesmenus.rs 3,752 lines, canvas.rs 2,941 linesDo not adoptFiles warn at 800 and fail at 1,500 lines
19Hand-taken screenshots in docsASSETS.md lists them as screenshots of the appDo not adoptDeclared, regenerated and compared in CI (docs pipeline)
20Workspace dependency declared but unused (egui_kittest)Cargo.toml:74; only named in xtask/src/layers.rsAvoidcargo-machete (or an xtask equivalent) flags unused declarations
21unsafe_code = "deny", example plug-in outside the workspace uses unsafe for the ABICargo.toml, crates/plugins/exampleAdopt and tightenforbid everywhere; the plug-in’s ABI shim is the single audited exception, checked by cargo xtask unsafe-audit

Decision

Follow VectorCraft’s conventions by default (rows marked Adopt), with the improvements listed. When VectorCraft changes a convention we follow, we re-evaluate here. When we improve on one (rows 5, 6, 7, 19, 20), we offer the improvement upstream where it is generic.

Consequences

  • VectorCraft contributors recognize the shape of the code, the gate and the rules.
  • Upstreaming (RFC proposals, phase 3) meets their review standards from the start.
  • We take on a little more CI (GitHub Actions on every PR), which external contributions need.