Storage#
Native file-based storage layer for requirements documents and items.
Document DAG#
- class jamb.storage.document_dag.DocumentDAG[source]#
Directed acyclic graph of document relationships.
Supports multiple parents per document (DAG structure).
- documents#
Mapping of document prefix to its
DocumentConfig.- Type:
- document_paths#
Mapping of document prefix to the filesystem path of the document directory.
- topological_sort()[source]#
Return prefixes in topological order (parents before children).
Uses Kahn’s algorithm. If there are cycles, remaining nodes are appended at the end.
- Raises:
ValueError – If any document references unknown parent documents.
- Return type:
Document Configuration#
- class jamb.storage.document_config.DocumentConfig[source]#
Configuration for a requirements document.
- jamb.storage.document_config.load_document_config(path)[source]#
Load document config from a .jamb.yml file.
- Parameters:
path (
Path) – Path to the config file (.jamb.yml).- Returns:
DocumentConfig– DocumentConfig parsed from the file.- Raises:
ValueError – If the config file is missing required fields.
- Return type:
- jamb.storage.document_config.save_document_config(config, directory)[source]#
Save document config as .jamb.yml in the given directory.
- Parameters:
config (
DocumentConfig) – The document configuration to save.directory (
Path) – The directory to write .jamb.yml into.
- Return type:
Discovery#
- jamb.storage.discovery.discover_documents(root=None)[source]#
Walk filesystem for .jamb.yml files and build a DAG.
- Parameters:
root (
Path|None) – Root directory to search. Defaults to current working directory.- Returns:
DocumentDAG– DocumentDAG containing all discovered documents.- Raises:
FileNotFoundError – If root directory does not exist.
- Return type:
Graph Builder#
- jamb.storage.graph_builder.build_traceability_graph(dag, document_prefixes=None, include_inactive=False, exclude_patterns=None)[source]#
Build a TraceabilityGraph from the native storage layer.
- Parameters:
dag (
DocumentDAG) – The document DAG with discovered documents.document_prefixes (
list[str] |None) – Optional list of prefixes to include. If None, includes all documents.include_inactive (
bool) – Whether to include inactive items.exclude_patterns (
list[str] |None) – Optional glob patterns to exclude documents (by prefix) and items (by UID) from the graph.
- Returns:
TraceabilityGraph– TraceabilityGraph populated with items and document relationships.- Return type:
Items#
- jamb.storage.items.read_item(path, document_prefix)[source]#
Read an item YAML file and return a normalized dict.
- Parameters:
- Returns:
uid, text, document_prefix, active, type, header, links, link_hashes, reviewed, derived, testable, custom_attributes.
- Return type:
Dict with keys
- Raises:
OSError – If the file cannot be read.
ValueError – If the file contains invalid YAML or has an empty UID.
- jamb.storage.items.read_document_items(doc_path, prefix, include_inactive=False, sep='')[source]#
Read all item YAML files from a document directory.
- Parameters:
- Returns:
- Raises:
ValueError – If the prefix pattern is invalid.
- Return type:
- jamb.storage.items.compute_content_hash(item_data)[source]#
Compute a SHA-256 hash of item content for review/suspect detection.
Hashes: text, header, links, type. All strings are normalized to NFC Unicode form for consistent hashing across platforms.
- jamb.storage.items.write_item(item_data, path, extra_fields=None)[source]#
Write an item as a YAML file.
- jamb.storage.items.next_uid(prefix, digits, existing_uids, sep='')[source]#
Generate the next available UID for a document.
- Parameters:
- Returns:
str– Next available UID string.- Raises:
ValueError – If digits < 1 or if the prefix pattern is invalid.
- Return type:
Validation#
- jamb.storage.validation.validate(dag, graph, *, check_links=True, check_suspect=True, check_review=True, check_children=True, check_empty_docs=True, check_empty_text=True, check_self_links=True, check_item_cycles=True, check_unlinked=True, skip_prefixes=None)[source]#
Run validation checks on the document tree.
- Parameters:
dag (
DocumentDAG) – The document DAG.graph (
TraceabilityGraph) – The traceability graph with items.check_links (
bool) – Check link validity and conformance.check_suspect (
bool) – Check for suspect links (hash mismatch).check_review (
bool) – Check review status.check_children (
bool) – Check that non-leaf docs have children linking to them.check_empty_docs (
bool) – Check for documents with no items.check_empty_text (
bool) – Check for items with empty text.check_self_links (
bool) – Check for items linking to themselves.check_item_cycles (
bool) – Check for cycles in item-to-item links.check_unlinked (
bool) – Check for unlinked normative items in child documents.skip_prefixes (
list[str] |None) – Document prefixes to skip during validation.
- Returns:
list[ValidationIssue] – List of ValidationIssue objects.- Return type:
Reorder#
- jamb.storage.reorder.reorder_document(doc_path, prefix, digits, sep, all_doc_paths)[source]#
Renumber items sequentially and update all cross-document links.
Items are sorted by current UID and assigned new sequential UIDs (e.g. PREFIX001, PREFIX002, …). Files are renamed on disk and every link reference across all documents is updated.
Note: This operation is not atomic. If an error occurs during link updates after files have been renamed, the document may be left in an inconsistent state. Consider committing to version control before reordering.
Returns {“renamed”: int, “unchanged”: int, “rename_map”: dict[str, str]}.
- jamb.storage.reorder.insert_items(doc_path, prefix, digits, sep, position, count, all_doc_paths)[source]#
Insert count new item slots at position, shifting existing items forward.
Items with number >= position are renamed to number + count. Links across all documents are updated to reflect the new UIDs.
- Parameters:
doc_path (
Path) – Path to the document directory.prefix (
str) – Document prefix (e.g. “SRS”).digits (
int) – Number of digits in item UIDs.sep (
str) – Separator between prefix and number.position (
int) – Position to insert at (must be >= 1).count (
int) – Number of items to insert.all_doc_paths (
dict[str,Path]) – Mapping of all document prefixes to their paths.
- Returns:
new_uids: List of new UIDs that were freed (e.g.
["SRS005"]). The caller is responsible for writing the actual item files at those paths.rename_map: Dict mapping old UIDs to new UIDs for items that were shifted.
- Return type:
A tuple of (new_uids, rename_map) where
- Raises:
ValueError – If position < 1 or count < 1.