13 Commits

Author SHA1 Message Date
Alex Dunmow
bba5946bb1 allow site-agent streaming hook createClient (WO-SA-006)
SiteAgentService.SendMessage is a Connect server-streaming RPC consumed
with for-await; generated Connect Query hooks are unary-only (same
justification as use-restart-operation).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-03 03:05:25 +08:00
Alex Dunmow
3c88b19ff6 docs: make README all-inclusive (full 31-check table, all CLI flags)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 15:12:19 +08:00
Alex Dunmow
936a7e7ef9 feat: enforce proto generation freshness 2026-06-20 12:40:06 +08:00
Alex Dunmow
f968cb31d9 fix: skip gitignored .worktrees/ dirs in repo scans
Directory walkers pruned .git/vendor/node_modules but not .worktrees/, so a repo scan descended into nested git worktrees (e.g. an orchestrator worktree under cms/.worktrees/). Their Go/TS files surfaced as false positives in the standalone-plugin import check and noise in the any-usage warnings.

Add ".worktrees" to the skip set across the implicated and common walkers: proto RBAC proto-scan, standalone-plugin imports, frontend extras, go-lint, sqlc-uuid, presets.json, and plugin segmentation.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 16:53:18 +08:00
Alex Dunmow
7b96ceac4d Link CLAUDE.md to AGENTS.md 2026-06-18 16:46:53 +08:00
Alex Dunmow
73259c6b30 fix(check-safety): recognize methodRolesSeed RBAC table; resolve backend scan-root
extractRBACMethodRoles matched only a map literal named MethodRoles. The CMS now
keeps its RBAC table behind an atomic-pointer copy-on-write live table, with the
static literal renamed to methodRolesSeed -- so the validator read an empty table
and reported 641 phantom "missing RBAC entry" methods, blinding the gate to any
genuine unregistered RPC. Match methodRolesSeed as well as MethodRoles, and add a
regression test (TestExtractRBACMethodRolesParsesSeedTable).

resolveScanRoots: also resolve a `backend` directory containing go.mod whose
parent holds buf.yaml or proto/, so the checker targets that layout correctly.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 11:04:40 +08:00
Alex Dunmow
c048766075 feat(checks): add check 28 — public page handlers inject admin toolbar
New AST check scans handler render functions that build site settings
(getSiteSettings + doc["site_settings"]) and fails if they don't also set
siteSettings["toolbar"], so admin-toolbar injection can't silently regress
when a new public page type is added.

- toolbar.go: AST scanner; exempts renderListingPage (auto SEO pages) and
  renderVersionPreview (carries its own preview banner).
- check_toolbar.go: registration at Seq 280 (ID "28").
- registry_test.go: +1 expected check; golden fixtures regenerated.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 22:37:59 +08:00
Alex Dunmow
7599fff971 feat: sanction /api/helpdesk/ as a known non-proto fetch prefix (WO-028)
Helpdesk attachment upload/download is multipart HTTP by design — ConnectRPC
has no multipart support — so the frontend fetch gets the same WARN-not-FAIL
treatment as /api/plugins/ and the other sanctioned REST endpoints.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-10 21:40:25 +08:00
Alex Dunmow
c3bb958f23 feat(frontend-check): flag raw <button> in JSX — use the shared <Button> component
New rules no-raw-button / no-raw-button-in-plugin ride inside Check 5's
walkers, same as the browser-confirm rules. Raw buttons bypass the
action=/entity= automation attributes (docs/BUTTON_AUTOMATION.md), so
MCP/Puppeteer can't target them.

Scope: .tsx/.jsx only (plain .ts builds DOM strings for non-React
surfaces), components/ui/ exempt (defines the primitives — same
carve-out as the button-automation check).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-10 15:15:46 +08:00
Alex Dunmow
fbe14f6c57 chore(frontend-check): document use-entity-search exception; allow helpdesk multipart fetches
use-entity-search reason expanded per 2026-06-10 work order Task 11
(Gate C: allowlist with documented reason). /api/support/ (CMS widget)
and /api/helpdesk/upload (orchestrator) are multipart FormData uploads
connect-query cannot express — WARN, not FAIL.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-10 14:52:35 +08:00
Alex Dunmow
0e8d0e6d1c fix(scan-roots): detect consolidated CMS layout (backend/go.mod + web/src)
The old detection keyed on backend/cmd/check-safety, which left the CMS
tree when check-safety was hoisted standalone. Since then the CMS
resolved as its own backend: web/ was classified as a plugin frontend
(strict rules, allowedFrontendFiles bypassed — audit F2's check-5 noise),
check 2 demanded RBAC entries for client-only orchestrator protos
(audit F3), check 2c flagged a bogus missing go.mod, and checks 3/3b
silently SKIPPED. Recognize backend/go.mod + web/src as the CMS shape
so backendDir resolves to backend/ and web/src scans under core rules.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-10 14:52:35 +08:00
Alex Dunmow
57bca429cc chore: follow CMS module rename in rule strings + test fixtures
CMS Go module renamed from git.dev.alexdunmow.com/block/ninja to
git.dev.alexdunmow.com/block/cms (along with the git remote rename
on gitea). All import paths, string-literal rules, test fixtures,
and doc references updated; (historical 'ninja-orchestrator' refs
preserved). go mod tidy regenerated checksums.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-06 13:55:47 +08:00
Alex Dunmow
cd88c808b0 initial: standalone check-safety module hoisted from CMS
Static safety/lint runner for the BlockNinja codebase. ~25 invariant
checks across Go and frontend sources. Was at git.dev.alexdunmow.com:block/ninja
in backend/cmd/check-safety/ until the 2026-06-06 consolidation moved
the BlockNinja repos under a shared ~/src/blockninja/ parent.

This repo is the standalone extraction:
- Own go.mod (git.dev.alexdunmow.com/block/check-safety, go 1.26.4)
- Vendored internal/{helpers,theme} from CMS (Go's internal/ rule
  blocks cross-module imports; vendoring is the workaround)
- CLI contract unchanged: `check-safety <target-dir> [--flags]`
- CMS Makefile shells into ../check-safety for safety-check /
  install-safety-checker targets

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-06 13:04:02 +08:00