Skip to main content

MedHarness

Design-control checks for software teams — traceability, verification, SOUP and releases, as CI gates.

PyPI License: MIT Python 3.11+

MedHarness keeps a Design History File (DHF) as plain YAML in your repository and checks it with ordinary code: does every requirement trace to its parent, is each one verified the way it says, does the SOUP register match what ships. Each check is a command that answers in JSON with an exit code, so it drops into any CI. An optional AI workflow drafts the design and the code for a change request; the checks never ask a model.

Quick start

pip install medharness
mkdir my-device && cd my-device
medharness init            # writes DHF/ with sample items, and CLAUDE.md
medharness verify dhf      # does the design hold together?

Replace the sample items with your own, then add the checks to CI.

What it checks

Command The question it answers
verify dhf Does the V-model hold together — schema, required links, dangling links, cycles, coverage?
verify tests Is each requirement verified by the method it declares — a Test requirement by a passing test?
verify soup Is the SOUP register what actually ships, and is any of it known-vulnerable?
verify completion Did a change request deliver what it proposed, verified?
workflow check-changes Did the branch change the items its change request said it would?
workflow check-approval Did a reviewer approve the exact commit being merged?
$ medharness verify dhf
FAIL [cycle] SRS-014 → SYS-006 → SRS-014
FAIL [required] SRS-022: SRS derives_from → SYS (count=0, need ≥1)
WARN [coverage] RISK→RCM: 3/4 covered

Broken structure — a cycle, a missing required link, a link to nothing — always fails. Design not yet written — an item with no child yet — only warns, unless you pass --fail-on-uncovered.

What a project looks like

my-device/
├── DHF/
│   ├── config/global.yaml       # the project name — and only what you change
│   └── items/                   # one YAML file per item, one directory per type
│       ├── 01_crs/CRS-001.yaml
│       ├── 03_srs/SRS-001.yaml
│       └── …                    # UC SYS SYSARCH MODULE SWDD RISK RCM SOUP CR DEF REL
└── CLAUDE.md                    # product context, read by the AI stages

The 13 item types, their lifecycles, which links are required, and the specification templates are defaults inside the package, so a project gets their improvements by upgrading medharness. To change one, override it:

To change Do this
A setting, e.g. which links are required Set its key in global.yaml — it replaces the default key
An item type's fields Put DHF/config/doc_types/<type>.yaml — it replaces the default type of that code
A new item type Add a file there with a new code
A type you don't use omit_doc_types: [UC] in global.yaml
A specification template Put a file of the same name in DHF/documents/specs/

The defaults are in dhfkit/templates/config and dhfkit/templates/specs.

An item is a small YAML file. Links are written on the child and point up:

id: SRS-012
title: Password must be at least 12 characters
derives_from: [SYS-004]
verification_method: [Test]
testing: |
  T1: an 11-character password is rejected

Fitting it into what you already have

  • Tests. Any runner that writes JUnit XML. Tag each test case with the requirement it verifies — the medharness.links property, or @links:SRS-012 in the test name. In pytest: @pytest.mark.dhf_links("SRS-012").

  • CI. Every check prints JSON to stdout and exits 0 pass, 1 fail. The smallest useful pipeline is two steps in a job that checks out the repository:

    - run: pip install medharness==0.38.0
    - run: medharness verify dhf --fail-on-uncovered
    

    The full recipe, including the release job, is in adopting.md.

  • Requirements kept elsewhere. MedHarness reads the item files under DHF/items/. To check requirements that live in another tool, export them into that format — one YAML file per item — and run the same commands. The format is specified in interface.md.

  • No AI. Nothing above needs a model. The AI workflow below is opt-in.

The AI change workflow (optional)

flowchart LR
    CR["CR opened"] --> PLAN["build plan<br/>AI drafts the design"]
    PLAN --> REV{"Human review"}
    REV -.->|rejected| PLAN
    REV -->|approved| CODE["build code<br/>AI writes code and tests"]
    CODE --> GATES["verify *<br/>ordinary code decides"]
    GATES -.->|fails| CODE
    GATES ==>|passes| MERGE["merge"]
    MERGE -.->|"tag v*"| REL["build release"]

build plan and build code run the claude CLI by default (npm install -g @anthropic-ai/claude-code), or any MEDHARNESS_{DESIGN,DESIGN_REVIEW,DEVELOP,CODE_REVIEW}_MODEL=provider:model (anthropic, openai, deepseek; MEDHARNESS_{STAGE}_BASE_URL for Azure, Ollama or vLLM). They run an agent with a shell, so run them on an ephemeral CI runner — read ai-security.md first.

Commands

Two CLIs from one package: medharness runs the checks and the workflow; dhfkit stores and reads the items. Both take --dhf PATH before the command, defaulting to DHF. Every command writes JSON to stdout and readable lines to stderr; --help on any of them lists its options.

verify — reads the DHF only

Command Returns
medharness verify dhf gate result¹
medharness verify tests --junit-dir test-results gate result
medharness verify soup gate result
medharness verify completion --cr CR-034 gate result

workflow — needs Git or GitHub; CI helpers

Command What it does Returns
medharness workflow check-changes --cr CR-034 Compares the branch diff with the CR's affected_items gate result
medharness workflow check-approval --cr CR-034 --pr 42 Requires an approving review of the PR's head commit; needs GH_TOKEN gate result
medharness workflow github-event Reads a GitHub event: which CR and stage, and what to do next. Not a gate cr_id, stage, action, mode, pr_number

