Live

SOUP Ingestion

RTMify Live ingests software of unknown provenance from dedicated SOUP JSON uploads, single-purpose SOUP workbooks, inbox file-drop, and an optional read-only SOUP Sync source. The resulting graph anchors each product to a software DesignBOM, its BOMItem component rows, and any explicit requirement or test references declared on those SOUP rows.

SOUP is not just an SBOM file

CycloneDX and SPDX are excellent automated software BOM formats, but they usually do not carry anomaly evaluation, safety class, or manual trace notes. Live treats SOUP as a software inventory with richer audit fields. Use the SOUP template when you need those software-specific columns and use automated SBOMs when your CI pipeline already emits them.

What Live supports now

Source Path Notes
SOUP JSON payload POST /api/v1/soup Dedicated software inventory API with per-row errors, warnings, and one product anchor per submission.
SOUP workbook (.xlsx) POST /api/v1/soup/xlsx or inbox drop Workbook must contain a SOUP Components tab. API binds product by form field; inbox uses the SOUP__{full_product_identifier}.xlsx filename convention.
Secondary SOUP Sync Dashboard Settings → SOUP Sync Optional read-only secondary source. Supports Google Sheets, Excel Online, or a local XLSX file anchored to one product in config.
Automated SBOM POST /api/v1/bom CycloneDX and SPDX still ingest as software DesignBOMs, but they do not carry the richer SOUP-only fields.

Product prerequisite

Every SOUP register is anchored to exactly one Product by full_product_identifier. That product must already exist in the primary RTM workbook.

SOUP Sync is stricter than grouped Design BOM ingest

The dedicated SOUP Sync source stores one product anchor in config. Save and validate fail if that product does not exist. SOUP does not create Product rows and does not infer the product per row from the workbook itself.

Workbook shape and column reference

The downloadable SOUP workbook is single-purpose. Live expects the exact SOUP Components tab and the columns below.

Column Required Notes
component_name Yes Mapped to BOMItem.part. Blank rows are skipped with SOUP_MISSING_REQUIRED_FIELD.
version Yes Mapped to BOMItem.revision. "unknown" is allowed and surfaces as SOUP_VERSION_UNKNOWN.
supplier No Stored on the BOMItem.
category No Stored on the BOMItem.
license No Stored on the BOMItem.
purl No Stored on the BOMItem.
safety_class No Free-text SOUP field stored on the BOMItem.
known_anomalies No Free-text SOUP field stored on the BOMItem.
anomaly_evaluation No Free-text SOUP field stored on the BOMItem.
requirement_ids No Comma-, semicolon-, or pipe-separated Requirement IDs.
test_ids No Comma-, semicolon-, or pipe-separated Test or TestGroup IDs.
Notes Ignored for ingest Accepted in the workbook and ignored by Live.

Template-first path

The published workbook already uses the supported column names. If your team is not generating CycloneDX or SPDX automatically, start with the template and keep it as the canonical software inventory for that product.

Requirement and test trace fields

SOUP rows can declare direct trace links, just like hardware Design BOM rows.

Requirement IDs

Live stores declared requirement_ids on each SOUP component and creates REFERENCES_REQUIREMENT edges for exact Requirement matches.

Test IDs

Live resolves exact IDs to Test first, then TestGroup, and creates REFERENCES_TEST edges for resolved matches.

Unresolved refs stay visible

If a declared ID does not resolve, the SOUP row still ingests. The raw IDs remain on the BOMItem and the component surfaces unresolved-ref statuses instead of failing the entire submission.

Ingest paths

Inbox drop

Drop a single-purpose SOUP workbook into the Live inbox. Successful ingests move to processed/; failures move to rejected/.

cp SOUP__ASM-1000-REV-C.xlsx ~/.rtmify/inbox/

Inbox SOUP workbooks use the SOUP__{full_product_identifier}.xlsx filename convention so Live can anchor the register to one product.

HTTP API

Use POST /api/v1/soup for dedicated SOUP JSON and POST /api/v1/soup/xlsx for the SOUP workbook path.

curl -X POST http://127.0.0.1:8000/api/v1/soup/xlsx \
  -H "Authorization: Bearer <token>" \
  -F "full_product_identifier=ASM-1000-REV-C" \
  -F "file=@RTMify_SOUP_Template.xlsx"

The dedicated SOUP routes return rows received, rows ingested, row-level errors, and warnings instead of a single opaque result.

SOUP Sync

The dashboard settings expose an optional read-only secondary source named SOUP Sync. That source is separate from the primary RTM workbook and is anchored to one Product in config.

  • GET /api/soup-sync
  • POST /api/soup-sync/validate
  • POST /api/soup-sync
  • DELETE /api/soup-sync

