How it Works

This page covers the internal architecture of the reqstool client. For general concepts like annotations, parsing, and validation, see Concepts. For detailed architectural decisions, see the DESIGN.md in the repository.

Pipeline overview

Location → parse → RawDataset → INSERT into SQLite → Repository/Services → Command output

Each command calls build_database() which:

  1. Parses all sources into the in-memory SQLite database (two-phase traversal, see below)

  2. Applies filters (DatabaseFilterProcessor) — removes out-of-scope requirements and applies user-defined filters: blocks

  3. Runs lifecycle validation (warns on DEPRECATED/OBSOLETE references)

  4. Commands then query via RequirementsRepository and service layer

Two-phase graph traversal

The requirement graph is a directed graph of URNs connected by two edge types:

  • import — "I reference requirements from this URN" (upward, toward requirement definitions)

  • implementation — "this URN provides evidence for my requirements" (downward, toward code/tests)

CombinedRawDatasetsGenerator traverses this graph in two phases:

Phase 1 — import chain (recursive DFS, full insert)

Follows imports: sections recursively, depth-first. For each node, all five data types are fully inserted into SQLite: requirements, SVCs, MVRs, annotations, and test results. Cycle detection raises CircularImportError.

Phase 2 — implementation chain (recursive, metadata-only insert)

Follows implementations: sections recursively. Think library-uses-library — lib-a can itself have implementations (lib-b → lib-c), all of which may contribute test evidence for the initial URN’s requirements.

For each implementation node, requirements.yml is parsed (validation runs) but only the URN metadata is inserted — the requirement rows are excluded. All other files (SVCs, MVRs, annotations, test results) are inserted normally; SQLite FK constraints automatically discard rows that reference requirements outside the current scope. Cycle detection raises CircularImplementationError.

imports: sections of implementation nodes are not followed — an implementation’s own imports belong to a different scope.

The variant field

variant: system/microservice/external in requirements.yml is optional advisory metadata. It is not a behavioral gate — parsing is entirely presence-based. If a file exists, it is read. If a section exists in YAML, it is parsed.

Overview of central components

Diagram

Sequence diagram

Below illustrates how reqstool processes the status command against an initial source that imports a parent system.

Diagram