diff --git a/docs/audits/2026-06-09.md b/docs/audits/2026-06-09.md new file mode 100644 index 0000000..d92e331 --- /dev/null +++ b/docs/audits/2026-06-09.md @@ -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 `
` landmark wrapping the page's + primary content (previously `
`). +- Added a visible-on-focus skip-to-content link at the top of ``. + Defined new `.skip-link` class in `style.css`. Keyboard users now + have a one-tap escape from the masthead repeats. +- Wrapped the `←` 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 `
` 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 `
` +landmark and skip link. diff --git a/package-lock.json b/package-lock.json index 5487514..8e4b231 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7,13 +7,15 @@ "": { "name": "solo-stack", "version": "1.0.0", + "license": "MIT", "dependencies": { "chalk": "^4.1.2", "inquirer": "^8.2.7", - "js-yaml": "^4.1.0" - }, - "devDependencies": { + "js-yaml": "^4.1.0", "playwright": "^1.50.0" + }, + "bin": { + "solo-stack": "cli/index.js" } }, "node_modules/@inquirer/external-editor": { @@ -265,7 +267,6 @@ "version": "2.3.2", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, "hasInstallScript": true, "license": "MIT", "optional": true, @@ -396,9 +397,9 @@ } }, "node_modules/lodash": { - "version": "4.17.23", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.23.tgz", - "integrity": "sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==", + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.18.1.tgz", + "integrity": "sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==", "license": "MIT" }, "node_modules/log-symbols": { @@ -474,7 +475,6 @@ "version": "1.58.2", "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.58.2.tgz", "integrity": "sha512-vA30H8Nvkq/cPBnNw4Q8TWz1EJyqgpuinBcHET0YVJVFldr8JDNiU9LaWAE1KqSkRYazuaBhTpB5ZzShOezQ6A==", - "dev": true, "license": "Apache-2.0", "dependencies": { "playwright-core": "1.58.2" @@ -493,7 +493,6 @@ "version": "1.58.2", "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.58.2.tgz", "integrity": "sha512-yZkEtftgwS8CsfYo7nm0KE8jsvm6i/PTgVtB8DL726wNf6H2IMsDuxCpJj59KDaxCtSnrWan2AeDqM7JBaultg==", - "dev": true, "license": "Apache-2.0", "bin": { "playwright-core": "cli.js" diff --git a/site/index.html b/site/index.html index cd5cb84..8b95aa4 100644 --- a/site/index.html +++ b/site/index.html @@ -37,6 +37,7 @@ + -
+
@@ -125,13 +126,13 @@

- +

- +