This source is read-only. Live ingests it but never writes status back into the workbook.

Replacement semantics

Same product + BOM name replaces the prior software inventory

SOUP replacement is keyed by (full_product_identifier, bom_type, bom_name). If a SOUP register and a CycloneDX/SPDX ingest target the same software key, last writer wins. If you want both inventories to coexist, give them distinct bom_name values.

Graph shape

Product (full_identifier = "ASM-1000-REV-C")
  └─[HAS_DESIGN_BOM]→ DesignBOM (bom_name = "SOUP Components", bom_type = "software", bom_class = "design")
       ├─[CONTAINS qty=1]→ BOMItem (part = "FreeRTOS", revision = "10.5.1")
       │    ├─ known_anomalies = "None known"
       │    ├─ anomaly_evaluation = "No anomalies to evaluate"
       │    ├─ safety_class = "C"
       │    ├─[REFERENCES_REQUIREMENT]→ Requirement (REQ-001)
       │    └─[REFERENCES_TEST]→ Test or TestGroup (TG-001)
       └─[CONTAINS qty=1]→ BOMItem (part = "lwIP", revision = "unknown")

SOUP components live on the same product graph as requirements, tests, risks, code evidence, and hardware Design BOMs, so software inventory questions stay on the same graph rather than in a separate spreadsheet silo.

How to query it

"List the software BOMs for ASM-1000-REV-C."
"Show SOUP components with missing anomaly evaluation."
"List SOUP components by safety class for ASM-1000-REV-C."
"Show unresolved requirement or test refs in the SOUP register."
"Group software components by license."
"Explain the impact if component lwIP is superseded or removed."
"Read soup-components://ASM-1000-REV-C/SOUP Components and summarize gap status."
"Show the linked requirements and tests for SOUP component FreeRTOS@10.5.1."

The key MCP affordances include:

  • list_software_boms for product-scoped software inventory across both manual SOUP and automated CycloneDX/SPDX ingests
  • get_soup_components, soup_by_safety_class, soup_by_license, plus unified bom_gaps and bom_impact_analysis
  • the software-boms://, soup-components://<full_product_identifier>/<bom_name>, and soup-component://... resources
  • prompts such as soup_audit_prep and soup_coverage

Dashboard report availability

The Reports group in the dashboard includes a product-scoped SOUP Register report in PDF, Markdown, and DOCX. The Software / SOUP workspace also exposes components, gaps, licenses, and safety-class views from the same graph.

SOUP vs automated SBOM

CycloneDX / SPDX

Best when your CI or build pipeline already emits a software BOM. Live ingests those formats through the generic BOM API and stores them as software DesignBOM nodes.

SOUP workbook or JSON

Best when you need richer, manual software evidence: known anomalies, anomaly evaluation, safety class, and explicit trace links. This is the better audit surface when those fields matter.

Known limits

  • SOUP Sync is a second concrete source, not a generalized multi-workbook attachment system.
  • The workbook is single-purpose. Live expects a SOUP Components tab, not a mixed Design BOM + SOUP workbook.
  • Free-text SOUP fields are not vocabulary-validated. Live distinguishes blank vs nonblank and detects unknown version values, but it does not enforce controlled terminology for anomaly text or safety class.
  • If SOUP and CycloneDX/SPDX target the same software key, last writer wins. Live does not merge them field-by-field.

Error and warning reference

Code Meaning
SOUP_PRODUCT_NOT_FOUND The target Product does not exist for the current full_product_identifier.
SOUP_NO_PRODUCT_IDENTIFIER Inbox workbook filename did not include the expected SOUP__{full_product_identifier}.xlsx anchor.
NO_SOUP_TAB Workbook/XLSX ingest did not find the required SOUP Components tab.
invalid_json The JSON payload shape was invalid for the dedicated SOUP API.
invalid_xlsx The uploaded workbook could not be parsed as a valid XLSX file.
SOUP_MISSING_REQUIRED_FIELD A row was skipped because component_name or version was blank.
SOUP_VERSION_UNKNOWN The component version was explicitly set to unknown.
SOUP_NO_ANOMALY_EVALUATION known_anomalies was nonblank while anomaly_evaluation was blank.
SOUP_NO_ANOMALIES_DOCUMENTED Both known_anomalies and anomaly_evaluation were blank.
SOUP_NO_REQUIREMENT_LINKAGE No requirement_ids were declared on the component row.
SOUP_NO_TEST_LINKAGE No test_ids were declared on the component row.
SOUP_UNRESOLVED_REQUIREMENT_REF One or more declared requirement IDs did not resolve.
SOUP_UNRESOLVED_TEST_REF One or more declared test or test-group IDs did not resolve.