Files
Codexandclaude[bot] 4f040c4c8e fix: exact upload quota, support palette allowlist, bounded SVG reference chains (#498)
Attachment uploads stage the body as `.upload-*` under files_root and then
asked the quota to count that file as stored usage *and* as the incoming
size, so the last file that still fit was refused at the boundary — by
bytes and by count. check_quota/dir_usage now take `exclude` for the
caller's own staged file; other staged files keep counting, so two
concurrent uploads can never both land past the limit.

The support package copied every string key of settings.fill_colors. The
schema stays open for compatibility, but the projection now keeps only the
eleven slots the card defines (SUPPORT_FILL_COLOR_KEYS, pinned to
src/logic.ts DEFAULT_FILL_COLORS by a test); an empty palette is omitted.

The SVG local-reference walk was a recursive DFS: a flat chain of a few
thousand hrefs passed every #436 bound and died with RecursionError, which
the upload view turned into a 500. The walk is iterative and measures the
longest chain through each node (memoised, order-independent); chains
deeper than MAX_SVG_REF_DEPTH = 64 are refused as too_large, cycles stay
invalid_image.

Tests: quota boundaries on the validator and the HA endpoint, a barrier
test for concurrent uploads, palette allowlist and TS parity, reference
chains (plain, hostile id order, cycle) on the validator and the endpoint;
six mutants caught by the standard runner.

Issue: #498
User-Visible: yes
2026-09-09 07:06:20 +00:00

3.4 KiB

House Plan private support reports

Updated: 2026-09-02, issue #43.

House Plan keeps normal configuration, layout and uploaded content inside the user's Home Assistant. The support relay is contacted only after the user presses Send in Help & feedback. Opening the dialog and building or downloading a preview do not make an external request.

What is sent

Every report contains the user's plain-text message, optional contact, bounded software versions and an idempotency key. The diagnostic JSON is optional and off by default. If selected, the integration sends the exact canonical bytes shown in the preview together with their size and SHA-256.

The package is constructed field by field. It contains plan geometry and dimensions, safe display settings (the fill palette only by the eleven slot names the card defines; any other key is dropped), structural counts, validation/repair families and bounded browser/registry capability enums. Space, room, wall, opening, marker and binding references receive random package-local names.

It excludes original names and text, Home Assistant installation/location, device/entity/area IDs, current states and attributes, IP addresses, hostnames, URLs, paths, filenames, plan/backdrop/manual bytes, vacuum calibration and trails, backup history, message and contact. Unknown fields are dropped rather than copied and redacted later.

The Zigbee topology snapshot is never offered to this package: raw provider payloads, IEEE addresses, neighbor links, base topics, timestamps and provider errors stay out of support preview/download/submission and out of browser storage and logs.

Preview and authorization

Only a Home Assistant user allowed to write House Plan can build or send a report. Preview bytes live in integration memory for at most ten minutes and are bound to that HA user and one dialog draft. Closing the dialog, disabling the attachment or a successful submit removes the token; process exit also removes it. Download uses the same preview text. The backend never rebuilds an attachment during submit.

A valid 48-character token in a response that the card cannot adopt is also discarded best-effort exactly once—even if the rest of the response is invalid, the dialog changed meanwhile, or the local state update was refused. Cleanup does not depend on whether that request is still current and never replaces the original UI error. Malformed token strings are not sent back; backend TTL remains the final guard if a discard transport itself fails.

Transport and retention

The integration can contact only https://support.houseplan.tech/v1/reports. The HTTPS host is compiled into the backend; redirects and user-configured destinations are refused. Provider response bodies and submitted content are not written to Home Assistant logs.

The relay writes an accepted report to its private spool before delivery to a private maintainer channel. Delivered reports, including message, contact and optional JSON, are retained for no more than 30 days. Rate-limit and idempotency records are retained for no more than 24 hours. A daily purge enforces both limits. No public GitHub issue or public Telegram post is created.

To request early deletion, contact the maintainer through the project's Telegram chat and provide the report ID shown after submission. The report ID is also the reference for follow-up; do not publish the downloaded support package unless you deliberately choose to do so.