AidFinder
Back to dashboard

af-mock-disaster-assistance-gov

FEMA Disaster Assistance Mock Website

Pixel-perfect vanilla-JS mock of the FEMA 29-page flow used to train and regression-test the AI agent containers without hammering the real gov site. MUST be served via python3 -m http.server.

Domain role
Test fixture / training environment
Last updated
2026-01-25
API style
StaticSite

Static HTML/CSS/JS site (no build step, no dependencies, no Node). 44 hash-routed pages — 29 in the main application sequence plus 15 supporting/conditional/utility pages. State is held in a 345-line schema (js/store/schema.js) that is the SINGLE source of truth — pages are not allowed to write to sessionStorage directly; they go through a session helper that validates dot-notation paths against the schema. Includes a Login.gov simulation layer (6 pages), progressive form validation, conditional page logic (skipped if conditionFn returns false), and a ?sessionFixture=name URL parameter that loads a pre-recorded JSON snapshot from /tests/fixtures/ for isolated page testing. Designed-in deterministic mode (?mode=deterministic) zeroes out simulated randomness (e.g. 10% identity-verification failure).

Role in the system: Drives agent regression tests; lets the AI agent containers be developed and validated without hammering DisasterAssistance.gov; intentionally insecure-by-design but safe because no real PII or auth flows through it

