Source-first arc42 architecture documentation from Markdown and AsciiDoc records
Project description
archledger
archledger is a source-first arc42 documentation tool. It stores architecture
knowledge as small, reviewable Markdown or AsciiDoc records with YAML front
matter, validates those records, tracks source drift, and assembles complete
arc42-style architecture documents on demand.
Release status
archledger is currently beta.
- Native Markdown and AsciiDoc source workflows are the most stable path.
- Converter-backed exports are supported when the required external tools are installed and validated by CI.
- See
CHANGELOG.mdfor recent release-oriented changes anddocs/release-process.rstfor the maintainer release checklist.
What archledger is
archledger is intentionally small:
- project-local config discovery from
archledger.tomlor.archledger.toml - canonical source fragments in Markdown or AsciiDoc
- a compact Typer CLI for init, read, record creation, validation, source drift tracking, migration, and builds
- deterministic native document assembly with optional converter-backed exports
The “ledger” is the project-local set of architecture records: requirements, decisions, constraints, building blocks, runtime scenarios, deployment nodes, quality scenarios, risks, glossary terms, and diagrams.
archledger is not an accounting ledger, blockchain ledger, Arch Linux package
tool, or task tracker.
When to use it
Use archledger when you want architecture documentation that can be updated incrementally by humans or coding agents, reviewed in Git, and assembled into arc42-style documents on demand.
Install
Editable development install:
python -m pip install -e ".[dev]"
Profiles, SDD, and BDD
Archledger has two project profiles:
arc42: documentation assembly profile for arc42 architecture sections.sdd: contract profile for specification, traceability, and validation policy.
BDD is not a standalone profile. BDD is behavior metadata on existing records and
an import/export bridge for Gherkin .feature files. Enable SDD when you want
archledger to enforce BDD metadata quality.
archledger init --profile arc42
archledger profile enable sdd
archledger bdd import specs/behavior/features/task-management/plan-gates.feature \
--kind runtime-scenario \
--status proposed
archledger sdd check --strict
Imported BDD records carry a bdd front-matter block with feature, rule,
scenario, tags, Given/When/Then steps, and optional automation metadata. Imported
records default to automation.status=linked. Keep feature files in source_refs
with role documents and link plain pytest validation through test_refs.
Supported Gherkin is intentionally small: Feature, Rule, Scenario/Example,
tags, and Given/When/Then/And/But. Unsupported constructs such as
Background, Scenario Outline, Examples, data tables, and doc strings fail
fast with structured validation and sync findings.
Archledger does not run Cucumber, behave, pytest, or any BDD runner. Commands and test refs are traceability only.
SDD lifecycle commands
# Initialize SDD with strict defaults and seed minimal contract records
archledger sdd init --strict-defaults --seed minimal
# Show and set policy without manual TOML editing
archledger sdd policy show
archledger sdd policy set --require-bdd-automation
# Under --require-bdd-automation, accepted behavior records must reach
# automation.status=automated (or not_applicable); linked alone is not enough.
# Explain rule codes and manage waivers
archledger sdd explain SDD-BDD-AUTOMATION
archledger sdd waive add al_requirement_0001 --rule SDD-REQ-AC --reason "Legacy."
# Detailed coverage with gaps
archledger sdd coverage --include-bdd
archledger sdd coverage --format markdown
# Scoped checks
archledger sdd check --record al_requirement_0001
archledger sdd check --kind requirement
BDD lifecycle commands
# Validate without importing/exporting
archledger bdd validate al_runtime_0042
archledger bdd validate --feature-file specs/behavior/features/task-management/plan-gates.feature
# List, status, set, link
archledger bdd list --automation pending
archledger bdd status
archledger bdd set al_runtime_0042 --feature "F" --scenario "S" --given g --when w --then t
archledger bdd link al_runtime_0042 \
--feature-file specs/behavior/features/task-management/plan-gates.feature \
--scenario "@bdd-implementation-blocked-before-plan-acceptance" \
--test tests/test_task_management_plan_gates.py::test_agent_cannot_start_implementation_before_plan_approval \
--status automated
# Dry-run import and batch export
archledger bdd import specs/behavior/features/task-management/plan-gates.feature --dry-run
archledger bdd export al_runtime_0123 \
--out specs/behavior/features/task-management/plan-gates.derived.feature
archledger bdd export --all --out-dir specs/behavior/features/derived
Archledger records are the canonical source for architecture/specification
records. SpecWeave-owned files under specs/behavior/features may be the
canonical behavior specifications. Archledger-exported .feature files are
derived unless a project explicitly changes ownership. bdd sync --check
reports drift between linked behavior specs and Archledger metadata.
bdd set and bdd link validate automation status, feature-file paths, and
pytest test refs before writing front matter, so rejected mutations do not leave
invalid BDD metadata behind.
Safe mutation commands update front matter and re-run repository validation:
archledger record set al_0013 --status accepted
archledger refs add al_0013 --path src/example.py --role implements
archledger links add al_0013 --rel decided_by --target al_0014
archledger ac add al_0013 --statement "The behavior is covered"
Published schemas and integration scaffolds are available from the CLI:
archledger --json schema --format jsonschema --target record
archledger install github-actions
Normal user install:
python -m pip install .
Docs build support:
python -m pip install -e ".[docs]"
Optional converter tools:
pandocfor Markdown-source exports and some AsciiDoc exportsasciidoctorfor native AsciiDoc HTML and DocBook conversionasciidoctor-pdffor native AsciiDoc PDF output
Converter-backed formats are part of the supported workflow only when those tools are present and the related integration checks pass.
Quick start
Markdown source
archledger init --source-format markdown
archledger init --source-format markdown --id-prefix ta --id-width 3
archledger init --source-format markdown --id-segment-mode type
archledger seed arc42-minimal
archledger --json read --body
archledger build --format markdown
AsciiDoc source
archledger init --source-format asciidoc
archledger seed arc42-minimal
archledger --json read --body
archledger build --format asciidoc
Core concepts
Workspace config
By default, archledger init writes archledger.toml at the workspace root and stores state under .archledger/. Relative archledger_dir values are resolved from the config file location, and [build].default_output_dir is resolved relative to that same config directory / workspace root.
Source fragments
Each section file and record file has YAML front matter plus a body in the configured dialect. Example:
---
schema_version: 2
id: al_0013
type: adr
title: "Treat source fragments as canonical"
status: accepted
section: architecture_decisions
order: 10
date: "2026-05-20"
body_format: markdown
created_at: "2026-05-20T00:00:00Z"
updated_at: "2026-05-20T00:00:00Z"
---
body_format must match the project source.format unless you explicitly use the migration escape hatch during a manual source conversion.
Sections and records
Sections are the arc42 chapter skeleton. Records hold individual requirements, decisions, building blocks, risks, and other architecture facts. Use the CLI to allocate paths and ids, then edit the generated fragment.
ID format is configurable via [ids]:
[ids]
prefix = "al"
width = 4
segment_mode = "none"
default_segment = "content"
Segmented IDs use:
<prefix>_<segment>_<number>
Example:
al_content_0013
al_risk_0014
segment_mode = "type" resolves the segment deterministically from front matter:
id_segmentmetadata (if present and valid)[ids.segment_map]lookup bytypedefault_segment
Use renumber to migrate existing IDs and references:
archledger renumber --prefix ta --width 3
archledger renumber --prefix ta --width 3 --apply
archledger renumber --id-segment-mode type
archledger renumber --id-segment-mode type --apply
archledger renumber --id-segment-mode none --apply
The numeric sequence is always global and unchanged (for example 0014 stays 0014).
Generated outputs
Generated build outputs are derived artifacts and should not be edited as source. New projects default to build/ under the workspace root, and [build].default_output_dir can place outputs elsewhere. This repository intentionally sets [build].default_output_dir = "." and writes ARCHITECTURE.md at the repository root.
What to commit
For a project that uses archledger, commit the canonical source and config:
archledger.toml.archledger/sections/**.archledger/records/**- optionally
.archledger/storage.yamlif you want deterministic id allocation across machines - optionally
.archledger/source-state.jsonif your team wants a shared drift baseline
Do not treat generated build output as canonical source. Determine its location from [build].default_output_dir (or archledger --json paths). Generated build output and converter intermediates are disposable unless you are intentionally debugging an export issue.
Record types
| Kind | Common aliases | Default section |
|---|---|---|
requirement |
requirement |
introduction_and_goals |
stakeholder |
stakeholder |
introduction_and_goals |
quality_goal |
quality-goal |
introduction_and_goals |
constraint |
constraint |
architecture_constraints |
context_interface |
context-interface |
context_and_scope |
strategy_item |
strategy-item |
solution_strategy |
white_box |
white-box |
building_block_view |
black_box |
black-box |
building_block_view |
interface |
interface |
building_block_view |
runtime_scenario |
runtime |
runtime_view |
infrastructure |
infrastructure |
deployment_view |
diagram |
diagram |
cross_cutting_concepts |
concept |
concept |
cross_cutting_concepts |
adr |
adr |
architecture_decisions |
quality_requirement |
quality-requirement |
quality_requirements |
quality_scenario |
quality-scenario |
quality_requirements |
risk |
risk |
risks_and_technical_debt |
glossary_term |
glossary-term |
glossary |
Reading source without exporting
Use read and the JSON commands to inspect the current source state directly:
archledger --json paths
archledger --json status
archledger --json check
archledger --json read --body --include-drafts
archledger --json read --section building_block_view --body
archledger --json read --kind adr --body
--json is a global option. Use archledger --json read ..., not archledger read --json.
read does not call the build pipeline and does not create generated output files.
Tracking implementation drift
Snapshots
archledger --json source snapshot --reason after-archledger-update
snapshot writes .archledger/source-state.json by default. Source-state payloads store SHA-256 content hashes only for files, do not persist mtimes or file sizes, and include a derived directory hash map. If [tracking].enabled = false, snapshot and changed fail explicitly instead of silently creating misleading tracking state.
Changed files
archledger --json source changed
archledger --json source changed --include-drafts
changed reports added, modified, deleted, and possible renamed files plus impacted records and sections linked through source_refs.
Linking source_refs
When fragments document real code or directories, add source_refs:
source_refs:
- archledger/repository.py#ArchitectureRepository
- path: archledger/storage/project_config.py
symbols:
- ProjectConfig
- load_project_config
reason: "Tracking configuration contract"
- path: archledger/templates/
reason: "Bundled templates"
Paths must be relative to the workspace root. Directory refs end with / and must point to an existing directory.
Practical drift workflow
archledger --json source changed
archledger --json read --body --include-drafts
# update the affected fragments and their source_refs
archledger --json check
archledger --json source snapshot --reason after-archledger-update
A useful pattern is:
- Link records to the relevant code or directories with
source_refs. - Run
changedbefore broad documentation refreshes. - Update only the fragments whose refs were impacted.
- Record a fresh snapshot only after the documentation update is validated.
Building output documents
Native builds
archledger build --format markdown
archledger build --format asciidoc
Converted builds
archledger build --format html
archledger build --format html --format markdown
archledger --json build --format html --format markdown
Tooling matrix
| Source format | Output format | Tooling |
|---|---|---|
| Markdown | Markdown | none |
| AsciiDoc | AsciiDoc | none |
| Markdown | HTML, DOCX, RST, Textile, PDF, AsciiDoc | pandoc |
| AsciiDoc | HTML | asciidoctor or pandoc |
| AsciiDoc | asciidoctor-pdf or pandoc |
|
| AsciiDoc | DOCX, Markdown, RST, Textile | asciidoctor + pandoc |
Per-output overrides live under [build.outputs.<format>]. Supported keys are tool, pdf_engine, reference_docx, and enabled. Supported tool values are auto, pandoc, and asciidoctor.
Diagram records
Diagram records are plain text by default. Dense architecture diagrams should use
diagram_type = "text" or "unicode" so they remain readable in source,
Git diffs, terminal output, and native Markdown/AsciiDoc builds. Mermaid remains
available for compact diagrams, but it is not the default.
Create first-class diagram records directly:
archledger new diagram "Runtime login flow" --section runtime_view --status proposed
archledger new diagram "Deployment topology" --section deployment_view --caption "Target deployment"
archledger new diagram "Login sequence" --diagram-type mermaid
Supported diagram_type values: text (default), ascii, unicode, svgbob, mermaid.
Native Markdown/AsciiDoc builds preserve text diagram blocks as readable fenced/literal blocks without any external tool. Rendered image materialization for converter-backed formats is optional and disabled by default:
[diagrams]
enabled = true
renderer = "mermaid-cli" # pass-through | mermaid-cli | asciidoctor-diagram
default_type = "text"
output_dir = "diagrams"
image_format = "svg"
kroki_url = ""
svgbob is a diagram_type, not a renderer. Supported renderer values are
pass-through, mermaid-cli, and asciidoctor-diagram. Kroki is not currently
accepted by config validation.
Migrating source dialects
source convert is a source migration command, not a general build/export command. It currently supports Markdown-source projects to AsciiDoc-source projects only.
Dry-run the migration first:
archledger source convert --to asciidoc
Write the migration:
archledger source convert --to asciidoc --apply
--apply now requires pandoc by default so the migrated .adoc files and the resulting source.format = "asciidoc" config stay consistent. If you intentionally want a temporary mixed-body migration, use:
archledger source convert --to asciidoc --apply --allow-mixed-body-format
Use this escape hatch only when you explicitly accept a manual cleanup step. Run the command from a clean VCS state.
Configuration reference
Example config v6:
config_version = 6
archledger_dir = ".archledger"
project_uuid = "..."
project_name = "my-project"
[ids]
prefix = "al"
width = 4
[source]
format = "markdown" # markdown | asciidoc
front_matter = "yaml"
section_extension = ".md" # .md or .adoc
record_extension = ".md"
schema_version = 2
[build]
default_output = "architecture.md"
default_format = "markdown"
default_output_dir = "build"
include_draft = false
include_superseded = false
strict = false
keep_intermediate = false
converter = "auto" # auto | pandoc | asciidoctor
pdf_engine = ""
reference_docx = ""
[tracking]
enabled = true
state_file = "source-state.json"
scanner = "auto" # auto | git | filesystem
[build].default_output_dir is relative to the directory containing archledger.toml or .archledger.toml.
source-state.json stores SHA-256 content hashes only for files. It does not persist mtimes or file sizes. Directory hashes are derived from file hashes.
CLI reference for agents
For coding agents, prefer this loop:
archledger --json pathsarchledger --json source changedarchledger --json read --body --include-drafts- Edit only source fragments under
archledger_dir/sectionsandarchledger_dir/records archledger --json check- Build only when the user asks for an exported artifact
archledger --json source snapshot --reason after-archledger-updateafter the docs have been updated and validated
Archiving and structural repair
Do not delete numbered source fragments. Use:
archledger archive al_0022 --reason "obsolete after al_0041"
Archived records move to .archledger/archive/ and keep their original ID. They are excluded from default read/list/build flows but still reserve their ledger number.
Use:
archledger doctor
archledger doctor --repair
archledger renumber --prefix ta --width 3
archledger renumber --prefix ta --width 3 --apply
doctor --repair can recreate missing required section files, create archive tombstones for missing non-section IDs, and recompute storage.yaml.next_number without renumbering existing records.
Development
Run the standard checks:
python -m pytest -q
python -m ruff check .
python -m ruff format --check .
python -m mypy archledger
python -m sphinx -b html docs docs/_build/html
Release-oriented checks:
rm -rf dist build *.egg-info
python -m build
python -m twine check dist/*
python -m venv /tmp/archledger-wheel-test
/tmp/archledger-wheel-test/bin/python -m pip install dist/*.whl
/tmp/archledger-wheel-test/bin/archledger --version
For the full maintainer checklist, see docs/release-process.rst.
Troubleshooting
| Symptom | Cause | Fix |
|---|---|---|
No archledger.toml found |
Command ran outside a configured workspace. | Run from the project tree or pass --root. |
| Draft records missing from builds | Drafts are excluded by default. | Use --include-drafts or promote the record status. |
| Build blocked by warnings | --strict treats warnings as failures. |
Fix the warnings or build without --strict. |
| Converter executable not found | Requested output needs pandoc, asciidoctor, or asciidoctor-pdf. |
Install the required tool or change the per-output converter config. |
source changed says no baseline found |
No source snapshot exists yet. | Run archledger --json source snapshot --reason after-archledger-update after the docs are current. |
snapshot or changed says tracking is disabled |
[tracking].enabled = false. |
Re-enable tracking or avoid tracking commands for that workspace. |
source convert --apply fails without pandoc |
Apply mode is strict by default. | Install pandoc or re-run with --allow-mixed-body-format if you accept a manual cleanup step. |
check reports missing ledger IDs |
Numbered fragments were deleted or moved manually. | Use archledger archive for lifecycle removal and archledger doctor --repair for safe structural repair. |
Skill
The repository-provided coding-agent protocol lives at skills/archledger/SKILL.md.
Security and trust
archledger reads local project files and only invokes external converters when you request output formats that need them. It does not sync or send project content anywhere by itself.
Three-tool traceability boundary
Archledger is the durable architecture/specification ledger. It stores external Taskledger IDs, SpecWeave feature references, pytest references, and evidence references as data only. It does not execute Taskledger, SpecWeave, pytest, behave, or Cucumber commands.
Taskledger owns active task lifecycle state. SpecWeave owns canonical Gherkin
behavior specs and normalized behavior evidence. Use source_refs for
SpecWeave feature files under specs/behavior/features and test_refs for
plain pytest tests that validate an Archledger record.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file archledger-0.3.0.tar.gz.
File metadata
- Download URL: archledger-0.3.0.tar.gz
- Upload date:
- Size: 356.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
16f6b9fd4d23d6d60905ee76fb16e2a7bd82005e292c74c4f455ef9bbdd25d97
|
|
| MD5 |
e25c850ee2c63940935b043b7a0ecbf6
|
|
| BLAKE2b-256 |
035de5c404f8d7dfba8e167e3d546fe429ac3e95ef1b120c485a97f6847fdbfd
|
File details
Details for the file archledger-0.3.0-py3-none-any.whl.
File metadata
- Download URL: archledger-0.3.0-py3-none-any.whl
- Upload date:
- Size: 199.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3d6e2e5a4576714e571be47e225a664ffbc00882e53394e0e9cf8ffe40898ea0
|
|
| MD5 |
3c7aabc98462e8e25ed6b81a7b85f14f
|
|
| BLAKE2b-256 |
baecc5fa5f24009ed3da98199bffe060c1ac92ec1a122154b92e73420a5731ba
|