¹ Every gate answers {gate, passed, summary, errors, warnings}; see interface.md.

build — writes items, code or artifacts

Command What it does Returns
medharness build plan --cr CR-034 AI drafts the CR's design items and impact analysis outcome, items_changed, review_cycles
medharness build code --cr CR-034 AI writes the code and tests for the approved design outcome, files_changed, review_cycles
medharness build dhf --write Reconciles SOUP items with your dependency manifests; without --write, only reports to_create, to_update, orphans
medharness build release --version 1.0.0 --out-dir release --write Checks the DHF, CRs and open defects, writes the baseline, BOM, SBOM and evidence, and — only if every check passed — records the REL item outcome, cr_ids, rel_uid, artifacts, errors

context — what an AI agent reads

Command Returns
medharness context --cr CR-034 Without --cr: every item summarized, and the traceability verdict. With it: the CR, the items it affects in full and the modules that own them — or every item, if the CR has not recorded what it affects yet. --junit-dir adds test coverage

Setup

Command What it does Returns
medharness init Scaffolds DHF/ and CLAUDE.md in the current directory; refuses if DHF/ exists project_name, created
medharness doctor Checks Python, the CLIs, gh auth, and the DHF checks, healthy

dhfkit — the items

Command What it does Returns
dhfkit item list --type SYS Lists items of a type one JSON object per line
dhfkit item get SRS-012 One item, with its links resolved the item
dhfkit item create --type SRS --data '{...}' Adds an item; its ID is allocated the item
dhfkit item update SRS-012 --data '{...}' Merges fields into an item the item
dhfkit item transition CR-034 completed Moves an item through its lifecycle; without a state, lists where it can go the item
dhfkit validate Checks every item against its type's schema, and that no two files claim one ID valid, errors, item_count
dhfkit doc SRS --format html Renders a specification from the items — md by default, html or pdf (needs medharness[docs]); ALL for every type md_path, plus html_path or pdf_path
dhfkit sbom CycloneDX 1.6 SBOM from the SOUP register path, components
dhfkit init A bare DHF, without CLAUDE.md created

Example project

ContourLab is an example project used to exercise MedHarness end to end: its DHF, its CI, and changes made through the AI workflow.

Documentation

adopting.md starting fresh, the CI recipe, bringing an existing DHF, releases
interface.md the gate result, exit codes, what may change
ai-security.md what the AI stages can do, and running without them
architecture.md how the code is organised
CHANGELOG.md version history

License

MIT. See LICENSE.

Metadata

Release files for medharness 0.38.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for medharness 0.38.0
File Size Uploaded
medharness-0.38.0.tar.gz 162.5 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for medharness 0.38.0
File Interpreter ABI Platform
medharness-0.38.0-py3-none-any.whl Python 3 none any Details

Total release size: 365.5 kB

Release files / medharness-0.38.0.tar.gz

Download URL medharness-0.38.0.tar.gz
Size 162.5 kB
Tags Source
SHA-256 checksum
How to use checksums
5b40a1c4ba4533adeadadf960e82ee3d80391927421045ca629f334e38091430
BLAKE2b-256 checksum
How to use checksums
97179039144be5b73478a82f312ee14cf957ac5eaa954dfb5b7185f62ada3724
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 27, 2026.

Transparency log

Release files / medharness-0.38.0-py3-none-any.whl

Download URL medharness-0.38.0-py3-none-any.whl
Size 203.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
c007663a9a13116fd30fd2178754ac29239b4357d0d17720d5a3837333207838
BLAKE2b-256 checksum
How to use checksums
4a9c019194ce94a78898d26b89685f6d2a373e969d91e565b1704f80ed219eee
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 27, 2026.

Transparency log

Release history Release notifications | RSS feed

0.48.0

2 release files

0.47.0

2 release files

0.46.2

2 release files

0.46.1

2 release files

0.46.0

2 release files

0.45.0

2 release files

0.44.0

2 release files

0.43.2

2 release files

0.43.1

2 release files

0.43.0

2 release files

0.42.0

2 release files

0.41.0

2 release files

0.40.0

2 release files

0.39.0

2 release files

0.38.1

2 release files

This release

0.38.0 This release

2 release files

0.37.0

2 release files

0.36.1

2 release files

0.36.0

2 release files

0.35.0

2 release files

0.34.0

2 release files

0.33.1

2 release files

0.33.0

2 release files

0.32.0

2 release files

0.31.0

2 release files

0.30.0

2 release files

0.29.1

2 release files

0.29.0

2 release files

0.28.0

2 release files

0.27.0

2 release files

0.26.3

2 release files

0.26.2

2 release files

0.26.1

2 release files

0.26.0

2 release files

0.25.0

2 release files

0.24.0

2 release files

0.23.0

2 release files

0.22.0

2 release files

0.21.0

2 release files

0.13.0

2 release files

0.12.1

2 release files

0.12.0

2 release files

0.11.0

2 release files

0.10.0

2 release files

0.9.0

2 release files

0.8.0

2 release files

0.7.0

2 release files

0.6.4

2 release files

0.6.3

2 release files

0.6.2

2 release files

0.6.1

2 release files

0.6.0

2 release files

0.5.0

2 release files

0.4.0

2 release files

0.3.8

2 release files

0.3.7

2 release files

0.3.6

2 release files

0.3.5

2 release files

0.3.4

2 release files

0.3.3

2 release files

0.3.1

2 release files

0.3.0

2 release files

0.2.1

2 release files

0.2.0

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page