Skip to main content

A Git-native requirements management tool with a scope-avalanche grounding layer: permanent UIDs, one file per item, typed links, suspect detection, and a CI-gating check.

Project description

throughline

ci

A Git-native requirements management tool with a built-in scope-avalanche grounding layer. Requirements live as one small YAML file per item under version control; a check command validates the whole graph and gates CI.

Two ideas, one system:

  1. throughline core — permanent, position-independent UIDs (never renumbered, never reused; deletion is a tombstone), one file per item, typed directed links, SHA-256 normative fingerprints that turn a real content change into a suspect link, and a check CLI with stable exit codes.
  2. grounding layer — every non-root item must justify itself by reaching a root ("why"); AI-generated items enter proposed and must be ratified by a human; assumptions are first-class and invalidating one cascades suspect across its blast radius. Unbounded generation yields a bounded, ranked review queue instead of silent sprawl.

The build contract is the throughline spec in docs/referenced-resource/ (docs 04 system requirements, 06 data format, 07 architecture).

New here? HOW_TO_USE.md is a fifteen-minute hands-on quick start: scaffold a project, add three linked requirements, watch the validator reject an ungrounded graph, fix it, and trace a requirement back to its reason for existing. Curious how the workflow relates to test-first practice? HOW_IDD_DIFFERS_FROM_BDD.md explains Intent-Driven Development and why it is the why axis to BDD's what.


Install

throughline is pure Python (one dependency, pyyaml) and needs Python >= 3.11 (for the stdlib tomllib). The same steps work on Linux, macOS, and Windows — only how you obtain Python and put scripts on PATH differs.

Recommended — pipx (installs the CLI in its own isolated environment):

pipx install throughline

Prefer the bleeding edge? Install straight from Git instead: pipx install "git+https://github.com/rhodium-org/throughline.git"

Per-OS notes:

  • Linux — system Python is often "externally managed" (PEP 668); don't pip install into it. Use pipx (sudo apt install pipx / pacman -S python-pipx) or a virtual environment.
  • macOSbrew install python pipx && pipx ensurepath, then install as above.
  • Windows — install Python 3.12 from python.org or winget install Python.Python.3.12 (tick Add to PATH), then python -m pip install --user pipx && pipx ensurepath. Both tl.exe and throughline.exe are generated.

Either way you get tl (and the long form throughline) on your PATH. For a local checkout you can develop against, see CONTRIBUTING.md.

Or run it containerised, no local Python at all:

docker build -t throughline .
docker run --rm -v "$PWD/my-project:/work" throughline -C /work check --strict

The format

A project is a directory: throughline.toml (config) + per-document folders, each with a .document.yml manifest and one <UID>.yml per item.

uid: FR-0022                 # permanent, immutable, never reused
type: requirement
status: approved
title: Guided setup wizard
text: The system shall walk new users through a 3-step setup.
normative: true
links:
  - target: BN-0003          # this requirement derives from a business need
    type: derives_from
  - target: ASM-0002         # …and depends on an assumption's validity
    type: assumes
    stamp: sha256:…          # target fingerprint when last confirmed (suspect tracking)

Roots (intent, business_need, risk, constraint, assumption) may exist ungrounded — they are the roots of "why". Everything else must reach a root through a grounding link (derives_from, mitigates, implements, verifies), which together form a DAG — circular justification is rejected.


CLI

tl init [--name NAME]                         # scaffold a project
tl doc new <PREFIX> <dir> [--parent P]        # add a document
tl new <PREFIX> [--uid U] [--type T] [--ground UID]  # allocate + create (grounded at birth)
tl link <SRC> <DST> --type <kind> [--stamp]   # add a typed link
throughline delete <UID> --reason "…"                  # tombstone (never erased)
throughline review [<UID> | --all-clean]               # mark reviewed at current content
tl check [--strict] [--format json]           # validate the graph — the CI gate
tl trace <UID> [--direction in|out] [--depth N]
tl blast <UID> [--format json]                # everything depending on an item
tl shape [--format json]                      # observed (from)-[link]->(to) triples
tl diagram [types|transitions|both]           # Mermaid of the model / lifecycle
tl docs [--doc PREFIX] [--at REF]             # render a Markdown requirements document
tl context                                    # agent-facing brief (IDD + this project's model)
tl ratify <UID> --by <who>                    # a human takes accountability
throughline invalidate <UID> --reason "…"              # falsify; cascade suspect

Exit codes are a stable contract: 0 ok · 1 findings at error severity · 2 usage/internal error. So tl check drops straight into a pre-commit hook or CI gate — an ungrounded, unserved, or otherwise invalid graph fails the build.

What check enforces

Upward and downward coverage are independent and both matter:

