Skip to content

feat(coverage): generated CUJ/CLI coverage matrix (RQ3)#1316

Merged
mchmarny merged 7 commits into
mainfrom
feat/1282-coverage-matrix
Jun 11, 2026
Merged

feat(coverage): generated CUJ/CLI coverage matrix (RQ3)#1316
mchmarny merged 7 commits into
mainfrom
feat/1282-coverage-matrix

Conversation

@mchmarny

Copy link
Copy Markdown
Member

Summary

Add tools/coverage, a generator for docs/user/coverage-matrix.md — a structural matrix of which CUJs and CLI verbs are exercised by an in-repo test or demo, on what hardware class, and at what cadence (RQ3 of epic #1265).

Motivation / Context

Promotes CUJ/CLI coverage from demo+chainsaw-only into a versioned, generated, public matrix that runs on main weekly (never a merge gate), cross-linked to the other recipe-quality surfaces. CLI verbs are derived from the live pkg/cli command registry so a new verb surfaces automatically as a not-yet-covered row instead of being silently dropped. Live pass/fail stays a link into the AICR TestGrid; this page is structural only.

Fixes: #1282
Related: #1265 (RQ epic), #1283 (RQ1 adds the reverse recipe-health cross-link), #1280 (DC6 owns the Azure revive-or-retire)

Type of Change

  • New feature (non-breaking change that adds functionality)
  • Documentation update
  • Build/CI/tooling

Component(s) Affected

  • CLI (cmd/aicr, pkg/cli) — new exported cli.RootCommand() (behavior-neutral)
  • Docs/examples (docs/)
  • Other: new tools/coverage generator + coverage-matrix-refresh workflow

Implementation Notes

  • Registry-derived verbs: exported cli.RootCommand() (extracted from the existing builder; Execute() unchanged) so the generator walks the live tree. Pure command groups (Action-less, e.g. evidence) expand to subcommands; action commands stay single.
  • Fully-generated page, no splice markers. The whole coverage-matrix.md is regenerated, so it passes tools/check-docs-mdx with zero exclusions — avoiding the single-file EXCLUDE carve-out the BOM doc needs (the issue's suggested {/* */} marker would itself fail the gate's bare-{ check; HTML-comment markers fail Check 3).
  • Honest signals: scanning found query/verify/trust update/skill are exercised; only diff/mirror list/evidence digest are genuinely not-yet-covered. Azure UAT trees render as stubbed (link to DC6/DC7 — Azure UAT revive-or-retire #1280). Deterministic output (byte-stable across runs).
  • Deferred cross-link: docs/user/recipe-health.md does not exist on main yet (ships with tools/health generator + make targets + public recipe-health matrix #1229), so the page references it in prose without a hyperlink to avoid a broken-link (lychee) failure; the reverse link is RQ1/RQ1 — recipe-health ⇄ TestGrid Evidence deep-link #1283's job.
  • make coverage-docs / coverage-check (opt-in, not in qualify/lint/merge gate); weekly coverage-matrix-refresh.yaml (Helm-free clone of bom-refresh, cron offset 30m); docs/index.yml registration; cli-reference.md cross-link; labeler.yml + CODEOWNERS for tools/coverage/**.

Testing

unset GITLAB_TOKEN && make qualify   # passes
go test ./tools/coverage/...          # 83.5% coverage (>75% floor)
make coverage-docs && make coverage-check

tools/coverage: new package, 83.5% statement coverage. pkg/cli: added TestRootCommand so the new exported func is not at 0%. make qualify green (tests, MDX gate on the new page, lint, e2e, scan).

Risk Assessment

  • Low — Additive tooling + a generated doc; the one production-code change (cli.RootCommand()) is a behavior-neutral wrapper over the existing builder. The matrix never gates merges.

Rollout notes: The matrix fills in as the dynamic-clusters epic (DC3/DC4/DC5) lands more execution; today it honestly reports not-yet-covered/stubbed where no executable signal exists.

Checklist

  • Tests pass locally (make test with -race)
  • Linter passes (make lint)
  • I did not skip/disable tests to make CI green
  • I added/updated tests for new functionality
  • I updated docs (new generated page + registration + cross-link)
  • Changes follow existing patterns in the codebase (tools/bom / bom-refresh)
  • Commits are cryptographically signed (git commit -S)

Add tools/coverage, a generator that emits docs/user/coverage-matrix.md — a
structural matrix of which critical user journeys and CLI verbs are exercised
by an in-repo test or demo, on what hardware class, and at what cadence. CLI
verbs are derived from the live pkg/cli command registry (new exported
cli.RootCommand()), so a new verb surfaces as a not-yet-covered row instead of
being silently dropped. Azure UAT trees render as stubbed (DC6, #1280); live
pass/fail is a link into the AICR TestGrid, never embedded.

The page is fully generated (no splice markers), so it stays inside the
tools/check-docs-mdx gate with zero exclusions. Adds make coverage-docs /
coverage-check (opt-in, not wired into qualify) and a weekly Helm-free clone of
bom-refresh. Registered in docs/index.yml and cross-linked from cli-reference;
the reverse recipe-health cross-link is deferred to RQ1 (#1283) since that page
ships with #1229.

Closes #1282
@github-actions

github-actions Bot commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

Coverage Report ✅

Metric Value
Coverage 77.0%
Threshold 75%
Status Pass
Coverage Badge
![Coverage](https://img.shields.io/badge/coverage-77.0%25-green)

Merging this branch will increase overall coverage

Impacted Packages Coverage Δ 🤖
github.com/NVIDIA/aicr/pkg/cli 68.84% (+0.02%) 👍
github.com/NVIDIA/aicr/tools/coverage 82.08% (+82.08%) 🌟

Coverage by file

Changed files (no unit tests)

Changed File Coverage Δ Total Covered Missed 🤖
github.com/NVIDIA/aicr/pkg/cli/root.go 85.27% (+0.12%) 129 (+1) 110 (+1) 19 👍
github.com/NVIDIA/aicr/tools/coverage/build.go 93.10% (+93.10%) 58 (+58) 54 (+54) 4 (+4) 🌟
github.com/NVIDIA/aicr/tools/coverage/main.go 0.00% (ø) 25 (+25) 0 25 (+25)
github.com/NVIDIA/aicr/tools/coverage/model.go 0.00% (ø) 0 0 0
github.com/NVIDIA/aicr/tools/coverage/render.go 100.00% (+100.00%) 58 (+58) 58 (+58) 0 🌟
github.com/NVIDIA/aicr/tools/coverage/scan.go 80.00% (+80.00%) 55 (+55) 44 (+44) 11 (+11) 🌟
github.com/NVIDIA/aicr/tools/coverage/verbs.go 100.00% (+100.00%) 17 (+17) 17 (+17) 0 🌟
github.com/NVIDIA/aicr/tools/coverage/wiring.go 88.89% (+88.89%) 27 (+27) 24 (+24) 3 (+3) 🌟

Please note that the "Total", "Covered", and "Missed" counts above refer to code statements instead of lines of code. The value in brackets refers to the test coverage of that file in the old version of the code.

@coderabbitai

This comment was marked as resolved.

coderabbitai[bot]

This comment was marked as resolved.

coderabbitai[bot]

This comment was marked as resolved.

coderabbitai[bot]

This comment was marked as resolved.

…ngs.Contains

- Add a top-level concurrency group to coverage-matrix-refresh so the scheduled
  and manual triggers cannot race the shared chore/coverage-refresh branch.
- Add an inline rationale for the single-use `make coverage-docs` shell step.
- Reword the cli-reference cross-link sentence for clarity.
- Replace the hand-rolled contains() test helper with strings.Contains.

@njhensley njhensley left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed the latest push and reconciled against the existing CodeRabbit comments. CodeRabbit's workflow/grammar/test-helper items look addressed, so I focused this review on remaining coverage-matrix correctness issues.

Comment thread tools/coverage/build.go Outdated
Comment thread tools/coverage/verbs.go Outdated
Comment thread tools/coverage/scan.go Outdated
Comment thread tools/coverage/build.go Outdated
Comment thread tools/coverage/render.go Outdated
mchmarny and others added 2 commits June 11, 2026 12:27
…b expansion

Respond to @njhensley's review on #1316:

- P0: derive CUJ/UAT coverage from the scheduled workflow's wired runner + config
  intent, not tree presence. cuj2-inference now renders `stubbed` (assets present,
  no scheduled inference config) instead of falsely claiming live nightly H100.
- P1: scan the extensionless UAT runner scripts and match the shell argv-array
  invocation form, so `evidence verify` (run via `args=(evidence verify ...)`) is
  correctly attributed to UAT.
- P1: include subcommands of action-bearing parents, so `recipe list` /
  `recipe verify-catalog` appear as rows instead of being collapsed into `recipe`.
- P1: render only the AICR versions actually exercised (main); the multi-version
  axis is deferred to DC5.
- P2: reword the legend so coverage reflects CUJ/CLI *journey* signals
  (chainsaw/KWOK/UAT/demo); Go unit-test coverage is a separate gate.

Adds tools/coverage/wiring.go (workflow-entrypoint parsing) and updates tests.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
docs/user/coverage-matrix.md (1)

5-18: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Clarify whether demo-backed rows count as covered.

The intro says the matrix tracks journeys exercised by an in-repo test or demo, but the legend defines covered only in terms of chainsaw/KWOK tests and wired UAT runners. That makes the demo-backed rows ambiguous, and cuj2-inference-dynamo is especially confusing because it is listed as demo-exercised but still marked stubbed.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/user/coverage-matrix.md` around lines 5 - 18, The doc is ambiguous about
whether demos count as "covered" (intro says "test or demo" but Legend's
`covered` mentions only chainsaw/KWOK and wired UAT); update the intro and
Legend to explicitly state how demos are treated (e.g., define a new status like
`demo-only` or state that demos count as `covered` only when accompanied by
scheduled UAT runs), then reconcile the example row `cuj2-inference-dynamo`
(either change its Status from `stubbed` to `demo-only` or add an explanatory
Note) so the table and legend consistently reflect the intended semantics for
demo-backed rows and remove the contradiction between the intro, Legend
(`covered`, `stubbed`), and the sample CUJ rows.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@docs/user/coverage-matrix.md`:
- Around line 5-18: The doc is ambiguous about whether demos count as "covered"
(intro says "test or demo" but Legend's `covered` mentions only chainsaw/KWOK
and wired UAT); update the intro and Legend to explicitly state how demos are
treated (e.g., define a new status like `demo-only` or state that demos count as
`covered` only when accompanied by scheduled UAT runs), then reconcile the
example row `cuj2-inference-dynamo` (either change its Status from `stubbed` to
`demo-only` or add an explanatory Note) so the table and legend consistently
reflect the intended semantics for demo-backed rows and remove the contradiction
between the intro, Legend (`covered`, `stubbed`), and the sample CUJ rows.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Enterprise

Run ID: 9fddee93-6bca-43e3-9d37-69e633a0e1c0

📥 Commits

Reviewing files that changed from the base of the PR and between bc2564a and 535c37e.

📒 Files selected for processing (8)
  • docs/user/coverage-matrix.md
  • tools/coverage/build.go
  • tools/coverage/build_test.go
  • tools/coverage/render.go
  • tools/coverage/scan.go
  • tools/coverage/verbs.go
  • tools/coverage/verbs_test.go
  • tools/coverage/wiring.go

njhensley
njhensley previously approved these changes Jun 11, 2026

@njhensley njhensley left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved. The coverage-matrix correctness issues from my previous pass look addressed at the latest head.

Non-blocking follow-up: consider filtering hidden commands out of the user-facing matrix. tools/coverage/verbs.go skips built-ins but not cmd.Hidden, so recipe sign-catalog appears in docs/user/coverage-matrix.md even though pkg/cli/recipe_sign_catalog.go marks it hidden and CI-only. A small follow-up could skip hidden commands in expandVerb while keeping visible nested verbs like recipe list and recipe verify-catalog.

recipe sign-catalog is marked Hidden in pkg/cli/recipe_sign_catalog.go
(CI-only, not user-facing) but was appearing in docs/user/coverage-matrix.md.
Skip cmd.Hidden in expandVerb alongside the existing builtins filter.
Visible nested verbs (recipe list, recipe verify-catalog) are unaffected.
@mchmarny mchmarny enabled auto-merge (squash) June 11, 2026 20:05
@mchmarny mchmarny merged commit eb8728d into main Jun 11, 2026
33 checks passed
@mchmarny mchmarny deleted the feat/1282-coverage-matrix branch June 11, 2026 20:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

RQ3 — CUJ/CLI coverage matrix

2 participants