6.0 KiB
Why
@suaveplan/crypto ships with versioned-key vocabulary fully implemented in source — DerivationCoordinate carries masterVersion u16 ‖ userId u32 ‖ depth u8 ‖ slotVersion u8 (packages/crypto/crypto/src/derivation/{coordinate,layouts}/), the eight-slot Keychain is built on it (packages/crypto/crypto/src/keychain/), and RootIdentity / ServerIdentity / RevocationList reference a server version (packages/crypto/crypto/src/{identity,revocation}/). The umbrella restore-crypto-keychain-packer-umbrella was archived on 2026-05-03 with 20 requirements covering this surface, but its spec deltas never folded into openspec/specs/crypto/spec.md. The live spec lost DerivationCoordinate, DerivationLayout, masterVersion, slotVersion, BaseKeySchema, Authority, hierarchical identity, revocation, audit log, packer, replay protection, KAT vectors, trust-anchor bootstrap, and OTel redaction as named requirements. The only "version" terms that survived are the password-blob header byte and a stray rollServer increments version scenario with no defining requirement. To compound it, openspec/specs/crypto-keys/spec.md exists as a stub describing the deleted @suaveplan/crypto-keys package, contradicting the live crypto/spec.md:204-207 requirement that the package be deleted (zero matches in packages/). The corpus is internally inconsistent and the central crypto invariant — every key carries (masterVersion, slotVersion) — is undocumented at the requirement layer, so no Verified by: chain pins the existing tests to a spec.
What Changes
- MODIFIED
cryptocapability: fold the 13 missing umbrella requirements intoopenspec/specs/crypto/spec.mdwithVerified by:pointers to existing tests inpackages/crypto/crypto/src/{derivation,keychain,identity,revocation,audit-log,packer,chunked-packer,bundles,wire-format,domain-tags,authority}/. New requirements:- Eight-slot Keychain with full-width derivation coordinates (
master / encrypt / sign / kx / salt / hash / stream / device) - DerivationLayout registry — pluggable u64 layout, default
DERIVATION_LAYOUT_V1(masterVersion u16 ‖ userId u32 ‖ depth u8 ‖ slotVersion u8) - Validity windows enforced at every verify call (
notBefore/notAfterper slot, injectable Clock) - Domain-separation tag on every signed payload (
DOMAIN_VAULT_V1,DOMAIN_PUBLIC_KEYCHAIN_V1,DOMAIN_PACKER_V1,DOMAIN_CHUNK_V1,DOMAIN_CRL_V1,DOMAIN_AUDIT_V1) - Public bundles are parent-signed and carry an issuer reference (
(masterVersion, userId, depth, slotVersion)) - Chain bundle traversal — concatenated parent-signed links
- Wire-format schemas exposed and committed (
PUBLIC_BUNDLE_MAGIC,CHAIN_BUNDLE_MAGIC,KEY_SLOT_PRIVATE_BYTE_SIZE,KEY_SLOT_PUBLIC_BYTE_SIZE,V1_COORDINATE_BYTE_SIZE,*_FORMAT_VERSION) - Authority — signing abstraction over hierarchical identity
- Hierarchical identity — Root and Server (
createRoot,createServer,rollServerwithversion + 1,revokeServer) - RevocationList — root-signed CRL keyed by
(serverId, version) - AuditLog — append-only Merkle log
- Packer — encrypt-and-sign envelope with replay protection (
issuedAt + nonce) - ChunkedPacker — per-chunk-signed P2P fragmentation
- Eight-slot Keychain with full-width derivation coordinates (
- NOT folded — deferred to a follow-up implementation change: the umbrella's
Trust-anchor bootstraprequirement specifiedsrc/trust-anchors/withloadTrustAnchor()/loadTrustAnchorFromEnv()/SUAVEPLAN_TRUST_ANCHOR_PATH. That directory and surface do not exist on genesis. Folding the requirement here would re-introduce the fail-mode this change is fixing (a requirement with noVerified by:pointer). It needs its own implementation change. - REMOVED
crypto-keyscapability: deleteopenspec/specs/crypto-keys/spec.md(the stub describing the deleted@suaveplan/crypto-keyspackage). The livecrypto/spec.mdrequirement "Keypair, Keychain storage, BIP39, and legacy Vault live inside@suaveplan/crypto" already asserts the package is gone; the orphan stub contradicts it. - This change is spec-only — no source code changes, no test changes. Every new requirement has its
Verified by:pointer resolve to an already-passing test file. If a requirement cannot be backed by an existing test, that requirement does not ship in this change (it gets a follow-up implementation change).
Capabilities
New Capabilities
(none)
Modified Capabilities
crypto: add 14 requirements covering versioned-key derivation, hierarchical identity, revocation, audit, packer envelopes, wire format, and trust-anchor bootstrap; no requirements modified or removed.crypto-keys: remove the entire spec file. The capability does not exist on genesis (the package was deleted as part ofrestore-crypto-fold-keys-vault); the stub spec is an artifact of an incomplete archive.
Impact
- Affected specs:
openspec/specs/crypto/spec.md(additions only),openspec/specs/crypto-keys/spec.md(deleted). - Affected code: none. Source already implements every requirement being folded; this change documents what already ships.
- Affected tests: none added, none removed. New
Verified by:pointers reference existing test files atpackages/crypto/crypto/src/{derivation,keychain,identity,revocation,audit-log,packer,chunked-packer,bundles,wire-format}/. - Conformance impact:
bun openspec validate crypto-spec-restore-versioning --strictmust pass. The post-archive live spec must also passopenspec validate --strictand the existingscripts/openspec-conformance.tsallowlist gate. - Downstream: future changes that touch
Keychain,Authority,RevocationList,AuditLog,Packer, orChunkedPackerwill now have a stable requirement surface to delta against, instead of free-form code drift. - Risk: low — no behaviour changes. The risk is a
Verified by:pointer resolving to a test that does not actually cover the requirement; mitigated by the validation step intasks.mdthat greps each cited test file for the asserted scenario before the change is archived.