| Healer | Status | Findings | Preventions | H | M | L | Score | Fixed | Duration | Tokens | ~$ | Backlog heading |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| self | clean | 0 | 0 | 0 | 0 | 0 | — | — | 4m 37s | 4.1M | $6.64 | — |
| arch | clean | 0 | 0 | 0 | 0 | 0 | — | — | 4m 1s | 1.4M | $2.08 | — |
| api | findings | 1 | 0 | 0 | 1 | 0 | — | — | 6m 54s | 2.5M | $2.66 | ## API contract health |
| db | clean | 0 | 0 | 0 | 0 | 0 | — | — | 4m 8s | 1.3M | $1.86 | — |
| ci | findings | 2 | 0 | 0 | 1 | 1 | — | — | 9m 38s | 5.8M | $3.21 | ## CI/CD health |
| packages | findings | 6 | 0 | 0 | 2 | 4 | — | — | 9m 40s | 4.9M | $2.78 | ## Dependency health |
| ai | findings | 1 | 0 | 0 | 0 | 1 | — | — | 4m 1s | 2.2M | $2.90 | ## AI/LLM health |
| security | findings | 1 +1 | 0 | 0 | 1 | 1 | — | — | 3m 43s | 3.2M | $3.12 | ## Security health |
| tests | findings | 1 | 1 | 0 | 0 | 1 | — | — | 4m 17s | 1.0M | $1.33 | ## Test-suite health |
| quality | findings | 3 | 1 | 0 | 1 | 2 | 88 | — | 4m 18s | 1.3M | $1.66 | ## Quality debt |
| perf | findings | 2 | 0 | 0 | 0 | 2 | 90 | — | 3m 29s | 1.7M | $2.11 | ## Performance health |
| docs | findings | 3 | 1 | 0 | 2 | 1 | — | — | 5m 34s | 4.6M | $2.49 | ## Docs drift |
| a11y | findings | 3 | 1 | 1 | 2 | 0 | — | — | 7m 4s | 12.1M | $5.04 | ## Accessibility health |
| design | findings | 3 | 1 | 0 | 2 | 1 | 82 | — | 7m 18s | 5.3M | $2.51 | ## UI consistency |
| Healer | New | Fixed | Persisting | Accepted |
|---|---|---|---|---|
| self | 0 | 1 | 0 | 0 |
| arch | 0 | 0 | 0 | 0 |
| api | 0 | 1 | 1 | 0 |
| db | 0 | 1 | 0 | 0 |
| ci | 1 | 1 | 1 | 0 |
| packages | 0 | 2 | 6 | 0 |
| ai | 1 | 1 | 0 | 0 |
| security | 0 | 1 | 1 | 1 |
| tests | 0 | 1 | 1 | 0 |
| quality | 1 | 1 | 2 | 0 |
| perf | 1 | 1 | 1 | 0 |
| docs | 2 | 1 | 1 | 0 |
| a11y | 1 | 1 | 2 | 0 |
| design | 0 | 1 | 3 | 0 |
| total | 7 | 14 | 19 | 1 |
ci:missing-concurrency:github/workflows/test.ymlai:legacy-model-alias:apps/server/src/services/description-service.tsquality:any-casts:apps/storefront/src/lib/cart-mapper.tsperf:hero-asset:apps/storefront/src/pages/home.tsxdocs:removed-script:README.mddocs:phantom-env-var:README.mda11y:placeholder-labels:apps/storefront/src/checkout/checkout-form.tsxself:stale-cited-path:.heal/axes/perf.mdapi:orphan-route:apps/server/src/routes/legacy-webhooks.tsdb:unindexed-fk:apps/server/src/db/schema.tsci:unpinned-action-sha:github/workflows/deploy.ymlpackages:deprecated-dep:apps/server/package.jsonpackages:stale-types:package.jsonai:removed-sampling-param:apps/server/src/services/description-service.tssecurity:missing-security-headers:apps/server/src/app.tstests:flaky-retry-poll:apps/server/src/services/inventory.test.tsquality:dead-exports:packages/shared/src/index.tsperf:n-plus-one-order-list:apps/server/src/services/order-service.tsdocs:wrong-build-command:README.mda11y:low-contrast-muted:apps/storefront/src/styles/tokens.cssdesign:inconsistent-empty-state:apps/storefront/src/pagessecurity:cookie-samesite:apps/server/src/lib/session.ts| Run | Finished | Healers | Findings | Burden | Score | Tokens | |
|---|---|---|---|---|---|---|---|
2026-06-21T09-02-11Z-dm01 |
2026-06-21 10:31:40 UTC | 14 | 41 | 39.8 | 79 | 61.2M | |
2026-06-28T09-05-42Z-dm02 |
2026-06-28 10:19:05 UTC | 14 | 38 | 31.5 | 81 | 55.9M | |
2026-07-05T09-01-27Z-dm03 |
2026-07-05 10:21:44 UTC | 14 | 34 | 24.6 | 82 | 52.5M | |
2026-07-12T10-39-53Z-demo |
2026-07-12 11:58:35 UTC | 14 | 27 | 18.9 | 87 | 59.1M |
Nothing to do — the suite still describes the repo as it is. Keep the discipline: any rename that touches a path a healer cites should run /heal:self in the same PR.
Nothing to do. Watch the seam that historically drifts first: any new route that returns computed totals should call the shared engine, never re-derive.
Fix the delete wrapper's return type first — it is the only remaining mismatch, and the change is 3 lines plus the contract test.
Nothing to do — the history applies cleanly, exactly once, in order. Keep indexing new hot-path FKs at declaration time as 0031 did.
Apply the artifact-action bump — it is mechanical, and the EOL clock is running.
Take the four low-severity bumps as one --fix batch (lint, test runner, data-fetching, icons) — green CI on one PR retires two thirds of this axis's count.
Take the alias bump with the fixture regeneration in one commit — cheapest finding on the board this sweep.
Land the reset-endpoint limiter with its 429 test — the only open medium on this axis, and the fix is a copy of an existing pattern.
Repair the checkout-total assertion — a money-path test that can't fail is worse than no test, because it reads as coverage.
Delete the duplicated price helper (5-minute PR), then schedule the order-service split — it is the root of both the complexity and half the review friction on this axis.
Compress the hero image — one asset swap, measurable on every first visit.
Apply the two mechanical fixes under --fix, then decide the phantom env var — it is the only judgment item on this axis.
Fix the checkout labels today — one high on the money path outweighs everything else in this report combined.
Swap the three spinners for the shared primitive — smallest diff, and it retires the axis's most visible inconsistency.
| Axis | Wired / active P-items | Coverage |
|---|---|---|
| design | 0/1 | open |
| a11y | 0/1 | open |
| quality | 0/1 | open |
| docs | 0/1 | open |
| tests | 1/2 | open |
| security | 1/1 | covered |
| db | 1/1 | covered |
.heal/runs/2026-07-12T10-39-53Z-demo — a whole-repo report-only /heal:sweep (14 healers, main @ 9f3d7c1). Suggest-only (no --apply): every artifact below is drafted, nothing written except the backlog convergence.2026-07-05T09-01-27Z-dm03 too), 2 first-sight. Burden trend across the two runs: 24.6 → 18.9.| Finding (axis) | Occurrences | Would-prevent layer | Channel | New / Promote | Generalises? |
|---|---|---|---|---|---|
| Raw select and hand-rolled spinners bypassing shared primitives (design) | 3 | lint no-restricted-syntax on raw select + spinner markup in app code (design) | Rule | Promote | yes |
| Unnamed icon buttons and placeholder-only labels (a11y) | 2 | jsx-a11y lint preset + aria-label as a required prop type (a11y) | Rule/Code | Promote | yes |
| God module regrowth past the size-watch threshold (quality) | 3 | stays detect — module splits are judgment; size-watch already ranks it first (quality) | (detect) | Promote | no |
| README documents removed scripts and phantom env vars (docs) | 1 | script comparing package.json scripts + env reads to README, wired pre-commit (docs) | Code/Script | New | yes |
| Presence-only assertions on money-path tests (tests) | 2 | stays detect — asserting the value is a per-test judgment call (tests) | (detect) | New | no |
prose to lint enforcement, the cheapest layer that makes the class impossible.
scripts/proposals/;wiring it into pre-commit stays a human call.
report, but a split is never proposed as a mechanical artifact.
Whole-repo sweep of acme/storefront (demo target), compared against the previous sweep (2026-07-05T09-01-27Z-dm03). Report-only — nothing was changed; low-risk items are marked auto-fixable under --fix.
| Check | Status |
|---|---|
| Cited paths/commands in all 14 healer specs exist | OK — 0 dangling references |
| Asserted facts match the project's CLAUDE.md | OK |
| Coverage: repo surfaces vs healer roster | OK — no orphan surface |
| Suite doc drift (README / overview page / run order) | OK |
Structural gate (check-heal-suite.mjs) | OK (exit 0) |
None. The previous sweep's finding (a healer citing a renamed script) was fixed and did not recur — the guardrail added for it (path check in the structural gate) is holding.
Nothing to do — the suite still describes the repo as it is. Keep the discipline: any rename that touches a path a healer cites should run /heal:self in the same PR.
Report-only run; nothing changed.
none
Whole-repo sweep of acme/storefront (demo target), compared against the previous sweep (2026-07-05T09-01-27Z-dm03). Report-only — nothing was changed; low-risk items are marked auto-fixable under --fix.
| Invariant | Status |
|---|---|
HTTP boundary — no apps/server ↔ apps/storefront imports | OK |
packages/shared purity (no I/O, no framework imports) | OK |
| Single source of pricing math (no hand-rolled totals) | OK |
| Server/client DTO parity on shared shapes | OK |
| Deterministic arch gate | OK (exit 0) |
None. The pricing engine remains the only place money math happens — both the checkout route and the storefront preview import it from packages/shared, and no arithmetic on raw price fields appears outside it.
Nothing to do. Watch the seam that historically drifts first: any new route that returns computed totals should call the shared engine, never re-derive.
Report-only run; nothing changed.
none
Whole-repo sweep of acme/storefront (demo target), compared against the previous sweep (2026-07-05T09-01-27Z-dm03). Report-only — nothing was changed; low-risk items are marked auto-fixable under --fix.
42 routes ↔ 42 client fetch wrappers, request schemas on every mutating route, the shared error-code union, and cache invalidation after each mutation.
apps/server/src/routes/orders.ts:142 *(persisting — 2nd sweep)*DELETE /orders/:id returns { deleted: true } but the client wrapper types the response as void, so the flag is silently discarded and a future consumer would type-check against the wrong shape.
server-side) — one commit touching both sides of the boundary, which is why this is never auto-applied.
matches the route's serialized output for a fixture order.
The orphan legacy-webhooks route flagged last sweep was removed — confirmed gone.
Fix the delete wrapper's return type first — it is the only remaining mismatch, and the change is 3 lines plus the contract test.
Report-only run; nothing changed.
API contract health — 1 open item(s) converged.
Whole-repo sweep of acme/storefront (demo target), compared against the previous sweep (2026-07-05T09-01-27Z-dm03). Report-only — nothing was changed; low-risk items are marked auto-fixable under --fix.
| Invariant | Status |
|---|---|
| Journal ordering strictly monotonic | OK (31 entries) |
Schema ↔ migration drift (drizzle-kit check) | OK |
| FKs indexed on hot paths | OK — order_items.order_id index added since last sweep |
| Backfill-safe data migrations (add-nullable → backfill → NOT NULL) | OK |
| Multi-step writes transactional | OK |
| Destructive DDL intentional & commented | OK |
None. Last sweep's unindexed foreign key on order_items.order_id was fixed in migration 0031 — the checkout hot path now walks an index.
Nothing to do — the history applies cleanly, exactly once, in order. Keep indexing new hot-path FKs at declaration time as 0031 did.
Report-only run; nothing changed.
none
Whole-repo sweep of acme/storefront (demo target), compared against the previous sweep (2026-07-05T09-01-27Z-dm03). Report-only — nothing was changed; low-risk items are marked auto-fixable under --fix.
Runtime currency (runner images, action majors), hermeticity, least-privilege (permissions: per job, no pull_request_target, no untrusted-code execution), and log quietness (zero tolerated deprecation warnings).
.github/workflows/test.yml:58 *(persisting — 2nd sweep)*The artifact-upload action is pinned to a major with an announced EOL date.
--fix. Flagged last sweep too; it should not survive a third.
.github/workflows/test.yml:3 *(new)*Rapid consecutive pushes run duplicate jobs to completion.
concurrency: block keyed on the ref withcancel-in-progress: true.
The unpinned third-party action flagged last sweep is now pinned to a full commit SHA — fixed and verified.
Apply the artifact-action bump — it is mechanical, and the EOL clock is running.
Report-only run; nothing changed.
CI/CD health — 2 open item(s) converged.
Whole-repo sweep of acme/storefront (demo target), compared against the previous sweep (2026-07-05T09-01-27Z-dm03). Report-only — nothing was changed; low-risk items are marked auto-fixable under --fix.
Currency across all three workspaces (respecting the declared pins), plus the trust pass: deprecated/archived deps, typosquat-adjacent names, new install scripts, lockfile integrity.
Six packages behind, all within range — 2 medium (the framework minors and a transitive advisory awaiting an upstream release) and 4 routine patch/minor lags. All are safe in-range bumps under --fix; the changelogs were read, none touches a breaking surface.
Since last sweep: the deprecated date library was replaced and the stale type-stub package removed — both confirmed gone from the lockfile.
Trust pass: clean. No deprecated or archived direct deps remain, no new install scripts, lockfile integrity verified.
Take the four low-severity bumps as one --fix batch (lint, test runner, data-fetching, icons) — green CI on one PR retires two thirds of this axis's count.
Report-only run; nothing changed.
Dependency health — 6 open item(s) converged.
Whole-repo sweep of acme/storefront (demo target), compared against the previous sweep (2026-07-05T09-01-27Z-dm03). Report-only — nothing was changed; low-risk items are marked auto-fixable under --fix.
The configured LLM provider registry: model ids active and non-deprecated, call-site parameters valid against current API docs, retry/timeout settings sane, and newly released models worth adopting.
description-service.ts:27 *(new)*The product-description generator pins a model alias that still resolves but has a newer snapshot at identical pricing with better instruction following.
--fix.fixture once, review the diff).
The removed sampling parameter flagged last sweep was cleaned up — the call site now passes only supported options.
Take the alias bump with the fixture regeneration in one commit — cheapest finding on the board this sweep.
Report-only run; nothing changed.
AI/LLM health — 1 open item(s) converged.
Whole-repo sweep of acme/storefront (demo target), compared against the previous sweep (2026-07-05T09-01-27Z-dm03). Report-only — nothing was changed; low-risk items are marked auto-fixable under --fix.
Secret hygiene, auth/session handling, access control on every data route (IDOR sweep), mass assignment, injection, XSS, CSRF, security response headers, and dependency advisories (pnpm audit).
routes/auth.ts:96 *(persisting — 2nd sweep)*The reset endpoint accepts unlimited requests, enabling enumeration and mail-bomb abuse.
mechanical, auto-fixable under --fix. Persisting a second sweep; prioritize.
returns 429 and no mail job is enqueued.
lib/session.ts:18 *(accepted baseline)*Standing tradeoff (cross-site navigation UX; CSRF covered by the token check). Re-reported for visibility; excluded from burden and NEW counts.
Fixed since last sweep: the security response headers now ship on every route — the middleware added after the previous finding is verified present and correctly ordered.
Land the reset-endpoint limiter with its 429 test — the only open medium on this axis, and the fix is a copy of an existing pattern.
Report-only run; nothing changed.
Security health — 1 open item(s) converged.
Whole-repo sweep of acme/storefront (demo target), compared against the previous sweep (2026-07-05T09-01-27Z-dm03). Report-only — nothing was changed; low-risk items are marked auto-fixable under --fix.
Assertion quality (no-assertion and presence-only tests), implementation coupling, redundancy, flakiness across recent runs, and coverage on the pricing engine's edge cases (rounding, currency, discount stacking).
order-service.test.ts:211 *(persisting — 2nd sweep)*The checkout-total test asserts the result is defined but never the amount — it would pass for any wrong total on the money path.
discount, tax lines individually).
right one, only the assertion is hollow.
Fixed since last sweep: the flaky inventory poll test now uses fake timers — zero flakes in the observed window.
Repair the checkout-total assertion — a money-path test that can't fail is worse than no test, because it reads as coverage.
Report-only run; nothing changed.
Test-suite health — 1 open item(s) converged.
Whole-repo sweep of acme/storefront (demo target), compared against the previous sweep (2026-07-05T09-01-27Z-dm03). Report-only — nothing was changed; low-risk items are marked auto-fixable under --fix.
Score 88/100 (structure 90 · duplication 85 · complexity 92 · type-safety 85) — up from 84 last sweep after the dead-export cleanup landed.
The deterministic size-watch + dead-export triage ranked the read; SOLID seams, duplication (jscpd-seeded), complexity hotspots, and type-safety erosion (any/assertion counts) audited on the ranked set.
order-service.ts *(persisting — 3rd sweep, escalated)*700+ lines, 24 exports, three responsibilities (checkout, fulfilment, refunds). The size-watch has ranked it #1 three sweeps running.
small enough to stay); judgment call, never auto-applied.
split.
format-price.ts *(persisting)* — the client re-implementsformatPrice that packages/shared exports; delete and re-import.
cart-mapper.ts:44 *(new)* — three as any casts where theinferred query type compiles; narrowing them keeps the DTO chain honest.
Delete the duplicated price helper (5-minute PR), then schedule the order-service split — it is the root of both the complexity and half the review friction on this axis.
Report-only run; nothing changed.
Quality debt — 3 open item(s) converged.
Whole-repo sweep of acme/storefront (demo target), compared against the previous sweep (2026-07-05T09-01-27Z-dm03). Report-only — nothing was changed; low-risk items are marked auto-fixable under --fix.
Score 90/100 (server 95 · bundle 92 · render 85) — up from 87 after the order-list N+1 fix landed.
Server query shapes (N+1, over-fetch) across all list endpoints, the client bundle against its size budget, and render cost (avoidable re-renders, unbounded lists, asset loading).
product-table.tsx:31 *(persisting)*Fine at demo scale; degrades past ~1k rows. Virtualize or paginate when the catalog grows — tracked, not urgent.
home.tsx:12 *(new)*Full-resolution image, no responsive sizes, no modern format — the largest single contributor to first-paint weight on the landing page.
srcset + a compressed modern format; no layout change.Fixed since last sweep: the order-list endpoint no longer issues one query per row — verified batched, p95 improved accordingly.
Compress the hero image — one asset swap, measurable on every first visit.
Report-only run; nothing changed.
Performance health — 2 open item(s) converged.
Whole-repo sweep of acme/storefront (demo target), compared against the previous sweep (2026-07-05T09-01-27Z-dm03). Report-only — nothing was changed; low-risk items are marked auto-fixable under --fix.
Every documented command against package.json scripts, every documented env var against .env.example and actual reads in code, every cited path, and the setup walkthrough end-to-end.
README.md:74 *(new)*Copy-pasting the setup section fails at this step — the db helper script was removed two sprints ago.
--fix); the replacement commandis already documented two lines below.
README.md:102 *(new)*Documented and templated but read nowhere — either wire it or drop it. Judgment call: reported, not auto-fixed.
CONTRIBUTING.md:33 *(persisting)* — moved one directory up in thelast refactor; mechanical fix.
Fixed since last sweep: the wrong build command in the README was corrected.
Apply the two mechanical fixes under --fix, then decide the phantom env var — it is the only judgment item on this axis.
Report-only run; nothing changed.
Docs drift — 3 open item(s) converged.
Whole-repo sweep of acme/storefront (demo target), compared against the previous sweep (2026-07-05T09-01-27Z-dm03). Report-only — nothing was changed; low-risk items are marked auto-fixable under --fix.
Semantic HTML, accessible names/ARIA, keyboard operability, focus management, and contrast across every storefront route plus the admin pages.
checkout-form.tsx:58 *(new — regression)*The checkout redesign shipped inputs with placeholder text as the only label: screen readers announce empty fields, and the label vanishes the moment the user types. This is the highest-traffic form in the app.
<label htmlFor> per field — mechanical, auto-fixableunder --fix, no visual redesign required (the design already reserves the space).
name.
modal.tsx:19 *(persisting — 2nd sweep)*Tab walks out of the dialog into the obscured page. The component library in use ships a focus-trap — wire it.
icon-button.tsx:9 *(persisting — 2nd sweep)*aria-label a required prop so the gap cannot recur —also proposed as a guardrail (see prevention backlog: recurring, promoted).
Fixed since last sweep: the muted-text contrast failure — the token was darkened and re-verified at 4.6:1.
Fix the checkout labels today — one high on the money path outweighs everything else in this report combined.
Report-only run; nothing changed.
Accessibility health — 3 open item(s) converged.
Whole-repo sweep of acme/storefront (demo target), compared against the previous sweep (2026-07-05T09-01-27Z-dm03). Report-only — nothing was changed; low-risk items are marked auto-fixable under --fix.
Score 82/100 (reuse 75 · tokens 90 · responsive 85 · gallery 80) — up from 76 after the empty-state unification landed.
The jscpd duplicate-cluster precompute seeded the read: duplicated markup, raw HTML where a primitive exists, styling-token drift, responsive integrity at the mobile floor, and component-gallery completeness.
src/pages *(persisting — 3rd sweep, escalated)*Three pages re-implement a spinner the design system exports; visually inconsistent and each a divergence point. Recurs despite the convention doc — promoted to a lint proposal (see prevention backlog).
<select> · filters.tsx:66 *(persisting — 3rd sweep, escalated)*Bypasses the shared Select primitive; renders unstyled on two browsers. Same promotion.
summary.tsx:23 *(persisting)* — one arbitrary pixel valueoutside the spacing tokens; mechanical token swap.
Fixed since last sweep: the four inconsistent empty-state layouts were unified onto the shared EmptyState component.
Swap the three spinners for the shared primitive — smallest diff, and it retires the axis's most visible inconsistency.
Report-only run; nothing changed.
UI consistency — 3 open item(s) converged.