Files
houseplan-card/docs/AUDIT-QUALITY.md
T
Cursor AgentandMatysh 99f7c3a4a9 docs: full project audit pack for agents (market, quality, gaps)
Add docs/AUDIT*.md covering competitive landscape (easy-floorplan 11→430★),
implementation quality, functional integrity, and P0–P3 recommendations.
Refresh PRODUCT.md competitor claim and point STATUS watchlist at the pack.

Co-authored-by: Matysh <Matysh@users.noreply.github.com>
2026-08-05 04:56:01 +00:00

6.7 KiB
Raw Blame History

Audit — implementation quality

Snapshot: 2026-08-05, product v1.58.0. Severity: critical / major / minor / nit. No critical RCE found under normal HA session auth.

1. Architecture snapshot

src/                         Lit 3 Lovelace cards (houseplan + space-card)
  houseplan-card.ts          ~8691 LOC — orchestration god-object
  logic.ts / devices.ts / …  extracted pure modules (good)
  styles.ts                  ~2223 LOC CSS-in-JS
custom_components/houseplan/ HA integration (storage, WS, HTTP, trails)
dist/ + frontend/            committed bundle (CI byte-compares)
demo/                        Playwright harness + smoke_*.mjs
tests_backend/               pure + HA-harness pytest

Bundle: ≈449 KB raw / ≈128 KB gzip — acceptable for a full editor+viewer.

2. What is strong

Backend

  • Single write-auth helper (auth.may_write) with fail-closed when entry missing (audit B2 lesson documented in the module).
  • Voluptuous validation with cross-language option-list tests that parse DISPLAY_MODES / TAP_ACTIONS from logic.ts — rare and valuable.
  • Config CAS via expected_rev; plan COW + quotas; never-delete-on-inference file policy (SCOPE).
  • Geometry migration with durable geom_pending intent (HP-1490 class).
  • Content HTTP: requires_auth, signed URLs for <image href>, SVG CSP sandbox.
  • Diagnostics / repairs / system_health present; quality_scale.yaml mostly honest (test-coverage, strict-typing, docs todos marked todo).

Frontend (extracted brain)

  • Tap security model in resolveTapAction — locks/alarms never toggle from the plan; cover garage/door/gate guarded; run limited to automation/script/scene.
  • Pure geometry / devices / sun / vacuum / resize / align-grid / signing modules with solid node:test coverage (~270 tests).
  • Shared config-store + space-geometry/render for houseplan-space-card.
  • Optimistic UI without rollback is documented intentional (ARCHITECTURE).

Process

  • Four test layers + smoke policy (“[manual] must have a failing auto check”).
  • Dual CHANGELOG (en/ru), SCOPE guard rail, CONTRIBUTING five-minute loop.
  • CI: hacs + hassfest + frontend + backend + smoke job.

3. Findings (ranked)

# Sev Finding Where
1 major God-object card: ~8691 LOC, ~359 methods, ~125 private fields; render() ~382 lines. Smokes-only coverage for orchestration. src/houseplan-card.ts
2 major strict: true hollowed by noImplicitAny: false; ~200 any sites in the card alone; hass: any everywhere tsconfig.json, card / devices / logic
3 major Write-policy split: UI _canEdit is always admin-gated; API default admin_only=False lets any authenticated user write via WS/HTTP houseplan-card.ts ≈L247–249, auth.py
4 major _canEdit fails open when hass.user is missing (is_admin !== false) card ≈L248
5 major styles.ts ~2223 LOC — second maintainability sink; untested src/styles.ts
6 minor layout/update has no expected_rev — multi-tablet last-writer-wins per point websocket_api.py
7 minor Marker binding is bare str; ripple_color not hex-matched; decor w/h allow negatives via _NORM validation.py
8 minor Card-level tap_action / resolveTapAction cardDefault is dead / ignored — confusing API surface types.ts, click path
9 minor Store _async_migrate_func is a no-op; real migrations live ad-hoc in setup store.py, __init__.py
10 nit quality_scale.yaml cites test_config_flow.py; file is test_ha_config_flow.py quality_scale.yaml
11 nit Duplicated fireEvent / navigate in card + space-card both files
— positive Forbidden-domain tap model + confirm + cover guards logic.ts
— positive Signed content + SVG sandbox http_api.py, signing.ts

No critical auth bypass of HA sessions found. Closest systemic issue is finding #3 (API openness vs UI) under the default options.

4. TypeScript & tooling

Item State
tsc --noEmit in build Yes — correct (rollup TS plugin can warn-and-ship)
ESLint / Prettier Absent
noImplicitAny Off
Frontend unit of the Lit class None
mypy strict (backend) quality_scale todo

5. Test map

Layer What it proves Gap
npm test (~270) Pure logic, i18n parity, tap security, geometry Not the card shell
pytest pure validation.py without HA —
HA-harness (py≥3.13) setup, WS races, auth, upload, geometry repair Coverage % unmeasured
demo/smoke_*.mjs (~100) Real pointer/UI against fake hass Pixel flakes (smoke_opening_measure); no Safari/Companion matrix

Human checklist in TESTING.md last full self-run recorded at v1.21.1 while product is at v1.58.0 — auto net grew; documented human pass did not.

6. Docs drift (quality of truth)

Doc Drift
ARCHITECTURE.md intro Still mentions old src/data/house.ts / 1489×1053 era in places; square/infinite canvas sections newer
UX-MODES.md header Still says “No code has been changed yet” — Phase 11 shipped
PRODUCT.md competitor table Stale — easy-floorplan 11→430★ (see AUDIT-MARKET)
STATUS.md Generally current as of 2026-08-04

Docs discipline is a project strength; these drifts are fixable and should be treated as debt, not ignored.

7. Top 10 technical debt (actionable)

  1. Split houseplan-card.ts into shell + Plan/Devices/Decor editors + dialogs.
  2. Turn on noImplicitAny incrementally; type a thin Hass surface.
  3. Align write policy: wire UI to admin_only, or default admin_only=True.
  4. Fail closed on missing hass.user.
  5. Add CAS / expected_rev to layout/update (or document single-writer assumption).
  6. Split styles.ts by feature surface.
  7. Tighten MARKER_SCHEMA (binding, colors, decor extents, space ids).
  8. Unit-test orchestration hotspots (_clickDevice, write-chain conflicts, modes).
  9. Real Store migrations or document setup-time migrations as the only path.
  10. Remove or re-wire dead card-level tap_action / cardDefault.

Detailed priority and sequencing: AUDIT-RECOMMENDATIONS.md.

8. Quality-scale honesty check

Claim Audit view
Bronze structural items done Accurate
Silver unloading / owner done Accurate
Gold diagnostics / repairs done Accurate
test-coverage / strict-typing / docs examples todo Accurate — keep them todo until measured
config-flow-test-coverage path typo Nit — fix filename in yaml

Overall: self-assessment is trustworthy; do not mark coverage done without a number.