Skip to main content

Ledgerwerk record owner for requirements and acceptance criteria

Project description

ReqLedger

ReqLedger is the Ledgerwerk record owner for requirements and acceptance criteria.

It stores durable requirement records as readable Markdown files with TOML metadata. It does not run tests, generate Gherkin, parse Gherkin, discover pytest tests, or own task/architecture records.

Downstream tools such as SpecMason can consume ReqLedger exports to create and validate behavior specs, pytest mappings, coverage reports, and evidence reports.

Scope boundary

Tool Owns
reqledger requirements and acceptance criteria
specmason behavior specs, mappings, coverage, and evidence
taskledger tasks and task workflow
archledger architecture records and ADRs
planledger implementation plans
wikimason wiki content

ReqLedger is normative: accepted requirement records define intended product behavior. Source code and tests describe observed behavior but never silently rewrite requirements.

Requirements live as readable files

requirements/
  README.md
  manifest.json
  records/
    req-0001.req.md
  reports/
    reqledger/
      review.md
      review.json
reqledger.toml

Each requirement is a Markdown file with TOML front matter delimited by +++:

+++
schema_version = 1
id = "REQ-0001"
title = "Reject invalid login passwords"
kind = "functional"
status = "accepted"
priority = "must"
tags = ["auth", "login"]
source = "manual"
created = "2026-06-16"
updated = "2026-06-16"

[[criteria]]
id = "AC-0001"
statement = "Login is rejected when an invalid password is submitted."
verification = "behavior"
status = "accepted"
tags = ["auth"]
+++

# REQ-0001: Reject invalid login passwords

## Intent

The product must reject invalid passwords for registered users.

Quickstart

pip install reqledger
reqledger init
reqledger new "Reject invalid login passwords" \
  --kind functional \
  --priority must \
  --criterion "Login is rejected when an invalid password is submitted."
reqledger validate
reqledger index
reqledger review
reqledger export --format json

Commands

reqledger init [--force] [--json]
reqledger new "Title" [--kind] [--priority] [--tag TAG]... [--criterion STMT]... [--status] [--source] [--json]
reqledger list [--status STATUS] [--tag TAG] [--json]
reqledger show REQ-0001 [--json]
reqledger validate [--json]
reqledger index [--json]
reqledger link REQ-0001 --task ID --arch ID --spec PATH --evidence PATH [--json]
reqledger review [--json]
reqledger export --format json [--output PATH] [--json]

Global options: reqledger --version, reqledger --config PATH <command>.

Validation is fail-closed and returns exit code 1 on validation errors, 2 on usage/config errors, and 0 when all records are valid.

Configuration

ReqLedger looks for config in this order (first wins):

  1. explicit --config PATH,
  2. reqledger.toml discovered upward from the current directory,
  3. .reqledger.toml discovered upward,
  4. built-in defaults.

When both reqledger.toml and .reqledger.toml exist in the same directory, reqledger.toml wins. Paths declared in config resolve relative to the config file's directory; with no config they resolve relative to the current working directory.

Default config:

schema_version = 1

[paths]
root = "requirements"
records_dir = "requirements/records"
manifest = "requirements/manifest.json"
reports_dir = "requirements/reports"
reports_state_dir = "requirements/reports/reqledger"

[ids]
requirement_prefix = "REQ"
criterion_prefix = "AC"
width = 4

[review]
draft_stale_days = 90

Manifest and export

reqledger index writes a deterministic requirements/manifest.json:

{
  "schema_version": 1,
  "tool": "reqledger",
  "requirements": [
    {
      "id": "REQ-0001",
      "title": "Reject invalid login passwords",
      "path": "requirements/records/req-0001.req.md",
      "kind": "functional",
      "status": "accepted",
      "priority": "must",
      "tags": ["auth", "login"],
      "source": "manual",
      "source_refs": [],
      "criteria": [
        {
          "id": "AC-0001",
          "statement": "Login is rejected when an invalid password is submitted.",
          "verification": "behavior",
          "status": "accepted",
          "tags": ["auth"]
        }
      ],
      "refs": {
        "tasks": [],
        "architecture": [],
        "specs": [],
        "evidence": []
      }
    }
  ]
}

The manifest is derived state; Markdown records remain the source of truth. reqledger export --format json emits the same shape for downstream tools.

Design constraints

  • Prefer readable files over hidden state.
  • Keep deterministic output.
  • Keep dependencies minimal (typer, ledgercore, tomli for Python < 3.11).
  • Preserve user-authored Markdown bodies.
  • Do not use title matching for identity; IDs are the identity.
  • Validation is fail-closed.
  • External links are references, not ownership transfers.
  • ReqLedger does not parse or generate Gherkin, discover or run tests, or import SpecMason at runtime.

Development

pip install -e ".[dev]"
pytest -q

ReqLedger reuses shared Ledgerwerk primitives from ledgercore (ID allocation, config discovery, deterministic JSON, atomic writes) and implements the TOML +++ front matter and requirements domain itself.

License

Apache-2.0.

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

reqledger-0.1.0.tar.gz (43.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

reqledger-0.1.0-py3-none-any.whl (33.7 kB view details)

Uploaded Python 3

File details

Details for the file reqledger-0.1.0.tar.gz.

File metadata

  • Download URL: reqledger-0.1.0.tar.gz
  • Upload date:
  • Size: 43.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for reqledger-0.1.0.tar.gz
Algorithm Hash digest
SHA256 26c97dd5af14a13ae3f18be5af63d70dc429a499ea7aae1ed53bdef4c825974d
MD5 26a3811ba28d6b7d683f25c255ab863d
BLAKE2b-256 ade45106896740d75ca7d2e7cb4618e655a67fc8b425aac33103f7648a548951

See more details on using hashes here.

File details

Details for the file reqledger-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: reqledger-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 33.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for reqledger-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 9c009e64ae673705792b0c1db676e64cea7853d72afe052e40bd155ace9cdd45
MD5 7ea45de10140cbd259704326a10b4847
BLAKE2b-256 2d6cf4b0e690535a4d5e48f27764c0d3abe689c1074732b15724a8213644e00f

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page