> ## 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.

# Gap Analysis

> Find requirements with no confirming tests, generate AI-suggested test skeletons via analyze_requirement_coverage, and close gaps systematically.

# Gap Analysis

A `gap` is a requirement that no test currently confirms. It's the most actionable coverage state — every gap is a piece of work you can hand to an engineer with a clear definition of done.

<Info>
  Gap closure is **the** measurable progress signal. Coverage percentage at the org level moves up only as gaps close. Treat the gap list as a backlog with priority and ownership.
</Info>

## The gap dashboard

**Traceability → Gaps**. The default view lists every requirement currently in state `gap`, sorted by:

1. Priority (`critical` first).
2. ASIL / PL / SIL (`ASIL-D` / `PLd` / `SIL-3` first).
3. Standard (requirements derived from pinned standards first).
4. Recency (newest gaps first — so a freshly-added safety requirement doesn't get buried under legacy backlog).

Each row shows the requirement ID, title, type, ASIL, source, and `external_id`. Clicking opens the requirement detail with a **Suggested tests** panel.

*\[Screenshot needed: gap dashboard with sorted list and one row expanded showing suggested tests]*

## Filters

The dashboard inherits filters from the [matrix](/traceability/matrix):

* **Standard** — show only gaps tied to a specific standard (e.g. *"every ISO 10218 §5.3 gap"*).
* **Repository** — for multi-repo projects, scope to one repo's gaps.
* **Tag** — your custom labels.
* **Source** — gap requirements that came from a PDF extraction may need different handling than those manually authored.

Save a filter as a view and link the URL in your team's standing meeting agenda.

## AI-suggested test skeletons

For each gap, Roboticks can generate a pytest (or gtest) skeleton via Bedrock Claude that proposes:

* A `test_*` function name and signature.
* The fixtures it would need (`robot`, `world`, `clock`).
* A docstring summarising what the test must demonstrate.
* An assertion stub tied to the requirement's measurable criteria (when the requirement text expresses them concretely).
* A `@confirms(...)` decorator already wired up.

Trigger from the dashboard with **Suggest test** on the requirement row, or from the SDK:

```python theme={null}
from roboticks import Client

client = Client()
suggestion = client.coverage.analyze_requirement_coverage("REQ-014")
print(suggestion.skeleton)
```

Sample output:

```python theme={null}
import pytest
from roboticks import confirms, deadline

@confirms("REQ-014")
@deadline(milliseconds=100)
def test_estop_halts_motion_within_100ms(robot, clock):
    """
    Per REQ-014: on E-stop, all actuators reach safe stop within 100 ms.
    Measured at wheel encoders, threshold 0.02 m/s.
    """
    robot.command_velocity(1.0)
    clock.advance_until(robot.linear_velocity >= 0.95)
    t0 = clock.now()
    robot.assert_estop()
    robot.wait_until(lambda: robot.wheel_velocity < 0.02)
    elapsed_ms = (clock.now() - t0) * 1000
    assert elapsed_ms < 100, f"safe-stop took {elapsed_ms:.1f} ms (limit 100)"
```

The suggestion is **a starting point, not a finished test**. The engineer reviews, tightens the fixtures, fills in any missing world setup, and commits — same as code review on any other PR. The suggestion is never silently inserted into the repo.

### How the suggestion is grounded

The LLM call is grounded on:

* The full requirement text and any `derives_from` parent text.
* The repo's existing test files (so the style matches — pytest fixtures vs gtest, your project's helper imports, your `robot.*` API).
* The pinned standard's clause text (so safety-derived requirements get safety-style assertions).
* A representative slice of the SDK reference for `@confirms`, `@deadline`, fault-injection helpers.

The prompt is bounded — we don't ship the entire repo or the entire standard. The suggestion includes a `confidence` field; low-confidence suggestions are flagged amber.

## Closing a gap

Workflow:

<Steps>
  <Step title="Pick a gap from the list">
    Filter to your team's scope. Sort by priority. Take the top one.
  </Step>

  <Step title="Generate or write the test">
    Either accept the AI-suggested skeleton or write from scratch.
  </Step>

  <Step title="Open a PR">
    Same as any other code change. The PR Check Run will show the requirement moving from `gap` → `unconfirmed` → `confirmed` on first successful run.
  </Step>

  <Step title="Merge">
    On merge to the default branch, the requirement's coverage state stays `confirmed`. The audit trail records the closure event with the merging PR.
  </Step>
</Steps>

## Gap aging

Each gap shows an **age** — days since the requirement was created. The dashboard sorts by age within priority groups so old gaps surface ahead of new ones at the same priority.

For projects subject to a regulation date — e.g. EU MR 2027 — set a **target date** on the project (Settings → Project → Compliance target). Gaps with age that pushes them past the target are flagged red in the dashboard.

## Bulk operations

| Action           | Effect                                                                                                        |
| ---------------- | ------------------------------------------------------------------------------------------------------------- |
| **Bulk suggest** | Run `analyze_requirement_coverage` on every selected gap. Each suggestion lands in a draft branch for review. |
| **Bulk assign**  | Tag selected gaps with an owner (a GitHub user or a team alias). Owners get email digests.                    |
| **Bulk export**  | CSV of gap requirements with all fields. Useful for spreadsheet planning.                                     |

## Gaps in inspection / analysis / demonstration requirements

Requirements with `verification_method != test` are **excluded from the gap list**. They will never be `confirmed` by Roboticks — they're verified out of band — so listing them as gaps would be noise.

To track inspection requirements separately, use a saved view in the matrix filtered by `verification_method: inspection`. Sign-off is via a manual link in the dashboard with a reference to the inspection report.

## Common gap-closure pitfalls

| Pitfall                                                                                          | Why it bites                                                                                                                        |
| ------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------- |
| Closing a gap with a tautological test (`assert True`)                                           | The audit trail records the diff; an auditor will spot it. Roboticks's review tooling also flags tests with no real assertion.      |
| Confirming a requirement with a test in a different repo without linking the repo to the project | The link won't resolve and the requirement stays `gap`. See [Multi-repo](/traceability/multi-repo).                                 |
| Using `@confirms("REQ-014")` on a test that's marked `xfail`                                     | The test counts as a known failure, not a confirming pass. The requirement stays `gap` (or moves to `partial` if other tests pass). |
| Adding a manual link from a test that doesn't actually demonstrate the requirement               | Tempting, never helpful. The audit trail makes it visible, and the test's content is what an auditor reads.                         |

## Next

<CardGroup cols={2}>
  <Card title="Matrix" icon="table-cells" href="/traceability/matrix">
    Filter to `gap` mode there too.
  </Card>

  <Card title="Coverage" icon="chart-pie" href="/traceability/coverage">
    The state machine driving the gap list.
  </Card>

  <Card title="SDK @confirms" icon="code" href="/sdk/confirms">
    The decorator the closed-gap test will need.
  </Card>

  <Card title="Writing tests" icon="flask-vial" href="/testing/writing-tests-pytest">
    Patterns for fault injection, deadlines, MCAP capture.
  </Card>
</CardGroup>
