Skip to content

feat(ci): a scheduled source-level nav-contract audit, closing the authed-surface gap - #11

Merged
github-actions[bot] merged 3 commits into
mainfrom
feat/nav-contract-audit
Aug 31, 2026
Merged

feat(ci): a scheduled source-level nav-contract audit, closing the authed-surface gap#11
github-actions[bot] merged 3 commits into
mainfrom
feat/nav-contract-audit

Conversation

@catomean

Copy link
Copy Markdown
Contributor

ui-defect-audit.mjs renders each site's public entry page — it cannot reach a sidebar behind a login, which is exactly where the bug that started this whole sweep lived. This is the other half.

What's in this PR

scripts/ci/nav-contract-audit.sh — reads source on every repo's default branch (public and authed surfaces alike), central, not a copy per repo, following hosted-supabase-audit.sh's established pattern exactly.

The rule is repo-level, deliberately. A first per-file draft — "a file that renders links and computes an active state must contain aria-current" — produced 19 findings, roughly a quarter wrong: evig spreads a helper that supplies the attribute, fleetcrown's parent passes current to a child that announces it, a tab list correctly uses aria-selected. A gate wrong a quarter of the time gets ignored. The repo-level assertion — somewhere in this repo, aria-current exists — has zero false positives in that class.

scripts/ci/test-nav-contract-audit.sh — self-test with synthetic git fixtures, run before every sweep (same doctrine as the hosted-Supabase and UI-defect audits: a clean report from a broken detector is worse than no report). It found a second real bug in the process: SKIP_FILE's tabs?\.(tsx|jsx)$ was unanchored and matched any file merely ending in "Tabs.tsx" as a substring — evig's AnalyseTabs.tsx included, silently skipped. Fixed by anchoring every alternative to (^|/). 7/7 self-tests pass.

.github/workflows/nav-contract.yml — actually schedules it. A script nothing calls enforces nothing; this is what turns the audit from something that exists into something that runs. Weekly + workflow_dispatch, same shallow-clone-the-fleet pattern as hosted-supabase.yml (--depth 1 --filter=blob:none, FLEET_READ_TOKEN, findings into the job summary).

scripts/ci/nav-contract.baseline — ships empty, with the ratchet's own convention: a genuine no-current-page nav gets a line with a reason, decided in a PR.

SHARED.md — records the gate landing (found and fixed six real repos on its first sweep: botsmann, datacat, petvity, printcraft, s-ink, surf-your-life) and a finding I deliberately did not act on: substrata, camille-boulangerie and wild-spirit are all on orangecat.ch subdomains but not yet linked from FLEET_SITES (the hand-maintained editorial list driving the rendered audit's discovery), and s-ink is genuinely off-pattern (sinktattoo.com). Adding entries there is a product/content decision — "each site's own words," per its own doc comment — not something to fold into a nav sweep.

Verification

  • 7/7 self-test cases pass, covering: catches a real defect, stays quiet with no active state, stays quiet when already correct, stays quiet on a tab list (the exact evig false-positive shape), baseline suppression, and dedup of two directories sharing one origin remote.
  • Ran live against the real fleet before and after each of the six fixes merged — went from 6 failing repos to fully green (35 repos, 227 nav files) as PRs landed during this session.
  • The workflow's shallow-clone step is proven end-to-end, not just asserted: cloned a real repo with gh repo clone --depth 1 --filter=blob:none, confirmed refs/remotes/origin/HEAD resolves correctly (some shallow-clone paths don't), ran the actual audit script against the result.
  • YAML validated.

🤖 Generated with Claude Code

https://claude.ai/code/session_01XeELB8b3N4JrT2asYL9WvE

catomean and others added 3 commits August 31, 2026 14:50
…n't see

ui-defect-audit.mjs renders each site's PUBLIC entry page — it cannot reach a
sidebar behind a login, which is exactly where the original bug in this
sweep lived. This is the other half: a source sweep run from this repo
against every default branch, the same pattern hosted-supabase-audit.sh
already uses (central, not a copy per repo).