Surfaces:

  • 44 hash-routed pages (28 unconditional + 16 conditional/Login/tools)
  • URL params: ?sessionFixture, ?mode=deterministic|randomized, ?debug, ?logEvents
  • /#/session-editor — dev-only direct JSON state editor
  • Fixtures in tests/fixtures/*.json
  • Playwright e2e suite (in /tests/)

User workflows

  • Serve site

    http://localhost:8000 ready

  • Run agent against mock

    Agent regression-tested without hitting real FEMA

  • Inject session fixture

    Single page testable in isolation with realistic state

  • Deterministic mode

    Reproducible runs

API endpoints

  • GET/Home (landing)
  • GET/#/recaptchaMock CAPTCHA
  • GET/#/locationLocation of loss
  • GET/#/disasterDisaster selection
  • GET/#/countyCounty selection
  • GET/#/assistance-infoAssistance info
  • GET/#/needsDisaster-related needs
  • GET/#/conditional-funeralCONDITIONAL: funeral expenses
  • GET/#/conditional-medicalCONDITIONAL: medical
  • GET/#/conditional-homeCONDITIONAL: primary home damage
  • GET/#/conditional-childcareCONDITIONAL: child care
  • GET/#/conditional-safetyCONDITIONAL: home safety
  • GET/#/needs-reviewReview selected needs
  • GET/#/date-of-lossDate of loss
  • GET/#/damage-typesDamage types
  • GET/#/privacyPrivacy Act statement
  • GET/#/login-signin … /#/login-successLogin.gov simulation (6 pages)
  • GET/#/app-center-introApplication Center entry
  • GET/#/personal-infoPersonal info form
  • GET/#/address + /#/address-verificationAddress + verify
  • GET/#/extent-of-damage (cond) … /#/home-insurance (cond)Conditional damage detail pages
  • GET/#/occupants /#/income-information /#/payment-information /#/notifications /#/disability-needs /#/other-needs /#/review-application /#/identity-error /#/successApplication Center remaining pages
  • GET/#/session-editorDev/test direct JSON state editor

Third-party APIs

  • DOMPurify (CDN)

    HTML sanitization for any user-supplied HTML

  • Google Fonts (CDN)

    Source Sans Pro + Merriweather

Service dependencies

  • Python http.server (MANDATORY)

    Static server with correct ES module MIME type

Analysis

overall health3.7 / 5strong
4Module overview / clarity of intent
5External dependencies
4Database schema
3Frontend components
4Data flow clarity
3Error handling & resilience
4Configuration
3Data refresh patterns
4Performance
4Module interactions
4Troubleshooting / runbooks
4Testing & QA
3Deployment & DevOps
2Security & compliance
4Documentation & maintenance

af-mock-disaster-assistance-gov — Prop-Build Analysis

Document Type: Critical Review & Analysis (companion to prop-build-template.md) Scope: Per-Repo / Per-Module Subject: af-mock-disaster-assistance-gov (FEMA Disaster Assistance Mock Website) Reviewer(s): Claude (automated code review) Date: 2026-04-09 Version: 0.1 Confidence Level: Medium What would raise confidence: running the mock end-to-end against the live AI agents, executing the Playwright/pytest integration suite, and interviewing the author (Gordon Zheng).

Inputs Reviewed:

  • Prop-build doc: data/af-mock-disaster-assistance-gov.yaml
  • Companion files: data/af-mock-disaster-assistance-gov/{component-tree,data-flow,deployment,runbook,api-examples}.md
  • Source: /Users/andres/src/af/af-mock-disaster-assistance-gov/ (js/, tests/, index.html, README.md)

Part A — Per-Repo / Per-Module Analysis

Note: this repo is a mock / test harness used as a deterministic fixture for training and regression-testing AidFinder AI agents. Judged on test-harness quality (determinism, fixture ergonomics, schema stability, observability), not production hardening.

A.1 Executive Summary

  • Overall health: Ambitious, well-structured vanilla-ES6 harness: 43 page modules, canonical session schema, fixture injection, sizeable Python/Playwright test suite — solid bones for an AI-agent training fixture.
  • Top risk: Left-behind debug console.log statements dumping personalInformation on every save/load (js/storage.js:21,29,69,79,88,90,97; js/state.js:68) — harmless in a mock but a footgun if repurposed for recording agent traces. See A.4.1.
  • Top win / thing worth preserving: Schema-first session model (js/store/schema.js) + session-adapter validation + storage.injectSnapshot() fixture pipeline (js/storage.js:44-52) — exactly the right shape for a deterministic agent harness.
  • Single recommended next action: Delete debug console.log block in js/storage.js and js/state.js:68; route diagnostics through logger.js.
  • Blocking unknowns: Pixel-parity vs. real DisasterAssistance.gov (not verifiable from code); whether Playwright suite is wired into CI; flake rate of schema-migration tests.

A.2 Health Scorecard

#DimensionScore (1–5)Justification
1Module overview / clarity of intent4README, prop-build YAML, and layout (js/pages, js/store, js/components) make intent obvious.
2External dependencies5Zero runtime deps; only playwright devDep (package.json).
3API endpointsN/AStatic site, no server API; api-examples.md documents the client state contract.
4Database schema4js/store/schema.js is versioned (_meta._version); migrations.js exists.
5Backend servicesN/ANo backend.
6WebSocket / real-timeN/ANone.
7Frontend components3Components reused (form-field, navigation-buttons, sidebar-*), but large modules: session-editor.js 1295 LOC, vehicle-damage.js 687, personal-info.js 572, review-application.js 507; inline innerHTML.
8Data flow clarity4Hash router → page render → state.setsession-adapter.patch → schema validate → storage.save is legible end-to-end.
9Error handling & resilience3error-handler.js (428 LOC) + forceErrors injection in config.js — good for a harness.
10Configuration4js/config.js centralizes deterministic/randomized mode, query-string flags (?debug, ?logEvents, ?mode=), failure rates, force-error toggles.
11Data refresh patterns3Auto-save every 30s + save-on-set; no multi-tab reconciliation.
12Performance4Static assets; heavy modules irrelevant at mock scale.
13Module interactions4Clean import graph from app.js; no obvious cycles.
14Troubleshooting / runbooks4runbook.md + logger.downloadEventLog() + ?debug + in-browser session-editor.js.
15Testing & QA4~20 Python/Playwright integration scripts + named fixtures (tests/fixtures/*.json). No JS unit tests.
16Deployment & DevOps3python3 -m http.server deliberate; deployment.md documents it. No visible CI.
17Security & compliance2Not meaningfully applicable to a mock, but debug console.log of personalInformation is a real smell even here.
18Documentation & maintenance4README + YAML + 5 companion docs + JSDoc headers.
19Roadmap clarityN/ANo roadmap artifact beyond status: Active.

Overall score: 3.69 (weighted for the harness role, effective grade is higher: dimensions 1/2/4/8/10/14/15 all score 4+; 7 and 17 are either cosmetic or out-of-scope).


A.3 What's Working Well

  • Strength: Schema-first session model with explicit versioning and migrations.

    • Location: js/store/schema.js:1-50, js/store/migrations.js, js/store/session-adapter.js (validateSchema, validatePath, patch).
    • Why it works: Every write funnels through a validated patch() path; _meta._version lets the harness evolve without breaking saved fixtures.
    • Propagate to: af-fema-form-automation and future mock repos.
  • Strength: Fixture-injection seam for deterministic agent runs.

    • Location: js/storage.js:44-52 (injectSnapshot), tests/fixtures/*.json, js/utils/fixtures.js.
    • Why it works: Jump straight to any page state without walking the 29-page flow.
    • Propagate to: Any real-site-replica mock.
  • Strength: Deterministic-vs-randomized mode via URL flags.

    • Location: js/config.js:11-45 (mode, identityVerificationFailureRate, forceErrors, enableDebugPanel, enableEventLogging).
    • Why it works: A/B correctness vs. robustness tests without code changes.
  • Strength: In-browser session editor for debugging agent runs.

    • Location: js/pages/session-editor.js (1295 LOC).
    • Why it works: Operator can inspect/patch live state mid-run.

A.4 What to Improve

A.4.1 P1 — Debug console.log leaking personalInformation on every save/load

  • Problem: js/storage.js and js/state.js unconditionally console.log the full personalInformation subtree on every save, load, and set() — bypassing logger.js.
  • Evidence: js/storage.js:21-22,28-30,69,79,88-90,97; js/state.js:68.
  • Suggested change: Delete; if still useful, route through logger.debug().
  • Estimated effort: S.
  • Risk if ignored: Console noise; if harness is ever repurposed for real data, a PII-in-logs incident.

A.4.2 P2 — Oversized page modules mixing render, validation, handlers

  • Problem: Multiple 500+ LOC pages inline large innerHTML strings alongside validation and handler wiring.
  • Evidence: js/pages/session-editor.js 1295, vehicle-damage.js 687, personal-info.js 572 (SSN toggle HTML at lines 70, 367, 370), review-application.js 507, needs.js 413.
  • Suggested change: Extract per-page templates into sibling *.template.js; lean more on js/components/form-field.js.
  • Estimated effort: M.
  • Risk if ignored: Shotgun-surgery pressure grows as the mock tracks upstream UI changes.

A.4.3 P2 — No JS-level unit tests

  • Problem: No unit coverage for js/store/schema.js, js/store/session-adapter.js, js/store/migrations.js, js/validation.js — the exact modules correctness depends on.
  • Evidence: tests/ is Python-only; package.json "test" is a stub echo.
  • Suggested change: Add Vitest or node --test suite for store modules.
  • Estimated effort: M.
  • Risk if ignored: Schema regressions only caught by slow Playwright runs.

A.5 Things That Don't Make Sense

  1. Observation: package.json hard-blocks npm start/npm run dev with echo && exit 1 and declares "engines": { "node": "DO NOT USE - ..." }, yet playwright is a devDep that needs Node.

    • Location: package.json scripts + engines.
    • Hypotheses considered: (a) past http-server ES-module MIME bug; (b) enforcing Python parity with CI.
    • Question for author: What specifically broke under Node servers?
  2. Observation: session-editor.js (1295 LOC) is larger than app.js (476) + router.js (338) combined.

    • Location: js/pages/session-editor.js.
    • Hypotheses considered: Debug-tool accumulation point; runbook UI.
    • Question for author: Split into js/components/session-editor/?

A.6 Anti-Patterns Detected

A.6.1 Code-level

  • God object / god function — js/pages/session-editor.js (1295 LOC).
  • Shotgun surgery
  • Feature envy
  • Primitive obsession
  • Dead code
  • Copy-paste / duplication — inline SVG toggles at js/pages/personal-info.js:367,370.
  • Magic numbers
  • Deep nesting (>3)
  • Long parameter lists (>4)
  • Boolean-flag parameters

A.6.2 Architectural

  • Big ball of mud
  • Distributed monolith
  • Chatty services
  • Leaky abstraction
  • Golden hammer
  • Vendor lock-in
  • Stovepipe
  • Missing seams for testing — explicitly not checked; injectSnapshot + forceErrors + mode=deterministic are exactly the seams this asks for.

A.6.3 Data

N/A — no database; localStorage schema is versioned and validated.

A.6.4 Async / Ops

N/A — no queues, no distributed work.

A.6.5 Security

  • PII/PHI in logs — console.log of personalInformation in js/storage.js:21,29,69,88 and js/state.js:68. Synthetic today, pattern is the smell.
  • Secrets in code / .env committed
  • Missing authn/z on internal endpoints — N/A
  • Overbroad IAM — N/A
  • Unvalidated input crossing trust boundary — N/A
  • Missing CSRF/XSS/SQLi/SSRF — not flagging (mock; store is schema-validated).

A.6.6 Detected Instances

#Anti-patternLocation (file:line)SeverityRecommendation
1God function / oversized modulejs/pages/session-editor.js (1295 LOC)P2Split into js/components/session-editor/{view,actions,schema-tree}.js.
2Copy-paste inline SVG togglejs/pages/personal-info.js:367,370P2Extract components/icon-toggle.js or use <svg><use> sprite.
3PII-shaped data in console.logjs/storage.js:21,29,69,79,88,90,97; js/state.js:68P1Delete or route through logger.debug().

A.7 Open Questions

  1. Q: Is tests/integration/ wired into CI or run manually?

    • Blocks: A.2 row 15, A.13.
    • Who can answer: Gordon Zheng / QA owner.
  2. Q: How is schema-version drift between this mock and af-disaster-assistance-gov-agent coordinated when FEMA changes a field?

    • Blocks: A.10, Part B lockstep risk.
    • Who can answer: Agent-container maintainers.
  3. Q: Are tests/fixtures/ guaranteed-synthetic or seeded from real runs?

    • Blocks: A.11 Information Disclosure.

A.8 Difficulties Encountered

  • Difficulty: No local execution — Playwright not run, flow not walked.

    • Impact: Cannot verify pixel parity, flake rate, or that migrations.js upgrades legacy fixtures cleanly.
    • Fix: One-command make verify that spins server, runs suite, emits JUnit.
  • Difficulty: Page modules mix HTML + handlers + validation; "where is field X written?" needs whole-file reads.

    • Impact: Could not cheaply sample all 43 pages; row 7 is based on 5 largest + core modules.
    • Fix: A.4.2 template extraction + per-page header listing schema paths written.
  • Difficulty: No git log review of churn.

    • Impact: A.15 answered from YAML author metadata only.

A.9 Risks & Unknowns

A.9.1 Known risks

#RiskLikelihoodImpactMitigation
1Schema drift between mock and live agent breaks training runsMMPublish SESSION_SCHEMA_VERSION as shared constant; contract test in agent repo.
2Debug console.log of personal fields leaks real data if repurposedLMA.4.1.
3Oversized page modules slow FEMA refresh cyclesMLA.4.2.
4Python-only rule breaks Node-only CI containersLLDocument known-good image; or ship Node wrapper.

A.9.2 Unknown unknowns

  • Area not reviewed: Actual correctness vs. real DisasterAssistance.gov.

    • Reason: No access during review; "pixel-perfect" untestable from code.
    • Best guess risk: M — silent divergence trains agents on stale UI.
  • Area not reviewed: js/store/migrations.js run end-to-end on legacy fixtures.

    • Reason: Tests not executed.
    • Best guess risk: L–M.
  • Area not reviewed: ~37 of 43 page modules (sampled ~6).

    • Reason: Time.
    • Best guess risk: L — sampled patterns are consistent.
  • Area not reviewed: dynamic_flow_enhacement/, FEMA-Video-Screen-Cap/, update-mock-webpage/, specs/.

    • Reason: Out of primary code path.
    • Best guess risk: L.

A.10 Technical Debt Register

#DebtQuadrantInterestRemediation
1Debug console.log of personalInformation (js/storage.js:21,29,69,79,88,90,97; js/state.js:68)Reckless & InadvertentChronic noise; latent PII riskA.4.1.
2Oversized page modules (session-editor.js 1295, vehicle-damage.js 687, personal-info.js 572, review-application.js 507) mixing HTML + handlers + validationPrudent & InadvertentSlows edits, complicates reviewA.4.2.
3No JS unit tests for js/store/* and js/validation.jsPrudent & DeliberateSchema bugs only caught by full PlaywrightA.4.3.
4Hard block on Node servers in package.json while keeping playwright devDepReckless & DeliberateCI-container frictionDocument reason or ship Node static-server wrapper.
5session-editor as single 1295-LOC modulePrudent & InadvertentHard to extendSplit directory.

A.11 Security Posture (lightweight STRIDE)

N/A — single-origin, client-only static mock; no auth, no network, no backend. The one real finding (PII-shaped data in console.log) is captured in A.4.1, A.6.5, and A.10 #1.

A.12 Operational Readiness

N/A — ops concepts (SLOs, on-call, DR, backups) don't apply to a dev-run static fixture. Harness-level observability is captured under A.2 row 14 and A.3.

A.13 Test & Quality Signals

  • Coverage: Unknown (no tooling).
  • Trend: Unknown.
  • Flake rate: Unknown.
  • Slowest tests: Likely e2e_full_flow_test.py, test_full_flow_to_success.py.
  • Untested critical paths: js/store/schema.js, js/store/session-adapter.js, js/store/migrations.js, js/validation.js.
  • Missing test types: [x] unit [ ] integration [ ] e2e [x] contract (no cross-repo contract test) [x] load (N/A) [x] security/fuzz (N/A).

A.14 Performance & Cost Smells

N/A — static site, localStorage, no infra.

A.15 Bus-Factor & Knowledge Risk

  • Only-person: authors: ["Gordon Zheng"] in the YAML. Bus factor ≈ 1 for the 29-page → schema mapping.
  • What breaks if they vanish: Upstream FEMA UI tracking; schema-drift reconciliation with the agent repo.
  • Tribal knowledge: Which pages hand-traced vs. auto-captured; conditional-skip logic; the Node-server taboo.
  • Knowledge-transfer actions: One-page "how to add a FEMA page" doc; document FEMA-Video-Screen-Cap/ and update-mock-webpage/ workflows.

A.16 Compliance Gaps

N/A — YAML claims no HIPAA/SOC 2/state-insurance compliance; explicitly a mock.


A.17 Recommendations Summary

PriorityActionOwnerEffortDepends on
P1Remove debug console.log of personalInformation in js/storage.js:21,29,69,79,88,90,97 and js/state.js:68; route any still-useful diagnostics through logger.debug().Mock maintainer (Gordon Zheng)S
P1Add JS unit-test suite (Vitest or node --test) for js/store/schema.js, js/store/session-adapter.js, js/store/migrations.js, js/validation.js.Mock maintainer + QAM
P1Publish SESSION_SCHEMA_VERSION as shared contract; add cross-repo contract test in af-disaster-assistance-gov-agent that imports a canonical tests/fixtures/ fixture.Agent owner + mock maintainerMSchema-version stabilization
P2Extract per-page HTML templates from session-editor.js, vehicle-damage.js, personal-info.js, review-application.js, needs.js; lean on js/components/form-field.js.Mock maintainerM
P2Split js/pages/session-editor.js into js/components/session-editor/.Mock maintainerMTemplate extraction
P2Extract inline SVG eye-toggle (js/pages/personal-info.js:367,370) into components/icon-toggle.js or <svg><use> sprite.Mock maintainerS
P2README: document why Node servers are blocked; list known-good CI image.Mock maintainerS
P2Write "how to add a FEMA page" runbook to reduce bus-factor risk.Mock maintainerS