diff --git a/scripts/lint_arch.ts b/scripts/lint_arch.ts index e513efa..81e9e18 100644 --- a/scripts/lint_arch.ts +++ b/scripts/lint_arch.ts @@ -6,24 +6,37 @@ let hasErrors = false; async function checkFile(path: string) { const content = await Deno.readTextFile(path); - const lines = content.split('\n'); + const lines = content.split("\n"); lines.forEach((line, index) => { // 1. Block banned DOM APIs - if (line.includes("document.getElementById") || - line.includes("document.querySelector") || - line.includes("document.createElement")) { - console.error(`[Arch Lint] ❌ Banned DOM API used in ${path}:${index + 1}`); + if ( + line.includes("document.getElementById") || + line.includes("document.querySelector") || + line.includes("document.createElement") + ) { + console.error( + `[Arch Lint] ❌ Banned DOM API used in ${path}:${index + 1}`, + ); console.error(` ${line.trim()}`); - console.error(` -> Use Datastar reactive attributes or SSE morphs instead.`); + console.error( + ` -> Use Datastar reactive attributes or SSE morphs instead.`, + ); hasErrors = true; } // 2. Block unescaped HTML in raw strings (basic heuristic for dangerouslySetInnerHTML) - if (line.includes("dangerouslySetInnerHTML") && !path.includes("error_fragments.tsx")) { - console.error(`[Arch Lint] ❌ dangerouslySetInnerHTML used in ${path}:${index + 1}`); + if ( + line.includes("dangerouslySetInnerHTML") && + !path.includes("error_fragments.tsx") + ) { + console.error( + `[Arch Lint] ❌ dangerouslySetInnerHTML used in ${path}:${index + 1}`, + ); console.error(` ${line.trim()}`); - console.error(` -> Native JSX HTML escaping should be used unless in explicit core fragments.`); + console.error( + ` -> Native JSX HTML escaping should be used unless in explicit core fragments.`, + ); hasErrors = true; } }); diff --git a/src/core/auth_guards.test.ts b/src/core/auth_guards.test.ts index 78c5529..cee0f13 100644 --- a/src/core/auth_guards.test.ts +++ b/src/core/auth_guards.test.ts @@ -1,16 +1,16 @@ import { assertEquals } from "jsr:@std/assert"; import { determineClientType } from "./content_negotiation.ts"; -import { Context } from "jsr:@hono/hono@4"; +import type { Context } from "jsr:@hono/hono@4"; Deno.test("determineClientType - correctly identifies datastar", () => { - const mockContext = { - req: { - header: (name: string) => { - if (name === "datastar-request") return "true"; - return ""; - } - } - } as unknown as Context; + const mockContext = { + req: { + header: (name: string) => { + if (name === "datastar-request") return "true"; + return ""; + }, + }, + } as unknown as Context; - assertEquals(determineClientType(mockContext), "datastar"); + assertEquals(determineClientType(mockContext), "datastar"); }); diff --git a/tasks/audits/2026-0827-audit-2-phase-1.md b/tasks/audits/2026-0827-audit-2-phase-1.md new file mode 100644 index 0000000..01c4c24 --- /dev/null +++ b/tasks/audits/2026-0827-audit-2-phase-1.md @@ -0,0 +1,27 @@ +# Post-Implementation Audit: Phase 1 (Hypermedia Architecture) + +## 1. Test Suite Status +- **`deno fmt`**: Passed (After 2 minor corrections in test files and scripts) +- **`deno task lint`**: Passed (Fixed one verbatim-module-syntax warning in test imports) +- **`deno task check`**: Passed +- **`deno test -A --no-check`**: Passed (68 tests across 30 steps) + +## 2. Structural & Architectural Verification +- **Directory Placement:** `src/core/` successfully established with all requested single-purpose modules (`db.ts`, `valkey.ts`, `spire_ffi.ts`, `auth_guards.ts`, `content_negotiation.ts`, `sse_adapter.ts`, `error_fragments.tsx`, `main.ts`). +- **Legacy Quarantine:** Jules did NOT modify any files in the read-only `server/` or `ui/` directories. +- **Dependency Invariants:** `sdk/` and `spire_ffi/` were kept isolated. +- **Architectural Linting Hook:** `scripts/lint_arch.ts` successfully wired. It correctly rejects banned DOM APIs (`getElementById`, `querySelector`, `createElement`) and `dangerouslySetInnerHTML`. + +## 3. Code Hygiene & Rule Alignment +- **Flat Call Chains:** Confirmed. Functions in `src/core/auth_guards.ts` (e.g., `rateLimitGuard`, `payloadCapGuard`) are shallow and self-contained. +- **Datastar SSE Typing:** `sse_adapter.ts` correctly isolates raw protocol strings from route handlers. +- **Error Handling:** `error_fragments.tsx` conforms to the invariant to return target-directed HTML toasts instead of JSON errors. + +## 4. Issues Addressed +1. Jules forgot to run a final `deno fmt` on two newly created files. (Fixed) +2. Jules included an import type issue caught by the standard linter. (Fixed via `deno lint --fix`) +3. Jules eagerly moved the Task Plan to `tasks/complete/`. Because this is a 5-phase migration, I moved it to `tasks/in-progress/` to maintain continuity. + +## 5. Go / No-Go Decision +**Decision: GO.** 🟢 +Phase 1 is strictly verified, cleanly isolated in `src/`, and the repository quality gates are 100% green. We are cleared to commence Phase 2.