Skip to content

[quality] Nothing verifies that local /img static asset references in docs/, blog/, src/ and data/ resolve under static/ #288

Closed

Description

@hivecommons-hive

Finding

The site references 83 distinct files under static/ from docs/, blog/, src/ and the top-level data/*.json files. Nothing verifies that any of them resolve.

The largest single group is the logo="/img/cncf-projects/*.svg" props on <CNCFProjectCard>, hand-authored in docs/architectures/*.md. The component renders the value straight into an <img src>.

Why the existing gates do not cover this:

  • docusaurus.config.js sets onBrokenLinks: 'throw', but that enforces page routes, not static assets. A typo in an absolute /img/... path builds clean and ships a broken image.
  • scripts/validate-architecture-assets.mjs checks data/architectures assets only.
  • scripts/validate-awards.mjs checks data/awards.json logos only.
  • Neither touches docs/, blog/, src/, or the other data/*.json files.

A case-only mismatch is the worst variant: /img/Social-card.png resolves on a case-insensitive developer filesystem and 404s on GitHub Pages, which serves from a case-sensitive one. existsSync() alone does not catch it.

Recommendation

Add tests/static-assets.test.mjs — a single new test-only file, no production code — that scans docs/, blog/, src/ and data/*.json, strips absolute and protocol-relative URLs (so a remote https://.../images/foo.jpg is never mistaken for a local /images/foo.jpg), keeps every path whose first segment is a real top-level entry of static/, and asserts:

  • every referenced asset exists and is a file
  • referenced assets are non-empty
  • the reference matches the on-disk name case-exactly
  • no reference escapes static/ via ..
  • every local CNCFProjectCard logo= prop in docs/ resolves
  • the scan itself finds references (guards against a silently vacuous suite)

Coverage evidence

  • Unit: node --test --experimental-test-coverage, local clone of cncf/endusers at revision 00b44df, node v26.8.2, after npm ci, run 2026-09-18. 55 tests, 0 fail. No test file reads static/ or scans docs//blog//src/ for asset references.
  • End-to-end: unavailable — this repository has no end-to-end or browser suite and publishes no coverage artifact from any suite (tracked in [quality] CI publishes no coverage evidence, so coverage findings cannot be verified #186). No claim is made that this path lacks end-to-end coverage.

Scope

One deliverable, closable by one PR. Deliberately disjoint from the open test PRs: docusaurus.config.js branding assets are asserted in #275, data/architectures assets in #231, awards.json slug parity in #253, and the CNCFProjectCard href allowlist in #249/#250. This issue claims the asset-path existence surface only, in a new file no other PR touches.

Priority

  • Impact: medium
  • Effort: low

🐝 Hive Agent: quality | Instance: hosted-available-lke648397-260827-5n31 | SHA: 00b44df

— hive: agent=quality backend=copilot model=claude-opus-5

Activity

  1. added
    qualityApproved by a Hive merger/owner for auto-merge on green CI
    testingApproved by a Hive merger/owner for auto-merge on green CI
    agent/qualityApproved by a Hive merger/owner for auto-merge on green CI
    on Sep 18, 2026
  2. added a commit that references this issue on Sep 21, 2026
    1f6dcf3
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    agent/qualityApproved by a Hive merger/owner for auto-merge on green CIqualityApproved by a Hive merger/owner for auto-merge on green CItestingApproved by a Hive merger/owner for auto-merge on green CI

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions