Skip to main content

Card Spec

A Card is drwn's independently versioned capability unit. A Blueprint is a Card that composes ordered plain Cards into one Worker root.

States

StateLocationMeaning
Source~/.agents/drwn/sources/<scope>/<name>/Mutable authoring tree.
Published~/.agents/drwn/cards/<scope>/<name>.git/Immutable Git-backed versions.
Extracted~/.agents/drwn/extracted/<tree-sha>/Content-addressed materialization.
Consumed<project>/.agents/drwn/card.lockExact root graph and Card provenance.

Card Refs

FormExample
Store range@your-handle/backend@^1.0.0
Store exact@your-handle/backend@1.2.3
Filefile:./cards/backend
Git refgit+https://github.com/me/card.git#v1.2.0
Git rangegit+https://github.com/me/card.git@^1.0.0
GitHubgithub:me/card@^1.0.0
GitLabgitlab:me/card#v1.2.0

Git URLs without a ref/range fail. GitHub/GitLab shorthands expand to HTTPS Git URLs. Git authentication remains owned by Git.

Card Manifest

Every Card has a validated card.json containing at least:

{
"name": "@your-handle/backend",
"version": "1.2.0"
}

Cards may include skills, MCP definitions, hook policies, persona, beliefs, memory, instructions, extensions, target intent, governance, and quality metadata.

A Blueprint adds:

{
"kind": "blueprint",
"composedFrom": [
"@your-handle/review@^1.0.0",
"@your-handle/testing@^1.0.0"
]
}

Blueprint members are ordered plain Cards. Nested Blueprints are rejected in the first supported contract.

Project Lock V1

<project>/.agents/drwn/card.lock is self-identifying:

{
"schema": "drwn.project-lock",
"schemaVersion": 1,
"store": { "minDrwnVersion": "0.8.0" },
"workerRoots": [
{
"name": "@your-handle/operator",
"requested": "@your-handle/operator@^1.0.0",
"kind": "blueprint",
"members": ["@your-handle/review", "@your-handle/testing"]
}
],
"cards": []
}

Root Fields

FieldMeaning
nameCanonical root Card name.
requestedRequirement ref from project config.
kindcard or blueprint.
membersOrdered direct member Card names; empty for a plain Card root.

Card Entry Fields

Each cards entry contains:

FieldMeaning
name / requested / versionArtifact identity and requirement provenance.
pathCurrent local extracted/content path.
integrityCanonical sha256-... tree integrity.
treeShaGit tree SHA for Store/Git artifacts.
manifestFull validated Card manifest.
skills / hooksLocked capability indexes.
persona / beliefs / memoryLocked Mind declarations when present.
hookConsentOptional Card/version-range hook consent.
originstore, git, file, or npm.
gitCommit and optional URL/ref for Store/Git origins.
registryReserved; currently null.

Every root and member must map to one Card entry. Orphan Cards, duplicate roots/members, root/member identity overlap, missing tree provenance, and incompatible same-name artifacts fail validation.

Integrity

computeCardIntegrity walks regular files, excluding .git and .integrity, and hashes canonical sorted records of:

  • relative path;
  • executable-bit class;
  • SHA-256 of file bytes.

The final value is sha256- plus the hash of the canonical JSON record array. This makes integrity sensitive to content, path, and executable state but not mtime/ownership.

Project Projection

Project config lists Worker roots and one selection. The selected root expands through the lock:

selected Blueprint root -> root Card -> ordered member Cards

Only that closure contributes Card capabilities. Explicit project skills, mcpServers, hooks, extensions, and targets remain project-owned overlays. Machine capabilities are not project declarations.

Local Development

.agents/drwn/config.local.json uses drwn.project-local V1 for replacements, local-only roots, source overrides, and local selection. .agents/drwn/card.lock.local uses the same project-lock V1 graph. Local state is ignored and does not rewrite committed intent.

Security

  • Card content never includes resolved environment secrets, API keys, or OAuth tokens.
  • Hook code requires explicit Card/version-range consent before materialization.
  • Notion OAuth and external stdio tool installation remain operator state.
  • Whole-Store export is disabled; deploy exports only one pinned closure through a separate allowlist.