Skip to content

How to add a new requirement

This is the canonical journey of a new regulated requirement, from someone identifying a need to it being permanently baselined in the project’s regulatory record.

Step 1 — Pick the tier, then author the requirement

Section titled “Step 1 — Pick the tier, then author the requirement”

The requirements graph has three tiers. Pick the right one before writing the item:

  • regulatory-docs/10_system.sdoc (SYS-) — device-level / stakeholder commitments. “The device shall…”
  • regulatory-docs/11_srs.sdoc (SRS-) — software-level requirements. “The software shall…”
  • regulatory-docs/20_architecture.sdoc (ARCH-) — software architecture (subsystems, interfaces, SOUP, segregation). Structural, not behavioural.

If a stakeholder commitment refines into a software requirement which in turn pulls in an architectural element, you may end up authoring one item in each tier, linked upward via derivedFrom. The tier-selection decision tree and TYPE vocabularies are in the strictdoc-requirements skill file §2.1–§2.5 — don’t duplicate them here, that’s the canonical source.

Add a [REQUIREMENT] block to the chosen .sdoc file following the grammar declared at the top of that file. The required fields on every tier are UID, TITLE, STATEMENT, TYPE, and STATUS (the lifecycle — Draft while you are still writing it, InReview once a PR is open, Approved after review, Obsolete when retired; Draft and Obsolete items are held outside the regulated checks). Most regulated requirements also want RATIONALE. Type- and tier-specific mandatory fields apply (e.g., RISK_CONTROL_REF + HARM_IF_ABSENT for safety; SOUP_VERSION for ARCH TYPE: soup; SAFETY_CLASS for ARCH TYPE: subsystem or segregation).

A minimal new requirement looks like:

[REQUIREMENT]
UID: SRS-006
TITLE: New requirement title
STATEMENT: >>>
What the system shall do, in one sentence.
<<<
TYPE: functional
RATIONALE: >>>
Why this requirement exists.
<<<
STATUS: Draft
NOTES: >>>
coverage-plan: IT item describing the integration test that will verify this.
<<<

Leave REVIEWED_HASH, REVIEWED_BY, and QMS_REVIEW_DATE empty. They are stamped automatically — see Step 5.

Step 2 — Author the verifying test specification

Section titled “Step 2 — Author the verifying test specification”

Every regulated requirement must have at least one verifying test or carry a coverage-plan: marker in NOTES for tests that don’t exist yet. To keep the chain closed, prefer adding the test in the same PR as the requirement.

Add a [REQUIREMENT] block to the appropriate regulatory-docs/*.sdoc file (UT for unit, IT for integration, ST for system). Link it back to the SRS item via:

RELATIONS:
- TYPE: Parent
VALUE: SRS-006
ROLE: verifies

Each test type has a slightly different field set — see the skill file §3.2 for the per-type grammar.

For Dart tests, add a file under test/integration/ or test/unit/ and tag the test with the StrictDoc UID:

test('IT-005: <description>', () { /* ... */ }, tags: ['IT-005']);

For VisionTrace ST tests, record the workflow with visiontrace-record and decorate the generated test with:

@visiontrace_test_case("ST-005")
def test_st_005_local_clinic_visible_in_patients_menu(agent, app_session):
# ...

The UID in the test’s name (and the tags= / decorator) is what the post-processor uses to join the test’s pass/fail to the StrictDoc spec.

Terminal window
git add regulatory-docs/11_srs.sdoc regulatory-docs/31_integration_tests.sdoc test/integration/<new-test>.dart
# (or regulatory-docs/10_system.sdoc / regulatory-docs/20_architecture.sdoc — whichever tier you authored)
git commit -m "feat(srs): add SRS-006 + IT-005 verification"
git push -u origin <branch>
gh pr create --title "Add SRS-006 + IT-005" --body "..."

The PR pipeline runs automatically. Watch the four jobs — all four must turn green for the PR to be mergeable.

The post-processor’s --fail-on-suspect step is the regulated gate: it fails the build if any baselined requirement has drifted without a covering change record. Adding a new requirement is not drift — it’s a new entry — so this should pass cleanly for new SRS items.

Per .github/CODEOWNERS, the qualified medical-device reviewer (@DougYoungberg for BioFlow) is auto-requested as reviewer. They review the requirement text, the verifying test, and the test implementation, and approve.

Branch protection enforces:

  • All four PR pipeline jobs are green
  • The code owner has approved
  • No new commits have been pushed since their approval (dismiss-stale rule)

Click Merge.

On merge, the auto-stamp Action fires:

  1. Reads the PR’s approver list, finds @DougYoungberg
  2. Validates against .github/CODEOWNERS — yes, they own regulatory-docs/**
  3. Computes the SHA-256 of the new SRS-006 (and IT-005, ST-005 if added) using the same hash function the post-processor uses for drift detection
  4. Writes REVIEWED_HASH: <hex> and REVIEWED_BY: @DougYoungberg into each touched .sdoc file
  5. Pushes the stamping commit to main as bioflow-autostamp[bot] with a Co-authored-by: DougYoungberg trailer

From this moment, SRS-006 is baselined: any future PR that edits its content without a covering change record will be flagged suspect-native by the post-processor and will be blocked at the --fail-on-suspect gate.

FailureDiagnosis + fix
StrictDoc export fails on a CI jobThe .sdoc file has a grammar error. Run uv run strictdoc export regulatory-docs/ locally to see the exact error message
--fail-on-suspect blocks mergeEither you’ve drifted an existing requirement without a change record, or a typed-link parent has drifted. Run uv run python -m tools.post_processor.rtm locally and inspect the RTM badges
Code owner approval requested but no one is availableAdd a backup reviewer to CODEOWNERS — see the CODEOWNERS playbook
Auto-stamp Action fails post-mergeThe PR is already merged but REVIEWED_HASH wasn’t written. The next CI run will show the requirement as unreviewed. Re-run via Actions → Auto-stamp → Run workflow → <PR number>