Archkit Docs
Archkit docs home.
Use this book for two tracks:
- AKS — language, grammar, examples, integration model
- Archkit — CLI, project workflows, architecture, operations
Start here
Learn AKS
Use Archkit
Docs model
docs/src/— mdBook entry pages, nav, wrappersdocs/AKS/— authored AKS source docsdocs/guides/— authored Archkit guidesdocs/reference/— curated reference docsdocs/architecture/— ADRs, boundaries, system designdocs/operations/— runbooks, CI, packaging, deploy
API docs
Use mdBook for product docs. Use rustdoc for crate API. See API Docs.
AKS: Architecture Knowledge Syntax
Welcome to the Architecture Knowledge Syntax (AKS) documentation. AKS is the native language for defining, modeling, and validating distributed system architectures in archkit.
What is AKS?
AKS is a domain-specific language (DSL) designed to model complex systems through:
- Entities - System components (services, databases, external systems)
- Shapes - Data structures and type definitions
- Events - State changes and system communications
- Relationships - Connections and dependencies between entities
- Policies - Governance rules and constraints
- Lattices - Domain-specific partial orders and refinements
- Views - Projections for different stakeholders (dependency graphs, workflows, data flows)
Why AKS?
Modern distributed systems are complex. Traditional documentation and diagrams fall out of sync with code. AKS solves this by:
- Single source of truth - One model drives all documentation, diagrams, and validation
- Machine-readable - Parse and transform AKS into TypeScript, JSON Schema, Mermaid diagrams, and more
- Type-safe - Shapes and events automatically generate type definitions for your code
- Governance-first - Define policies and constraints that archkit can validate
- Evidence-tracked - Know where every piece of architecture came from (code, documentation, or mirrored)
Quick Start
The 2-Minute Version
Create a file myapp.archkit.model.aks:
workspace "MyApp"
module myapp@1.0.0
shape User
id: String
email: String
created_at: Timestamp
end shape
entity auth_service: User
has role: orchestration
end entity
entity user_db database
end entity
entity frontend
has role: presentation
edge auth_service depends on
end edge
end entity
end workspace
Then ask archkit to validate it or generate types from it:
archkit parse -i myapp.archkit.model.aks
archkit generate code -i myapp.archkit.model.aks -t typescript.type -o generated/
Where to Go Next
I want to…
- Learn AKS basics in 15 minutes → Getting Started
- Understand core concepts → Core Concepts
- See real examples → Examples (choose your use case)
- Look up syntax → Full Grammar
- Generate code from my model → Type Extraction
- Understand how archkit processes AKS → How Archkit Uses AKS
- Trace exact frontend behavior against source (lexer/parser/lowering internals, live vs. dead pipelines) → Frontend Internals
- Extend archkit with custom behavior → Extension Pipeline
- Migrate from AKS v1 → Migration Guide
Core Concepts at a Glance
| Concept | Purpose | Example |
|---|---|---|
| Workspace | Root container for all architecture | workspace "MyApp" … end workspace |
| Entity | System component (service, database, queue) | entity user_db database … end entity |
| Shape | Data structure or type definition | shape User … end shape |
| Event | State change or message | event UserCreated … end event |
| Relationship | Dependency or connection between entities | relationship api calls db … end relationship |
| Policy | Governance rule or constraint | policy pii_encryption … end policy |
| Lattice | Partial order for domain-specific reasoning | lattice Environment … end lattice |
| View | Projection for specific audience | view revenue_overview … end view |
| Evidence | Source of truth (code, docs, mirror) | derived from: "doc:checkout-design" |
File Naming Convention
AKS files follow a predictable naming pattern:
<subject>.archkit.<kind>.<format>
Examples:
workspace.archkit.model.aks (authored model)
tags.archkit.overlay.aks (overlay annotations)
2026-06-30.cargo-workspace.archkit.mirror.aks (timestamped mirror)
- Subject: What the file describes (workspace, service, module)
- Kind:
model(authored),overlay(patches),mirror(auto-generated) - Format: Always
aksfor AKS files
Learning Path
Beginner
- Getting Started — Write your first model
- Examples: Systems Modeling — See progression from minimal to complex
Intermediate
- Core Concepts — Deep dive on each construct
- Grammar Reference — Detailed syntax rules
- Examples: Your Use Case — Type definition, governance, or data flow examples
Advanced
- Integration Docs — How archkit processes AKS
- Extension Framework — Custom validators, transformers
- Best Practices — Patterns for large models
Getting Help
Common Questions:
- See Troubleshooting for errors and debugging
- Check FAQ below
Need More?
- Read the Full Grammar for comprehensive syntax
- Explore Examples for working code
- Check the Integration Guide for how archkit works internally
FAQ
Q: Do I need AKS for every project? A: No. AKS is ideal for distributed systems with multiple components, complex dependencies, or governance needs. Simple microservices might not benefit.
Q: Can I use AKS with existing code? A: Yes. Archkit can mirror your Cargo workspace or Rustdoc and auto-generate an AKS model as a starting point.
Q: What if my system is too complex for AKS? A: Break it into modules. AKS supports multi-file models with imports.
Q: Can I generate code from AKS? A: Yes. Shapes and events automatically generate TypeScript, JSON Schema, and other type definitions. See Type Extraction.
Q: What formats does archkit export to? A: TypeScript, JSON Schema, Mermaid diagrams, Graphviz/DOT, and more. See Artifact Generation.
Ready? Start with Getting Started or jump to Examples.
Getting Started with AKS
Write your first AKS model in 15 minutes. We’ll build a simple e-commerce system step by step. Every snippet below parses with the real toolchain — the CI conformance test guarantees it.
Prerequisites
- archkit CLI built (
cargo build -p archkit-cli) or on your PATH - A text editor
- 15 minutes
Step 1: Create Your First Model (2 min)
Create a file called ecommerce.archkit.model.aks:
workspace "Ecommerce"
end workspace
Two rules to notice immediately: the workspace name is a quoted string,
and every block — including the workspace itself — closes with
end <keyword>. Verify it:
archkit parse -i ecommerce.archkit.model.aks
Step 2: Add Your First Entities (2 min)
Entities are system components. Properties always take the has keyword:
workspace "Ecommerce"
entity frontend
has role: presentation
end entity
entity api
has role: orchestration
end entity
end workspace
Step 3: Define a Shape (2 min)
Shapes are typed data structures:
workspace "Ecommerce"
shape Product
id: String
name: String
price: Float
in_stock: Bool
end shape
entity frontend
has role: presentation
end entity
entity api
has role: orchestration
end entity
end workspace
Fields are name: Type. Add ? for optional (String?) and [] for lists
(String[]).
Step 4: Add a Shape Reference (2 min)
An entity that owns/manages a data structure references it in the header:
entity api: Product
has role: orchestration
end entity
Step 5: Add Dependencies (3 min)
Dependencies are edge blocks inside entities. depends on is one of the
built-in edge phrases:
workspace "Ecommerce"
shape Product
id: String
name: String
price: Float
in_stock: Bool
end shape
entity frontend
has role: presentation
edge api depends on
end edge
end entity
entity api: Product
has role: orchestration
edge product_db depends on
end edge
end entity
entity product_db database
end entity
end workspace
Now we have a dependency chain: frontend → api → product_db. Note
entity product_db database — database is one of the built-in element
kinds (database, queue, container, component, person,
external system).
Step 6: Add an Event (2 min)
Events use the same field syntax as shapes and mark async messages:
event ProductPurchased
product_id: String
quantity: Int
timestamp: Timestamp
end event
Add it inside the workspace alongside your shapes.
Step 7: Try archkit Commands (2 min)
Parse and validate:
archkit parse -i ecommerce.archkit.model.aks
# or the dedicated validator:
archkit-validate -i ecommerce.archkit.model.aks
Generate code from your shapes (TypeScript, JSON Schema, Python, Go, Protobuf, OpenAPI):
archkit generate code -i ecommerce.archkit.model.aks -t typescript.type -o generated/
archkit generate code -i ecommerce.archkit.model.aks -t json.schema -o generated/
Project a view:
archkit view file --help # see projection options
Your First Complete Model
# Simple e-commerce system model
workspace "Ecommerce"
module ecommerce@1.0.0
shape Product
id: String
name: String
price: Float
in_stock: Bool
end shape
event ProductPurchased
product_id: String
quantity: Int
timestamp: Timestamp
end event
entity frontend
has role: presentation
has description: "User-facing web application"
edge api depends on
end edge
end entity
entity api: Product
has role: orchestration
has description: "Backend API server"
edge product_db depends on
end edge
end entity
entity product_db database
has description: "Data persistence layer"
end entity
end workspace
Common Patterns
Modeling external systems
entity payment_gateway external system
has description: "Stripe or similar"
end entity
Adding documentation
entity api
has role: orchestration
has description: "Main REST API. Implements GraphQL in v2.0"
end entity
Tagging for governance
entity api
has tag critical
has tag revenue_path
end entity
Troubleshooting
Parse error: “expected string, found Ident” — quote the workspace name:
workspace "Ecommerce".
Parse error: “expected newline, found Ident” inside an entity — you wrote
a bare key: value; entity properties need has key: value.
Parse error: “expected ‘end entity’” — every block needs its
end <keyword> closer.
Parse error mentioning tabs — AKS indentation is spaces-only.
More in TROUBLESHOOTING.md.
Next Steps
- See more complex examples → Examples by Use Case
- Learn all constructs → Core Concepts
- The full grammar → grammar/FULL_GRAMMAR.md
Core Concepts
The mental model behind AKS: what each construct is for and how they compose. All snippets here are validated against the real parser in CI.
Workspaces
A workspace is the root container — one per file, quoted name, explicit
end workspace:
workspace "Commerce"
module commerce@1.0.0
end workspace
The optional module <name>@<version> line versions the model itself.
Entities
Entities are the nodes of your architecture graph: services, databases, queues, people, external systems.
entity checkout_api
has role: orchestration
has description: "Order checkout flow"
has tag critical
end entity
Entity kinds
Structural classification uses the built-in kind vocabulary in the header:
entity payments_db database
end entity
entity events queue
end entity
entity stripe external system
end entity
Kinds: database, queue, container, component, person,
external system. An entity without a kind is generic.
Entity properties and tags
has <key>: <value>— arbitrary properties (strings, numbers, booleans, identifiers, lists, objects)has tag <name>— tags, the primary grouping mechanism for views and policies
The has keyword is required — bare key: value lines are a parse error in
entity bodies.
Shapes (Data Structures)
Shapes define typed data structures — the input to type modeling and code generation.
Basic shape
shape User
id: String
email: String
age: Int
end shape
Nested shapes
Reference other shapes by name:
shape Address
street: String
city: String
end shape
shape User
id: String
address: Address
end shape
Collections and optionals
shape Order
id: String
item_ids: String[]
coupon: String?
audit_trail: Json
end shape
T[] list, T? optional, suffixes stack (String?[]), Json for open
key-value data. Map/tuple/union types and field constraints (@min etc.) are
not part of the grammar — model invariants as policies.
Events (State Changes)
Events are shapes with async/message semantics — same field grammar, different keyword:
event OrderPlaced
order_id: String
user_id: String
timestamp: Timestamp
end event
Events vs shapes: use event for records of things that happened
(past-tense names), shape for commands, entities’ data, and value objects.
Relationships
Two ways to express edges in the graph:
Local edges (inside the entity)
entity checkout_api
edge payments_db depends on
has via: "SQL"
end edge
end entity
Standalone relationships
relationship checkout_api calls payment_service
has protocol: https
end relationship
Both use the same phrase vocabulary (calls, depends on, sends data to,
publishes, subscribes, produces, consumes, … — see
grammar §6). Unknown single words become custom
phrases.
Shape conformance
An entity that owns/implements a data structure references the shape in its header:
entity user_service: User
has role: orchestration
end entity
Multiple services may reference the same shape; an entity can reference at most one shape directly (model composites with edges or tags).
Provenance (Evidence)
Track where a claim about the architecture comes from:
entity checkout_api
derived from: "doc:checkout-design"
evidenced by: "trace:prod:checkout"
verified by: "test:integration-suite"
end entity
Verbs: derived from, evidenced by, observed in, verified by,
deprecated by. Provenance also attaches to edges and relationships. Values
conventionally encode a source category prefix (doc:, trace:, test:,
mirror:, code:).
Governance: Lattices and Policies
Lattices define ordered domains; policies state rules over the graph:
lattice Tier
order best_effort < standard < critical
end lattice
policy critical_ownership
applies to tag: critical
must have owner
requires tier at least standard
end policy
See grammar §8–9 and the governance examples.
Views and Projects
Views are filtered projections for diagrams; projects bundle entities with configuration:
view revenue_overview
kind: system
schema: c4
include: tag: revenue_path
focuses_on: checkout_api
end view
project checkout_system
includes entity checkout_api
has team: payments
end project
A Complete Workspace
workspace "Commerce"
module commerce@1.0.0
# Data structures
shape Product
id: String
price: Float
end shape
# Events
event ProductPurchased
product_id: String
timestamp: Timestamp
end event
# System components
entity storefront
has role: presentation
edge catalog_api depends on
end edge
end entity
entity catalog_api: Product
has role: orchestration
has tag critical
has owner: catalog_team
edge catalog_db depends on
end edge
end entity
entity catalog_db database
end entity
# Governance
policy critical_ownership
applies to tag: critical
must have owner
end policy
# Projection
view overview
kind: system
schema: c4
include: tag: critical
end view
end workspace
Next
- Step-by-step tutorial → GETTING_STARTED.md
- Every construct in detail → grammar/FULL_GRAMMAR.md
- Worked examples → examples/
AKS Reference Index
Complete index to AKS documentation and resources.
Quick Links
Just starting?
- README.md - What is AKS
- GETTING_STARTED.md - Your first model (15 min)
Learning by example?
- Examples - Four use cases with progression
- CORE_CONCEPTS.md - Detailed concept explanations
Need syntax?
- Grammar Reference - Complete EBNF
- Lexical Rules - Tokens and keywords
Generating code?
- Type Extraction - Shapes → code
- Artifact Generation - All output formats
Stuck?
- Troubleshooting - Common errors and solutions
- Best Practices - Patterns and recommendations
Documentation Structure
docs/AKS/
├── README.md # Start here
├── GETTING_STARTED.md # 15-minute introduction
├── CORE_CONCEPTS.md # Detailed explanations
├── BEST_PRACTICES.md # Patterns & recommendations
├── TROUBLESHOOTING.md # Error solutions
├── MIGRATION.md # v1 → v2 upgrade
├── REFERENCE.md # This file
│
├── grammar/ # Syntax reference (authoritative)
│ ├── README.md
│ ├── FULL_GRAMMAR.md # Complete grammar + EBNF
│ └── LEXICAL_RULES.md # Tokens & keywords
│
├── examples/ # Runnable, CI-validated examples
│ ├── README.md # How to use examples
│ ├── PROGRESSION.md # Learning path
│ ├── 01-systems-modeling/ # Model architecture
│ ├── 02-type-definition/ # Generate code
│ ├── 03-governance-policies/ # Add policies
│ └── 04-data-flow-events/ # Model events
│
└── integration/ # How archkit works
├── README.md # Pipeline overview
├── HOW_ARCHKIT_USES_AKS.md # Parse → workspace
├── ARTIFACT_GENERATION.md # Output formats
├── TYPE_EXTRACTION.md # Shapes → code
├── GRAPH_MODEL.md / GRAPH_EXAMPLES.md
├── EDGES_AND_PROVENANCE.md
├── LATTICE_DEEP_DIVE.md / POLICY_DEEP_DIVE.md
├── OPERATIONS_AND_PROJECTS.md
└── EXTENSION_PIPELINE.md # Custom extensions
By Use Case
I want to model a system
- Read README.md
- Try GETTING_STARTED.md
- Follow Systems Modeling Examples
- Reference Best Practices
I want to generate code
- Read Type Extraction
- Try Type Definition Examples
- Use
archkit generate code -i model.aks -t typescript.type - See Artifact Generation
I want to add governance
- Read CORE_CONCEPTS.md (policies section)
- Try Governance Examples
- Reference Grammar: Policies
- See Best Practices (policies section)
I want to model events
- Try Data Flow Examples
- Read CORE_CONCEPTS.md (events section)
- Reference Grammar: Shapes & Events
I want to understand archkit internals
- Read Integration README
- Study How Archkit Uses AKS
- Explore ARTIFACT_GENERATION.md
- See parser source:
crates/archkit-frontend/src/aks/
I want to extend archkit
- Read Extension Pipeline
- See full guide:
docs/guides/AKS_EXTENSION_FRAMEWORK.md - Reference existing extensions in codebase
Command Reference
Parsing & Validation
archkit parse -i workspace.aks
# Parse and lower through the full frontend
archkit-validate -i workspace.aks
# Dedicated validator binary (same pipeline, JSON output options)
archkit check --help
# Project-level checks (schema, layout, policies)
Code Generation
archkit generate code -i workspace.aks -t typescript.type -o generated/
archkit generate code -i workspace.aks -t json.schema -o generated/
archkit generate code -i workspace.aks -t python.type -o generated/
# Targets: json.schema, typescript.type, python.type, go.type,
# protobuf.type, openapi.schema
Views & Reports
archkit view file --help # project a view from a single file
archkit report --help # drift, health, compatibility reports
Help
archkit --help
archkit parse --help
archkit generate --help
Glossary
| Term | Definition |
|---|---|
| Workspace | Root container for all architecture |
| Entity | System component (service, database, queue) |
| Shape | Data structure or type definition |
| Event | Immutable record of something happening |
| Relationship | Connection between entities (dependency, conformance) |
| Conformance | Entity conforms to / implements a shape |
| Dependency | Entity requires/depends on another entity |
| Lattice | Partial order for domain-specific reasoning |
| Policy | Governance rule or constraint |
| Evidence | Source of truth (code, mirror, authored, observation) |
| View | Projection for specific stakeholder |
| Module | Sub-workspace for organization |
| Overlay | Additional annotations/properties |
| Mirror | Auto-generated snapshot from code |
File Naming
<subject>.archkit.<kind>.<format>
Examples:
workspace.archkit.model.aks
security.archkit.overlay.aks
2026-06-30.cargo-workspace.archkit.mirror.aks
Kinds: model, overlay, mirror
Format: Always 'aks'
Quick Syntax
Basic Structure
workspace "MyApp"
module myapp@1.0.0
shape User
id: String
email: String
end shape
entity user_service: User
has role: orchestration
edge user_db depends on
end edge
end entity
entity user_db database
end entity
end workspace
Common Keywords
| Keyword | Purpose |
|---|---|
workspace | Root container (quoted name, end workspace) |
module | Model version (module name@version) |
shape | Data structure |
event | Async message/state change |
entity | System component (node) |
edge | Local relationship inside an entity |
relationship | Standalone edge between entities |
has | Property/tag prefix in entity bodies |
policy | Governance rule |
lattice | Ordered domain (chains) |
derived from / verified by / … | Provenance verbs |
Element Kinds and Roles
Structural kinds go in the entity header; roles are a has property
convention:
- Kinds:
database,queue,container,component,person,external system - Role convention (
has role: …):presentation,orchestration,storage,messaging,external,observability
Common Types
String,Int,Float,Bool,Timestamp— named types (conventions; names are not validated at parse time)Json— untyped JSON (the only special-cased name)Type?— optional (suffix)Type[]— list (suffix)
There are no map, tuple, or union type literals — use Json.
Tips & Tricks
Validate
archkit parse -i workspace.aks
archkit-validate -i workspace.aks --json-out validation.json
Generate Code from Shapes
for target in typescript.type json.schema python.type go.type; do
archkit generate code -i workspace.aks -t $target -o generated/
done
Project Checks (drift, layout, health)
archkit check --help
archkit report --help
Debug Issues
archkit parse -i workspace.aks -v 2>&1 | head -50
External Resources
Related Documentation
- Full Grammar - Complete EBNF specification
- Examples - Runnable, progressive examples
- Best Practices - Patterns and anti-patterns
Project System
Archkit API
- Public API:
crates/archkit/src/lib.rs - Type System:
crates/archkit-type-model/src/lib.rs - Extensions:
crates/archkit-extensions/src/lib.rs
Common Tasks
| Task | Reference |
|---|---|
| Write first model | GETTING_STARTED.md |
| Learn concepts | CORE_CONCEPTS.md |
| Find syntax | Grammar |
| Model system | Systems Examples |
| Generate types | Type Extraction |
| Add policy | Governance Examples |
| Model events | Data Flow Examples |
| Fix error | Troubleshooting |
| Migrate v1 | MIGRATION.md |
| Extend archkit | Extension Pipeline |
Getting Help
Documentation Flow
1. Start with README.md
↓ (What is AKS?)
2. Try GETTING_STARTED.md
↓ (15-minute intro)
3. Pick your path:
├─ Examples (learn by doing)
├─ Core Concepts (deep dive)
├─ Grammar (syntax reference)
└─ Integration (understand internals)
4. When stuck: Troubleshooting
↓ (solve specific errors)
5. Advanced: Best Practices
↓ (patterns at scale)
Support Checklist
- Read README.md
- Try GETTING_STARTED.md
- Check Troubleshooting for error
- Find relevant Example
- Review Best Practices
- Search Grammar Reference
- Check CORE_CONCEPTS.md
Site Map
Main Entry Points:
- README.md - Overview
- GETTING_STARTED.md - Quick start
- Examples - Progressive learning
- Grammar - Syntax reference
Learning:
- CORE_CONCEPTS.md - Detailed explanations
- BEST_PRACTICES.md - Patterns & recommendations
- Examples/PROGRESSION.md - Structured learning path
Reference:
- Grammar/FULL_GRAMMAR.md - Complete EBNF
- Grammar/LEXICAL_RULES.md - Tokens/keywords
- Grammar - All constructs
Integration:
- Integration/README.md - Pipeline overview
- Integration/HOW_ARCHKIT_USES_AKS.md - Internals
- Integration/ARTIFACT_GENERATION.md - Outputs
- Integration/TYPE_EXTRACTION.md - Code generation
- Integration/EXTENSION_PIPELINE.md - Extensibility
Support:
- TROUBLESHOOTING.md - Error solutions
- MIGRATION.md - v1 → v2 upgrade
- REFERENCE.md - This file (index)
Ready to start? → Go to README.md or GETTING_STARTED.md
Have an error? → See TROUBLESHOOTING.md
Want to learn? → Try Examples or CORE_CONCEPTS.md
Need syntax? → Go to Grammar
Best Practices
Patterns and recommendations for effective AKS modeling. All ```aks
snippets are CI-validated against the real parser.
File Organization
Single-File Models
For small systems (< 20 entities):
workspace/
├── workspace.archkit.model.aks (main model)
└── README.md (documentation)
Project-System Layout
For larger systems, use the archkit project system
(archkit project init) and its directory ownership rules:
project/
├── authored/ *.archkit.model.aks (hand-written models)
├── overlays/ *.archkit.overlay.aks (annotations; separate dialect)
├── mirror/ YYYY-MM-DD.*.archkit.mirror.aks (auto-generated)
├── generated/ (schemas, types — auto-generated, do not edit)
└── reports/ (drift, health — auto-generated)
See docs/guides/PROJECT_SYSTEM.md for the full ownership table.
File Naming
- Model files:
*.archkit.model.aks - Overlay files:
*.archkit.overlay.aks - Mirror files:
YYYY-MM-DD.source.archkit.mirror.aks
Naming
Entities: snake_case ids
entity user_service
end entity
entity product_db database
end entity
entity event_bus queue
end entity
Entity ids are graph node ids — keep them short, lowercase, and stable; they appear in edges, views, and policies.
Shapes and events: PascalCase, singular
shape User
id: String
end shape
event UserCreated
user_id: String
end event
Shapes are singular (User, not Users); events are past-tense
(UserCreated, not CreateUser — that’s a command shape).
Fields: snake_case
shape User
user_id: String
created_at: Timestamp
end shape
Modeling Patterns
Layered architecture
Dependencies point downward: presentation → orchestration → storage.
entity web_frontend
has role: presentation
edge api_gateway depends on
end edge
end entity
entity api_gateway
has role: orchestration
edge user_service depends on
end edge
end entity
entity user_service
has role: orchestration
edge user_db depends on
end edge
end entity
entity user_db database
end entity
Data ownership
One service owns the authoritative copy — express it with a shape reference; consumers depend on the owner, not the shape:
shape User
id: String
email: String
end shape
entity user_service: User
has role: orchestration
end entity
entity order_service
edge user_service depends on
end edge
end entity
Event-driven communication
Prefer pub/sub through a bus over direct coupling:
entity user_service
edge event_bus publishes
has emits: UserCreated
end edge
end entity
entity notification_service
edge event_bus subscribes
has listens_for: UserCreated
end edge
end entity
entity event_bus queue
end entity
Governance with tags
Tags are the selector mechanism for policies and views — tag consistently:
entity checkout_api
has tag critical
has tag revenue_path
has owner: payments_team
end entity
policy critical_ownership
applies to tag: critical
must have owner
end policy
Documentation
Descriptions and properties
entity user_service
has role: orchestration
has description: "Manages user authentication and profiles"
has owner: platform_team
end entity
Provenance
Track where every claim comes from with the built-in verbs:
entity user_service
has role: orchestration
derived from: "code:src/services/user_service.rs"
verified by: "test:integration-suite"
end entity
Prefix values by source category: code:, doc:, trace:, test:,
mirror:, authored:.
Comments
# This dependency exists for legacy compatibility (v1.x);
# remove when decommissioning the old API.
entity old_api
edge legacy_service depends on
end edge
end entity
Avoid Anti-Patterns
❌ Circular dependencies
If a → b → c → a, break the cycle with an event bus or an intermediary:
entity a
edge event_bus publishes
end edge
end entity
entity b
edge event_bus subscribes
end edge
end entity
entity event_bus queue
end entity
❌ Everything depending on everything
Introduce an aggregator so consumers have a single dependency:
entity api_gateway
has role: orchestration
edge user_service depends on
end edge
edge order_service depends on
end edge
end entity
entity frontend
edge api_gateway depends on
end edge
end entity
❌ Overly generic shapes
value: Json everywhere defeats type modeling. Create specific shapes:
shape User
id: String
email: String
name: String
end shape
Reserve Json for genuinely open data (metadata, config).
❌ Untagged, roleless entities
Policies and views select on tags and properties — an entity with neither is invisible to governance:
entity user_service
has role: orchestration
has tag service
end entity
Validation
Validate on every change; wire it into CI:
archkit parse -i workspace.archkit.model.aks
archkit-validate -i workspace.archkit.model.aks
# Project-level checks (drift, layout, health):
archkit check --help
archkit report --help
Versioning
Version the model with the module line and bump it like semver:
workspace "MyApp"
module myapp@1.2.3
end workspace
- MAJOR — breaking architecture changes
- MINOR — new services/shapes
- PATCH — fixes, refinements
Troubleshooting
Real error messages from the AKS parser and how to fix them. Errors include
line:column positions. Validate any file with:
archkit-validate -i workspace.aks
# or
archkit parse -i workspace.aks
Parse Errors
expected string, found Ident("...") (at 1:11)
Cause: unquoted workspace name.
workspace Ecommerce # WRONG
Fix:
workspace "Ecommerce"
end workspace
expected newline, found Ident("...") in an entity body
Cause: bare key: value property — entity properties require has.
entity api
role: orchestration # WRONG
end entity
Fix:
entity api
has role: orchestration
end entity
expected 'end <kind>' / unexpected token in declarations
Cause: a block was never closed, or closed with the wrong keyword.
Every block needs its own end:
workspace "Demo"
shape User
id: String
end shape
entity api
end entity
end workspace
Also raised when an end at the wrong indentation level makes the parser see
a mismatched block boundary — the end <kind> must sit at the opener’s
indentation, not the body’s.
tabs not allowed in indentation (use spaces only)
Cause: a tab character anywhere in leading whitespace. Convert to spaces; AKS never accepts tabs.
expected type, found LBracket / expected type, found Question
Cause: prefix type syntax from other languages. AKS types use suffixes:
items: [OrderItem] # WRONG (prefix list)
phone: ?string # WRONG (prefix optional)
Fix:
shape Order
items: OrderItem[]
phone: String?
end shape
expected newline, found At
Cause: field constraint annotations (@min(0), @pattern(...)) — these
are not part of the grammar. Remove them; express invariants as policies.
unknown element kind '...'
Cause: a word after the entity id that isn’t a kind. Only
database, queue, container, component, person, external system
are valid there:
entity payments_db database
end entity
If you meant a shape reference, use a colon: entity api: Service.
unexpected keyword in view: ...
Cause: unsupported view body keyword. Views accept exactly kind:,
schema:, include:, exclude:, focuses_on: (note the spelling — not
focus_on), and layout (bare keyword, no colon):
view overview
kind: system
schema: c4
include: tag: critical
focuses_on: checkout_api
layout
rankdir: LR
end view
unknown selector type: ...
Cause: view selectors are limited to entity:, tag:, and
relationship:. There is no tier: or other custom selector — put the
property on a tag and select the tag.
unsupported lattice syntax 'level' (also covers, join, meet)
Cause: partial-order lattice syntax is reserved but not implemented. Only chains work:
lattice Env
order dev < staging < prod
bottom dev
top prod
end lattice
expected identifier, found <Keyword>
Cause: using a reserved word (event, view, order, top, …) as an
entity id or property key. Rename it (has emits: instead of has event:).
Full reserved list: grammar §17.
unexpected character '*' (or =, +, ->)
Cause: characters outside the AKS token set — often inside
expands to blocks, whose bodies must still lex as AKS tokens.
expected newline, found LBrace
Cause: brace-block syntax (entity Foo { ... }) from other modeling
languages. AKS uses indentation + end markers, never braces — except as
property values (has config: {timeout: 30}), which are fine.
Lowering Errors (Parse Succeeds, Validation Fails)
expression: unexpected end in operation
Known limitation: <> op operation trees in the expression
sub-language parse but do not lower yet — only variable/constant forms
(o quantity) survive the full pipeline.
Lattice bottom/top mismatch
bottom must name the first element of the chain and top the last;
anything else fails during lowering with an explicit message.
Overlay Files Fail to Parse
*.overlay.aks files containing annotate <id> { ... } blocks are a
separate dialect processed by the project system (archkit-project), not
the workspace grammar. Do not feed overlay files to archkit parse;
they are applied through project operations (archkit project ...).
Still Stuck?
- Grammar reference: grammar/FULL_GRAMMAR.md
- Working examples (CI-validated): examples/
- Lexical rules (tokens, strings, numbers): grammar/LEXICAL_RULES.md
Migration Guide: Legacy Dialects → Current AKS
Two legacy dialects appear in old documents and models:
- v1 (brace-based) —
app MyApp { ... },data,relates_to - Terse draft (indentation, no
endmarkers) —workspace MyApp, barerole:properties,depends_on:/conforms_to:lines
Neither parses with the current toolchain. This guide maps both onto the
implemented grammar. Old-dialect snippets below are tagged as plain text
because they are intentionally not valid AKS; every ```aks snippet is
CI-validated.
Quick Mapping Table
| Legacy | Current AKS |
|---|---|
app MyApp {} / workspace MyApp | workspace "MyApp" … end workspace |
version 1.0.0 | module myapp@1.0.0 |
data User { … } | shape User … end shape |
role: storage (bare) | has role: storage |
conforms_to: User | entity <id>: User (shape ref in header) |
depends_on: X / relates_to: | edge x depends on … end edge |
produces: E / subscribes_to: X | edge E produces / edge x subscribes |
evidence: "src" | provenance verbs: derived from:, verified by:, … |
[Type] | Type[] |
?type | Type? |
{string: Type} | Json |
@min(0) constraints | not supported — model as policies |
policy: "prose" | named policy <id> … end policy blocks |
lattice X + a < b | lattice X + order a < b |
role: external | entity <id> external system |
Side-by-Side
Workspace
Legacy:
app MyApp {
version: "1.0.0"
}
workspace MyApp
version 1.0.0
Current:
workspace "MyApp"
module myapp@1.0.0
end workspace
Entities and dependencies
Legacy:
entity UserService {
role: "orchestration"
depends_on: ["UserDB"]
}
entity UserService
role: orchestration
depends_on: UserDB
Current:
entity user_service
has role: orchestration
edge user_db depends on
end edge
end entity
entity user_db database
end entity
Shapes
Legacy:
data User {
fields: {
id: "string"
email: "string"
}
}
shape User
id: string
email: string
Current:
shape User
id: String
email: String
created_at: Timestamp
end shape
Conformance
Legacy:
entity UserService
conforms_to: User
Current — the shape reference lives in the entity header:
entity user_service: User
has role: orchestration
end entity
Events and messaging
Legacy:
entity EventBus
role: messaging
produces: UserCreated
entity NotificationService
subscribes_to: EventBus
listens_for: UserCreated
Current:
entity event_bus queue
edge UserCreated produces
end edge
end entity
entity notification_service
edge event_bus subscribes
has listens_for: UserCreated
end edge
end entity
Policies
Legacy:
policy: "PII data must be encrypted"
applies_to: Sensitivity.pii
Current:
policy pii_encryption
applies to tag: pii_handler
when sensitivity at least pii
requires encryption: enabled
end policy
Evidence
Legacy:
entity Service
evidence: "code:src/main.rs line 42"
Current — use the closed provenance verbs:
entity service
derived from: "code:src/main.rs line 42"
verified by: "test:integration-suite"
end entity
Migration Steps
- Quote the workspace name and add
end workspace. - Close every block with
end <keyword>(end shape,end entity, …). - Prefix entity properties with
has; convertconforms_to:into a header shape reference; convert roleexternalinto theexternal systemkind. - Convert relationship properties to edges (
edge <target> <phrase>withend edge), or standalonerelationship <from> <phrase> <to>blocks. - Fix types:
[T]→T[],?T→T?, maps →Json, drop@constraints. - Rewrite policies as named blocks with
applies toselectors. - Validate:
archkit parse -i model.aks— errors include line:column; see TROUBLESHOOTING.md for each message.
Reference
- Current grammar: grammar/FULL_GRAMMAR.md
- Validated examples of every construct: examples/
- Historical record of the v1 dialect:
docs/reference/aks-syntax-migration.md(archived analysis)
AKS Examples
This section contains runnable AKS examples organized by use case, each with progressive complexity.
Choose Your Path
Pick the use case that matches your needs:
1. Systems Modeling
Learn: How to define system architecture, entities, dependencies, and layers.
Good if:
- You’re designing a new microservices system
- You need to document existing architecture
- You want dependency validation
Progression:
01-minimal/- One entity, one shape (5 lines)02-microservices/- Multi-service system with layers (50 lines)03-distributed-system/- Complex system with overlays and evidence (200+ lines)
2. Type Definition
Learn: How to model data structures and generate TypeScript/JSON Schema.
Good if:
- You need to generate types for your code
- You want a single source of truth for data models
- You’re building type-safe APIs
Progression:
01-basic-shapes/- Simple shapes → TypeScript (20 lines)02-event-sourcing/- Events and event types (50 lines)03-complex-types/- Nested shapes, generics, constraints (100+ lines)
3. Governance & Policy
Learn: How to define policies, constraints, and domain rules.
Good if:
- You need to enforce architecture decisions
- You’re modeling compliance or governance
- You want to define domain-specific rules
Progression:
01-simple-constraints/- Basic policy rules (20 lines)02-domain-lattices/- Partial orders and refinement rules (50 lines)03-governance-framework/- Complex compliance framework (150+ lines)
4. Data Flow & Events
Learn: How to model events, event streams, and data transformations.
Good if:
- You’re building event-driven systems
- You need to track data flow through your system
- You want to validate event causality
Progression:
01-basic-events/- Simple event definitions (20 lines)02-event-streams/- Stores and event producers (60 lines)03-event-sourcing-pipeline/- Full CQRS/ES system (150+ lines)
How to Use These Examples
Each example has:
- workspace.aks - The actual AKS model
- EXPLANATION.md - Detailed walkthrough of concepts
- Generated outputs (where applicable):
*.ts- Generated TypeScript types*.json- Generated JSON Schema*.mmd- Mermaid diagrams
Running an Example
Navigate to any example and try:
cd examples/01-systems-modeling/01-minimal
# Parse and validate
archkit parse workspace.aks
# Generate diagram
archkit view file -i workspace.aks --output diagram.mmd
# Generate TypeScript types
archkit generate code -i workspace.aks -t typescript.type -o generated/
# Generate JSON Schema
archkit generate code -i workspace.aks -t json.schema -o generated/
Reading an Example
- Start with the first file in each progression (e.g.,
01-minimal/) - Skim the workspace.aks file (notice the syntax)
- Read EXPLANATION.md for detailed commentary
- Try running the commands above
- Move to the next complexity level
Learning Paths
Path 1: Beginner (30 min)
- Start here: Systems Modeling 01-minimal
- Then: Core Concepts
- Then: Systems Modeling 02-microservices
Path 2: Type Generation (45 min)
- Start here: Type Definition 01-basic-shapes
- Then: Type Extraction Guide
- Then: Type Definition 02-event-sourcing
- Then: Type Definition 03-complex-types
Path 3: Governance (45 min)
- Start here: Governance 01-simple-constraints
- Then: Grammar: Policies
- Then: Governance 02-domain-lattices
- Then: Governance 03-governance-framework
Path 4: Complete Walkthrough (2 hours)
- Follow all progressions in order (1→2→3→4)
- Read EXPLANATION.md for each
- Try generating outputs for each
Quick Reference
Each example folder contains:
examples/
01-systems-modeling/
README.md (use case intro + progression)
01-minimal/
workspace.aks (the model)
EXPLANATION.md (detailed walkthrough)
02-microservices/
workspace.aks
entities.txt (entity reference)
EXPLANATION.md
03-distributed-system/
workspace.aks
overlays/
tags.aks
policies.aks
EXPLANATION.md
Progression Complexity Matrix
| Level | Example | LOC | Constructs | Concepts |
|---|---|---|---|---|
| Beginner | systems 01-minimal | 10 | entity, shape | Basics |
| type 01-basic-shapes | 20 | shape | Type definition | |
| Intermediate | systems 02-microservices | 50 | entity, depends_on, shape | Layers, dependencies |
| type 02-event-sourcing | 50 | event, shape, conforms_to | Events | |
| governance 02-lattices | 50 | lattice, policy | Domain rules | |
| Advanced | systems 03-distributed | 200+ | overlays, evidence, modules | Complexity at scale |
| type 03-complex-types | 100+ | nested shapes, constraints | Type sophistication | |
| governance 03-framework | 150+ | complex policies, evidence | Compliance |
Tips
Debugging an example:
- Check indentation (AKS uses off-side rule)
- Verify all strings are quoted
- Run
archkit parseto validate - See Troubleshooting for common errors
Modifying an example:
- Copy the .aks file to your project
- Edit entities and shapes to match your system
- Run
archkit generate codeto generate output - See Best Practices for patterns
Want more?
- Read Full Grammar
- Check How Archkit Uses AKS
- See Best Practices
Pick a use case above and dive in!
AKS Grammar Reference
Authoritative syntax specification for the Architecture Knowledge Syntax language,
derived from and validated against the real parser in crates/archkit-frontend/src/aks/.
Contents
- FULL_GRAMMAR.md — every construct with rules, verified examples, and an EBNF summary. Start here.
- LEXICAL_RULES.md — tokens, keywords, indentation, closed phrase tables, string/number rules
Guarantees
Every ```aks fenced example in these documents (and everywhere else under
docs/) is parsed and lowered by the real frontend in CI:
crates/archkit-frontend/tests/docs_aks_conformance.rs. If a snippet stops
matching the implementation, the test suite fails.
Examples that intentionally show invalid syntax use ```text fences.
Quick Navigation
- Workspace / module syntax → FULL_GRAMMAR.md §1–2
- Shapes, events, types → FULL_GRAMMAR.md §3–4
- Entities, edges, provenance → FULL_GRAMMAR.md §5–7
- Relationships & phrase vocabulary → FULL_GRAMMAR.md §6
- Lattices → FULL_GRAMMAR.md §8
- Policies → FULL_GRAMMAR.md §9
- Operations, projects, views → FULL_GRAMMAR.md §10–12
- Sub-languages (
expands to) → FULL_GRAMMAR.md §13 - Reserved words → FULL_GRAMMAR.md §17
- Token-level details → LEXICAL_RULES.md
Validating Your Own Files
cargo run -p archkit-cli --bin archkit-validate -- -i workspace.aks
# or through the main CLI:
archkit parse --input workspace.aks
Related
- Working examples (also CI-validated): ../examples/
- How AKS lowers into the workspace/substrate model: ../integration/HOW_ARCHKIT_USES_AKS.md
- Overlay files (
annotateblocks inoverlays/) are a separate dialect handled byarchkit-project, not this grammar - Parser source:
crates/archkit-frontend/src/aks/parser/ - Lexer source:
crates/archkit-frontend/src/aks/lexer/
AKS Full Grammar Reference
This is the authoritative grammar specification for AKS (Architecture Knowledge Syntax).
Every ```aks example in this document is validated against the real parser by
crates/archkit-frontend/tests/docs_aks_conformance.rs — if it’s written here, it parses.
Grammar style: off-side rule (indentation-sensitive) with explicit end <keyword> block closers.
Parser: hand-written lexer + recursive-descent parser in crates/archkit-frontend/src/aks/.
1. High-Level Structure
Every AKS file contains exactly one workspace block. The workspace name must be a quoted string. Nine kinds of declaration may appear inside, in any order.
workspace "Commerce"
module commerce@v1
shape Service
id: String
end shape
entity checkout_api: Service
has tag critical
end entity
end workspace
Rules:
- Must start with
workspace "name"(quoted string, not a bare identifier) - Optional
module <name>@<version>immediately after the header - Declarations:
shape,event,entity,relationship,lattice,policy,operation,project,view - Every block closes with
end <keyword>, includingend workspace - Indentation is significant: spaces only, one level per block
2. Module Declaration (Optional)
workspace "Demo"
module archkit_core@v2.0
end workspace
Rules:
- Optional; appears immediately after the
workspaceheader - Syntax:
module <identifier>@<version>— the version is free text to end of line (v1,2.0,1.2.3-betaall work) and must be non-empty end moduleis optional
3. Shapes (Data Structures)
shape Account
id: String
email: String
balance: Float?
tags: String[]
fallbacks: String?[]
metadata: Json
end shape
shape EmptyShape
end shape
Rules:
shape <identifier>followed by newline- Fields are
name: TypeExpr, one per line, indented end shaperequired; empty shapes allowed
Type expressions (implemented):
| Syntax | Meaning |
|---|---|
Name | named type (String, Int, Float, Bool, or any shape name — names are not validated at parse time) |
Json | untyped JSON (the only special-cased type name) |
T? | optional |
T[] | list |
| suffix stacking | String?[] = list of optionals |
Not implemented (do not use): [T] prefix lists, {k: T} map types,
(T1, T2) tuples, T1 | T2 unions. The AST reserves nodes for map/tuple/union,
but no surface syntax produces them.
4. Events
Events use identical field syntax to shapes; the keyword marks async message/event semantics.
event OrderPlaced
order_id: String
customer_id: String
amount: Float
end event
5. Entities (Instances / Nodes)
Header forms
entity plain_node
end entity
entity account1: Account
end entity
entity payments_db database
end entity
entity stripe external system
end entity
entity <id>— generic kindentity <id>: <ShapeName>— with shape referenceentity <id> <kind>— with element kind. Kind vocabulary:database,queue,container,component,person, and the two-word phraseexternal system. Any other word in kind position is a parse error.
Body
entity checkout_api: Service
has tag critical
has tag revenue_path
has owner: payments_team
has sla: "4 hour response"
has config: {timeout: 30, retries: 3}
has regions: ["us-east", "eu-central"]
derived from: "service-catalog:checkout_api"
verified by: "arch-review:AR-2026-041"
edge payment_service calls
has protocol: https
verified by: "trace:prod:checkout/payment"
end edge
edge notification_queue sends data to
has async: true
end edge
end entity
Body items (all optional, repeatable):
has tag <identifier>— attach a taghas <key>: <value>— attach a property (thehaskeyword is required; barekey: valuelines are not valid in entity bodies)- provenance clauses (§7)
edge <target> <phrase> … end edge— local edges (§6 phrase vocabulary); edge bodies takehasproperties and provenance clausesexpands to <kind> … end <kind>— sub-language blocks (§12)
6. Relationships (Global Edges)
relationship user uses api
end relationship
relationship frontend calls backend
has protocol: "JSON-RPC"
has timeout_ms: 5000
end relationship
relationship db serves api
evidenced by: "trace:prod:db-query"
verified by: "test:integration"
end relationship
Rules:
relationship <from> <phrase> <to>followed by newline- Body (optional):
has <key>: <value>properties and provenance clauses end relationshiprequired
Edge phrase vocabulary — these normalize to a closed EdgeKind set:
- Multi-word (pre-tokenized by the lexer):
depends on,sends data to,receives data from,reads from,writes to,connects to,owned by,contained by,extended by,implemented by,used by,provided by,served by,cached by,monitored by - Single-word:
calls,publishes,subscribes,precedes,follows,triggers,owns,contains,extends,implements,uses,produces,consumes,exports,imports,serves,caches,monitors - Any other single word is accepted as a custom phrase (
EdgeKind::Custom). Custom multi-word phrases are not possible.
7. Provenance (Evidence Tracking)
Provenance clauses may appear in entity, edge, and relationship bodies:
entity user_service
derived from: "doc:requirements"
evidenced by: "trace:prod:user-table"
observed in: "runbook:user-mgmt"
verified by: "test:user-factory"
deprecated by: "doc:migration-2026"
end entity
Verbs (closed set, pre-tokenized): derived from, evidenced by,
observed in, verified by, deprecated by.
Format: <verb>: <value> where value is a string or identifier; repeatable.
replacesis not a provenance verb. Express supersession as a property:has replaces: "old_notification_queue".
8. Lattices (Ordered Domains)
Only chain lattices are implemented:
lattice Criticality
order low < medium < high
end lattice
lattice Severity
order minor < moderate < major < critical
bottom minor
top critical
end lattice
Rules:
lattice <identifier>followed by newlineorder a < b < c— a single ascending chain- Optional
bottom <element>(must be the chain’s first element) andtop <element>(must be the last) end latticerequired- Lowering computes the reflexive-transitive closure automatically
Explicitly rejected (reserved for future partial orders): level, covers,
join, meet, incomparable — using them is a parse error, not a silent no-op.
9. Policies (Governance Rules)
policy revenue_reliability
applies to tag: revenue_path
when source.env: prod
unless source.experimental: true
requires monitoring.enabled
must have owner
forbids tier: best_effort
requires reaches via depends on where target.owner: platform
end policy
Structure:
policy <identifier>followed by newline- Selector (required):
applies to tag: <tag>|applies to entity: <id>|applies to shape: <name>|applies to relationship: <phrase> - Conditions (optional, repeatable):
when <predicate>,unless <predicate> - Requirements (optional, repeatable):
requires <predicate>,forbids <predicate>,must have <predicate>(alias ofrequires),must not <predicate>(alias offorbids) end policyrequired
Predicates:
- Free text to end of line (
monitoring.enabled,source.owner: platform) — captured as a simple predicate and interpreted during evaluation - Lattice comparisons:
<expr> at least <expr>,<expr> at most <expr>,<expr> above <expr>,<expr> below <expr> - Reachability:
reaches via <edge-phrase>with optionalwhere <predicate>(nestable). Reachability predicates currently lower as advisory (info) diagnostics — they parse and are preserved, but are not evaluated against the graph yet.
10. Operations (Behavior Property Bags)
operation DataSync
action: "synchronize replicas"
timeout_sec: 3600
retry: 3
end operation
Rules: operation <identifier>, body is bare key: value lines
(no has prefix here), schema is user-defined. end operation required.
11. Projects (Bundles)
project checkout_system
includes entity user
includes entity api
has team: payments
deployment: production
end project
Rules:
project <identifier>followed by newline- Body may contain, in any order:
includes <free text>— repeatable; stored asincludes_<n>propertieshas <key>: <value>or bare<key>: <value>— both accepted here
end projectrequired
12. Views (Projections)
view revenue_overview
kind: system
schema: c4
include: tag: revenue_path
include: entity: payments_db
exclude: tag: experimental
focuses_on: checkout_api
layout
rankdir: LR
fontsize: 12
end view
Body keywords:
kind: <identifier>— view type (defaults tosystem)schema: <identifier>— rendering schema (defaults toc4)include: <selector>/exclude: <selector>— repeatablefocuses_on: <entity>— highlight one entity (note the spelling:focuses_on, notfocus_on)layout— bare keyword, no colon, followed by an indented block ofkey: valuepairs; the block ends at dedent (there is noend layout)end viewrequired
Selectors: entity: <name>, tag: <tag>, relationship: <phrase>.
No other selector types exist.
13. Sub-Language Blocks (expands to)
Entities can embed domain-specific sub-language blocks:
entity pricing_rules
expands to expression
o quantity
end expression
end entity
Rules:
expands to <kind>followed by newline and an indented block- The block body is captured as a raw token stream (it must still lex as AKS:
tokens like
*,=,+are rejected by the lexer) - Closed by
end <kind>at the parent indentation
The expression sub-language:
o <name>— variable reference;o 42/o "lit"— constants<> <op>withleft:/right:ports — operation trees. Known limitation: operation trees currently parse but fail lowering (“unexpected end in operation”); only variable/constant expressions survive the full pipeline today. Track before relying on<>forms.
14. Property Values
Values in has k: v, operation/project/layout bodies:
| Form | Example |
|---|---|
| string | "4 hour response" (double quotes only; escapes \n \t \" \\) |
| integer | 5000 (no negative literals, no exponents) |
| float | 3.14 |
| boolean | true, false |
| identifier | https, payments_team (colon-joined idents like a:b also parse) |
| list | ["us-east", "eu-central"], [1, 2, 3] |
| object | {timeout: 30, retries: 3, cache: true} (nestable) |
15. EBNF Summary
workspace = "workspace" STRING newline module? decl* "end" "workspace"
module = "module" IDENT "@" line_text newline ("end" "module")?
decl = shape | event | entity | relationship | lattice
| policy | operation | project | view
shape = "shape" IDENT newline (indent field* dedent)? "end" "shape"
event = "event" IDENT newline (indent field* dedent)? "end" "event"
field = IDENT ":" type_expr newline
type_expr = ("Json" | IDENT) ("?" | "[" "]")*
entity = "entity" IDENT ((":" IDENT) | kind_phrase)? newline
(indent entity_item* dedent)? "end" "entity"
kind_phrase = "database" | "queue" | "container" | "component"
| "person" | "external system"
entity_item = "has" "tag" IDENT newline
| "has" IDENT ":" value newline
| provenance
| edge
| expands_to
edge = "edge" IDENT edge_phrase newline
(indent (has_prop | provenance)* dedent)? "end" "edge"
expands_to = "expands" "to" IDENT newline indent raw_tokens dedent "end" IDENT
relationship = "relationship" IDENT edge_phrase IDENT newline
(indent (has_prop | provenance)* dedent)? "end" "relationship"
edge_phrase = EDGE_PHRASE_TOKEN | IDENT (* see §6 vocabulary *)
provenance = PROVENANCE_VERB ":" line_text newline (* see §7 verbs *)
lattice = "lattice" IDENT newline indent
"order" IDENT ("<" IDENT)+ newline
("bottom" IDENT newline)? ("top" IDENT newline)?
dedent "end" "lattice"
policy = "policy" IDENT newline indent
("applies" "to" selector newline)
(("when" | "unless") predicate newline)*
(("requires" | "forbids" | "must have" | "must not") predicate newline)*
dedent "end" "policy"
selector = ("tag" | "entity" | "shape" | "relationship") ":" value
operation = "operation" IDENT newline (indent kv* dedent)? "end" "operation"
project = "project" IDENT newline
(indent ("includes" line_text | has_prop | kv)* dedent)? "end" "project"
view = "view" IDENT newline (indent view_item* dedent)? "end" "view"
view_item = ("kind" | "schema") ":" IDENT newline
| ("include" | "exclude") ":" selector_type ":" IDENT newline
| "focuses_on" ":" IDENT newline
| "layout" newline indent kv* dedent
selector_type = "entity" | "tag" | "relationship"
has_prop = "has" IDENT ":" value newline
kv = IDENT ":" value newline
value = STRING | INT | FLOAT | BOOL | IDENT
| "[" (value ("," value)*)? "]"
| "{" (IDENT ":" value ("," IDENT ":" value)*)? "}"
16. Common Errors
Missing end marker — every block needs its closer:
entity user
has tag actor
# error: expected 'end entity'
Mismatched end:
entity user
end shape # error: expected 'end entity', found 'end shape'
Bare property in entity body (entity bodies require has):
entity user
role: storage # error: expected newline — write `has role: storage`
end entity
Unquoted workspace name:
workspace Ecommerce # error: expected string — write workspace "Ecommerce"
Tabs in indentation — the lexer rejects tabs outright.
17. Reserved Words
Reserved (cannot be used as bare identifiers in most positions):
workspace module shape event entity relationship lattice policy
operation project view end edge has tag with includes excludes
focuses on renders shows hides groups orders by expands
when unless requires forbids above below
order level top bottom join meet covers incomparable
Notes:
with,renders,shows,hides,groups,orders,by,on,focuses,excludesare reserved but currently consumed by no grammar rule (reserved for future view syntax)at least,at most,must have,must not,applies to, the edge phrases (§6), the provenance verbs (§7), andexternal systemare pre-tokenized multi-word phrases
18. Related
- Lexical detail (tokens, indentation, phrase tables): LEXICAL_RULES.md
- Working examples (validated in CI): ../examples/
- Overlay files (
annotateblocks) are a separate dialect handled byarchkit-project, not this grammar — seedocs/guides/PROJECT_SYSTEM.md - Parser source:
crates/archkit-frontend/src/aks/parser/ - Lexer source:
crates/archkit-frontend/src/aks/lexer/ - Conformance test:
crates/archkit-frontend/tests/docs_aks_conformance.rs
Integration Guide
How archkit processes, extends, and generates artifacts from AKS models.
Overview
AKS Source File
↓
[Lexer] - Tokenization
↓
[Parser] - Syntax analysis
↓
[AST] - Abstract syntax tree
↓
[Lowering] - AKS → Workspace (internal representation)
↓
[Workspace] - Validated architecture model
↓
[Generators] - Output to target formats
├─ TypeScript generator
├─ JSON Schema generator
├─ Mermaid diagram generator
├─ Graphviz DOT generator
└─ Other generators
Key Documents
HOW_ARCHKIT_USES_AKS.md
Deep dive: The complete pipeline from source to workspace.
Topics:
- Lexer (tokenization with off-side rule)
- Parser (recursive descent implementation)
- AST data structures
- Lowering process (AST → Workspace)
- Evidence handling
- Graph construction
- Workspace validation
Read this if: You want to understand how archkit internally processes AKS.
Need source-verified precision instead? This guide is a conceptual tour and has known drift from current code (e.g. token/AST examples that don’t match today’s grammar). For claims traced to exact functions and file:line references — including which of the two AKS lowering pipelines is actually live — see ../internals/.
ARTIFACT_GENERATION.md
Output formats: How archkit generates TypeScript, JSON Schema, diagrams.
Topics:
- TypeScript type generation
- JSON Schema export
- Mermaid diagram rendering
- Graphviz DOT export
- AKS roundtripping
- Which constructs generate what
Read this if: You want to know what outputs archkit can generate and why.
TYPE_EXTRACTION.md
Code generation: How shapes and events become types.
Topics:
- Shape → TypeScript interface mapping
- Event → TypeScript class mapping
- Constraint → validation rules
- Codegen pipeline
- Custom type mappings
- Integration patterns
Read this if: You’re generating code from shapes and events.
GRAPH_MODEL.md
The Graph Model: How AKS becomes a queryable, traversable graph.
Topics:
- Nodes and edges (entities, shapes, relationships)
- Building graphs (AKS → graph factory)
- Graph traversal (paths, reachability, cycles)
- Conformance relationships
- Event flow graphs
- Views and projections
- Rendering from graphs
- Performance characteristics
- Graph queries and analysis
Read this if: You want to understand how archkit models relationships, traverse dependencies, or implement custom graph operations.
GRAPH_EXAMPLES.md
Practical Examples: Concrete examples showing AKS → graph → analysis.
Topics:
- 5 worked examples (simple to complex)
- AKS syntax, graph visualization, query results
- Common graph query patterns
- Problem detection and fixing (cycles)
- Complex analysis scenarios
- Query performance benchmarks
- Integration with validation
Read this if: You want to see concrete examples of graphs in action, query patterns, or how to analyze specific scenarios.
EXTENSION_PIPELINE.md
Extensibility: Writing custom validators, transformers, generators.
Topics:
- Extension trait (AksExtension)
- Preprocess/postprocess phases
- Extension registry
- Custom validators
- Custom transformers
- Custom generators
- Extension examples
Read this if: You want to extend archkit with custom behavior.
Quick Start Paths
I want to generate TypeScript from my model
- Read ARTIFACT_GENERATION.md (5 min)
- Read TYPE_EXTRACTION.md (10 min)
- Try:
archkit generate code -i workspace.aks -t typescript.type -o generated/ > types.ts
I want to understand how archkit works
- Read HOW_ARCHKIT_USES_AKS.md (20 min)
- Read ARTIFACT_GENERATION.md (10 min)
- Explore source in
crates/archkit-core/src/schema/frontend/aks/
I want to extend archkit
- Read EXTENSION_PIPELINE.md (15 min)
- See full extension guide in
docs/guides/AKS_EXTENSION_FRAMEWORK.md - Try implementing a custom validator
I’m troubleshooting a parse error
- Read Troubleshooting
- Check LEXICAL_RULES.md
- Verify indentation and syntax
Architecture
Parser
Location: crates/archkit-core/src/schema/frontend/aks/parser/
Recursive descent parser that:
- Accepts tokenized input from lexer
- Builds abstract syntax tree (AST)
- Reports syntax errors with line/column
- Continues parsing after errors (best-effort)
Lowering
Location: crates/archkit-core/src/schema/frontend/aks/lowering/
Transforms AST to Workspace:
- Validates references (shapes, entities, events)
- Builds dependency graph
- Tracks evidence and provenance
- Handles computed values (expressions)
- Applies lattice and policy constraints
Type System
Location: crates/archkit-core/src/schema/frontend/aks/type_system.rs
Extracts shapes and events to TypeSystemModel:
- Maps shape fields to type properties
- Captures constraints and validation rules
- Builds type hierarchies
- Feeds to code generators
Generators
Location: crates/archkit-core/src/schema/render/ and crates/archkit-core/src/schema/export/
Output renderers:
typescript.rs- TypeScript interface generationjson_schema.rs- JSON Schema exportmermaid.rs- Mermaid diagram syntaxgraphviz.rs/dot.rs- Graphviz DOTaks.rs- AKS roundtripping
Data Structures
AST (Abstract Syntax Tree)
Location: crates/archkit-core/src/schema/frontend/aks/ast/
Represents parsed AKS syntax:
#![allow(unused)]
fn main() {
pub enum Declaration {
Shape { name, fields },
Event { name, fields },
Entity { name, attributes },
Relationship { source, target, kind },
// ...
}
}
Workspace
Location: crates/archkit-core/src/schema/workspace.rs
Validated internal representation:
#![allow(unused)]
fn main() {
pub struct Workspace {
pub name: String,
pub entities: Vec<Entity>,
pub shapes: Vec<Shape>,
pub relationships: Vec<Relationship>,
// ...
}
}
TypeSystemModel
Location: crates/archkit-type-model/src/lib.rs
Type information extracted from workspace:
#![allow(unused)]
fn main() {
pub struct TypeSystemModel {
pub records: Vec<Record>, // From shapes
pub events: Vec<Event>, // From events
pub constraints: Vec<Constraint>,
}
}
Processing Steps
1. Lexical Analysis
"entity UserService" → [KEYWORD(entity), IDENT(UserService), NEWLINE]
2. Parsing
[KEYWORD(entity), IDENT(UserService), ...] → AST(Entity)
3. Lowering
AST(Entity) → Workspace(Entity) + validate references
4. Type Extraction
Workspace(Shape User) → TypeSystemModel(Record User)
5. Code Generation
TypeSystemModel(Record User) → TypeScript(interface User)
Error Handling
Archkit reports errors with context:
$ archkit parse bad.aks
Error: undefined entity "Database"
at bad.aks:5:15
entity Service
depends_on: Database ← undefined
Error categories:
- Syntax - Grammar violation
- Reference - Undefined entity/shape
- Validation - Constraint violation
- Type - Type mismatch
See Troubleshooting for solutions.
Integration Patterns
With Your Build System
# Generate types during build
cargo build --pre-build "archkit generate code -i model.aks -t typescript.type -o generated/ > src/types.ts"
With CI/CD
# GitHub Actions example
- name: Validate AKS
run: archkit verify workspace.aks --check-all
- name: Generate types
run: archkit generate code -i workspace.aks -t typescript.type -o generated/ > types/generated.ts
- name: Generate diagrams
run: archkit view file -i workspace.aks --output diagram.mmd > docs/architecture.mmd
With Custom Tools
Use archkit as a library:
#![allow(unused)]
fn main() {
use archkit::AksService;
let workspace = AksService::parse(source)?;
let types = TypeSystemModel::from_workspace(&workspace)?;
let ts_code = TypeScriptGenerator::generate(&types)?;
}
See crates/archkit/src/lib.rs for public API.
Performance
Typical performance (single-file models):
| Operation | Time |
|---|---|
| Parse | < 10ms |
| Lowering | < 5ms |
| Type extraction | < 2ms |
| TypeScript generation | < 5ms |
| Diagram generation | < 20ms |
For multi-file models (100+ files):
- Parse: 100-500ms
- Full pipeline: 200-1000ms
Next Steps
- Deep dive on pipeline → HOW_ARCHKIT_USES_AKS.md
- Generate code → ARTIFACT_GENERATION.md
- Extend archkit → EXTENSION_PIPELINE.md
- See it in action → Examples
- Full API →
crates/archkit/src/lib.rs
Pick a topic above or explore the source code!
Type Extraction
How shapes and events become code (TypeScript, JSON Schema, etc.).
The Type Extraction Pipeline
AKS Shapes & Events
↓
TypeSystemModel
(canonical type representation)
↓
├─ TypeScript Generator
├─ JSON Schema Generator
├─ Python Generator
├─ Go Generator
└─ Other Generators
↓
Generated Code
TypeSystemModel
Location: crates/archkit-type-model/src/lib.rs
Intermediate representation of types extracted from shapes/events:
#![allow(unused)]
fn main() {
pub struct TypeSystemModel {
pub records: Vec<Record>, // From shapes
pub events: Vec<Event>, // From events
pub enums: Vec<Enum>, // Enumeration types
pub constraints: Vec<Constraint>, // Validation rules
}
pub struct Record {
pub id: RecordId,
pub name: String,
pub properties: Vec<Property>,
pub required: Vec<String>,
}
pub struct Property {
pub name: String,
pub type_spec: TypeSpec,
pub constraints: Vec<Constraint>,
pub optional: bool,
}
}
Shape → Record Mapping
Basic Mapping
shape User
id: String
email: String
age: Int
created_at: Timestamp
end shape
Becomes:
#![allow(unused)]
fn main() {
Record {
name: "User",
properties: [
Property { name: "id", type_spec: String, optional: false },
Property { name: "email", type_spec: String, optional: false },
Property { name: "age", type_spec: Int, optional: false },
Property { name: "created_at", type_spec: Timestamp, optional: false },
],
required: ["id", "email", "age", "created_at"],
}
}
Optional Fields
shape BlogPost
title: String
content: String
published_at: Timestamp?
end shape
Becomes:
#![allow(unused)]
fn main() {
Record {
properties: [
Property { name: "published_at", optional: true, ... },
],
required: ["title", "content"], // published_at NOT required
}
}
Collections
shape Order
items: OrderItem[]
tags: String[]
metadata: Json
end shape
Becomes:
#![allow(unused)]
fn main() {
Property { name: "items", type_spec: List(Record(OrderItem)) },
Property { name: "tags", type_spec: List(String) },
Property { name: "metadata", type_spec: Json },
}
Event → Event Mapping
event UserCreated
user_id: String
email: String
timestamp: Timestamp
end event
Becomes:
#![allow(unused)]
fn main() {
Event {
name: "UserCreated",
properties: [
Property { name: "user_id", type_spec: String },
Property { name: "email", type_spec: String },
Property { name: "timestamp", type_spec: Timestamp },
],
required: ["user_id", "email", "timestamp"],
}
}
Difference from Record:
- Events always have
timestamp - Events are immutable/final
- Events imply causality
Constraint Mapping (Not Implemented)
Inline field constraints were part of an early draft and are not in the grammar — annotations like these are parse errors today:
shape Product
price: decimal @min(0.01) # NOT valid AKS
email: string @pattern("^[^@]+$") # NOT valid AKS
Express invariants as policies on the entities that carry the data, or enforce them in the generated code’s validation layer.
Type Extraction Entry Points
Via CLI
archkit generate code -i workspace.aks -t typescript.type -o generated/ > types.ts
# Internally: parse → TypeSystemModel → TypeScriptGenerator
Via Rust API
#![allow(unused)]
fn main() {
use archkit::AksService;
use archkit_type_model::TypeSystemModel;
let workspace = AksService::parse(source)?;
let type_model = TypeSystemModel::from_workspace(&workspace)?;
// Use type_model for code generation
}
From File
#![allow(unused)]
fn main() {
let type_model = TypeSystemModel::from_file("workspace.aks")?;
}
Code Generators
TypeScript
Location: crates/archkit-codegen/src/generators/typescript.rs
Generates TypeScript interfaces:
// From shape User
interface User {
id: string;
email: string;
age: number;
created_at: Date;
}
// With constraints
export const UserValidator = z.object({
email: z.string().email(),
age: z.number().min(0).max(150),
});
JSON Schema
Location: crates/archkit-codegen/src/generators/json_schema.rs
Generates JSON Schema with validation:
{
"User": {
"type": "object",
"properties": {
"email": { "type": "string", "format": "email" },
"age": { "type": "integer", "minimum": 0, "maximum": 150 }
},
"required": ["id", "email"]
}
}
Python
Generates Python dataclasses:
from dataclasses import dataclass
@dataclass
class User:
id: str
email: str
age: int
created_at: datetime
Go
Generates Go structs:
type User struct {
ID string `json:"id"`
Email string `json:"email"`
Age int `json:"age"`
CreatedAt time.Time `json:"created_at"`
}
OpenAPI/Swagger
Generates OpenAPI schema:
components:
schemas:
User:
type: object
properties:
id:
type: string
email:
type: string
format: email
required:
- id
- email
Type Mapping Reference
Primitive Types
| AKS | TypeScript | JSON Schema | Python | Go |
|---|---|---|---|---|
| string | string | { “type”: “string” } | str | string |
| int | number | { “type”: “integer” } | int | int64 |
| decimal | number | { “type”: “number” } | float | float64 |
| bool | boolean | { “type”: “boolean” } | bool | bool |
| timestamp | Date | { “type”: “string”, “format”: “date-time” } | datetime | time.Time |
| bytes | Buffer | { “type”: “string”, “format”: “byte” } | bytes | []byte |
Collection Types
| AKS | TypeScript | JSON Schema | Python | Go |
|---|---|---|---|---|
| [string] | string[] | { “type”: “array”, “items”: {…} } | List[str] | []string |
| {str: str} | Record<string, string> | { “type”: “object” } | Dict[str, str] | map[string]string |
Optional
| AKS | TypeScript | JSON Schema | Python | Go |
|---|---|---|---|---|
| ?string | string | undefined | not in required | Optional[str] | *string |
Constraint Mapping
| AKS | TypeScript | JSON Schema | Validation |
|---|---|---|---|
| @min(0) | - | minimum: 0 | Zod: .min(0) |
| @max(100) | - | maximum: 100 | Zod: .max(100) |
| @pattern(rx) | - | pattern: “rx” | Zod: .regex(rx) |
| @format(url) | - | format: “url” | Zod: .url() |
Custom Type Mappings
Extend type extraction for custom needs:
#![allow(unused)]
fn main() {
pub struct CustomTypeMapper;
impl TypeMapper for CustomTypeMapper {
fn map_property(&self, prop: &Property) -> CustomType {
// Custom mapping logic
}
}
let type_model = TypeSystemModel::from_workspace_with_mapper(
&workspace,
CustomTypeMapper,
)?;
}
Performance
Type extraction performance (single model):
| Step | Time |
|---|---|
| Parse AKS | 10ms |
| Build TypeSystemModel | 5ms |
| Generate TypeScript | 5ms |
| Total | 20ms |
Multi-file (100 shapes):
- Build TypeSystemModel: 50-100ms
- Generate TypeScript: 50-100ms
- Total: 100-200ms
Common Patterns
API Request/Response Types
shape CreateUserRequest
email: String
name: String
end shape
shape UserResponse
id: String
email: String
created_at: Timestamp
end shape
entity user_api
edge CreateUserRequest consumes
end edge
edge UserResponse produces
end edge
end entity
Domain Models
shape Money
amount: Float
currency: String
end shape
shape Order
id: String
total: Money
items: OrderItem[]
end shape
Event Models
event UserCreated
user_id: String
email: String
timestamp: Timestamp
end event
event OrderPlaced
order_id: String
user_id: String
timestamp: Timestamp
end event
Integration Examples
Express Validation
import { UserValidator } from './types';
app.post('/user', (req, res) => {
const result = UserValidator.safeParse(req.body);
if (!result.success) {
return res.status(400).json(result.error);
}
// result.data is typed as User
});
OpenAPI Documentation
archkit generate code -i workspace.aks -t openapi.schema -o generated/
# Generate Swagger UI automatically
Database Schema
# JSON Schema → SQL schema generator
archkit generate code -i workspace.aks -t json.schema -o generated/ | json-schema-to-sql
Next Steps
- Generate code → Try
archkit generate code -i workspace.aks -t typescript.type -o generated/ - See examples → Type Definition Examples
- Integration → Integration README
- Extend → EXTENSION_PIPELINE.md
Type extraction bridges AKS models and code generation!
How Archkit Uses AKS
Complete walkthrough of the AKS processing pipeline from source to workspace.
The Pipeline
AKS Source File
↓ [Input: String]
[Lexer]
- Tokenizes source
- Handles indentation (off-side rule)
- Produces token stream
↓ [Token Stream]
[Parser]
- Recursive descent parsing
- Builds abstract syntax tree
- Reports syntax errors
↓ [AST: Declaration Nodes]
[Lowering]
- Validates references
- Builds graph structures
- Tracks provenance
- Handles computed values
↓ [Validated Graph]
[Workspace]
- Entities, shapes, relationships
- Evidence tracking
- Policy constraints
- Ready for analysis/generation
1. Lexer (Tokenization)
File: crates/archkit-core/src/schema/frontend/aks/lexer/
The lexer converts source text into tokens:
Input: "entity UserService\n role: orchestration"
Output: [
KEYWORD(entity),
IDENT(UserService),
NEWLINE,
INDENT(2),
KEYWORD(role),
COLON,
IDENT(orchestration),
DEDENT,
EOF
]
Key Features
- Off-side rule: Tracks indentation levels
- Error recovery: Continues after lexical errors
- Line/column tracking: For error reporting
- Context-aware: Keywords vs identifiers
2. Parser (Syntax Analysis)
File: crates/archkit-core/src/schema/frontend/aks/parser/
The parser builds an AST from tokens:
[KEYWORD(entity), IDENT(UserService), COLON, IDENT(orchestration)]
↓
Parser
↓
ast::Declaration::Entity {
name: "UserService",
attributes: [
("role", "orchestration"),
]
}
Parsing Strategy
- Recursive descent - Top-down parsing
- Multi-pass - Separate passes for different constructs
- Error recovery - Best-effort parsing
Grammar Hierarchy
program
→ workspace
→ shape | event | entity | ...
→ field: type | relationship: target | ...
3. Abstract Syntax Tree (AST)
File: crates/archkit-core/src/schema/frontend/aks/ast/
Represents parsed structure:
#![allow(unused)]
fn main() {
pub enum Declaration {
Shape {
name: String,
fields: Vec<FieldDef>,
},
Event {
name: String,
fields: Vec<FieldDef>,
},
Entity {
name: String,
attributes: Vec<Attribute>,
},
Relationship {
source: String,
target: String,
kind: RelationshipKind,
phrases: Vec<(String, String)>,
},
// ... more variants
}
pub struct FieldDef {
pub name: String,
pub type_spec: TypeSpec,
pub constraints: Vec<Constraint>,
}
}
4. Lowering (AST → Workspace)
File: crates/archkit-core/src/schema/frontend/aks/lowering/
Transforms AST to validated Workspace:
4a. Reference Resolution
All references are validated:
- Entity dependencies → must reference defined entities
- Shape conformance → must reference defined shapes
- Event production → must reference defined events
Entity: "UserService depends_on: UserDB"
↓ [Validate UserDB exists]
↓ [Validate it's an entity]
→ Relationship created
4b. Graph Construction
Builds internal graph representation:
#![allow(unused)]
fn main() {
pub struct Workspace {
pub entities: Vec<Entity>,
pub shapes: Vec<Shape>,
pub events: Vec<Event>,
pub relationships: Vec<Relationship>,
// ... more fields
}
pub struct Entity {
pub id: EntityId,
pub name: String,
pub role: Role,
pub conformances: Vec<ShapeId>,
pub dependencies: Vec<Relationship>,
// ...
}
}
4c. Provenance Handling
Tracks source of truth:
evidence: "code:src/service.rs line 42"
↓ [Parse source indicator]
→ Provenance { kind: Code, location: "src/service.rs", line: 42 }
Evidence categories:
code:- From source codemirror:- Auto-generated observationauthored:- Manual documentationobservation:- External source
4d. Computed Values
Evaluates expressions:
entity Count
current_entities: @count(entity) # Computed via aggregation
5. Workspace (Internal Representation)
File: crates/archkit-core/src/schema/workspace.rs
Validated, normalized representation ready for:
- Analysis (dependencies, cycles, coverage)
- Validation (policies, constraints, evidence)
- Generation (TypeScript, diagrams, etc.)
Structure
#![allow(unused)]
fn main() {
pub struct Workspace {
pub name: String,
pub version: Version,
pub entities: Vec<Entity>,
pub shapes: Vec<Shape>,
pub events: Vec<Event>,
pub relationships: Vec<Relationship>,
pub policies: Vec<Policy>,
pub lattices: Vec<Lattice>,
pub evidence: ProvE nanceGraph,
}
}
Validation Steps
- Syntactic - Grammar compliance (lexer/parser)
- Referential - All references exist and are typed correctly
- Semantic - Domain-specific rules (policies, lattices)
- Consistency - No conflicts or contradictions
Entry Points
Parsing Only
#![allow(unused)]
fn main() {
use archkit::AksService;
let workspace = AksService::parse(source)?;
// Returns parsed, lowered, validated Workspace
}
With File Path
#![allow(unused)]
fn main() {
let workspace = AksService::parse_file("workspace.aks")?;
}
From String
#![allow(unused)]
fn main() {
let source = r#"
workspace MyApp
entity Service
role: orchestration
"#;
let workspace = AksService::parse(source)?;
}
Error Handling
Errors include context:
#![allow(unused)]
fn main() {
pub struct ParseError {
pub message: String,
pub location: SourceLocation, // line, column, file
pub context: String, // relevant code snippet
pub suggestion: Option<String>, // helpful hint
}
}
Example output:
Error: undefined entity "Database"
at workspace.aks:5:15
entity Service
depends_on: Database ← undefined
Suggestion: define "Database" entity or check spelling
Type System Integration
Type Extraction
Workspace (shapes, events)
↓ [TypeSystemModel::from_workspace()]
→ TypeSystemModel (types, constraints, properties)
↓ [CodeGenerator::generate()]
→ TypeScript, JSON Schema, etc.
See TYPE_EXTRACTION.md for details.
Performance Characteristics
Single File
- Lex: < 5ms
- Parse: < 10ms
- Lower: < 5ms
- Total: < 20ms
Multi-File (100 files)
- Lex all: 50-100ms
- Parse all: 100-200ms
- Lower all: 50-100ms
- Total: 200-400ms
Implementation Files
| File | Purpose |
|---|---|
lexer/lexer_impl.rs | Tokenization |
parser/parser_impl.rs | Parse workspace/modules |
parser/entities.rs | Entity parsing |
parser/shapes.rs | Shape parsing |
parser/relationships.rs | Relationship parsing |
lowering/substrate_impl.rs | AST → Workspace |
lowering/evidence.rs | Provenance tracking |
lowering/graph_factory.rs | Graph construction |
type_system.rs | Type extraction |
Next Steps
- Generate code → ARTIFACT_GENERATION.md
- Extract types → TYPE_EXTRACTION.md
- Extend archkit → EXTENSION_PIPELINE.md
- Public API →
crates/archkit/src/lib.rs
Understanding the pipeline helps you use archkit more effectively and extend it for custom needs!
Extension Pipeline
Writing custom extensions to archkit.
Extension Trait
Location: crates/archkit-extensions/src/lib.rs
#![allow(unused)]
fn main() {
pub trait AksExtension: Send + Sync {
/// Preprocess phase - modify AKS before lowering
fn preprocess(&self, source: &str) -> Result<String>;
/// Postprocess phase - modify workspace after lowering
fn postprocess(&self, workspace: &mut Workspace) -> Result<()>;
/// Extension metadata
fn name(&self) -> &str;
fn version(&self) -> &str;
}
}
Phases
Extensions hook into two phases:
1. Preprocess (Source → AST)
When: Before parsing
Can modify:
- AKS source text
- Add/remove/modify constructs
- Expand macros
Use cases:
- Validation rules (e.g., “all entities must have description”)
- Transformations (e.g., “convert v1 to v2 syntax”)
- Macro expansion
- Templating
Example: Validate all entities have descriptions
#![allow(unused)]
fn main() {
pub struct DescriptionValidator;
impl AksExtension for DescriptionValidator {
fn preprocess(&self, source: &str) -> Result<String> {
// Parse and validate
let lines: Vec<&str> = source.lines().collect();
for (i, line) in lines.iter().enumerate() {
if line.trim_start().starts_with("entity ") {
// Check next line for description
if i + 1 >= lines.len() || !lines[i + 1].contains("description:") {
return Err(format!(
"Entity at line {} missing description",
i + 1
));
}
}
}
Ok(source.to_string())
}
fn postprocess(&self, _workspace: &mut Workspace) -> Result<()> {
Ok(())
}
fn name(&self) -> &str { "description-validator" }
fn version(&self) -> &str { "1.0.0" }
}
}
2. Postprocess (AST → Workspace)
When: After lowering to Workspace
Can modify:
- Entities, shapes, relationships
- Add computed properties
- Validate constraints
- Generate derived data
Use cases:
- Adding computed entities (e.g., count, aggregates)
- Validating policies
- Computing metrics
- Enriching with metadata
Example: Count entities
#![allow(unused)]
fn main() {
pub struct EntityCounter;
impl AksExtension for EntityCounter {
fn preprocess(&self, source: &str) -> Result<String> {
Ok(source.to_string())
}
fn postprocess(&self, workspace: &mut Workspace) -> Result<()> {
let count = workspace.entities.len();
// Log or use count
println!("Workspace contains {} entities", count);
Ok(())
}
fn name(&self) -> &str { "entity-counter" }
fn version(&self) -> &str { "1.0.0" }
}
}
Extension Registry
Location: crates/archkit-extensions/src/registry.rs
#![allow(unused)]
fn main() {
pub struct ExtensionRegistry {
extensions: Vec<Box<dyn AksExtension>>,
}
impl ExtensionRegistry {
pub fn new() -> Self { ... }
pub fn register(&mut self, ext: Box<dyn AksExtension>) -> Result<()> { ... }
pub fn preprocess(&self, source: &str) -> Result<String> { ... }
pub fn postprocess(&self, workspace: &mut Workspace) -> Result<()> { ... }
}
}
Using Extensions
In Rust Code
#![allow(unused)]
fn main() {
use archkit::AksService;
use archkit_extensions::{ExtensionRegistry, DescriptionValidator};
let mut registry = ExtensionRegistry::new();
registry.register(Box::new(DescriptionValidator))?;
let source = std::fs::read_to_string("workspace.aks")?;
// Preprocess with extensions
let preprocessed = registry.preprocess(&source)?;
// Parse and lower
let mut workspace = AksService::parse(&preprocessed)?;
// Postprocess with extensions
registry.postprocess(&mut workspace)?;
// Use workspace
}
Via CLI
# Register extensions in archkit.toml
[extensions]
validators = ["description-validator", "policy-enforcer"]
# archkit automatically loads and applies them
archkit parse workspace.aks
Common Extension Patterns
1. Validator
Checks properties and enforces rules:
#![allow(unused)]
fn main() {
pub struct PolicyValidator;
impl AksExtension for PolicyValidator {
fn preprocess(&self, source: &str) -> Result<String> {
// Check all policies are defined
Ok(source.to_string())
}
fn postprocess(&self, workspace: &mut Workspace) -> Result<()> {
for policy in &workspace.policies {
if policy.description.is_empty() {
return Err("Policy must have description".into());
}
}
Ok(())
}
fn name(&self) -> &str { "policy-validator" }
fn version(&self) -> &str { "1.0.0" }
}
}
2. Transformer
Modifies content programmatically:
#![allow(unused)]
fn main() {
pub struct VersionUpgrader;
impl AksExtension for VersionUpgrader {
fn preprocess(&self, source: &str) -> Result<String> {
// Convert v1 syntax to v2
let updated = source
.replace("entity_type: ", "role: ")
.replace("relates_to: ", "depends_on: ");
Ok(updated)
}
fn postprocess(&self, _workspace: &mut Workspace) -> Result<()> {
Ok(())
}
fn name(&self) -> &str { "version-upgrader" }
fn version(&self) -> &str { "1.0.0" }
}
}
3. Enricher
Adds computed or derived data:
#![allow(unused)]
fn main() {
pub struct MetricsEnricher;
impl AksExtension for MetricsEnricher {
fn postprocess(&self, workspace: &mut Workspace) -> Result<()> {
// Add computed metrics
workspace.metrics.entity_count = workspace.entities.len();
workspace.metrics.dependency_count =
workspace.relationships.iter()
.filter(|r| r.kind == RelationshipKind::DependsOn)
.count();
Ok(())
}
fn preprocess(&self, source: &str) -> Result<String> {
Ok(source.to_string())
}
fn name(&self) -> &str { "metrics-enricher" }
fn version(&self) -> &str { "1.0.0" }
}
}
4. Generator
Generates additional content:
#![allow(unused)]
fn main() {
pub struct DiagramGenerator;
impl AksExtension for DiagramGenerator {
fn postprocess(&self, workspace: &mut Workspace) -> Result<()> {
// Generate diagrams as side effects
let mermaid = generate_mermaid(workspace);
std::fs::write("diagram.mmd", mermaid)?;
Ok(())
}
fn preprocess(&self, source: &str) -> Result<String> {
Ok(source.to_string())
}
fn name(&self) -> &str { "diagram-generator" }
fn version(&self) -> &str { "1.0.0" }
}
}
Built-in Extensions
Archkit includes standard extensions:
| Name | Phase | Purpose |
|---|---|---|
syntax-validator | Pre | Check grammar compliance |
reference-validator | Post | Validate all references exist |
policy-enforcer | Post | Enforce governance policies |
metrics-collector | Post | Compute system metrics |
diagram-generator | Post | Generate diagrams |
Creating a Custom Extension
Step 1: Define Struct
#![allow(unused)]
fn main() {
pub struct MyExtension {
config: MyConfig,
}
impl MyExtension {
pub fn new(config: MyConfig) -> Self {
MyExtension { config }
}
}
}
Step 2: Implement Trait
#![allow(unused)]
fn main() {
impl AksExtension for MyExtension {
fn preprocess(&self, source: &str) -> Result<String> {
// Modify source or validate
Ok(source.to_string())
}
fn postprocess(&self, workspace: &mut Workspace) -> Result<()> {
// Modify workspace or validate
Ok(())
}
fn name(&self) -> &str { "my-extension" }
fn version(&self) -> &str { "1.0.0" }
}
}
Step 3: Register
#![allow(unused)]
fn main() {
registry.register(Box::new(MyExtension::new(config)))?;
}
Step 4: Use
archkit parse --with-extensions workspace.aks
Publishing Extensions
Create a package for distribution:
[package]
name = "archkit-ext-myext"
version = "1.0.0"
[dependencies]
archkit = "0.2"
archkit-extensions = "0.2"
Users can then import:
#![allow(unused)]
fn main() {
use archkit_ext_myext::MyExtension;
}
Error Handling
Extensions should report clear errors:
#![allow(unused)]
fn main() {
fn postprocess(&self, workspace: &mut Workspace) -> Result<()> {
for entity in &workspace.entities {
if entity.role.is_none() {
return Err(format!(
"Entity '{}' missing required 'role' property",
entity.name
));
}
}
Ok(())
}
}
Testing Extensions
#![allow(unused)]
fn main() {
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_validator_rejects_missing_description() {
let ext = DescriptionValidator;
let source = r#"
workspace Test
entity Service
role: orchestration
"#;
assert!(ext.preprocess(source).is_err());
}
}
}
Performance
Extension overhead:
- Preprocess string transformations: < 5ms (typical)
- Postprocess workspace modifications: < 10ms (typical)
- Total for all built-in extensions: < 50ms
Keep extensions fast—they run on every parse!
Full Example Extension
See docs/guides/AKS_EXTENSION_FRAMEWORK.md for complete working example.
Next Steps
- Extension framework guide →
docs/guides/AKS_EXTENSION_FRAMEWORK.md - See examples → Examples
- Integration → Integration README
Extensions make archkit flexible and adaptable to your needs!
AKS Frontend Internals
Source-grounded, function-level documentation of how the AKS frontend
(crates/archkit-core/src/schema/frontend/aks/) actually works today —
as opposed to ../integration/, which is a higher-level,
less precisely-sourced tour of the same territory.
Written 2026-07-02 as part of an audit that resolved two open questions
about the frontend: which of two lowering pipelines is actually live, and
why single-word entity-kind phrases (database, queue, …) weren’t
raising the validation error they were supposed to. Both are answered
here, and the answers are load-bearing for anything that touches
ElementKindRef, lower_workspace, or lower_aks_to_substrate next.
Read pipeline-overview.md first. It’s the trunk everything else hangs off. The other files go deep on one stage:
- lexer.md — off-side rule, closed-phrase tokenization, tab rejection
- ast.md —
AksDeclvariants,ElementKindRef, sub-language capture - parser.md — module map, closed-vocabulary idiom, hard-error scope limits
- lowering.md —
lower_workspacetrace,GraphRecordFactory, canonicalization - known-gaps.md — dated list of confirmed-but-unresolved issues
Staying accurate over time: every file here names real functions and file paths so claims can be re-checked against source. When you find a claim that’s drifted from the code, fix the doc in the same change that changes the code — don’t let it rot into the next audit’s problem.
Archkit
Archkit = architecture modeling, validation, projection, generation toolkit.
Core capabilities
- author architecture in AKS
- organize models in managed project layout
- validate modeled system and project health
- mirror external systems into AKS artifacts
- detect drift between authored and observed state
- promote reviewed changes into authored source
- generate code, schemas, reports, diagrams
Main workflows
Docs split
- mdBook — product docs, tutorials, language guide, ops
- rustdoc — Rust crate API
Source docs
This section wraps existing authored docs under docs/guides/, docs/reference/, docs/architecture/, and docs/operations/.
Quickstart
Official packaging policy: docs/operations/packaging.md.
Audience and install path
- End users and external adopters: install a pinned binary from GitHub Releases (primary path).
- Rust-native fallback:
cargo install archkit --locked --version <x.y.z>. - Contributors to this repo: use source workflow below (
cargo make onboarding), with optionalcargo install --path .for local install checks.
0) Install prerequisites
Rust toolchain is pinned by this repo to 1.94.1 via rust-toolchain.toml.
Required for onboarding:
rustccargo
Optional (warn-only in onboarding preflight):
dot(Graphviz render gate)git(doc drift checks likecargo make autodoc-check;docgen-checkis a compatibility alias)nu(parity script)
Install cargo-make once:
cargo install cargo-make --version 0.37.24 --locked
1) One-command onboarding
Run the local onboarding flow:
cargo make onboarding
This runs a preflight, verifies formatting, builds the workspace, runs the production-like dogfood validate/project path, and regenerates docs artifacts.
Discoverability commands:
cargo make
cargo make help
cargo make --list-all-steps --output-format short-description
2) Main workflow (recommended)
Use the canonical AKS path (Tier 1):
cargo make dev
This emits deterministic artifacts under generated/ephemeral/dogfood/main/, including canonical JSON, DOT, and Mermaid outputs.
3) Docs and artifacts
Generate docs and rustdoc artifacts:
cargo make docs-artifacts
4) Full local test suite
cargo make test-all
Recommended first 5-10 minutes after clone:
cargo make onboarding
cargo make dev
cargo make docs-artifacts
cargo make test-all
5) Optional Graphviz render gate
Requires Graphviz (dot -V):
cargo make render
5b) Canonical project architecture workflow
Run the canonical self-model for this repository:
cargo make architecture-self
Canonical source model: architecture/models/archkit_self.ncl.
6) Direct CLI flow (contributor/source workflow)
Enter the Nix dev shell:
nix develop -c bash
Validate a Nickel spec:
cargo run -p archkit-cli -- validate -i docs/dogfood/examples/workspace.ncl
Project a named view to DOT (+ Mermaid companion):
cargo run -p archkit-cli -- view -i docs/dogfood/examples/workspace.ncl --view-id container_main -o generated/ephemeral/run/container.dot
This also writes generated/ephemeral/run/container.document.json and generated/ephemeral/run/container.mmd.
6b) (Optional, experimental) Generate AKS from canonical JSON
cargo run -p archkit-cli -- export-aks -i generated/ephemeral/run/container.document.json -o generated/ephemeral/run/container.aks
6c) (Optional) Generate Nickel from canonical JSON
cargo run -p archkit-cli -- export-nickel -i generated/ephemeral/run/container.document.json -o generated/ephemeral/run/container.ncl
6d) Render DOT to SVG
cargo run -p archkit-cli -- render -i generated/ephemeral/run/container.dot -f svg -o generated/ephemeral/run/container.svg
This also writes generated/ephemeral/run/container.document.json, generated/ephemeral/run/container.dot, and generated/ephemeral/run/container.mmd (copied canonical JSON and Mermaid companion from projection artifacts).
7) Clean-room setup verification (sprint baseline)
Use this checklist to verify a new machine can run the documented CLI path without hidden assumptions.
- Build:
cargo build
Expected: build succeeds.
- Validate Nickel example:
cargo run -p archkit-cli -- validate -i docs/dogfood/examples/workspace.ncl
Expected: exit 0, workspace valid.
- View named diagram:
cargo run -p archkit-cli -- view -i docs/dogfood/examples/workspace.ncl --view-id container_main -o generated/ephemeral/run/container.dot
Expected: generated/ephemeral/run/container.dot, generated/ephemeral/run/container.mmd, and generated/ephemeral/run/container.document.json.
- Render when Graphviz is installed:
dot -V
cargo run -p archkit-cli -- render -i generated/ephemeral/run/container.dot -f svg -o generated/ephemeral/run/container.svg
Expected: exit 0, generated/ephemeral/run/container.svg plus render companions.
- Graphviz-absent behavior:
- If
dot -Vfails, onboarding and validate/project checks are still valid baseline success. renderis expected to fail witherror[render]and exit class4until Graphviz is installed.
- Feature-flag variants:
cargo test --no-default-features
cargo test --features dot-import
Expected: both commands pass; feature-disabled command paths report exit class 5 where applicable.
Recommended repo layout
architecture/
workspace.aks
generated/ephemeral/run/
*.dot
*.mmd
*.document.json
*.svg
Use validate and view in CI to keep architecture specs reviewable and deterministic.
AKS is Tier 1 canonical specification language. Nickel is Tier 2 complementary for contracts.
Dogfood target
The repository includes a realistic end-to-end target under dogfood/:
archkit validate -i dogfood/architecture/main.ncl
archkit view -i dogfood/architecture/main.ncl --view-id container_main -o generated/ephemeral/dogfood/main/container.dot
Archkit Project System Guide
Archkit project system organizes authored models, generated artifacts, reports, and inspection workflows under one deterministic project root.
Project shape
my-project/
├── archkit.project.toml
├── authored/
├── overlays/
├── mirror/
├── promoted/
├── generated/
├── reports/
│ └── generate/
│ ├── project-generate.archkit.plan.json
│ └── project-generate.archkit.report.json
└── .archkit/index/
Core commands
Initialize project:
nix develop -c cargo run -p archkit-cli -- project init --root ./my-project --name "My Project"
Validate layout and health:
nix develop -c cargo run -p archkit-cli -- project layout-check --root ./my-project
nix develop -c cargo run -p archkit-cli -- project dogfood --root ./my-project
Self-Hosting Assessment (M1-M9)
Assess self-hosting adoption readiness using the complete meta-model foundation:
# Text report (human-readable)
nix develop -c cargo run -p archkit-cli -- project self-hosting-assess --root ./my-project
# JSON report (machine-readable)
nix develop -c cargo run -p archkit-cli -- project self-hosting-assess --root ./my-project --format json
# Save to file
nix develop -c cargo run -p archkit-cli -- project self-hosting-assess --root ./my-project --out adoption-report.txt
The self-hosting assessment command:
- Loads your project manifest and structure
- Generates all 4 meta-models (GenerationPlan, Capability, Extension, Topology)
- Runs comprehensive validation across all models
- Reports adoption status: Ready, WarningsPending, or Failed
- Provides remediation guidance for any issues found
See: SELF_HOSTING_CLI_ASSESSMENT.md for complete guide including:
- Detailed usage examples
- Output format reference
- Integration patterns (CI/CD, dashboards)
- Remediation guide
- Troubleshooting
Manifest-driven generation
Generation now comes from [[generate]] entries in archkit.project.toml.
Example:
[project]
name = "My Project"
[[generate]]
name = "schema"
model = "authored/domain.aks"
target = "json.schema"
output = "generated/domain.schema.json"
[[generate]]
name = "types"
model = "authored/domain.aks"
target = "typescript.type"
output = "generated/domain.types.ts"
[[generate]]
name = "summary"
model = "authored/domain.aks"
target = "json.schema"
output = "generated/domain.summary.md"
template = "artifact.summary.md"
Run configured generation set:
nix develop -c cargo run -p archkit-cli -- project generate --root ./my-project
Current built-in targets:
json.schematypescript.type
Generation inspection flow
Write plan + artifacts + report
nix develop -c cargo run -p archkit-cli -- project generate --root ./my-project
Writes generated outputs plus persisted files:
reports/generate/project-generate.archkit.plan.jsonreports/generate/project-generate.archkit.report.json
Show persisted plan
nix develop -c cargo run -p archkit-cli -- project generate --root ./my-project --plan
Use when reviewing planned artifact ids, targets, inputs, renderers, and output paths.
Check persisted plan drift
nix develop -c cargo run -p archkit-cli -- project generate --root ./my-project --check
Use when manifest or model changed and you need to know whether persisted plan stale.
Check reads current manifest-derived plan and compares it to persisted reports/generate/project-generate.archkit.plan.json.
Explain all planned artifacts
nix develop -c cargo run -p archkit-cli -- project generate --root ./my-project --explain
Use when you need inventory of artifact ids, targets, renderers, templates, inputs, and output paths.
Explain one artifact by id
nix develop -c cargo run -p archkit-cli -- project generate --root ./my-project --explain --artifact-id json.schema:schema
Explain one artifact by output path
nix develop -c cargo run -p archkit-cli -- project generate --root ./my-project --explain --output-path generated/domain.schema.json
Template overrides
Template-backed generation supports:
- explicit
template_override = "..." - conventional project overrides in
templates/codegen/ - conventional shared overrides in
templates/shared/codegen/ - builtin fallback templates
Resolution order:
explicit override
-> templates/codegen/
-> templates/shared/codegen/
-> builtin template
Unused conventional override files do not fail generation. They emit warning diagnostics in generation report and persisted reports/generate/project-generate.archkit.report.json.
File ownership rules
| Directory | Typical contents | Human-editable |
|---|---|---|
authored/ | source AKS models | yes |
overlays/ | tags, notes, tracking overlays | yes |
mirror/ | generated observations | usually no |
promoted/ | proposal workflow files | mixed |
generated/ | generated artifacts | no |
reports/ | generated reports | no |
.archkit/index/ | generated indexes | no |
Practical workflow
- edit models under
authored/ - adjust
[[generate]]manifest entries if outputs change - run
project generate - inspect with
--plan,--check, or--explainwhen needed - review generated outputs plus persisted
project-generate.archkit.plan.jsonandproject-generate.archkit.report.json - run
layout-checkanddogfoodfor broader project health
Notes
- output paths for
[[generate]]entries must stay undergenerated/ - generation plan stays deterministic and persisted under
reports/generate/ - artifact lookups use either stable
artifact_idor relativeoutput_path - use Nix-wrapped commands in this repo
Future Enhancements (Optional M7 Roadmap)
The generation-spec implementation is complete as of 2026-06-23. Optional enhancements are documented in the M7 enhancement roadmap:
See: docs/plans/archkit-codegen-m7-enhancement-roadmap.md
Planned future work includes:
- Diff/Report Command: Rich visibility into generation plan changes with HTML diffing
- Additional Targets: Python (dataclass/Pydantic), Go, Rust, GraphQL, OpenAPI, Protobuf
- Richer UX: Enhanced explain output, interactive CLI explorer, HTML plan viewer, verbose reporting
- Cross-Cutting: Metrics collection, config profiles, dry-run mode, plugin system
These enhancements are not blockers for the current generation-spec flow and can be implemented in phases.
Project System Example Walkthrough
This guide walks through creating and managing a real project using the Archkit project system.
Setup: Create a New Project
# Create project directory
mkdir my-ecommerce-arch
cd my-ecommerce-arch
# Initialize the project structure
archkit project init --root . --name "E-Commerce Architecture"
# Check that everything was created
ls -la
Output:
archkit.project.toml
authored/
overlays/
mirror/
promoted/
generated/
reports/
.archkit/
Step 1: Define Your Architecture Model
Edit authored/E-Commerce Architecture.archkit.model.aks:
workspace "E-Commerce Architecture"
module ecommerce@v1.0
entity customer
has tag actor
end entity
entity admin
has tag actor
end entity
entity ecommerce_platform
has tag system
end entity
entity payment_gateway
has tag external
end entity
entity email_service
has tag external
end entity
entity api
has tag backend
has tech: "Node.js"
end entity
entity frontend
has tag frontend
has tech: "React"
end entity
entity database
has tag datastore
has tech: "PostgreSQL"
end entity
relationship customer uses frontend
end relationship
relationship admin uses frontend
end relationship
relationship frontend calls api
end relationship
relationship api writes to database
end relationship
relationship api calls payment_gateway
end relationship
relationship api calls email_service
end relationship
end workspace
Step 2: Check Initial Layout
archkit project layout-check --root .
Expected output:
{"errors": 0, "warnings": 0, "diagnostics": []}
Step 3: Run Initial Health Check
archkit project dogfood --root . --json-out health-baseline.json
cat health-baseline.json
Output:
{
"schema_version": 1,
"status": "green",
"project_name": "E-Commerce Architecture",
"stages": [
{"stage": "manifest_load", "status": "green", "message": "Manifest loaded successfully"},
{"stage": "index_build", "status": "green", "message": "Index built: 2 entries"},
{"stage": "layout_check", "status": "green", "message": "Layout check: 0 errors, 0 warnings"},
{"stage": "frontend_parse", "status": "green", "message": "AKS models parse successfully"}
]
}
Step 4: Tag Key Components
Tag components as public API or critical for governance:
# Tag the API server as public-facing
archkit project tag --root . api public-api
# Tag the database as critical infrastructure
archkit project tag --root . database critical-infrastructure
# Tag the payment gateway integration
archkit project tag --root . payment_gateway pci-scope
# Mark components by stability
archkit project tag --root . frontend stable
archkit project tag --root . api stable
archkit project tag --root . database stable
Check the tags file:
cat overlays/tags.archkit.overlay.aks
Output (overlay file with annotations):
workspace "Tags"
entity api
has tag public-api
has tag stable
end entity
entity database
has tag critical-infrastructure
has tag stable
end entity
entity payment_gateway
has tag pci-scope
end entity
entity frontend
has tag stable
end entity
end workspace
Step 5: Document Decisions
Add decision notes for audit trails:
# Document API design decision
archkit project note --root . api "REST API following OpenAPI 3.0 spec. Decision made 2026-05-30 by Architecture Board."
# Document data storage decision
archkit project note --root . database "PostgreSQL chosen for ACID compliance and complex queries. Evaluated MySQL and MongoDB."
# Document security decision
archkit project note --root . payment_gateway "PCI DSS compliance required. Never stores credit card data, delegates to Stripe."
Check the notes file:
cat overlays/notes.archkit.overlay.aks
Step 6: Build the Project Index
Generate a complete index of all project files:
archkit project index --root . --json-out project-index.json
cat project-index.json
Output (abbreviated):
{
"schema_version": 1,
"project_name": "E-Commerce Architecture",
"entries": [
{
"rel_path": "authored/E-Commerce Architecture.archkit.model.aks",
"subject": "E-Commerce Architecture",
"kind": "model",
"format": "aks",
"origin": "authored",
"editable": true,
"generated": false,
"content_hash": "a1b2c3d4...",
"size_bytes": 1024
},
{
"rel_path": "overlays/tags.archkit.overlay.aks",
"subject": "tags",
"kind": "overlay",
"format": "aks",
"origin": "authored",
"editable": true,
"generated": false,
"content_hash": "e5f6g7h8...",
"size_bytes": 512
}
],
"unclassified": []
}
Step 7: Add More Models
Create additional models for different system aspects:
# Data model
cat > authored/data-model.archkit.model.aks << 'EOF'
workspace "Data Model"
module data_model@v1.0
shape Order
id: String
customer_id: String
items: [OrderItem]
total: Float
status: String
created_at: String
end shape
shape OrderItem
product_id: String
quantity: Int
price: Float
end shape
entity current_order: Order
has status: "pending"
end entity
end workspace
EOF
Check layout:
archkit project layout-check --root .
Step 8: Run Full Health Check
archkit project dogfood --root . --json-out health-final.json --strict
echo "Exit code: $?"
This will exit with 0 (success) because all checks pass. Without --strict, it would also succeed on Yellow status.
Step 9: Review Health Report
cat health-final.json | jq '.stages[]'
Output:
{
"stage": "manifest_load",
"status": "green",
"message": "Manifest loaded successfully"
}
{
"stage": "index_build",
"status": "green",
"message": "Index built: 3 entries"
}
{
"stage": "layout_check",
"status": "green",
"message": "Layout check: 0 errors, 0 warnings"
}
{
"stage": "frontend_parse",
"status": "green",
"message": "AKS models parse successfully"
}
Step 10: Simulate an Error Condition
Intentionally place a file in the wrong directory to see error handling:
# Create a model in the wrong directory (generated instead of authored)
mkdir -p generated
cp authored/E-Commerce\ Architecture.archkit.model.aks generated/bad-placement.archkit.model.aks
# Run layout check
archkit project layout-check --root . --json-out bad-layout.json
Output:
{
"errors": 1,
"warnings": 0,
"diagnostics": [
{
"severity": "error",
"code": "misplaced_model",
"rel_path": "generated/bad-placement.archkit.model.aks",
"message": "model files should live in authored, found in generated",
"expected_dir": "authored",
"actual_dir": "generated"
}
]
}
Dogfood will now report Red:
archkit project dogfood --root . --json-out health-error.json
cat health-error.json | jq '.status'
Output: "red"
Step 11: Fix the Error
rm generated/bad-placement.archkit.model.aks
archkit project layout-check --root .
CI/CD Integration
Add to your CI pipeline (e.g., GitHub Actions, GitLab CI):
#!/bin/bash
set -e
# Check layout rules are followed
archkit project layout-check --root . --json-out layout-report.json
# Run full health check (fail if not Green)
archkit project dogfood --root . --json-out dogfood-report.json --strict
# Generate updated index
archkit project index --root . --json-out project-index.json
# Upload reports as artifacts
echo "✅ All project checks passed"
Project Maintenance
Regular commands for project maintenance:
# Monthly: Review architecture health
archkit project dogfood --root . --json-out reports/monthly-health-$(date +%Y-%m).json
# After major changes: Update tags
archkit project tag --root . "New Component" "new" "pending-review"
# Quarterly: Audit project structure
archkit project index --root . --json-out reports/quarterly-index-$(date +%Y-Q%q).json
# Before release: Final validation
archkit project dogfood --root . --json-out reports/pre-release-health.json --strict
Self-Hosting Assessment (M1-M9)
Before finalizing your architecture, assess self-hosting readiness:
# Comprehensive adoption assessment
archkit project self-hosting-assess --root . --format text
# JSON format for dashboards
archkit project self-hosting-assess --root . --format json --out adoption-report.json
# Track over time
archkit project self-hosting-assess --root . --format json \
--out reports/adoption-$(date +%Y-%m-%d).json
This generates a complete adoption report showing:
- Status: Ready / WarningsPending / Failed
- Statistics: Artifacts, capabilities, extensions, packages
- Validation: Consistency, integrity, completeness checks
- Findings: Specific errors, warnings, information
- Recommendations: Actionable next steps
Example report:
ARCHKIT SELF-HOSTING ADOPTION REPORT
System: E-Commerce Architecture
Status: WarningsPending
STATISTICS
Artifacts: 3
Capabilities: 2
Extensions: 1
Packages: 8
Workspace Elements: 12
Issues: 1
VALIDATION RESULTS
Consistency: ✓ Pass
Referential Integrity: ✓ Pass
Completeness: ✗ Fail (1 warning)
Errors: 0
Warnings: 1
FINDINGS
1. [Warning] empty_extensions
Remediation: Add extensions to enable extension-based workflows
RECOMMENDATIONS
1. Address validation warnings to reach Ready status
2. Define extensions for modeling updates
3. Once Ready, ready for production adoption
See: SELF_HOSTING_CLI_ASSESSMENT.md for the complete assessment guide.
Summary
The project system provides:
- ✅ Structured organization of architecture models
- ✅ Metadata tracking via overlays (tags, notes, decisions)
- ✅ Automated validation and health checks
- ✅ Deterministic indexing for reproducibility
- ✅ Self-hosting assessment for adoption readiness
- ✅ CI/CD integration for governance
- ✅ Audit trail of decisions and changes
Your project is now ready for collaboration, review, and evolution!
Dogfooding: Project Health Checks
Dogfooding is Archkit’s multi-stage project health check system. It validates your architecture models across seven dimensions, giving you a comprehensive view of model quality, completeness, and consistency.
Overview
The dogfood check runs automatically as part of the project dogfood command and provides deterministic status reporting: Green (all checks pass), Yellow (warnings present), or Red (errors found).
archkit project dogfood --root /path/to/project
The Seven Stages
Stage 1: Manifest Load
What it checks: Can your project manifest be parsed?
{
"stage": "manifest_load",
"status": "green",
"message": "Manifest loaded successfully"
}
Status Rules:
- 🟢 Green:
archkit.project.tomlexists and is valid TOML - 🔴 Red: Parse error or file missing
What it means: If this fails, none of the other stages can run. Fix the manifest TOML syntax and try again.
Stage 2: Index Build
What it checks: Can all files in your project be classified and indexed?
{
"stage": "index_build",
"status": "yellow",
"message": "Index built: 14 entries, 2 unclassified"
}
Status Rules:
- 🟢 Green: All files classified (follow
<subject>.archkit.<kind>.<format>naming) - 🟡 Yellow: Some files couldn’t be classified
- 🔴 Red: Index build failed (disk error, permissions, etc.)
What it means: Unclassified files are warnings, not errors. Review your file naming to ensure models follow the convention.
Example valid names:
workspace.archkit.model.aks- authored modeltags.archkit.overlay.aks- overlay annotationscargo-workspace.archkit.mirror.aks- mirror observation2026-06-14.cargo-workspace.archkit.mirror.aks- timestamped mirror
Stage 3: Layout Check
What it checks: Do files live in the correct directories?
{
"stage": "layout_check",
"status": "green",
"message": "Layout check: 0 errors, 0 warnings"
}
Status Rules:
- 🟢 Green: All files in correct directories, 0 errors, 0 warnings
- 🟡 Yellow: Layout warnings (e.g., unexpected files in
authored/) - 🔴 Red: Layout errors (e.g., editable files in
generated/, orphaned models)
Directory Rules:
| Directory | Editable | Auto-Generated | Expected Files |
|---|---|---|---|
authored/ | ✅ | ❌ | .model.aks |
overlays/ | ✅ | ❌ | .overlay.aks |
mirror/ | ❌ | ✅ | .mirror.aks, .import.json |
generated/ | ❌ | ✅ | schemas, types, diffs |
promoted/ | ⚠️ | ⚠️ | proposals, accepted, rejected |
reports/ | ❌ | ✅ | analysis reports |
.archkit/index/ | ❌ | ✅ | project index |
What it means: Layout violations can prevent other tools from finding your models. Fix directory ownership and try again.
Stage 4: Frontend Parse
What it checks: Do all AKS models parse without syntax errors?
{
"stage": "frontend_parse",
"status": "green",
"message": "AKS models parse successfully"
}
Status Rules:
- 🟢 Green: All
.aksfiles parse successfully - 🔴 Red: One or more files have syntax errors
- 🟡 Yellow: Parsing disabled (when
frontend-aksfeature is not enabled)
What it means: AKS files must follow the correct syntax. Use archkit parse --input model.aks to debug specific files.
Stage 5: Drift Check
What it checks: How well do your authored models match mirror observations (cargo workspace)?
{
"stage": "drift_check",
"status": "yellow",
"message": "Drift check: 8 matched, 2 missing from authored, 0 missing from mirror"
}
Status Rules:
- 🟢 Green: 100% of mirror entities have authored models
- 🟡 Yellow: Some drift found (entities in mirror but not modeled, or vice versa)
- 🔴 Red: Mirror data missing or drift detection failed
Metrics:
- Matching entities: Crates/modules present in both mirror and authored models
- Missing from authored: Mirror observations you haven’t modeled yet
- Missing from mirror: Models you’ve authored but aren’t in the actual codebase
What it means: Drift indicates gaps between intent (your models) and reality (mirror observations). High drift often means your architecture models are out-of-sync with your codebase.
How to fix:
# See what's drifting
archkit project dogfood --root . --json-out report.json
# Look at the drift findings in reports/mirror/
# Create proposals to bridge the gap
archkit project promote plan --root . --kind cargo.workspace
# Review and apply them
archkit project promote apply --root . --proposal promoted/pending/<proposal>.aks
Stage 6: Quality Check
What it checks: How complete and consistent are your authored models?
{
"stage": "quality_check",
"status": "yellow",
"message": "Quality check: 80% completeness (8/10), 0 orphans, 2 unmodeled deps"
}
Status Rules:
- 🟢 Green: ≥90% completeness, 0 orphan entities, 0 unmodeled internal dependencies, 0 naming violations
- 🟡 Yellow: ≥70% completeness, but may have warnings
- 🔴 Red: <70% completeness or violations found
Metrics:
- Completeness: % of actual crates/modules that have been modeled
- Orphan entities: Entities in your models that don’t exist in the codebase
- Unmodeled dependencies: Internal package-to-package dependencies you haven’t captured
- Naming violations: Entities that don’t follow snake_case convention
What it means: Quality score tells you how much of your system you’ve documented. Aim for ≥90% Green.
How to improve:
- Model missing crates: add more Crate entities to
authored/models - Fix orphans: remove modeled entities that no longer exist
- Capture dependencies: add morph edges for internal package dependencies
- Use consistent naming: ensure entity names follow naming conventions
Stage 7: Type Check
What it checks: Are all type references in your models valid and consistent?
{
"stage": "type_check",
"status": "green",
"message": "Type check: 0 unresolved, 0 ambiguous, 0 union violations, 0 cross-model issues"
}
Status Rules:
- 🟢 Green: 0 unresolved references, 0 ambiguous references, 0 union violations
- 🟡 Yellow: Cross-model type issues (types defined in multiple models)
- 🔴 Red: Unresolved or ambiguous type references found
Diagnostics:
- Unresolved refs: Type references that don’t have matching definitions
- Ambiguous refs: Type names that match multiple definitions
- Union violations: Union types defined inconsistently across models
- Cross-model issues: Same type defined in multiple models (potential incompatibility)
What it means: Type validation ensures your type system is well-formed. References should point to valid, uniquely-named types.
How to fix:
- Add missing type definitions (shape, event, entity type)
- Rename duplicate types to be unique within scope
- Ensure union types have consistent members across models
Overall Status Rollup
The dogfood status is determined by the worst stage:
Red > Yellow > Green
If any stage is Red, the overall status is Red. If no Red stages exist but Yellow stages exist, the status is Yellow. Only if all stages are Green is the overall status Green.
Usage Examples
Run dogfood on a project
archkit project dogfood --root /path/to/my-project
Output:
{
"schema_version": 1,
"status": "yellow",
"project_name": "my-project",
"stages": [
{ "stage": "manifest_load", "status": "green", "message": "..." },
{ "stage": "index_build", "status": "green", "message": "..." },
{ "stage": "layout_check", "status": "green", "message": "..." },
{ "stage": "frontend_parse", "status": "green", "message": "..." },
{ "stage": "drift_check", "status": "yellow", "message": "..." },
{ "stage": "quality_check", "status": "green", "message": "..." },
{ "stage": "type_check", "status": "green", "message": "..." }
]
}
Get JSON output for scripting
archkit project dogfood --root . | jq '.status'
# Output: "yellow"
archkit project dogfood --root . | jq '.stages[] | select(.stage == "drift_check")'
# Output: { "stage": "drift_check", "status": "yellow", "message": "..." }
View historical trends
archkit project history --root . --limit 10
Shows Green/Yellow/Red status over time plus improvement rate percentage.
Integration with CI/CD
GitHub Actions Example
- name: Check architecture health
run: |
STATUS=$(archkit project dogfood --root . | jq -r '.status')
if [ "$STATUS" = "red" ]; then
echo "Architecture health check failed"
exit 1
fi
Exit codes
- Green or Yellow: exit 0 (success)
- Red: exit 1 (failure)
Feature Gates
The frontend_parse stage (Stage 4) requires the frontend-aks feature:
# With feature enabled (default)
cargo build --features frontend-aks
# Stage runs, validates AKS syntax
archkit project dogfood --root .
# Without feature
cargo build --no-default-features
# Stage is skipped, status defaults to Yellow
Related Commands
| Command | Purpose |
|---|---|
archkit project init | Create project skeleton with starter models |
archkit project index | Rebuild and view the project file index |
archkit project layout-check | Detailed layout validation report |
archkit project drift | Deep dive into mirror vs. authored drift |
archkit project quality | Detailed quality metrics and analysis |
archkit project type-check | Detailed type validation report |
archkit project verify | Aggregate health check (includes dogfood + mirror-check) |
archkit project promote plan | Generate proposals from drift findings |
archkit project promote apply | Apply proposals to authored models |
Troubleshooting
“Drift check returned Red”
Cause: Mirror data not found or mirror-check failed
Fix: Generate mirror observations first
archkit mirror run --root . --kind cargo.workspace --write
“Quality check is Yellow”
Cause: <90% of crates are modeled
Fix: Add more Crate entities to your authored models
archkit project promote plan --root . --kind cargo.workspace
archkit project promote apply --root . --proposal promoted/pending/<generated>.aks
“Type check shows unresolved refs”
Cause: Type references without matching definitions
Fix: Either define the missing types or remove invalid references
# Add a shape definition
archkit parse --input my-model.aks # to see errors
# Edit the file to fix type references
“Index build shows unclassified files”
Cause: Files don’t follow <subject>.archkit.<kind>.<format> naming
Fix: Rename files to match the convention
# Bad: my-types.aks
# Good: my-types.archkit.model.aks
# Bad: annotations.txt
# Good: annotations.archkit.overlay.aks
Best Practices
-
Aim for Green on all stages. Yellow is acceptable for drift during active development, but work toward closure.
-
Fix from top to bottom. Manifest → Index → Layout → Parse → Drift → Quality → Type. Earlier stages block later ones.
-
Keep models in sync. Run
archkit project promote planregularly to identify drift early, before it accumulates. -
Use consistent naming. Follow snake_case for entity names (e.g.,
my_service, notmyService). -
Version your models. Commit dogfood reports to see trends over time. Use
archkit project historyto track improvement. -
Integrate into CI. Make dogfood status part of your PR checks. Prevent Red from merging.
See Also
- Project System Guide - Comprehensive project-system documentation
- AKS Grammar - Architecture Knowledge Syntax reference
Promotion System Guide
This guide explains how to use Archkit’s promotion system to convert mirror observations (drift findings) into authored model updates.
Overview
The promotion system bridges the gap between automated observations (mirrors) and curated architectural intent (authored models). It allows you to:
- Discover what’s missing in your authored model vs. actual system (via mirrors)
- Review proposed changes (promotion proposals)
- Selectively choose which items to promote
- Apply changes to overlays or authored models
- Reject proposals you don’t want
Core Concepts
Mirror vs. Authored
- Mirror: Auto-generated observation of actual system structure (read-only)
- Authored: Human-written architectural intent (read-write)
- Drift: Difference between the two
- Promotion: Process of closing the gap by updating authored models
Promotion Workflow
1. Mirror → Scan actual system (cargo, rustdoc, etc.)
↓
2. Drift → Compare to authored model
↓
3. Plan → Generate proposal with missing items
↓
4. Review → Examine what would be promoted
↓
5. Apply/Reject → Merge into model or discard
↓
6. Health Check → Verify new model is valid
Targets
Overlays (Default, Non-Destructive):
- Appends entities to
overlays/promoted.archkit.overlay.aks - Preserves original authored model
- Good for annotations and progressive updates
Authored (Direct Model Updates):
- Inserts entities into
authored/workspace.archkit.model.aks - Modifies authoritative model directly
- Requires
--allow-authored-writesafety flag - Better for complete model migrations
Command Reference
Plan: Discover Missing Items
# Plan promotion to overlay (default)
archkit project promote plan \
--root . \
--kind cargo.workspace
# Plan promotion to authored model
archkit project promote plan \
--root . \
--kind cargo.workspace \
--to authored
# Plan with output file
archkit project promote plan \
--root . \
--kind cargo.workspace \
--json-out promoted/plans/workspace.json
Output: JSON report with:
- Proposal file path
- Entity count (what was found missing)
- Dependency count
- Status (green=found items, yellow=nothing to promote, red=drift error)
Selective Promotion: Choose What to Promote
By Entity
# Select single entity
archkit project promote plan \
--root . \
--kind cargo.workspace \
--select-entity archkit-core
# Select multiple entities
archkit project promote plan \
--root . \
--kind cargo.workspace \
--select-entity archkit-core \
--select-entity archkit-project \
--select-entity archkit-type-model
By Dependency
# Format: --select-dep FROM:TO
# Single dependency
archkit project promote plan \
--root . \
--kind cargo.workspace \
--select-dep archkit:archkit-core
# Multiple dependencies
archkit project promote plan \
--root . \
--kind cargo.workspace \
--select-dep archkit-app:archkit \
--select-dep archkit-app:archkit-core
Combined Selection
# Entities AND dependencies
archkit project promote plan \
--root . \
--kind cargo.workspace \
--select-entity archkit-core \
--select-entity archkit-project \
--select-dep archkit:archkit-core \
--select-dep archkit-app:archkit-project
Apply: Merge Proposal into Model
# Apply to overlay (default, safe)
archkit project promote apply \
--root . \
--proposal promoted/pending/cargo-workspace.archkit.proposal.aks
# Apply to authored model (requires safety flag)
archkit project promote apply \
--root . \
--proposal promoted/pending/cargo-workspace.archkit.proposal.aks \
--allow-authored-write
# Apply with output file
archkit project promote apply \
--root . \
--proposal promoted/pending/cargo-workspace.archkit.proposal.aks \
--json-out promoted/reports/apply.json
Safety:
--allow-authored-writeis required for authored target- Missing flag → Error (safe by default)
- Overlay target → No flag needed (non-destructive)
- Destination root must be
authored/oroverlays/ - Proposal path must resolve under
promoted/pending/ - Absolute paths and parent traversal are rejected
- Proposal header target must match command destination
- Proposal finding codes must match expected codes when supplied
- Proposal and destination hashes are rechecked immediately before mutation
See also: ../architecture/command-path-hardening-phase-2-1.md
Reject: Discard Proposal
# Reject proposal (moves to promoted/rejected/)
archkit project promote reject \
--root . \
--proposal promoted/pending/cargo-workspace.archkit.proposal.aks
Workflow Examples
Example 1: Full Workspace Promotion
Scenario: You have a new Rust project and want to model all crates at once.
# 1. Scan cargo workspace
archkit project mirror \
--root . \
--kind cargo.workspace \
--source . \
--write
# 2. Plan promotion
archkit project promote plan \
--root . \
--kind cargo.workspace \
--source . \
--json-out /tmp/plan.json
# 3. Review proposal (examine /tmp/plan.json)
jq '.entities, .dependencies' /tmp/plan.json
# 4. Apply to authored model
archkit project promote apply \
--root . \
--proposal promoted/pending/cargo-workspace.archkit.proposal.aks \
--allow-authored-write
# 5. Verify health
archkit project dogfood --root .
Example 2: Selective Promotion by Tier
Scenario: Large codebase, promote tier by tier.
# Tier 1: Core infrastructure
archkit project promote plan \
--root . \
--kind cargo.workspace \
--select-entity archkit-core \
--select-entity archkit-substrate-model \
--to authored
archkit project promote apply \
--root . \
--proposal promoted/pending/cargo-workspace.archkit.proposal.aks \
--allow-authored-write
# Tier 2: Libraries
archkit project promote plan \
--root . \
--kind cargo.workspace \
--select-entity archkit-type-model \
--select-entity archkit-project \
--to authored
archkit project promote apply \
--root . \
--proposal promoted/pending/cargo-workspace.archkit.proposal.aks \
--allow-authored-write
# Tier 3: Applications
archkit project promote plan \
--root . \
--kind cargo.workspace \
--select-entity archkit-app \
--select-entity archkit-cli \
--to authored
archkit project promote apply \
--root . \
--proposal promoted/pending/cargo-workspace.archkit.proposal.aks \
--allow-authored-write
Example 3: Mixed Overlay and Authored
Scenario: Use overlays for temporary annotations, authored for permanent model updates.
# First pass: Add to overlay for review
archkit project promote apply \
--root . \
--proposal promoted/pending/cargo-workspace.archkit.proposal.aks
# Review the overlay annotations
cat overlays/promoted.archkit.overlay.aks
# Second pass: Promote selected items to authored
archkit project promote plan \
--root . \
--kind cargo.workspace \
--select-entity archkit-core \
--to authored
archkit project promote apply \
--root . \
--proposal promoted/pending/cargo-workspace.archkit.proposal.aks \
--allow-authored-write
Proposal Format
Generated proposals are valid AKS files with metadata headers:
# archkit:file kind=proposal origin=generated subject=cargo-workspace
# archkit:source reports/drift/cargo-workspace.archkit.drift.json
# archkit:target overlays/promoted.archkit.overlay.aks
# archkit:status pending
# archkit:entities 11
# archkit:dependencies 14
workspace "Cargo Workspace Promotion"
module cargo_workspace_promotion@v0
operation PromoteProposal
kind: proposal
subject: "cargo.workspace"
target: "overlays/promoted.archkit.overlay.aks"
entities: 11
dependencies: 14
end operation
entity archkit: Crate
has name: "archkit"
has path: "crates/archkit"
has manifest: "crates/archkit/Cargo.toml"
has promoted_from: "cargo.workspace"
end entity
# ... more entities and relationships ...
end workspace
Best Practices
Command-Path Safety Model
promote_apply is first command-governed mutation sample in Archkit.
Validation invariants
Before mutation, command validation enforces:
- proposal path under
promoted/pending/ - destination under
authored/oroverlays/ - workspace-relative paths only
- no absolute paths
- no
..traversal - proposal metadata target matches destination
- authored writes require explicit opt-in
Pre-mutation recheck
Immediately before write/move, Archkit rechecks:
- proposal still exists
- proposal hash unchanged
- destination hash or missing/present state unchanged
- proposal target still matches destination
- finding code expectations still match
If any recheck fails, apply aborts without writing target or moving proposal.
Event behavior
Command path emits:
command.acceptedcommand.startedproject.promote.appliedcommand.completedcommand.failed
Failure policy:
- pre-mutation lifecycle emit failure → command fails closed
- post-mutation fact emit failure → mutation remains, report marks
audit_gap
1. Validate Before Applying
# Generate proposal first
archkit project promote plan \
--root . \
--kind cargo.workspace \
--json-out /tmp/plan.json
# Review the report
jq . /tmp/plan.json | less
# Only then apply
archkit project promote apply --root . ...
2. Start with Overlay, Move to Authored
# Safe: Try in overlay first
archkit project promote apply --root .
# Review overlay annotations
cat overlays/promoted.archkit.overlay.aks
# When ready: Move to authored with selection
archkit project promote plan --root . --to authored --select-entity ...
archkit project promote apply --root . --allow-authored-write
3. Use Selective Promotion for Large Codebases
# Don't promote everything at once
# Break into manageable chunks
archkit project promote plan \
--root . \
--select-entity core-lib \
--select-entity util-lib
4. Track Changes with History
# Before promoting
archkit project dogfood --root . > /tmp/before.json
# After promoting
archkit project dogfood --root . > /tmp/after.json
# Compare
diff /tmp/before.json /tmp/after.json
Directory Structure
After running promotion commands, your project will have:
project/
├── promoted/
│ ├── pending/ # Awaiting apply/reject
│ │ └── cargo-workspace.archkit.proposal.aks
│ ├── accepted/ # Applied proposals
│ │ └── cargo-workspace.archkit.proposal.aks
│ └── rejected/ # Rejected proposals
│ └── old-workspace.archkit.proposal.aks
├── authored/
│ └── workspace.archkit.model.aks # Updated by apply
└── overlays/
└── promoted.archkit.overlay.aks # Updated by apply
Troubleshooting
Proposal Shows 0 Entities
Cause: All items already in authored model
Solution: Update mirror if system changed, or review authored model
Error: “proposal targets authored model but –allow-authored-write was not provided”
Cause: Trying to apply to authored without safety flag
Solution: Add --allow-authored-write flag to apply command
Error: “proposal path must be under promoted/pending/”
Cause: Proposal file in wrong location
Solution: Only proposals in promoted/pending/ can be applied
Merge Conflict in Authored Model
Cause: Proposal tries to add duplicate entities
Solution: Use selective promotion to target only new items
See Also
- PROJECT_SYSTEM.md — Project system overview
- DOGFOODING.md — Dogfooding guide
- STAGES_COMPLETE.md — All 5 stages overview
CLI Commands (Curated Guide)
Canonical CLI help lives in generated reference:
apps/archkit-cli/generated/persistent/docs/cli-reference.md
Use this page for navigation + policy, not copied help text.
Ownership model
- Generated command details:
gen_docsoutput (cli-reference.md) - Curated/operator guidance: this page + adjacent reference docs
- Drift rule: do not duplicate full
--helpblocks here
Common flows
- Parse/validate/view:
archkit parse,archkit validate,archkit view - Batch operations:
archkit validate-all,archkit view-all,archkit index - Project management:
archkit project <subcommand>(init, index, layout-check, tag, note, dogfood, check, mirror, drift, promote, verify) - Docs pipeline:
archkit docgen - Type model workflows:
archkit type-model <subcommand> - Snapshot lifecycle:
archkit snapshot <subcommand>
Project Init Configuration
The archkit project init command is configurable via CLI flags:
archkit project init --root <dir> --name <name> \
[--version <version>] \
[--description <description>] \
[--overlay <overlay>...]
--root- Project root directory (default:.)--name- Project name (required if not inferring from –root)--version- Semantic version for archkit.project.toml (default:v0)--description- Optional project description--overlay- Custom overlay file stems (repeatable; when provided, replaces defaults)
Configuration is persisted in archkit.project.toml under [init]. Re-running init on an existing project is idempotent and respects saved configuration as defaults.
Feature-gated commands
See generated matrix:
apps/archkit-cli/generated/persistent/docs/feature-command-matrix.md
Quick start
archkit --help
archkit <command> --help
For full command tree coverage, rely on generated cli-reference.md only.
Canonical Project Architecture
architecture/ is canonical authored source-of-truth for architecture-as-code in this repository.
This directory defines how archkit models itself and other first-class architecture artifacts.
Ownership and Policy
- Canonical authored models live in
architecture/models/*.aks. - AKS (
.aks) is source-of-truth authoring format. - Nickel (
.ncl) remains complementary for parity and contract workflows. - Generated outputs must go under
generated/ephemeral/**. - Do not commit generated outputs from architecture workflows.
Directory Layout (v0)
architecture/models/- Canonical architecture specs.
architecture/models/modules/stores reusable structure modules referenced by canonical specs.
architecture/views/- View intent map and review guidance.
architecture/contracts/- Modeling guardrails and evolution notes.
architecture/decisions/- ADRs for major architecture modeling decisions.
canonicalization-design.md— Design of SubstrateAksDocument fingerprinting and JCS canonicalization
command-path-hardening-phase-2-1.md- Hardening record for
ProjectCommand::PromoteApplyvalidation, path safety, TOCTOU checks, event policy, and build-state boundary.
- Hardening record for
../guides/RUNTIME_WATCH.md- Runtime host architecture for foreground watch/live execution.
../guides/TUI.md- Phase 7 terminal UI client/view architecture over runtime, event, build, command, and store surfaces.
Modeling Conventions
- IDs use prefixes:
person_*,sys_*,ctr_*,cmp_*. - Relationship labels are verb-first (
parses,projects,renders,emits). - Every container/component includes
properties.pathwhen mapped to repo code. architecture/models/archkit_self.aksis canonical entrypoint.- Start small (10-20 elements), then add detail only when view needs it.
Command Loop
Validate canonical model:
cargo run --bin archkit -- validate -i architecture/models/archkit_self.aks
Project selected review views (DOT + Mermaid sidecar + canonical JSON sidecar):
cargo run --bin archkit -- project -i architecture/models/archkit_self.aks --view-id ctx_archkit -o generated/ephemeral/architecture/archkit-self/ctx_archkit.dot
cargo run --bin archkit -- project -i architecture/models/archkit_self.aks --view-id ctr_archkit -o generated/ephemeral/architecture/archkit-self/ctr_archkit.dot
cargo run --bin archkit -- project -i architecture/models/archkit_self.aks --view-id wf_from_cli -o generated/ephemeral/architecture/archkit-self/wf_from_cli.dot
cargo run --bin archkit -- project -i architecture/models/archkit_self.aks --view-id dep_all -o generated/ephemeral/architecture/archkit-self/dep_all.dot
cargo run --bin archkit -- project -i architecture/models/archkit_self.aks --view-id cmp_cli -o generated/ephemeral/architecture/archkit-self/cmp_cli.dot
cargo run --bin archkit -- project -i architecture/models/archkit_self.aks --view-id cmp_frontends -o generated/ephemeral/architecture/archkit-self/cmp_frontends.dot
cargo run --bin archkit -- project -i architecture/models/archkit_self.aks --view-id cmp_render -o generated/ephemeral/architecture/archkit-self/cmp_render.dot
cargo run --bin archkit -- project -i architecture/models/archkit_self.aks --view-id int_external -o generated/ephemeral/architecture/archkit-self/int_external.dot
Optional render gate (requires Graphviz dot):
cargo run --bin archkit -- render -i generated/ephemeral/architecture/archkit-self/ctr_archkit.dot -f svg -o generated/ephemeral/architecture/archkit-self/ctr_archkit.svg
Cargo-Make Shortcut
Use:
cargo make architecture-self
This runs validate + deterministic projection for canonical self-model.
All generated architecture artifacts must remain under generated/ephemeral/** and are not committed.
Operations
ci.mdpackaging.mdrelease-process.mdrelease-checklist.md
Cloudflare Pages Deployment for mdBook
This repo can publish docs with mdBook to Cloudflare Pages.
Build output
- mdBook config:
docs/book.toml - source:
docs/src/ - build output:
docs/book/
Local build
Use repo docs shell:
nix develop .#docs -c mdbook build docs
Serve locally:
nix develop .#docs -c mdbook serve docs --open
Recommended deploy path
Recommended path: GitLab CI builds book, deploys to Cloudflare Pages.
Reason: repo already has .gitlab-ci.yml; docs should publish from same CI system.
Required Cloudflare config
Create Pages project in Cloudflare dashboard.
Set GitLab CI/CD variables:
CLOUDFLARE_API_TOKENCLOUDFLARE_ACCOUNT_IDCLOUDFLARE_PAGES_PROJECT_NAME
GitLab CI jobs
Pipeline file: .gitlab-ci.yml
Build job:
- installs
mdbook - runs
mdbook build docs - stores
docs/book/as artifact
Deploy job:
- runs in
node:22-bullseye - installs
wrangler - runs:
wrangler pages deploy docs/book \
--project-name "$CLOUDFLARE_PAGES_PROJECT_NAME" \
--branch "$CI_COMMIT_REF_SLUG"
Current rule: deploy on default branch only.
Native Cloudflare Pages build
Possible, but weaker fit. Reason: Cloudflare Pages build image does not use repo Nix shell by default.
If using native Pages build, configure:
- Framework preset:
None - Build command: install
mdbook, thenmdbook build docs - Build output directory:
docs/book
Use native build only if you accept non-Nix tool bootstrap in build step.
Custom domain
After first deploy, attach custom domain in Pages project settings.
Notes
- Do not commit
docs/book/ - Keep authored docs in
docs/ - Keep rustdoc separate from mdBook site
- Local dev can still use Nix docs shell even if CI installs
mdbookdirectly
API Docs
Use rustdoc for Rust API surface.
Local build
nix develop .#docs -c cargo doc --workspace --no-deps
Open output:
xdg-open target/doc/index.html
Publishing model
Recommended split:
- mdBook / Cloudflare Pages — AKS + Archkit docs site
- rustdoc — API reference artifact
Link strategy
Link from this book to hosted rustdoc once publish target exists. Until then, treat rustdoc as local or CI artifact.