Changelog
What we shipped, in plain language. Generated from our commit history, so it cannot quietly fall behind the product.
What's new - 4 October 2026
Across STERRYK™
Plain words, right where you read them
Household, suite, seat and room now have a short "What's a household?" style explanation beside the first place each word appears - on your Account page, on Pricing and on the checkout card.
Vonkara
Weekly review
A new Weekly review page shows which projects are ready for a next step and which have been quiet for 30 days. Park a project on Someday and it comes back for a look after 90 days. Mark the review complete and Vonkara remembers when you last did one.
Next steps at a glance
Projects with no task to start today carry an "Add a next step" tag, and a filter on the Projects page lists them together. When you complete a task, a small green check mark and the word Done appear right beside it.
A clearer Dashboard
Your Dashboard labels what is about you and what is about your team, and shows your streak and points. It shows the two notices that matter most, and once you close a notice it stays closed on every browser.
Recycle bin
Drafts you delete from the Study Room wait in the Recycle bin for 30 days, with a note on how long each one is kept. Restore one and it returns with the status it had before.
Light room
Vonkara now follows your light theme, and text, buttons and badges stand out clearly.
On your phone
The top bar and the banner buttons fit the screen, and buttons such as Update payment show their full label.
Invitations
Invite a teammate on the People page opens Invitations, and confirm buttons say what they do - Delete, Remove or Withdraw.
Screen readers
Screen readers now hear the same updates you see on screen.
Heldaro
Your money at a glance
Net worth and savings rate now sit at the top of your Dashboard as their own cards, beside the risk cards.
Clear about what a number rests on
When you change an input, a result that was worked out from your earlier inputs says so, with a one-tap Recalculate.
Rand everywhere
Stress-test amounts and portfolio figures are labelled in rand, and losses show with a minus sign.
Goals total
Under your goals table, a total row sets the monthly amounts you have set aside against what the last calculation left over.
A note on the sample funds
Stress results and the workspace result card carry one short line - "Sample uses US-listed funds, no currency conversion" - with a tooltip for the detail.
On your phone
Heldaro's menu folds into a top bar and tables turn into easy-to-read cards.
Kragara
A light room that reads comfortably
Kragara's light room has clearer control edges, soft tints for each state and clear cues for errors, so every screen is easy on the eyes.
A warm-up for new learners
Your first visit to Review opens a short practice round - three prompts you reveal and move through. It is just for getting the feel of it and is not recorded. Finish it or skip it; it shows once.
Mixed sessions, calmer
In a mixed session the skill label stays out of the way, and the Watch-Out tip arrives after your answer as a "For next time" note. Elsewhere it waits until you tap the chip.
On your phone
Signed-in pages now fit a phone screen without sideways scrolling.
Features
- shell: name the open rooms on the home picture and list every room under it
- shell: founder portrait on the Who we are page
- shell: the House footer on every signed-in surface
- web: marketing slice 0 - docs real 404, trust sitemap + canonicals, noindex on private routes
- shell: new-password boxes stay empty - the rule is the visible helper line; gate holds it
- shell: example text fainter and italic, one shared rule; name example "Jane Doe"
- shell: example text in every sign-in-page input; a11y_pages holds the rule
- gates: product preflight - check an app batch against House before it merges
- shell: plan-active - dark-lit arch frame in dark theme (same outline), frame no longer dimmed in code
- shell: plan-active - quiet period for the competing controls, one balanced block at 1440
- shell: plan-active moment - the plan's own painted room, with a plain confirmation under it
- shell: 404 lantern - light-card bloom held back, caption under the button, balanced wrap
- shell: 404 lantern - larger desk picture, the sentence fades in, tight text block
- shell: 404 lantern - the repainted light (owner pick 2026-10-08), words wait for the fade
- shell: the stuck-room notice names the ROOM (Your Office is taking a moment), from the catalogue
- shell: 404 lantern - larger picture, warmer turn-up, contact shadow, words only when lit
- shell: 404 lantern - the owner-picked painted light replaces the drawn glow
- shell: stuck-room safety net from PR #616 without the entry animation
- shell: warm paper light theme - the House's own surfaces on the landing's cream, a paper frame for the signed-in home, pricing/legal/404 follow the theme, a room island keeps rooms cool
- catalogue: free course levels as catalogue data, held equal to the compose literal
- lighthouse_public: --desktop preset flag + runner pin
- shell: 404 lantern round 3 - light that reads as light, one ground, phone-size picture
- shell: house-page quick wins (sticky CTA timing, 44px targets, footer dedupe, companion dvh, hub fit)
- shell: motion moment 1, round 2 - lantern arrival, honest reconnect, shared glow layer
- shell: motion moment 1 - illustration accessor, banked ember (offline), 404 lantern
- landing: sky v7 - sideways weather, warmer underside-lit felt, per-env runtime switch
- landing: sky v6 - opaque amber felt, rims carry the product colours, calmer
- landing: sky v5 - felt clouds, whole clouds sized to the margin, lazy chunk
- landing: moving sky in the side margins behind VITE_LANDING_SKY (off by default)
- per-seat claim-survival rollup (verify --rollup) and board KPI reader (EXEC-H1-CHRO-01)
- deletion: nightly erase job, lifecycle emails E2-E5, deletion_queue signal, self_serve_deletion gate (app plan P1 steps 6+8)
- identity: the shared /_verify cache reports its own state (HOUSE-R-226 follow-up)
- billing: self-serve deletion stops renewal at the request and restores it on keep (app plan P1 step 5)
- identity: deletion confirmation email E1 (app plan P1 step 6, E1 only)
- house: switch ON three finished product features for House only
- shell: Kragara is light-ready - the bar above the room follows the visitor theme
- identity: self-serve account deletion step 4 - request, grace, restore
- shell: owner decisions D1=option 2, D2=option 1 in storePolicy
- gate: object_ownership - no superuser-owned objects in House schemas; migrate.py refuses a superuser (HOUSE-R-287)
- notes drawer: focus trap, visible label, one live status line, saving feedback; tests for keyboard, focus, save/close, 390 px, rule 7
- check_rls: member_private_probe_values - declared values for CHECK-limited columns; draft_links declares role=from
- shell: app plan P1 - store channel no-sell fence + store_no_sell gate
- tools: Lighthouse over the public pages, worst score + local budget gate (HOUSE-LIGHTHOUSE-TOOL)
- first per-seat golden eval set (CFO, 14 cases) + eval_seat harness and gate
- registry: declare vonkara.waiting_for member-private (dual-member probe)
- analytics: return_visit and paywall_to_paid funnel queries + fixture gate (EXEC-H1-CDO-02)
- shell: Notes jot drawer behind Vonkara's capability probe (notes.v1 step 6) [DRAFT, untested]
- shell: light register + hero picture on the landing page (DRAFT, owner pick A)
- shell: 'Notes' pill - a doorway to the Study Room from every room, the lot and the landing (notes.v1 step 4)
- shell: light register for sign-in, sign-up, forgot-password (DRAFT, design round)
- shell: app plan P0 - installable web app (manifest, minimal service worker, offline page, install hint)
- gate: check_glossary - House words are glossed per surface or allowlisted with a reason
- ui: near-limit usage line states the count left (owner ruling)
- ui: warmer insight lines - lead with what is left and when it refreshes
- ui: Term shows a visible label (What's a household?) instead of a bare ?
- pitr: one writer sub-account per environment (owner ruling 2026-10-03)
- ui: one interpretation line per data display - AI meter + product usage
- ui: Term - define House words (household, suite, seat, room) at first use
- pitr: house-postgres image (pinned postgres + wal-g v3.0.9), preprod only (HOUSE-R-042 PR 2)
- pitr: declare the PITR credentials and confine them (HOUSE-R-042, PITR plan PR 1)
- billing: the status answer says which Paddle it is (sandbox lane 1A)
- billing: the credit reconcile reads Paddle with its OWN read-only key (no fallback)
- billing: schedule the customer-credit reconcile inside billing + surface it as a prod signal
- prod-signals: chain_integrity - read-only money hash-chain verdict in the prod snapshot
- billing: Gate B P1b - book Paddle customer credit through a liability (D40)
- catalogue: drive the plan picker's Recommended badge from the catalogue (REC-1)
- shell: Paddle INLINE checkout step on /account, proven under the prod CSP (HOUSE-R-258)
- gates: two CSP gates for HOUSE-R-225 - bundle style pins + nonce wiring
- merge-steward: pre-flight, gate_teeth baseline shortcut, stall watchdog, baseline cache, cheap-first order
- ciso: per-feature ai-egress kill switch + runtime content-safety gate
- gateway: add HSTS/CSP/X-Content-Type-Options/X-Frame-Options headers
- preprod-to-prod promotion gate (Azure-DevOps-style release gate)
- preprod: add ai-egress so the AI-abuse entitlement gate is testable before prod (#213)
- trust: W6 launch — announcement copy + a credential-rotation qualifier on the RLS trust claim
- billing: say the 14-day refund window BEFORE the money moves
- gates: wire typecheck into local_ci -- it was running in no lane at all
- local_ci: refuse a dirty tree, void a verdict whose tree moved (owner ruling)
- identity: record released email addresses, close HOUSE-R-175 Half A (0056)
- identity: key OAuth identities on the provider subject, not the email (HOUSE-R-175)
- shell: head metadata — brand-first title, description, OG basics
- shell: account credential cards + change-email landing; gate the Cancel surface for Free households (HOUSE-R-146, HOUSE-R-163)
- identity: self-service change-email + change-password (HOUSE-R-146)
- gateway: serve the Apple Pay domain association file
- paddle: the arming pre-flight, the dunning gap's real defect, and the runbook
- release-os: let the health pass be re-run without deploying again
- release-os: the prod path — typed confirmation, the 423 lock, and automatic promotion
- release-os: the preprod deploy button, streamed progress, and the health pass that arms the lock
- release-os: mechanical review facts, and an AI digest that can never become one
- release-os: the git map, the wire probes and the diff view
- release-os: the deploy pane's skeleton — prod lock, HTTP gates, Jarvis child on 8768
- gates: HOUSE-R-134 price-map CONTENT gate + HOUSE-R-133 late-claim ledger tie test
- seo: write the robots.txt and sitemap the site has been 404ing, and gate them
- preprod: mount vonkara/heldaro/kragara into the preprod compose
- registry: declare Kragara's content surface as a CLASS + the DISJOINT gate
- refund: the tracked refund-request queue — a mechanism for the 14-day promise
- copy: reposition the regulated wording, place the claim footnotes, clear the landing jargon
- catalogue: declare the levers Vonkara and Kragara actually enforce
- catalogue: remove the hollow Capacity pack, and retire the rung its price was propping up
- catalogue: park the Office SKU — it sold two features that 403 for every House buyer
- auth: let a person actually verify their own email
- legal: the POPIA data-subject request machinery — cluster A closed
- gates: watch the compliance docs; framework §12 — before a new purpose ships
- identity: waitlist marketing consent (POPIA s69) + the dormancy ruling
- docs: F2 notice on Ask-the-docs; F3 checklist; PIIA corrected — F2 was already live
- identity: enforce the 18-or-older attestation on both signup doors (PIIA F1)
- legal: PIIA (Reg 4(1)(b)) — G3 closed; four claims found ahead of their mechanisms
- legal: Reg 4(1)(a) compliance framework + request register; correct a 2FA over-claim
- legal: generate the PAIA manual PDF; s51(3)(b) needed one and none existed
- legal: E4 fully closed — the IO was registered on 2026-08-06, cert 2026-063826
- legal: E4 — PAIA entity facts filled, plus the s55(2) gate the fill created
- finance: Phase 9.3 — zero opening basis RATIFIED + marker one-shot + basis_at cutoff
- finance: Phase 9.4 — the v1-vs-v2 divergence reporter (shadow-period second half)
- finance: Phase 9.1 — prod finance lane behind the owner-ratified arm var
- finance: Phase 8.4 — partition roller sidecar (posting survives the year boundary)
- finance: Phase 8.3 — KRI/reporting layer on the tie-out sidecar
- finance: Phase 8.2 — AR/manual-collection lane per the ratified CAO shape
- finance: Phase 8.1 — payment_attempt/dunning projection lane
- finance: ruling 6.1 v2 Stage 1 — tax-only fee-return detection, posts nothing
- erasure: finance retention phase in check_erasure_safety + schema-wide preflight (Ruling G)
- finance: implementation wave 2 — the projector, the tie-out engine, and their teeth
- preprod: wire the finance-v2 lane — finance-migrate, projector + tie-out sidecars, inbox flag
- finance: implementation wave 1 — uuid7, inbox ingest lane, roles+guards, RETAIN class, containment gate
- finance: fold Phase 3 wave-2 board conditions + owner-ratified CLO rulings
- finance: Phase 2 — the greenfield finance schema proposal (DDL + design + uuidv7 gate)
- preprod: Phase 0 — generated Caddyfile.preprod + gate, gateway bake, money-path compose subset
- t5: the gate over the gates — one mechanism for teeth-loss, and the three gates it found
- t4-6: control total + stuck-reservation sweeper for the free-tier AI meter
- billing,shell: name the period-end DATE before the cancel click — S3d §5.K-B
- billing: resolve a returning customer's household when the nonce is dead — R-133 opt 2
- identity,shell: let the reset link follow the server's email capability — HOUSE-R-017
- billing: detect charge-after-cancel — nothing ever scanned cancel_request_open
- billing,shell: show a SCHEDULED cancel on every visit — S3d §5.K-A
- billing: claim-side grace for a late first webhook delivery — HOUSE-R-133
- billing: content-aware money-path signal on /version — HOUSE-R-134
- legal: S4b — legal pages authored vs actual tracking + R-128 acceptance recording (roadmap §C2–C6)
- erasure: PR-4.2 right-to-erasure built + gated — closes R-052 + R-126 (roadmap §C1)
- billing: tag the personal-suite refund contra with its room (S3b-2)
- registry: hero addons unsellable until the Q4 allowance consumer ships (S3b-1)
- shell: the v2 purchase surface — per-room tier cards + room-overlay plans (S3a)
- analytics: checkout_opened — the funnel's missing middle step (S3a)
- shell,analytics: S2d — first_value_reached event, R-018/R-019 UX dead-ends closed
- tour: UXD-27.10 — the tour rides the 2D world, and the home mount is pinned
- world: the 2D world becomes the home, and the 3D lot becomes the testbed
- world: the 2D world rendered through the S1b seam — panorama, badge, line, doors
- world: the 2D world's sixteen rooms + their hotspot geometry, with a gate
- lot-art: Timeless Lot room panoramas -> production assets + provenance
- tools: parameterise room_probe's target slug
- tools: room_probe — prove a mounted room BOOTS before a human walks it
- tools: local_ci — a runner you can trust when Actions minutes are gone
- tools: a live-shot harness — see the world, not a diagram of it
- tour: intent capture as the tour's opening beat (W1-2, UXD-20)
- lot: the generalised armature — UXD-22/23/24, bands, and a level axis
- lot: draw the lot as a PLAN, and ratchet the thing it exposes
- tour: video-scene direction — script for approval, free roam restored, build gated
- tour: move the tour onto the LIVE LOT, driving its own spirit (W1-1i)
- tour: she FLIES, the first pass runs itself, and actions get a nudge (W1-1c)
- tour: the two presenters — 2D room card + 3D werf guide (W1-1b)
- werf: keep FELT Rykie - the procedural rebuild was wrong (owner call)
- werf: Rykie rebuilt in the werf's own material language
- tour: the mascot tour spine (W1-1) - runtime, types, locale guard
- signup: close self-serve signup behind a waitlist (UXD-12)
- werf: build out the werf - two wings close the courtyard, products bound to buildings
- werf: material + scale gate with teeth (owner ruled full scope)
- werf: engine proof round 3 — polish + condition 5 answered
- werf: engine proof round 2 — the silhouette test now passes
- werf: the engine proof for the world direction — round 1, partial pass
- email: wire the six SES SMTP env vars into identity — the runbook's no-compose-edit claim was wrong (O-5 class)
- i18n: Paraglide JS across the House-owned surfaces, en + af
- growth: public roadmap (Fider) + generated GA-gated product directory
- lot3d: seat the study round-2b re-roll — warm-umber graduation set (CWO PASS)
- lot3d: Phase-1 signatures — ship FIVE vignettes; study re-roll pending (owner rulings)
- privacy: replay erasure runbook + export metadata — close the P1/P2 replay trust gaps
- lot: in-world upsell overlay — a locked-room click no longer ejects to /account (P0/E1)
- analytics: register fireplace_entered — D3 dwell baseline
- world-ux: wire the wave-1 lot HUD/scene changes (D1.1-D1.5, D2, D3)
- world-ux: Account control, Help card, postcard fallback components
- world-ux: D1.2 first-paint splash + branded loading rungs
- world-ux: pure decision helpers for the wave-1 lot interactions
- gateway: bake docs dist + route /docs and /api/ask-docs (no new hostname)
- ai-egress: "Ask the docs" RAG endpoint on the egress chokepoint
- docs: Starlight docs workspace + Scalar API reference (baked under /docs)
- replay: gateway @replay surface (forward_auth, before /api/* catchall)
- replay: shell recorder + consent UI + default-deny + viewer
- replay: DB sink + identity ingest/viewer routes
- flags: the shell/product consumer seam — useSession().hasFlag + the exported hasFlag helper
- flags: the flag:<name> gradual-rollout namespace — /_verify DB-resolved, fail-soft, kill-switched (FLAGS_ROLLOUT_DESIGN.md)
- analytics: bake the Umami website id — the landing beacon goes live
- analytics: re-enable Umami — pgcrypto fixed, migrate hand-proven
- pricing: P7 RATIFIED — Math Board 2026-07-19 verdict recorded, price gate flipped
- pricing: encode Math Board caveats — allowance 75, refund clamp, trial policy, overage invoicing
- identity: /_verify enforces expires_at at read time + mints X-House-Allowances
- billing: v2 runtime — one-main CAS, tier reconcile, allowances write, 0031 hardening; suite 24F/55P -> 99P
- analytics: T0-3 in-house product-analytics pipeline (HOUSE-R-007 storage half)
- catalogue: P7 go-live price gate — LIVE Paddle sync refuses unratified seed prices
- tools: sync_paddle_catalogue — the registry is the source of truth, Paddle is derived
- catalogue: registry 0.3.0 — per-room tier ladders, packs, hero addons + catalogue gate v2
- shell: /verify-email landing page (unblocks the email-verification prod-flip)
- identity: email delivery seam for forgot-password + verify-email (HOUSE-R-017)
- billing: book non-USD MoR settlement in the functional currency (HOUSE-R-012)
- identity: build the self-serve password-reset flow (HOUSE-R-017)
- lot3d: the tree wears its coils — sitting 2b PASSES and F3 CLOSES with zero residuals
- lot3d: F3 sitting 2 — the walk winds, the facade closes, the rim rings (5 of 6 shipped)
- lot3d: the clip gate sees the signature anchors — and its first run caught two real clips
- lot3d: the wall probe PASSES — the house is felt (sitting 1b)
- lot3d: F3 sitting 1 — 6 of 8 assets shipped; the yard comes alive
- lot3d: the felt hill — plateau, skirt, treeline, stitch hem + drag clamp (W4a)
- lot3d: F3 AUDIT #1 + every confirmed composition/scene fix (W2+W3)
- 3d: F3 W1 eyes — unpack_kit.py + render_lot.py headless review renders
- lot3d: F3 W0+W1 CI slice — clip/parity + material-law gates, day-one fixes
- lot3d: spirits roam free — home-tethered wander per the motion law
- lot3d: F2 — the spirits move in (Rykie, Vonkie, Heldie, Kraggie)
- lot3d: the lamplighting — dusk parity pass (Track D round 2)
- lot3d: the amber hour — dusk horizon glow + warm dusk grade (Track D gap fix)
- 3d: Tier-3 felt pass — cream walls + oak floors; compose fixes
- lot3d: V3 re-compose of the default lot — the Hearthfelt landmark silhouette
- 3d: Hearthfelt Minimum Lot Set installed — 11 new pieces + 4 replacements, catalog + thumbs
- 3d: Hearthfelt intake processor + proof-round adjudication + batch convention
- gates: token-drift gate covers the mascot-law colours (star-glow, ember, krag)
- lot3d: Hearthfelt F0 — warm token night, a sky full of homes, hearth glow, void fix
- kragara: wire the ingest+generate worker + ai-egress base URL (Kragara W6a/W6b go-live)
- dashboard: remediation steps per risk row — normal + novice toggle, "no known fix" highlight (#58)
- dashboard: one-click interactive viewer (dashboard.cmd → localhost server + Run buttons) (#57)
- dashboard: DASH-P1b + P3 — light the last blind lanes + verdict-change alerting (adversarially reviewed) (#56)
- dashboard: DASH-P1 — module-budget gate (lights blind QUA) + reconcile newly-measurable rows (#55)
- dashboard: DASH-P2 — must-act aging + multi-run history/trend (assess change, not just state) (#53)
- dashboard: EFF efficiency dimension + apply the top-tier infra optimizations (#52)
- dashboard: house health + risk register dashboard (tools/house_health.py) (#50)
- shell: wire the paywall into the 3D lot + delete the dead 2D-lot engine (#46)
- gateway: serve Microsoft publisher-domain verification file
- shell: Phase 2 — per-product 'open the door' room previews
- shell: Sterryk legal pages + close Phase-1 gaps
- shell+identity: Sterryk landing + /login + /signup + 14-day gate + Google/Microsoft OAuth (Phase 1)
- gateway+services: X-Request-Id correlation (PR-2.6) + /healthz probes & compose healthchecks (PR-2.5)
Fixes
- store_no_sell: S3 declares the footer Pricing label as a plans-cta primitive
- docs-ask: a provider failure is "answers paused", not "signed out"; Sign in that returns; one origin
- gate: cast the door lookup to oid in jwt_key_write_fence (HOUSE-R-370)
- ui: one-line Terms consent, normal-case tick labels, color-scheme follows the chosen theme
- ui: themed tick box (.house-check) + the invitation link in the card's typeface
- shell: disabled primary button gets a tonal fill so it reads as a button, not an input
- shell: disabled primary button readable in Light + Night on every auth page; gate measures it
- shell: error-tracker release = House build sha, environment from the host at runtime (HOUSE-R-354)
- shell: switch off the error tracker's automatic session ping (HOUSE-R-354)
- lighthouse_public: the process-tree known-bads record the refusal exit (2) they stage, not exit 0
- merge_steward_e2e: heartbeat so a busy box is not read as STALLED
- lighthouse_public: kill the whole browser tree, clean profiles, refuse on a crowd
- gate: reword a docstring line the secrets scan read as Basic Auth credentials
- gate: store_no_sell selftest anchors on the new /pricing line (PricingPage is eager now) + clearer anchor-missing message
- shell: Export my data is reachable by everyone, not only from the Cancel tab
- shell: 404 contact shadow stays dark on the warm-paper light theme
- shell: chips-to-dots breakpoint 600px -> 640px (canonical phone width; the breakpoints gate refuses 600)
- shell: plan-active - night frame file names match the doorway PR (threshold.arch-frame-dark-*)
- shell: stuck-room notice primary button holds 4.5:1 in every room and theme
- whats_running: a scan that could not finish is CANNOT MEASURE, named - never a red
- gates: disclose house.account.returnTo on the Cookies page; allowlist two placeholder/live-region glossary pairs
- shell: light-theme leftovers + first-visit speed (login/signup CLS, pricing/home LCP, smaller first bundle)
- gateway: CSP script hash for the pre-paint theme script (check_csp_hashes)
- gateway: CSP style hash for the splash rule added to index.html (check_csp_hashes)
- gateway: CSP style hash for the splash rule added to index.html (check_csp_hashes)
- shell: light accent follows the warm palette (gold, not blue) so the 404 and account buttons match
- shell: no name on file - the account button says Account (owner ruling)
- shell: drop a brand hex from a comment (brand_token_drift)
- shell: light-theme sweep - account menu panel on theme tokens, bar shows the person's name, signed-in opened-state a11y_pages scenarios
- shell: 404 lantern - isolate the light's blend to the niche
- shell: the unmounted-room frame's back bar is a header landmark
- bootstrap: guard the product eraser policies on household_id, not on the table - and prove it two ways
- bootstrap: guard the 0070 eraser block on its columns; walk prior migration heads (HOUSE-R-297)
- merge-steward: a baseline that could not measure is never "inherited"
- check_lighthouse_public: selftest judges recorded runner cases so a silenced gate fails (gate_teeth DE-TOOTHED)
- vitest_instances: keep credential-shaped text out of source so secrets_scan stays clean
- js: one vitest instance + CANNOT MEASURE on a tree that crosses instances
- check_lighthouse_public: retry-ladder cases are runner pins, not gate known-bads (new_gate --verify)
- selftest: erase-due scrub fixture DSN built from parts (secrets_scan)
- gates: pair the self_serve_deletion fixture grants with their audit rows; build the eraser fixture DSN from parts
- shell: disclose house.landing.skyPaused on the Cookies page
- ai-egress: screen Ask-the-docs answers with content_safety.check_output (HOUSE-R-291)
- lighthouse_public: NO_NAVSTART root cause - site isolation off keeps about:blank->page in one process; 13/13 pages measured
- landing: clip the sky's drift field to its margin (paint containment)
- gate: self_serve_deletion splits proconfig on newline - a search_path value carries commas
- landing: sky sides are their own fixed boxes; no new stacking contexts
- ai-egress: docs-rag mints its own request id; a PK-race duplicate reserve is a 409 replay (HOUSE-R-283)
- dep_audit: bump vue/smol-toml/source-map-js/postcss-selector-parser via overrides; triage python-jose GHSA-3qf3-8w2g-rqmx
- billing: every Paddle adjustment books exactly once per adjustment id (SEC-10 F5)
- risk_row: UTF-8 stdout/stderr and child processes, so /risk open survives a bare Windows console
- erasure: fail closed when the Kragara row cannot be tied to the principal (HOUSE-R-278)
- lighthouse_public: retry NO_NAVSTART with settle pauses, anti-throttle flags, old-headless last try; DARK reason lists each attempt
- shell: disclose sk.channel + sk.store_install on the Cookies page; secrets-scan-safe docstring
- steward: append-only register union read an unbound name
- shell: offline page theme-color comes from the hub token, not a literal
- steward: split the merge-steward selftest into a fast and a slow tier
- erasure: resolve the Kragara row by house_principal, not email (HOUSE-R-286)
- steward: list all open PRs (--limit 1000) and refuse plan --prs naming a PR not open
- billing: refunds book only on approval; park early transactions; stale grants cannot undo a cancel (HOUSE-R-279, HOUSE-R-280)
- auth: retry a lost renewal inside the reuse grace window (HOUSE-R-289)
- gateway,ai-egress: strip X-House-Request-Id/AI-Feature; refuse request-id replays; route-keyed kill switch (HOUSE-R-283, HOUSE-R-284)
- identity: replay viewer operator gate reads a VERIFIED live email (HOUSE-R-285)
- R-282: keep secrets out of GlitchTip in all three services
- erasure: house_eraser teardown policies on Kragara's dual-key tables (HOUSE-R-278)
- ux: notes placeholder uses text-muted (4.28:1 -> 6.34:1 on bg-inset) + UX-02 audit
- glossary: notes drawer - reasoned allowlist for 'household' (radio label) and 'room' (placeholder name)
- registry: waiting_for in all three registry copies + the erasure strict list
- notes drawer: client id falls back to getRandomValues where crypto.randomUUID is missing
- notes drawer: the save split stacks intrinsically (auto-fit) instead of a 400px media query
- check_rls selftest: newline escapes in the probe-values messages
- shell: hide the sonar ring in the left-aligned landing hero (clipped by the band edge)
- registry: draft_links in the strict block of VONKARA_PERSONAL; note counts twelve strict
- shell: landing light test reads index.html via ?raw (typecheck); reword hex in a CSS comment (token drift)
- lighthouse_public: subject floor in the gate, JSON-parsed selftest counts, cannot_measure_skip
- notes-pill: crumb-name collapse at the canonical 480px step (was 400px, off the breakpoint ledger)
- auth-light: re-pin app-theme pre-paint script hash (prod+preprod CSP); doc status DECIDED/BUILT
- identity: any member name verifies, and products get it as X-House-Display-Name
- shell: Notes pill fits one line at 360px in en + af; lighter pill type
- dashboard teeth: classify the LIVE wrong-role probe; pin the projector replay clock (HOUSE-R-272)
- shell: install hint uses only the canonical 640px breakpoint
- steward/i18n: end the transient Paraglide README false alarm (HOUSE-R-272)
- glossary: allowlist the manifest description (OS install dialog is plain text, no Term can render)
- follow-up (viewport-safe tooltip, plan's-limit wording)
- follow-up (viewport-safe tooltip, plan's-limit wording)
- pitr: assemble the OpenSSH PEM markers so secrets_scan does not read them as a key
- billing,shell: offer a plan only where billing can sell it (HOUSE-R-263)
- gateway: /account back on the strict SPA CSP - the HOUSE-R-258 interim profile is removed
- ui: move Spinner/Switch/AiCapNotice inline styles into real stylesheets (HOUSE-R-261)
- billing: serialise customer-credit movements + bound refunds cumulatively (#440)
- audit-chain: serialise appends per (household, month) chain - concurrent writers forked it
- billing: Gate B P1 receiver hardening - book proration shapes, no strip on upgrade refunds
- i18n: checkout copy says subscription, not order
- identity: keep the customer email out of provision_user's RuntimeError
- subprocessors: correct Cloudflare R2 entry — not live, backups are Hetzner
- subprocessors: mark Higgsfield/Gemini internal-tooling (owner ruling)
- shell: pin the exact inline frameStyle instead of storing its CSP hash literal
- gateway: HOUSE-R-258 interim - a checkout-only CSP profile for /account
- gateway: let Paddle's checkout stylesheet through the CSP; serve /who-we-are at 200
- rename selftest fixture to avoid secrets_scan false positive
- release: blue/green parity no longer deadlocks on a credential rotation
- a11y: wire aria-invalid/aria-describedby on AccountCredentials cards (F1/F2)
- shell: every checkout return lands on the account confirmation (HOUSE-R-246)
- dep_audit: chunk OSV querybatch at 1000 and count a 4xx as ERROR, not offline
- colour_file_e2e: derive the both-missing/both-garbage expectation from the real select.caddy, never a hardcoded literal
- risk_row: resolve register conflicts by parsed id blocks, never git hunks (HOUSE-R-230)
- cookies: escape the apostrophe that broke the string (typecheck red in the steward batch)
- local_ci: build the selftest's placeholder passwords instead of writing literals (secrets_scan flagged them)
- local_ci: gate DSNs name 127.0.0.1, never localhost (a silent 15-minute hang on Windows)
- gates: subject floors for check_csp_hashes and check_static_dirs (subject_floor gate red on main)
- gate: check_token_drift resolves product siblings relative to the House tree under test, not D:/Projects
- lot: write the room-usage cache key as an inline template so the disclosure gate reads it as <slug>
- cookies: disclose the house.room-usage-<slug> cache the account page writes (browser_storage gate was red on main)
- fonts: self-host Satoshi and Space Grotesk; drop the CSP-blocked Fontshare @import
- compose: identity's Redis DSN can no longer be overridden by a stale Coolify env row (HOUSE-R-204 §6)
- signup: offer the invitation-code box from the up-front closed notice, before any submit
- thread a per-request CSP nonce to Vonkara's MantineProvider (VNK-R-4)
- hash-pin Heldaro's base CSS into the gateway CSP (HLD-R-12)
- mounted-product frame shrinks to content width instead of filling it
- "Unlock" label no longer trails off with a bare em-dash
- authenticated "Open the door" trapped visitors on the landing page
- shell: keep chrome dark for dark-only mounted products in Light mode
- shell: mount AppThemeScope on the real ProductBoot path, not just App.tsx's dead /app/:slug route
- docs: register af as a real Starlight locale for hreflang + lang
- pricing: drop literal brand hex from a JSX comment (brand_token_drift)
- main is red — HOUSE-R-208 is missing 'opened', and the changelog is stale
- repair risk/RISK_REGISTER.yaml — the previous commit left conflict markers
- docs: declare the W6 claim table's terminal status for doc_freshness
- disclose the new storage key, correct R-178's likelihood, regenerate
- auth: clear the verification card in OTHER tabs too
- auth: don't show "Send verification email" to someone who just verified
- nav: the You menu opened off the top of the screen in the 2D world and on landing
- auth: tell the refused OAuth visitor how to actually fix it
- release-os: isolate the ledger in the selftest's HTTP section
- registry: re-sync the baked catalogue copies after the Paddle reclassification
- local_ci: the selftest fixtures tripped the secrets scanner
- shell: providers can be null where the card stays mounted (TS18047)
- shell: change-email warns that provider sign-in follows the address; the cancel empty state no longer asserts a negative from an unresolved fetch (HOUSE-R-163, HOUSE-R-175)
- identity: pending change-email tokens die on credential rotation; issue supersedes; escape the takeover notice; control-char email floor (HOUSE-R-146 review)
- runbook: the login is team@sterryk.com — finance@ has limited rights
- runbook: Step 1 named one scope where six are needed
- gates: a tooth that could not run is a FAILURE, not a skip — and a correction to HOUSE-R-172
- gates: bound the vitest worker pool — the shell suite was running 28 of its 404 assertions
- gates: a generated artifact is not a broken pointer — and file HOUSE-R-172 for the vitest OOM
- services: stop sentry re-wrapping every sync endpoint once per request
- release-os: give the health pass a wire settle budget, and stop a prod pass claiming to arm
- release-os: check Vonkara for REACHABILITY, not for a sha it can never report
- release-os: deploy_lag is ADVISORY — it asks a different question from the health pass
- gates: risk/RISK_REGISTER.md gets the diff-guard it was already annotated as having (HOUSE-R-170)
- money: HOUSE-R-154 hard revocation outranks grace + HOUSE-R-155 per-period seat tie-out
- gates: run the F14 per-route forward_auth walk on the REAL Caddyfiles (HOUSE-R-014)
- shell: scrub token URLs from rrweb replay capture + declare Referrer-Policy (HOUSE-R-144)
- identity: revoke-by-subject epoch, atomic registration guard, reset-issuance floor (HOUSE-R-164/150/144)
- gates: check_gate_teeth read role/DSN state PR #87 moved to gate_db_roles
- health: house_health --full gave every DB gate ONE DSN — six read red for the role, twelve for the absence
- web: trust.sterryk.com answered 200 to every path — HOUSE-R-147's disease on a second host
- tooling: local_ci --help died on a cp1252 console — the gate crashed on the box that needs it
- qua: HOUSE-R-152 — gates DECLARE known-bads and nothing re-ran them; execute the corpus
- auth: HOUSE-R-139 — a tab woken past expiry took the row's own symptom; single-flight reissue
- ci-guard: add -Windowless, so the hourly watchdog stops opening a console
- docs: CLAUDE.md's plan-of-record pointer targeted a deleted plan file
- i18n: drop orphaned feature_ai_analysis key after the O3 pull — feature_labels + i18n gates green
- registry: pull "AI analysis" from Heldaro Free (O3, owner-ruled)
- account: gate the Cancel-tab screen on pendingCancelAt (M4/F-041 residual)
- account: anonymous /account is no longer a dead end (M3/FLW-A-04)
- pricing: disclose the invite gate before the CTA click (H6)
- landing: CTA honesty while signup is closed (H6/CXO-A-05/FLW-A-06)
- account: route the support-email link text through a message key
- auth: LoginPage renders the session-expired banner (H5/E3 contract)
- identity: M5/F-052 — /account seats figure is the purchased seat block, not the member count
- account: activation-stall message now has an escape route
- auth: a refused invite code now shows why, keeps what you typed
- landing: topbar responsive at ~480px, Sign-up CTA no longer clipped
- directory: /directory drops banned system-ui + rogue accent, gates dead Office CSS
- shell: H1/FLW-A-03 House seam — a product CSS preload failure no longer kills the room
- auth: F-090 mount half — a transient /me failure at page load no longer deletes the stored token
- trust: security.html sub-processor table said AWS SES, mail moved to Google Workspace
- auth: H5/R-139b — an expired stored token now redirects to /login?next=<here>&reason=expired
- gateway: missing /assets/* chunk 404s instead of poisoning the client cache
- email: our mail had no Date and no Message-ID, which is why it hit spam
- email: the endpoint is the RELAY, not plain Gmail SMTP
- email: swap the transactional seam off SES to Google Workspace, AWS said no
- docs: SES runbook Step 5 still pointed at app 3, the wrong Coolify app
- identity: make a failed email say WHY, and correct two stale SES facts
- gateway: the `to` subdirective is a third way to name an upstream
- gateway: close the two holes in the gate I just wrote, record the RLS ordering
- gateway: gate the client-IP pin, and stop the trust flag outrunning it
- web: close two B1 escalations on merge; record B3's grown scope
- copy: apply the two S6 owner rulings — footer label + the PAIA gloss
- copy: close the five /code-review findings — bundle footnotes, hover-Escape, selftest crash
- ai-egress: correct overage price default 6->9, gate the drift
- parity: re-bless the standalone baseline after the audited Heldaro fix
- catalogue: close the five findings the review raised against the Office park
- legal: close S7's two open items per owner rulings; add S14 (refund queue)
- legal: attach the 14-day refund promise to the door that can keep it (F1)
- web: state per-tier features on the public pricing page (Paddle verification)
- identity: stop the checkout-nonce tests depending on a pristine database
- billing: repair the 6 DB-backed receiver tests broken by the R-155 split
- identity: repair the 41 DB-backed tests broken by the age attestation
- auth: make a closed signup navigable from both doors
- shell: ES-module worker format — Kragara's PGlite sandbox worker code-splits
- legal: Paddle domain review — 14-day unqualified refund policy + legal name in Terms
- finance: divergence anti-vacuity floor — 0 households is a state, not a misconfig
- finance: T4 item 10 ratified + implemented — identity-2 refund term gated on principal
- finance: pre-mortem findings 11-13 + real-shape revision recording
- finance: docs-sweep finding #10 — identity 5 compared fields adjusted_totals cannot carry
- finance: docs-sweep finding #9 — reversal flips the original adjustment's status
- finance: adjustment_item records on first observation only (sweep open item 1)
- finance: finding #8 completion — identity 3's totals term uses the posting-event snapshot
- finance: sweep finding #8 — tie-out expected side reads the posting event's snapshot
- finance: sweep findings 5-7 — payload-time state ordering, entity idempotence, retained_fee path
- finance: encode the CAO refund-basis ruling (sweep finding #4)
- finance: sweep findings 1-3 — dict money fields, per-event isolation, transaction.updated
- finance: 0003 — the writer's missing GRANT USAGE ON SCHEMA finance
- migrate: per-product mode creates the target schema before its ledger
- migrate-image: bake db/finance_v2 into house-migrate
- finance: fold Phase 3 wave-1 audit findings into the v2 proposal
- reconcile: distinguish empty-platform (exit 3) from misconfig; preprod opt-in grace
- billing: the sandbox customer-portal host was silently refused
- t3-1: suppress the purge selftest's redaction-pin fixture password
- t3: published falsehoods — the replay purge that never ran, dead legal links, an undisclosed storage set
- t2: the revenue path — entitlement key proof, seat floor 1, threaded 402, dunning honesty, public pricing
- t1b: the session/product-boot seam — T1-2..T1-5, with the gates that hold them
- t5-2: house_health.py review_due check — catch OPEN rows past review_by regardless of proof class
- t0: close the OAuth account takeover + the login enumeration oracle; gate the launch checklist
- billing: actually RUN the charge-after-cancel detector in prod
- shell: give an authenticated visitor a way in from the landing topbar — S3d §5.J
- billing: log WHY an outbound cancel failed + warn on a truncated Paddle key — S3d (checklist 5.N)
- identity: /me must not advertise a plan /_verify has stripped — S3d D10 (checklist 5.M)
- billing: an EMPTY Paddle base URL must not pass the pairing guard — S3d D9 (checklist 5.K)
- billing: a placeholder key must not crash the boot — S3d D9 follow-up (checklist 5.K)
- billing: treat a non-Paddle-shaped API key as absent — S3d D9 / HOUSE-R-109 (checklist 5.K)
- shell: stamp the landing gate from /account — S3d D8 (checklist 5.J)
- billing: a never-granted subscription can no longer claim the one-main slot — S3d D7 (checklist 5.I)
- billing: refuse an INVERTED BILLING_PRICE_MAP at boot — S3d D6 (checklist 5.H)
- checkout: S3d — the four sandbox-E2E defects (checklist §5.E-RESULT): one-plan enforced at the nonce, checkout-return logout, visible success, plan+cancel surface
- export: scope each product table by ITS declared predicate — closes the S4b §4b P1 503
- shell: carry the account/sign-out control to World2D (S1d follow-up)
- gates: two teeth made vacuous by the addon availability flip (S3b follow-up)
- billing: wire the 0013 cancel_request inbound closure (S3b-3)
- registry: re-sync baked events.json copies — S2d's first_value_reached was missed
- gate: a provenance ledger is made of hashes — scope the shape, not the file
- tools: room_probe hardcoded a password literal — generate it, and regenerate the changelog
- dev: NF-5 — failures in a mounted room now NAME themselves (3 fixes)
- paywall: a deep-linked office key checked out the WRONG PRODUCT (W0-2 residual)
- dev: the dev gateway could not start at all — build the real Caddy
- gate: the trophy pin was STALE, not wrong — and the test said so badly
- gate: check_lot_materials could not fail — the emissive check was unfailable
- gates: clear four pre-existing reds — and one was hiding a real bug
- identity: signup was closed at /register only — OAuth created accounts freely
- werf: the scale gate was checking four numbers no pixel depended on
- lot: declare the camera — it was an accident that hid five rooms
- gate: follow STRUCTURE_IS_ITS_OWN_SIGNATURE to its new home
- lot: the Garden and Tool Shed were not clickable at all
- werf: the proof route has been rendering at MIDNIGHT on every cold load
- tour: use the LOT's spirit motion law, on triggered paths (W1-1g)
- tour: one motion law for everything that moves (W1-1f)
- tour: the camera was cancelling her — lead in, HOLD, settle (W1-1e)
- tour: she TRAVELS — a timed journey, not a damped chase (W1-1d)
- waitlist: the endpoint accepted addresses and wrote NOTHING
- gateway: route /api/identity/waitlist as public, or the form is dead
- werf: only the manor carries a shaped gable
- werf: rebuild the gable properly - one roof, real parapet, aligned axis
- werf: owner's four corrections from the live proof
- paywall: quote the right SKU at every room door + UX audit of record
- i18n: notfound_back speaks House — EN aligned to the world-language (owner ruling)
- ai-egress: clamp Ask-the-docs question length (input-token cost guard)
- catalogue: canonical tier-key grammar (Math Board A3) + 2 known-bad teeth
- ai-egress: generalize the free-path gate off 'home' + wire Kragara through ai-egress in dev
- dr: make bootstrap_roles.py restore-clean on a truly fresh target (HOUSE-R-112)
- health: score gate launch-failure (rc 127) as unknown, not a false red
- compose: mount ./registry into reconcile-seats + reconcile-ai-cogs (crash on /registry/plans.json)
- gateway: route-wrap kragara/heldaro/vonkara (HOUSE-R-117 class hardening)
- gateway: route-wrap ai-egress to end the /health+/version 404 (HOUSE-R-117)
- gates: wire lot_clip/lot_materials into health_signals + raise the asset budget for Hearthfelt
- gates: re-bless Kragara's standalone entrypoint after W6a ingestion (rebaseline)
- gates: acknowledge tools/house_health.py in the module-budget allowlist (HOUSE-R-068)
- lot3d: the night world comes back — homes over the canopy (C-23) + the outbuildings lamplight (C-26)
- lot3d: the black arc dies (4 layers deep) + the live-shot verification harness
- lot3d: rose glow, window panes, treeline — all placed by measurement
- lot3d: the sky orb, the floating window glows, and the flat hill
- 3d: re-aim the postcard + room review cameras
- lot3d: dusk brightness floor raised + rose-window glow seated on the ring
- lot3d: GableWing rose-window end faces the camera; chimney seated as the library hearth
- identity: handle Microsoft personal-account id_tokens (no email_verified)
- identity: OAuth outcome lands on /login (was dropped on the landing)
Performance
- landing: wait for the hero picture to paint before requesting the sky
- landing: request the sky chunk only after load + idle
- identity: pool the /_verify DB connections; close HOUSE-R-061