Core Models#

Data models for requirements items, test links, coverage, and the traceability graph.

Item#

class jamb.core.models.Item[source]#

Represents a requirements item (requirement, info, heading, etc.).

uid#

Unique identifier for the item (e.g. REQ001).

Type:

str

text#

Body text of the requirement.

Type:

str

document_prefix#

Prefix of the document this item belongs to.

Type:

str

active#

Whether the item is active. Inactive items are ignored during validation and coverage checks.

Type:

bool

type#

Item type.

Type:

Literal[“requirement”, “info”, “heading”]

header#

Optional heading text displayed instead of body text.

Type:

str | None

UIDs of parent items this item traces to.

Type:

list[str]

reviewed#

Content hash recorded when the item was last reviewed, or None if never reviewed.

Type:

str | None

derived#

Whether the item is derived (intentionally has no parent links).

Type:

bool

testable#

Whether the item can be verified by testing. If False, the item shows “N/A” instead of “NOT COVERED” in the matrix.

Type:

bool

custom_attributes#

Arbitrary user-defined key-value pairs.

Type:

dict[str, Any]

Construct an item and access its display text::

    >>> item = Item(
    ...     uid="SRS001",
    ...     text="The system shall log in users.",
    ...     document_prefix="SRS",
    ... )
    >>> item.uid
    'SRS001'
    >>> item.display_text
    'The system shall log in users.'

An item with a header uses the header as display text::

    >>> item = Item(
    ...     uid="SRS002",
    ...     text="Details...",
    ...     document_prefix="SRS",
    ...     header="Login",
    ... )
    >>> item.display_text
    'Login'
property display_text: str#

Return header if present, otherwise truncated text.

Truncation is safe for multi-byte UTF-8 characters since Python strings are Unicode codepoint sequences, not byte sequences.

property full_display_text: str#

Return ‘header - text’ if header present, otherwise just text.

Used for full chain matrices where both header and text are desired.

__init__(uid, text, document_prefix, active=True, type='requirement', header=None, links=<factory>, reviewed=None, derived=False, testable=True, custom_attributes=<factory>)#
Parameters:
Return type:

None

LinkedTest#

class jamb.core.models.LinkedTest[source]#

Represents a link from a pytest test to a requirements item.

test_nodeid#

The pytest node ID of the test (e.g. tests/test_foo.py::test_bar).

Type:

str

item_uid#

UID of the requirements item the test covers.

Type:

str

test_outcome#

Result of the test — "passed", "failed", "skipped", or "error". None before execution.

Type:

str | None

notes#

Free-form notes captured during test execution.

Type:

list[str]

test_actions#

Steps performed by the test.

Type:

list[str]

expected_results#

Expected outcomes for each test action.

Type:

list[str]

actual_results#

Actual outcomes observed during test execution.

Type:

list[str]

execution_timestamp#

ISO 8601 UTC timestamp of test execution.

Type:

str | None

__init__(test_nodeid, item_uid, test_outcome=None, notes=<factory>, test_actions=<factory>, expected_results=<factory>, actual_results=<factory>, execution_timestamp=None)#
Parameters:
  • test_nodeid (str)

  • item_uid (str)

  • test_outcome (Literal['passed', 'failed', 'skipped', 'error'] | None)

  • notes (list[str])

  • test_actions (list[str])

  • expected_results (list[str])

  • actual_results (list[str])

  • execution_timestamp (str | None)

Return type:

None

ItemCoverage#

class jamb.core.models.ItemCoverage[source]#

Coverage status for a single requirements item.

item#

The requirements item being tracked.

Type:

Item

linked_tests#

Tests linked to this item via requirement markers.

Type:

list[LinkedTest]

property is_covered: bool#

Return True if at least one test links to this item.

property all_tests_passed: bool#

Return True if all linked tests passed.

Returns False if there are no linked tests, since an item with no tests cannot be considered to have “all tests passing”. This is intentional - use is_covered to check if tests exist.

__init__(item, linked_tests=<factory>)#
Parameters:
Return type:

None

TraceabilityGraph#

class jamb.core.models.TraceabilityGraph[source]#

Graph representing the full traceability hierarchy.

Stores items by UID and tracks parent-child relationships based on document hierarchy and item links.

items#

Mapping of item UID to Item instance.

Type:

dict[str, Item]

item_parents#