THE RULE IS REPO-LEVEL, DELIBERATELY. A first per-FILE draft — "a file that
renders links and computes an active state must contain aria-current" —
produced 19 findings of which roughly a quarter were wrong, because the
active state and the announcement legitimately live in different files:
evig spreads a helper that supplies the attribute, fleetcrown's parent
passes `current` to a child that announces it, a tab list correctly uses
aria-selected. A gate wrong a quarter of the time gets ignored. The repo-
level assertion — somewhere in this repo, aria-current exists at all — has
no false positive in that class, at the cost of not pinpointing the file. The
rendered audit's job is the per-surface precision a live DOM can give; this
gate's job is coverage no renderer can reach.

Proven live, not just by fixture: on the first real run it named botsmann,
datacat, petvity, printcraft, s-ink and surf-your-life by their genuine
defect (checked against each repo's origin/main before any of them were
fixed), and cleared to green as each was fixed and merged during this same
session.

check:test-nav-contract-audit.sh, the self-test that runs before the sweep,
caught a second real bug in the process: SKIP_FILE's `tabs?\.(tsx|jsx)$` was
unanchored, so it matched any file merely ENDING in "Tabs.tsx" as a
substring — evig's AnalyseTabs.tsx included — and skipped it silently. All
four SKIP_FILE alternatives now anchor to `(^|/)`, matching a whole basename
rather than a suffix. The anchor fix surfaced 7 more nav files across the
fleet that a prior sweep had silently excluded; re-run after fixing, the
fleet is still fully green — the files were skipped, not violating.

Two things a fresh reader would ask, answered in the script itself:

- Two directories are not two repos. fleetcrown/fleetcrown-scripts and
  hirnli/revamp-info are each one repo cloned twice; the loop dedupes by
  origin URL so a finding is not doubled or a merge missed on one clone.
- `set -e` traps: `cmd && continue` is fatal when cmd's grep does not match,
  and `git symbolic-ref -q` on a clone with no default-branch tracking is
  the same trap. Every such probe here is an explicit `if`, not a `&&`.

Baseline file (nav-contract.baseline) ships empty with the ratchet's own
convention: a repo with a genuine no-current-page nav (a single-page tool
whose nav is anchors) gets a line with a reason, decided in a PR, not by
silently going green.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XeELB8b3N4JrT2asYL9WvE
…othing

nav-contract-audit.sh existed in the previous commit and nothing called it.
A check nothing runs is a suggestion, not a gate — the exact failure mode
SHARED.md already names for the accent-ink and duplication checks.

Mirrors hosted-supabase.yml's established pattern for this shape of audit
exactly: self-test before the sweep, shallow-clone the fleet with
--depth 1 --filter=blob:none (this repo has no package.json on purpose),
FLEET_READ_TOKEN for private repos with the gap stated rather than hidden,
weekly schedule plus workflow_dispatch, findings into the job summary where
a human actually looks.

Proven end-to-end against a real shallow clone, not just asserted: `gh repo
clone --depth 1 --filter=blob:none` sets refs/remotes/origin/HEAD correctly
(verified — some shallow-clone paths do not), and the audit script reads it
and runs clean against the result.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XeELB8b3N4JrT2asYL9WvE
… gap

The nav contract section described a two-gate plan (rendered audit + a couple
of per-repo checks) as the working state. As of this session there is a
third gate that actually shipped and ran: nav-contract-audit.sh, weekly,
central, self-tested, found and fixed six real repos on its first sweep.
Recorded with the date and the six names, not just "it exists."

Also records a finding the sweep surfaced but should not silently fix:
s-ink, substrata, camille-boulangerie and wild-spirit are all outside
FLEET_SITES, the hand-maintained editorial list that drives the rendered
audit's site discovery. Three of the four are actually on orangecat.ch
subdomains and would match the discovery regex if linked — only s-ink is
genuinely off-pattern (sinktattoo.com). Adding entries to FLEET_SITES is a
product/content decision ("each site's own words," per its own doc comment),
not a mechanical nav fix, so it is written down here for a human rather than
edited as a side effect of this sweep.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XeELB8b3N4JrT2asYL9WvE
@github-actions
github-actions Bot merged commit 3abb6ee into main Aug 31, 2026
1 check passed
@github-actions
github-actions Bot deleted the feat/nav-contract-audit branch August 31, 2026 12:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant