Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 72 additions & 0 deletions docs/audits/2026-06-09.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# Audit Log: 2026-06-09

Foundational audit pass against The Pragmatic Programmer principles
plus a11y on `site/` and dep vuln scan. PR: `audit/2026-06-09` → main.

## Shipped in this PR

**Orthogonality (`/coupling`):**
- Verdict: codebase is genuinely exemplary. `shared/recommend.js`,
`shared/questions.json`, `shared/labels.json`, `shared/constants.js`,
`cli/data.js` are documented canonical singletons in CLAUDE.md,
consumed by both CLI and site (via the build artifact pattern).
- Verified `shared/recommend.js` and `site/recommend.js` are
byte-identical — `scripts/build-site.js` copies one to the other
and the result is in sync. The "don't fork the recommendation
engine" rule holds.
- Zero cycles, zero wildcards, zero cross-layer violations.

**DRY (`/drift`):**
- No model IDs, no year-bound constants, no hand-typed enums.
- Em-dash usage exists in `site/data.json` (tool descriptions). It's
content, not code, and CLAUDE.md doesn't forbid em-dashes here.
Not drift.
- One hardcoded `https://surfrrosa.github.io/solo-stack/` in
`cli/index.js:70` (a help message). Single site = not duplication.

**Broken windows (`/zombie`):**
- Zero commented-out code blocks, zero TODOs/FIXMEs/HACKs, zero empty
catch blocks, zero dead exports across `cli/`, `shared/`, `scripts/`.

**Accessibility (`/a11y`) on `site/`:**
- Added `<main id="main-content">` landmark wrapping the page's
primary content (previously `<div class="scene">`).
- Added a visible-on-focus skip-to-content link at the top of `<body>`.
Defined new `.skip-link` class in `style.css`. Keyboard users now
have a one-tap escape from the masthead repeats.
- Wrapped the `&larr;` glyph in the "Back to start" button in
`aria-hidden="true"` so screen readers don't announce it as
content. Added explicit `type="button"` for clarity.

**Dependency vulnerability (`/vuln`):**
- `npm audit fix` resolved the high-severity lodash CVEs
(prototype-pollution + code-injection) via a transitive bump.
Zero vulnerabilities remaining.
- The fix also reconciled drift between `package.json` (which had
`playwright` in `dependencies`) and `package-lock.json` (which had
treated it as a dev dep). The lock now matches package.json's
declaration.

## Light verifications

- `node scripts/validate-yaml.js` — clean (35 files, 0 errors, 4
pre-existing warnings unrelated to this PR).
- `node scripts/build-site.js` — clean (32 tools, 3 stacks).

## Out of scope (declined / not needed)

- A `<main>` landmark on `404.html`. The 404 page is intentionally
minimal; not worth the churn.
- Em-dash sweep in `site/data.json` tool descriptions. Content, not
drift.
- The `playwright` package being declared as a regular `dependency`
rather than `devDependency`. Pre-existing decision; the audit
surfaces it but doesn't change it.

## Onlooker takeaway

The repo's discipline is already strong: canonical singletons in
`shared/`, documented "don't fork" rule (with a commit referenced for
the original incident), schema-validated YAML, weekly Playwright
pricing checks. The audit's most visible additions are the `<main>`
landmark and skip link.
17 changes: 8 additions & 9 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 4 additions & 3 deletions site/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,15 @@
<link rel="stylesheet" href="style.css">
</head>
<body>
<a href="#main-content" class="skip-link">Skip to main content</a>
<noscript>
<div class="noscript-banner">
This interactive stack builder requires JavaScript.
<a href="https://github.com/surfrrosa/solo-stack">View the full guide on GitHub</a>
for the same content as plain Markdown.
</div>
</noscript>
<div class="scene">
<main id="main-content" class="scene">

<!-- Landing -->
<div id="screen-landing" class="screen active">
Expand Down Expand Up @@ -125,13 +126,13 @@ <h1>
<div class="tx-table" id="tx-table"></div>

<div class="tx-back">
<button class="back-btn" onclick="resetBuilder()">&larr; Back to start</button>
<button type="button" class="back-btn" onclick="resetBuilder()"><span aria-hidden="true">&larr;</span> Back to start</button>
</div>
</div>
</div>
</div>

</div>
</main>

<footer class="site-footer">
<span>No affiliate links. Real costs.</span>
Expand Down
19 changes: 19 additions & 0 deletions site/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,25 @@ body {
border: 0;
}

.skip-link {
position: absolute;
left: -9999px;
top: 0;
z-index: 999;
background: #fff;
color: #000;
padding: 8px 16px;
border-radius: 4px;
font-family: inherit;
text-decoration: none;
}

.skip-link:focus {
left: 8px;
top: 8px;
outline: 2px solid currentColor;
}

h1 { margin: 0; padding: 0; }

/* --- Screens --- */
Expand Down
Loading