Mapping of item UID to list of parent item UIDs (derived from each item’s links field).

Type:

dict[str, list[str]]

item_children#

Reverse index mapping item UID to list of child item UIDs that link to it.

Type:

dict[str, list[str]]

document_parents#

Mapping of document prefix to list of parent document prefixes (the document-level DAG).

Type:

dict[str, list[str]]

Build a graph and add linked items::

    >>> graph = TraceabilityGraph()
    >>> graph.set_document_parents("SRS", ["SYS"])
    >>> graph.set_document_parents("SYS", [])
    >>> sys_item = Item(uid="SYS001", text="System req", document_prefix="SYS")
    >>> srs_item = Item(
    ...     uid="SRS001",
    ...     text="Software req",
    ...     document_prefix="SRS",
    ...     links=["SYS001"],
    ... )
    >>> graph.add_item(sys_item)
    >>> graph.add_item(srs_item)
    >>> graph.item_children["SYS001"]
    ['SRS001']
add_item(item)[source]#

Add an item to the graph.

Parameters:

item (Item) – The Item to add. Its links are used to populate the parent and child reverse-index maps.

Raises:

ValueError – If the item links to itself (self-loop).

Return type:

None

set_document_parent(prefix, parent_prefix)[source]#

Set a single parent document, replacing any existing parents.

Backward-compatible wrapper for single-parent hierarchies. For DAG support with multiple parents, use set_document_parents().

Parameters:
  • prefix (str) – The document prefix to set the parent for.

  • parent_prefix (str | None) – The parent document prefix, or None to clear.

Return type:

None

set_document_parents(prefix, parents)[source]#

Replace all parent documents with the given list.

Use this when you need to set the complete list of parents at once. Existing parents are replaced, not merged.

Parameters:
  • prefix (str) – The document prefix to set parents for.

  • parents (list[str]) – List of parent document prefixes.

Return type:

None

add_document_parent(prefix, parent)[source]#

Add a parent document without removing existing parents.

Use this when building the graph incrementally. No-op if the parent already exists for this prefix.

Parameters:
  • prefix (str) – The document prefix to add a parent to.

  • parent (str) – The parent document prefix to add.

Return type:

None

get_ancestors(uid)[source]#

Get all ancestor items by following links upward.

Returns items in order from immediate parent to root.

Return type:

list[Item]

Parameters:

uid (str)

get_descendants(uid)[source]#

Get all descendant items by following children downward.

Returns items in BFS order from immediate children to leaves.

Return type:

list[Item]

Parameters:

uid (str)

get_neighbors(uid)[source]#

Get all neighbor items: ancestors + descendants + self.

Returns the item itself plus all items connected to it through the traceability hierarchy.

Return type:

list[Item]

Parameters:

uid (str)

get_children_from_document(uid, prefix)[source]#

Get children of uid that belong to the given document.

Parameters:
  • uid (str) – The parent item UID.

  • prefix (str) – The document prefix to filter children by.

Returns:

list[Item] – List of child Item objects in the specified document.

Return type:

list[Item]

get_parents_from_document(uid, prefix)[source]#

Get parents of uid that belong to the given document.

Parameters:
  • uid (str) – The child item UID.

  • prefix (str) – The document prefix to filter parents by.

Returns:

list[Item] – List of parent Item objects in the specified document.

Return type:

list[Item]

get_items_by_document(prefix)[source]#

Get all items belonging to a specific document.

Parameters:

prefix (str) – The document prefix to filter by.

Returns:

list[Item] – List of Item objects with the given document prefix.

Return type:

list[Item]

get_root_documents()[source]#

Get document prefixes that have no parents.

Returns:

list[str] – List of document prefix strings with no parent documents.

Return type:

list[str]

get_leaf_documents()[source]#

Get document prefixes that are not parents of any other document.

Returns:

list[str] – List of document prefix strings that have no child documents.

Return type:

list[str]

get_document_children(prefix)[source]#

Get child document prefixes for a document.

Parameters:

prefix (str) – The document prefix to find children for.

Returns:

list[str] – List of document prefix strings that have this document as a parent.

Return type:

list[str]

__init__(items=<factory>, item_parents=<factory>, item_children=<factory>, document_parents=<factory>)#
Parameters:
Return type:

None

JambError#

class jamb.core.errors.JambError[source]#

Base exception for all expected jamb errors.