Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.roboticks.io/llms.txt

Use this file to discover all available pages before exploring further.

Traceability Overview

Traceability in Roboticks is the live mapping from requirements to tests to results. Every requirement has a coverage state. Every state is computed from concrete artifacts — a @confirms decorator in source, a JUnit row, a pass/fail flag — not from a hand-curated spreadsheet that drifts the moment someone is on holiday.
Traceability is the diagonal of the V-model. Requirements engineering owns the left arm; verification engineering owns the right arm; Roboticks owns the link between them. Without that link, the V-model is two disconnected staircases.

The five coverage states

Each requirement is in exactly one of these states per SHA:
StateMeaning
confirmedAt least one test annotated @confirms("REQ-...") passed on this SHA.
partialA confirming test passed and at least one other confirming test failed. The requirement is partially verified — likely flakiness or an incomplete behavioural cover.
regressionThe requirement was confirmed on a prior SHA on this branch but now isn’t. The strongest signal we emit.
unconfirmedA @confirms link exists but no run has produced a result yet. Common right after a test is written but before it has run on the platform.
gapNo test annotates this requirement at all. The most actionable state — see Gap analysis.
Hierarchy rolls these states up — see Coverage for the per-state semantics on parent requirements. Three sources, all merged into a single RequirementLink table on the backend:

1. The @confirms decorator (primary)

The SDK exports a decorator. You annotate a test with it. The pytest plugin (or the equivalent for gtest / launch_testing) emits the link into JUnit metadata. The backend reads it on ingest.
from roboticks import confirms, deadline

@confirms("REQ-014")
@deadline(milliseconds=100)
def test_estop_halts_motion(robot):
    ...
For C++/gtest:
#include <roboticks/confirms.hpp>

TEST(EStop, HaltsWithin100ms) {
  ROBOTICKS_CONFIRMS("REQ-014");
  // ...
}
Both render the same <property name="roboticks.confirms" value="REQ-014"/> in JUnit XML. The backend parses these into RequirementLink rows. Right-click a cell in the matrix and pick Link. Useful for tests in third-party suites you can’t annotate, or for verification_method: inspection requirements that get human sign-off rather than a passing test. Manually-created links are flagged in the audit trail with the user who added them; they’re not silently equivalent to source-code-derived links. For mature repos with a lot of legacy tests, Roboticks can suggest links by matching test names and docstrings against requirement text via Bedrock Claude. Every suggested link is flagged source: llm and requires human acceptance before it counts toward coverage. See Change-impact analysis for how LLM-inferred links surface on PRs.

What you see on each surface

SurfaceWhat it shows
Check RunAffected requirements on this PR, before/after coverage, regressions called out.
MatrixFull requirement × test grid, filterable / sortable, with heatmap colouring per coverage state.
Gap dashboardThe list of gap-state requirements. The list you work down on a quiet Friday afternoon.
Graph viewVisual mode — useful when reviewing decomposition for an upcoming audit.
Evidence packSnapshot of the full matrix per release, signed in the hash chain.

How traceability runs on a PR

The expensive piece — the actual test run — happens on a runner (hosted or self-hosted). Roboticks itself is the orchestrator and the merge point of every signal.

What traceability is not

  • Not a static analysis. A test that compiles but never runs doesn’t move a requirement out of gap — only a run does.
  • Not a coverage percentage in lines of code. This is requirement coverage, not source-line coverage. Two systems with the same line-coverage can have wildly different requirement-coverage.
  • Not a substitute for review. A test that passes proves what the test asserts; whether what the test asserts is what the requirement actually means is a judgement call — that’s why every link is recorded with author and timestamp.

A worked example

You have one requirement and one test:
- id: REQ-014
  title: E-stop halts motion within 100 ms
  type: safety
  asil_pl: PLd
  text: |
    On assertion of E-stop, all actuators reach safe stop within 100 ms.
@confirms("REQ-014")
@deadline(milliseconds=100)
def test_estop(robot):
    robot.command_velocity(1.0)
    robot.assert_estop()
    robot.wait_until_stopped()
Then:
  1. You push the YAML alone — REQ-014 is gap (no test).
  2. You push the test alone (no @confirms) — REQ-014 is still gap.
  3. You push the test with @confirms("REQ-014") but it hasn’t run yet — REQ-014 is unconfirmed.
  4. The PR-time run passes — REQ-014 is confirmed.
  5. Someone changes the brake code, the test now takes 215 ms — REQ-014 is regression.
That’s the whole loop. Everything else in this section is detail on top of it.

Next

Matrix

The requirement × test grid with filters and exports.

Coverage

State machine details, multi-repo rollup, snapshot vs live.

Gaps

The list of unconfirmed requirements and AI-suggested skeletons.

Change-impact

How a code diff maps to affected requirements on a PR.