A Go CLI for managing complex documentation as structured, validated YAML. Your specifications, designs, and requirements live as interconnected nodes with schema validation, reference tracking, and audit trails. Works with git, works with AI.
| Domain | Example Nodes |
|---|---|
| Game Design | systems, mechanics, items, characters, quests |
| API Specs | endpoints, schemas, authentication, versioning |
| Technical Architecture | components, interfaces, services, data flows |
| Product Requirements | features, user stories, epics, acceptance criteria |
| Knowledge Bases | concepts, definitions, relationships |
| Aspect | Decision |
|---|---|
| Language | Go |
| License | Open source (eventually) |
| Schema | Extensible - core fields required, custom sections allowed |
| File location | Configurable, default .deco/ |
| History | Audit log (append-only: who, what, when) |
| AI workflow | Both patch operations and full file rewrites |
| Development | TDD - tests first, then implementation |
Core fields (required at top level, not nested under meta):
id: Unique identifier, maps to file pathkind: Node type (system, component, feature, requirement, etc.)version: Auto-incremented on updatesstatus: draft, review, approved, published, deprecatedtitle: Human-readable name
References (refs):
uses: Hard dependencies with contextrelated: Informational linksemits_events: Events this node producesvocabulary: Shared term definitions
Content (content.sections):
- Blocks of type: table, rule, param, mechanic, list, doc
- Custom block types can be defined in project config
- Block fields are strictly validated; unknown fields are errors (table columns allow only
key,type,enum,display)
External docs (docs):
- Reference external
.mdfiles withpath(required),keywords(optional),context(optional) - Available as node-level field (
docs:) and as block type (type: doc) in content sections deco validatechecks file existence (E055) and keyword presence (E056, case-insensitive)deco syncincludes referenced.mdfile contents in content hash; changes trigger version bumps and review resets
Issues (issues):
- Tracked TBDs with id, description, severity (low/medium/high/critical), location, resolved
Optional/extensible:
tags,summary,glossary,contracts,llm_context,constraints,reviewers,docs,custom
# Project setup
deco init [dir] # Initialize project
# Reading
deco list # List all nodes (--kind, --status, --tag)
deco show <id> # Show node details + reverse refs
deco query [term] # Search/filter nodes
deco validate # Check schema + refs + constraints
deco stats # Project health overview
deco issues # List all open TBDs
deco graph # Output dependency graph (DOT/Mermaid/ASCII)
# Modifying (edit YAML files directly, then sync)
deco sync # Detect edits, bump versions, track history
# Review workflow
deco review submit <id> # Submit for review
deco review approve <id> # Approve node
deco review reject <id> # Reject back to draft
deco review status [<id>] # Check review status
# History
deco history [--node <id>] # Show audit log
deco diff <id> # Show before/after changes
No ambiguity in complete documentation. A spec is "complete" when:
- Zero open
issues(no TBDs, no unanswered questions) - All refs resolve to existing nodes
- All required fields populated
No contradictions. Deco validates internal consistency through:
- Enum values must match their definitions
- Explicit constraints you define are enforced across nodes
Example constraint:
constraints:
- expr: "self.rate_limit == refs['systems/api'].default_rate_limit"
message: "Rate limit must match API default"Deco doesn't magically detect semantic contradictions - you declare what must be consistent, and Deco enforces it.
- Gherkin compilation or test execution
- UI or editor plugins (CLI only)
- Runtime integration (it's a documentation tool)
.deco/
config.yaml # Project configuration
history.jsonl # Audit log
nodes/
systems/
auth/
core.yaml
tokens.yaml
components/
database.yaml
The .deco/config.yaml file supports:
project_name: my-project
nodes_path: .deco/nodes
history_path: .deco/history.jsonl
version: 1
required_approvals: 2 # For review workflow
# Define custom block types with validation (simple syntax)
custom_block_types:
endpoint:
required_fields:
- method
- path
- response
optional_fields:
- auth
- rate_limit
# Define custom block types with typed fields (advanced syntax)
# Supports type checking, enum validation, and cross-references
custom_block_types:
building:
fields:
name: {type: string, required: true}
size: {type: string, required: true}
age: {type: string, required: true, enum: [stone, bronze, iron]}
category: {type: string, required: true, enum: [production, military]}
materials:
type: list
ref:
- {block_type: resource, field: name}
- {block_type: recipe, field: output}
resource:
fields:
name: {type: string, required: true}
tier: {type: number, required: true}
recipe:
fields:
output: {type: string, required: true, ref: {block_type: resource, field: name}}
building: {type: string, required: true, ref: {block_type: building, field: name}}
inputs: {type: list, ref: {block_type: resource, field: name}}
# Define per-kind schema rules for nodes
schema_rules:
requirement:
required_fields:
- priority
- acceptance_criteria
component:
required_fields:
- owner
- dependenciesCustom block types extend the built-in types (rule, table, param, mechanic, list, doc). When a custom type shares a name with a built-in type, both validations apply.
Simple syntax: required_fields + optional_fields + id. Validates field presence only.
Advanced syntax: fields map with typed field definitions. Supports:
- Type checking:
typecan bestring,number,list, orbool(error E052) - Enum validation:
enumconstrains string values with did-you-mean suggestions (error E053) - Cross-references:
ref: {block_type, field}validates values exist in another block type (error E054) - Union references:
ref:as array of targets validates with OR logic — value must exist in any target - Required enforcement:
required: trueensures the field is present (error E047)
Both syntaxes can coexist. Block fields are strictly validated: unknown block fields produce validation errors with suggestions (E049).
Block-level queries: deco query --block-type building --field age=bronze filters blocks across all nodes. Field filters support list membership: --field materials=Planks matches blocks where the materials list contains Planks.
Follow queries: deco query --block-type building --follow materials traverses ref constraints to find related blocks, grouped by value with reference counts. Supports explicit targets for ad-hoc joins: --follow materials:recipe.output.
Schema rules enforce required custom fields per node kind. The required_fields must be present in the node's custom: section. Nodes with kinds not listed in schema_rules are not constrained.
Two modes:
- Patch mode: AI outputs JSON patch operations, Deco validates and applies
- Rewrite mode: AI rewrites full YAML files, Deco validates after
The engine is the source of truth, not the AI.