Skip to content

feat(recipe-health): deep-link Evidence to dashboard + link-check bot#1809

Open
njhensley wants to merge 1 commit into
NVIDIA:mainfrom
njhensley:feat/recipe-health-evidence-deeplink
Open

feat(recipe-health): deep-link Evidence to dashboard + link-check bot#1809
njhensley wants to merge 1 commit into
NVIDIA:mainfrom
njhensley:feat/recipe-health-evidence-deeplink

Conversation

@njhensley

Copy link
Copy Markdown
Member

Summary

Turn the recipe-health matrix's pending Evidence column into deterministic deep-links into the evidence dashboard (validation.aicr.run) for recipes with a real dashboard presence (RQ1), and add a weekly, warning-only bot that verifies those links still resolve (RQ2).

Motivation / Context

The Evidence column was a uniform literal pending. RQ1 makes it a stable, hermetic deep-link to each recipe's dashboard coordinate; RQ2 keeps those links honest without ever blocking a merge.

Fixes: #1283, #1284
Related: #1265 (parent), #1400 (dashboard)

Type of Change

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

Component(s) Affected

  • Recipe engine / data (pkg/recipe) — consumes shared CoordinateFor (no change to it)
  • Docs/examples (docs/)
  • Other: new pkg/testgrid, tools/testgrid-link-check, tools/health rendering, CI workflow

Implementation Notes

Scope pivot (per the issue comments): links target the live GitHub Pages dashboard validation.aicr.run, not the deferred live TestGrid. Because the dashboard is a hash-routed SPA (a GET on the /#/ fragment can't reveal coordinate presence), the RQ2 bot checks presence in the published data/index.json, not the fragment URL.

  • pkg/testgrid (new): dashboard origin, hash-route link scheme (LinkFor over the shared pkg/recipe.CoordinateFor), the committed presence manifest presence.yaml (the 6 UAT-covered coordinates today), and LivePaths to read present coordinates from a parsed index. The generator reads the embedded manifest, so link construction is fully offline/hermetic and byte-deterministic; the coordinate carries no k8s version, so links survive version rolls.
  • RQ1 — tools/health: the Evidence cell renders [<path>](<link>) for a recipe whose resolved coordinate is present, else honest pending. No status/count token. docs/user/recipe-health.md prose rewritten to explain the link, the author-asserted-provenance caveat, and coexistence with ADR-009's deferred in-cell freshness state; cross-links to the coverage matrix and dashboard.
  • RQ2 — tools/testgrid-link-check + .github/workflows/testgrid-link-check.yaml: a clone of bom-refresh minus the PR step — weekly cron + dispatch, contents: read, report to $GITHUB_STEP_SUMMARY, always exits 0. Bounded HTTP client pinned to the dashboard origin with off-origin redirects refused and a LimitReader-bounded body. Classifies each linked coordinate resolved / missing-but-present (warn: dead link) / not-yet-linked (expected, not a warning). A Go workflow-structure test enforces the read-only / no-create-pull-request contract.

Testing

go test -race ./pkg/testgrid/... ./tools/testgrid-link-check/... ./tools/health/...
golangci-lint run -c .golangci.yaml ./pkg/testgrid/... ./tools/testgrid-link-check/... ./tools/health/...
make recipe-health-check   # matrix is fresh
  • All new tests pass with -race; golangci-lint, go vet, yamllint, and actionlint clean.
  • Coverage: pkg/testgrid 94.6%, tools/testgrid-link-check 87.9%, tools/health 82.8% — all above the 75% floor, no new exported func at 0%.
  • Verified all 6 committed links resolve against the live dashboard (-index-file fixture and real fetch).

Risk Assessment

  • Low — Additive: new package + tool + advisory workflow; the only behavior change is doc rendering, and it degrades to pending if the manifest is absent.

Rollout notes: N/A. The bot is report-only and never blocks merges.

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 if user-facing behavior changed
  • Changes follow existing patterns in the codebase
  • Commits are cryptographically signed (git commit -S)

@njhensley
njhensley requested review from a team as code owners July 17, 2026 23:11
@njhensley njhensley added theme/recipes Recipe expansion, overlays, mixins, and component registry theme/ci-dx CI pipelines, developer experience, and build tooling labels Jul 17, 2026
@njhensley njhensley self-assigned this Jul 17, 2026
@github-actions

Copy link
Copy Markdown
Contributor

@coderabbitai

coderabbitai Bot commented Jul 17, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Enterprise

Run ID: 0e19c9ca-a10f-4fee-8020-50c0bd112495

📥 Commits

Reviewing files that changed from the base of the PR and between a8c5ed7 and a966aa9.

📒 Files selected for processing (14)
  • .github/workflows/testgrid-link-check.yaml
  • docs/user/recipe-health.md
  • pkg/testgrid/doc.go
  • pkg/testgrid/presence.yaml
  • pkg/testgrid/testgrid.go
  • pkg/testgrid/testgrid_test.go
  • tools/health/main.go
  • tools/health/main_test.go
  • tools/health/markdown.go
  • tools/testgrid-link-check/check.go
  • tools/testgrid-link-check/check_test.go
  • tools/testgrid-link-check/main.go
  • tools/testgrid-link-check/main_test.go
  • tools/testgrid-link-check/workflow_test.go

📝 Walkthrough

Walkthrough

Adds canonical TestGrid dashboard links, embedded presence data, and live dashboard path extraction. Recipe health output now renders Evidence deep-links for present coordinates and pending otherwise. A warning-only link-check command classifies live coverage, produces deterministic reports, validates bounded same-origin access, and runs weekly or manually through a read-only GitHub Actions workflow. Documentation and tests cover the new behavior.

Estimated code review effort: 4 (Complex) | ~60 minutes

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: Evidence deep-links plus a link-check bot.
Description check ✅ Passed The description is directly related to the changeset and accurately describes the feature, docs, and workflow updates.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands.

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

Actionable comments posted: 3

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

Inline comments:
In `@pkg/testgrid/testgrid_test.go`:
- Around line 65-78: Refactor TestPresenceHas into a table-driven test with
cases containing a recipe.Coordinate and expected presence result. Iterate over
the cases and compare p.Has for each coordinate against its want value,
preserving the existing coordinates and expectations.

In `@tools/testgrid-link-check/main.go`:
- Around line 183-188: Update the CheckRedirect callback to require both the
expected origin host and an HTTPS request scheme, rejecting HTTP downgrade
redirects with the existing invalid-request error. Add a test covering an
HTTPS-origin request redirected to an HTTP URL and verify that the redirect is
rejected.

In `@tools/testgrid-link-check/workflow_test.go`:
- Around line 65-68: Update the workflow permission assertions around
wf.Permissions to iterate over every top-level permission entry and fail
whenever any value is "write", rather than checking only the "contents" key.
Retain validation that contents is read if required by the existing test.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Enterprise

Run ID: f13489ff-6b4f-47c3-ae8d-ca8df2f4c79a

📥 Commits

Reviewing files that changed from the base of the PR and between 6f9050b and bb7777b.

📒 Files selected for processing (14)
  • .github/workflows/testgrid-link-check.yaml
  • docs/user/recipe-health.md
  • pkg/testgrid/doc.go
  • pkg/testgrid/presence.yaml
  • pkg/testgrid/testgrid.go
  • pkg/testgrid/testgrid_test.go
  • tools/health/main.go
  • tools/health/main_test.go
  • tools/health/markdown.go
  • tools/testgrid-link-check/check.go
  • tools/testgrid-link-check/check_test.go
  • tools/testgrid-link-check/main.go
  • tools/testgrid-link-check/main_test.go
  • tools/testgrid-link-check/workflow_test.go

Comment thread pkg/testgrid/testgrid_test.go
Comment thread tools/testgrid-link-check/main.go
Comment thread tools/testgrid-link-check/workflow_test.go Outdated
@njhensley
njhensley force-pushed the feat/recipe-health-evidence-deeplink branch from bb7777b to ad76d03 Compare July 17, 2026 23:40
@njhensley

Copy link
Copy Markdown
Member Author

Addressed all three CodeRabbit findings in the amended commit:

  1. Redirect scheme pinning (main.go) — CheckRedirect now also rejects a scheme downgrade to plain HTTP, not just off-origin hosts; added a downgrade-redirect test case.
  2. Workflow permission test (workflow_test.go) — now iterates every top-level permission and fails on any write, so a future pull-requests: write can't slip through.
  3. Table-driven TestPresenceHas (testgrid_test.go) — refactored to cases per the repo test guideline.

Tests + golangci-lint green on all touched packages.

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

Actionable comments posted: 2

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

Inline comments:
In `@pkg/testgrid/testgrid.go`:
- Around line 60-89: Update LoadPresence to decode presenceManifest with a YAML
decoder configured with KnownFields(true), rejecting unknown manifest keys.
After decoding, validate that doc.Coordinates is present and non-empty,
returning an error before path processing when absent or empty, and add
regression coverage for both cases.

In `@tools/testgrid-link-check/main_test.go`:
- Around line 86-107: Convert the specified multi-case tests to table-driven
subtests: in tools/testgrid-link-check/main_test.go ranges 86-107, 109-128, and
177-201, cover the decoding, file-input, and HTTP-response cases respectively;
in tools/testgrid-link-check/check_test.go range 113-141, cover clean and
dead-link reports. Preserve each test’s existing inputs, expected outcomes, and
relevant assertions while using descriptive case names.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Enterprise

Run ID: 133d94fe-8d16-4969-b00c-edcd144fe402

📥 Commits

Reviewing files that changed from the base of the PR and between bb7777b and ad76d03.

📒 Files selected for processing (14)
  • .github/workflows/testgrid-link-check.yaml
  • docs/user/recipe-health.md
  • pkg/testgrid/doc.go
  • pkg/testgrid/presence.yaml
  • pkg/testgrid/testgrid.go
  • pkg/testgrid/testgrid_test.go
  • tools/health/main.go
  • tools/health/main_test.go
  • tools/health/markdown.go
  • tools/testgrid-link-check/check.go
  • tools/testgrid-link-check/check_test.go
  • tools/testgrid-link-check/main.go
  • tools/testgrid-link-check/main_test.go
  • tools/testgrid-link-check/workflow_test.go

Comment thread pkg/testgrid/testgrid.go
Comment thread tools/testgrid-link-check/main_test.go
@njhensley

Copy link
Copy Markdown
Member Author

Second round addressed:

  1. Strict presence-manifest decoding (testgrid.go) — LoadPresence now uses KnownFields(true) and rejects an absent/empty coordinates list, so a typo like coordinate: fails closed instead of silently loading an empty set (which would drop every Evidence link). Factored out parsePresence and added regressions for unknown-key, absent, empty, and malformed-path manifests.
  2. Table-driven tests — consolidated decodeIndex, readIndexFile, fetchIndex, and renderReport into table-driven forms per the repo guideline.

pkg/testgrid coverage now 100%; lint clean.

@njhensley
njhensley force-pushed the feat/recipe-health-evidence-deeplink branch from ad76d03 to a8c5ed7 Compare July 17, 2026 23:49

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

Actionable comments posted: 2

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

Inline comments:
In `@pkg/testgrid/testgrid.go`:
- Around line 87-97: Update parsePresence in pkg/testgrid/testgrid.go to decode
once more after the first document and require io.EOF, returning the existing
parse error for any trailing YAML document or malformed content. Add a
multi-document regression case in pkg/testgrid/testgrid_test.go covering a valid
manifest followed by extra content.

In `@tools/testgrid-link-check/workflow_test.go`:
- Around line 100-115: The TestWorkflowRunsLinkCheckToStepSummary assertion must
verify that the tools/testgrid-link-check invocation passes $GITHUB_STEP_SUMMARY
specifically as the value for -report-out, rather than merely checking both
strings independently. Update the step.Run validation in
TestWorkflowRunsLinkCheckToStepSummary to match that argument pairing while
preserving the existing invocation check.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Enterprise

Run ID: 45dcbfef-8ce2-40a6-8fe2-52ecea3bff36

📥 Commits

Reviewing files that changed from the base of the PR and between ad76d03 and a8c5ed7.

📒 Files selected for processing (14)
  • .github/workflows/testgrid-link-check.yaml
  • docs/user/recipe-health.md
  • pkg/testgrid/doc.go
  • pkg/testgrid/presence.yaml
  • pkg/testgrid/testgrid.go
  • pkg/testgrid/testgrid_test.go
  • tools/health/main.go
  • tools/health/main_test.go
  • tools/health/markdown.go
  • tools/testgrid-link-check/check.go
  • tools/testgrid-link-check/check_test.go
  • tools/testgrid-link-check/main.go
  • tools/testgrid-link-check/main_test.go
  • tools/testgrid-link-check/workflow_test.go

Comment thread pkg/testgrid/testgrid.go
Comment thread tools/testgrid-link-check/workflow_test.go
RQ1 (NVIDIA#1283): render the recipe-health Evidence column as a deterministic,
hermetic deep-link into the evidence dashboard (validation.aicr.run) for
each recipe with a committed dashboard presence; keep an honest `pending`
otherwise. Link construction reuses the shared pkg/recipe.CoordinateFor
mapping and carries no k8s version, so links are stable across version
rolls. New pkg/testgrid owns the dashboard origin, link scheme, and the
committed presence manifest (presence.yaml). Evidence-column prose in
docs/user/recipe-health.md is rewritten to explain the link, the
author-asserted-provenance caveat, and its coexistence with ADR-009's
deferred in-cell freshness state.

RQ2 (NVIDIA#1284): add tools/testgrid-link-check and a weekly, warning-only
workflow (clone of bom-refresh minus the PR step) that fetches the live
dashboard data with an origin-pinned, redirect-hardened, bounded HTTP
client and reports any linked coordinate the dashboard no longer serves.
Never blocks merges, never edits the doc; a coordinate not yet linked is
expected, not a warning.

Signed-off-by: Nathan Hensley <nhensley@nvidia.com>
@njhensley

Copy link
Copy Markdown
Member Author

Third round (both Minor) addressed:

  1. Single-document manifest (testgrid.go) — parsePresence now decodes once more and requires io.EOF, rejecting a manifest with a trailing --- second document; added a multi-document regression.
  2. Exact flag pairing (workflow_test.go) — asserts the run step passes -report-out "$GITHUB_STEP_SUMMARY" specifically, not just both strings somewhere in the command.

Tests + lint green; pkg/testgrid still 100%.

@njhensley
njhensley force-pushed the feat/recipe-health-evidence-deeplink branch from a8c5ed7 to a966aa9 Compare July 17, 2026 23:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/ci area/docs size/XL theme/ci-dx CI pipelines, developer experience, and build tooling theme/recipes Recipe expansion, overlays, mixins, and component registry

Projects

None yet

Development

Successfully merging this pull request may close these issues.

RQ1 — recipe-health ⇄ TestGrid Evidence deep-link

1 participant