Skip to content

chore(audit): execute 2026-06-10 (1223) audit — 6 findings, 3 new/extended guardrails - #157

Merged
agjs merged 6 commits into
mainfrom
chore/audit-fixes-20260610-1223
Jun 10, 2026
Merged

chore(audit): execute 2026-06-10 (1223) audit — 6 findings, 3 new/extended guardrails#157
agjs merged 6 commits into
mainfrom
chore/audit-fixes-20260610-1223

Conversation

@agjs

@agjs agjs commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

Summary

Executes the 2026-06-10 monorepo audit (6 findings, 0 critical / 2 high / 2 medium / 2 low). Each class-of-defect finding lands the guardrail and the fix; one-off logic bugs are fixed directly. All per-app gates green; full pre-push gate (gitleaks + semgrep + Docker smoke e2e) passed locally.

ID Finding Fix Guardrail
F005 Untracked generated worker-configuration.d.ts in docs gitignored
F002 api overrides had no //overrides rationale (ui/docs did) documented @typescript-eslint/utils pin extended package-override-parity to require a //overrides entry per override key, all apps
F003 Security scans used cancel-in-progress: true (PR #156 saw semgrep cancelled) flipped all 11 *-security-{sast,secrets,deps} to false new github-actions-security-no-cancel (lint-meta)
F006 gitleaks/semgrep versions duplicated per-file with no parity check none needed (already consistent) new security-scanner-version-parity (lint-meta, preventive)
F001 useNotificationsList ignored pageParam, re-fetched page 1 forever thread cursor through queryFn like useActivityFeed + regression test cross-repo tanstack-query-cache plugin (flagged, not editable here)
F004 Email rate limiter was process-local (bypassable across replicas) Valkey-backed counter when CACHE_PROVIDER=valkey, in-memory fallback on cache failure; check() now async one-off (deploy-topology dependent)

Done 6/6 · failed 0 · skipped 0. 3 new/extended lint-meta guardrails close these classes for every future consumer.

Notable decisions

  • F003 scoped the rule to all *-security-* (incl. dependency scans), not just sast/secrets — dependency scans are equally security gates.
  • F004 falls back to in-memory on a Valkey blip (defense-in-depth: degrade to per-process, never to no enforcement) and reuses the exact env gate security.ts already uses — no new config surface.

Test plan

  • bun run check from repo root (api / ui / docs all PASS)
  • cd apps/api && bun run check · cd apps/ui && bun run check · cd apps/docs && bun run check:docs-data
  • Pre-push gate: gitleaks clean, semgrep (api+ui) clean, Docker smoke e2e passed

App merge bars

Area Command
API cd apps/api && bun run validate
UI cd apps/ui && bun run validate
Docs cd apps/docs && bun run build:ci
Repo drift bun run check

Conventions

  • No any, no blind as, no !
  • No new env vars (F004 reuses existing CACHE_ENABLED/CACHE_PROVIDER)
  • Tests updated for changed behavior (notifications pagination, email rate-limit async, 3 new lint-meta rule tests)

Cross-repo follow-up

  • @boring-stack-pkg/eslint-plugin-tanstack-query-cache: flag useInfiniteQuery whose queryFn ignores pageParam when getNextPageParam is defined — would have caught F001 statically. Lives in boringstack-xyz/eslint-plugins.

agjs added 6 commits June 10, 2026 12:23
Extend package-override-parity to flag overrides lacking a //overrides rationale; document api's @typescript-eslint/utils pin.

Audit: F002
Add github-actions-security-no-cancel lint-meta rule and set cancel-in-progress: false on all 11 *-security-{sast,secrets,deps} workflows so no pushed ref goes unscanned.

Audit: F003
…orkflows

Add security-scanner-version-parity lint-meta rule so a scanner version bumped in one workflow can no longer drift from its siblings (different version = different ruleset).

Audit: F006
useNotificationsList ignored pageParam and re-fetched the first page on every fetchNextPage; thread the cursor through like useActivityFeed. Add a regression test asserting page 2 sends the prior nextCursor.

Audit: F001
Per-process Map enforced the resend/forgot-password cap per replica, so horizontal scale multiplied the real limit by the replica count. Use a shared Valkey counter when CACHE_PROVIDER=valkey, falling back to in-memory on any cache failure (degrade to per-process, never to no enforcement). check() is now async; await it at all 5 call sites.

Audit: F004
@agjs
agjs merged commit ff16cec into main Jun 10, 2026
31 checks passed
@agjs
agjs deleted the chore/audit-fixes-20260610-1223 branch June 10, 2026 11:13
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