canpuff-v1.md
The vault layout, the journal (JSONL events), the catalog (Markdown +
YAML frontmatter cards), attachments, identifiers, units, import
merging, and the extension mechanism. Scoped to inhaled cannabis,
recorded by weight.
Frozen · 12 sections
canpuff-sealed-v1.md
End-to-end encryption with age v1, a key hierarchy rooted in a BIP39
mnemonic, and a synchronisation protocol that works against a dumb file
server which never sees plaintext.
Under active development
canpuff-edibles-v1.md
Edibles, kept out of the core on purpose: pieces instead of grams,
milligrams per piece instead of mg/g, servings instead of weighed
doses. It adds fields to core objects; an application that ignores it
simply carries them through.
Companion profile · no implementation yet
mapping-pufftab-ios.md
Field by field, lossless, both directions: how the first
implementation's 13-entity SwiftData model becomes CanPUFF and comes
back unchanged.
Conformance contract
schemas/v1/<type>.json
JSON Schema 2020-12 for every object type, served at the canonical
$id URLs. Normative for the JSON form.
12 schemas · 3 profile overlays
examples/
A complete example plain vault, plus one standalone JSON object per
type that validates against the schemas.
Copy-paste starting points
fixtures/
Edge-heavy valid vaults and deliberately broken ones, each with the
reference validator's expected verdict, plus a runner. This is what
makes a third-party implementation testable.
Distributed via git, not the site
tools/
validate-vault.py for conformance and
diff-vaults.py for semantic equivalence of two vaults.
Standalone, no dependencies; both accept a directory or a
.canpuff.zip.
Round-trip verification