Rule Meaning
orphan a non-root item with no grounding chain to a root
unserved-root a delivery root nobody derives from / mitigates
grounding-cycle circular justification
dangling-link / deleted-link-target link to a missing/tombstoned item
uid-grammar / uid-collision malformed UID, or one UID in two places (merge)
tombstone-deleted a retired UID's tombstone was erased (bad merge / stray git rm)
schema missing required attr or out-of-enum value
suspect-link target changed since the link was last confirmed
unreviewed item content changed since last review
unratified AI-origin item still proposed
ambiguous flagged ambiguous — blocked from ratification
coverage a declared [[rules.coverage]] link requirement is unmet

Every rule's severity is configurable per project under [rules]; --strict promotes every warning to an error for CI.


Try it

The examples/grounding-demo/ project is a small, fully grounded graph (intents, a business need, a risk, a constraint, an assumption, requirements, an NFR, and verifying tests):

tl -C examples/grounding-demo check --strict     # green, exit 0
tl -C examples/grounding-demo trace FR-0055      # walk its justification tree
tl -C examples/grounding-demo blast ASM-0002     # what a bad assumption would take down

Self-hosting — throughline's own requirements

throughline manages its own spec. The requirements/ project is throughline's vision, goals, user requirements, system requirements, and NFRs seeded as throughline items, with the full grounding chain wired up (SR/NFR --implements--> UR --derives_from--> goal --derives_from--> vision):

tl -C requirements check --strict     # green, exit 0 — the tool gates its own scope
tl -C requirements trace SR-0001      # walk a system requirement up to the vision

This is the discipline the tool exists to provide, applied to the tool itself: a new system requirement that doesn't justify itself against a user requirement — or a user requirement that doesn't derive from a goal — fails the build. Both the demo and the self-host graph are gated in CI and by the pre-commit hook.


Grounding operations

  • ratify — a human takes accountability. Refused for ambiguous or ungrounded items: the two states that must never be signed off.
  • invalidate — falsify an assumption (or any node): it is rejected and every transitive dependent is marked suspect (its blast radius).

Testing & gates

pytest -q                                    # model, UID, fingerprint, validate, grounding
tl -C examples/grounding-demo check --strict   # the demo graph gate (exit 1 = broken)
tl -C requirements check --strict              # throughline's own requirements (self-host gate)
  • .pre-commit-config.yaml runs the gate on commits touching either project (demo and self-host). Enable with pre-commit install.
  • .github/workflows/ci.yml runs the tests, both grounding gates, and a Docker build + image smoke-test on push/PR.

What this is

M0 — Core: UID model, one-file-per-item storage, typed links, fingerprints/suspect, the validation pipeline, the grounding layer, and the tl CLI. Not included: baselines/diff, HTML/PDF publish, and CSV/ReqIF import-export. Assumption items carry provenance attributes (attrs.owner / attrs.last_validated / attrs.confidence) alongside their content.

throughline is early software (alpha) and unfinished by design — see ROADMAP.md for what's built, what's next, and where help is most useful.


Contributing

Contributions are welcome. CONTRIBUTING.md gets you to a checked development environment; ROADMAP.md lists good first work; all participation is under the Code of Conduct. To report a vulnerability, see SECURITY.md.

License

Copyright © 2026 Time Back Solutions Limited. Released under the Apache License 2.0 — see LICENSE and NOTICE. Provenance and prior-art are recorded in PROVENANCE.md.

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

throughline-0.1.3.tar.gz (53.3 kB view details)

Uploaded Source

Built Distribution

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

throughline-0.1.3-py3-none-any.whl (44.6 kB view details)

Uploaded Python 3

File details

Details for the file throughline-0.1.3.tar.gz.

File metadata

  • Download URL: throughline-0.1.3.tar.gz
  • Upload date:
  • Size: 53.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for throughline-0.1.3.tar.gz
Algorithm Hash digest
SHA256 30c95e3f61d3b3de68d1166ac601a25476ca7c862d63f5cf68d730dfae15798c
MD5 583a052a5989959c5d238cd3d8d4db20
BLAKE2b-256 363863d0a0fd5d781279ca8b68791cee3327e9f84fa8e45c9a325a4f2717ec25

See more details on using hashes here.

Provenance

The following attestation bundles were made for throughline-0.1.3.tar.gz:

Publisher: release.yml on rhodium-org/throughline

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file throughline-0.1.3-py3-none-any.whl.

File metadata

  • Download URL: throughline-0.1.3-py3-none-any.whl
  • Upload date:
  • Size: 44.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for throughline-0.1.3-py3-none-any.whl
Algorithm Hash digest
SHA256 5e32f16b4ef6eb5435c53a26b8581c90a6b8ae43a2c9428487e4b7eff9ed3267
MD5 a8e98c0596eedab1983baa4adf34134c
BLAKE2b-256 96b0029fa02ad0671b32bdf6c8ee667397f680d93a1e8aa297afc5834e567595

See more details on using hashes here.

Provenance

The following attestation bundles were made for throughline-0.1.3-py3-none-any.whl:

Publisher: release.yml on rhodium-org/throughline

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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