db-findings-intakerun.md01_define/output/spec.mdThe honest database audit (PR #489) now reliably surfaces leanness findings — unused/redundant
indexes, missing tenant indexes, oversized documents, unbounded arrays, orphaned references — but
nothing turns those findings into action. They land in a CI job summary and stop there; acting on
them is ad-hoc and easily forgotten. Meanwhile the pipeline already has a clean way to capture and
sequence work the team picks up: intake stubs in pipeline/intake/, spun out one-per-run with
/pipeline new. Database-change requirements should flow the same way, so the admin / data-quality
guardrails behind the "Refine the bridge" initiative convert detected bloat into shipped migrations
instead of warnings nobody owns.
Make audit findings first-class pipeline intake, picked up exactly like features:
pipeline/intake/db-audit-findings/ — the home for DB-change
requirements, sitting beside the feature-stub epics. It holds a breakdown.md (current findings,
sequenced) and one stub .md per actionable finding, in the standard intake stub format, so
/pipeline new <stub> pre-seeds Define's spec with no special handling.db-auditor skill into a triage pass (mirroring decompose): it takes the audit
findings, interprets/triages them, and writes/refreshes the db-audit-findings stubs. Each finding
maps to one independently-shippable stub (e.g. "drop redundant index tenantId_1_status_1 on
leads") whose Build writes a single migration._done/) or no longer reported (resolved) — a self-pruning breakdown.pipeline/intake/db-audit-findings/ by hand — a breakdown.md (full 110-finding backlog) and the
first stub (add-invoices-tenant-index.md). The triage writes into that same folder and is
idempotent against the hand-written stubs: it matches on finding identity (kind + collection +
index/field), so an already-captured finding (e.g. the invoices missing-tenant-index) is refreshed
in place, never duplicated, and its existing filename is preserved.The audit's CI behaviour is unchanged (still honest, still advisory exit 0). This pass adds the detection → intake bridge; each spun-out run carries the actual fix through Define → Build → Release on the gated migration pipeline.
pipeline/intake/db-audit-findings/ exists as an intake epic with a breakdown.md in the
standard breakdown format.db-auditor triage writes one stub per actionable finding into that folder, each in
the intake stub format (fields map onto Define's spec.md), persona admin, carrying the
initiative/objective link.touches: hint._done/) and prunes findings no longer present in
the latest audit, so the breakdown reflects current reality.pipeline/intake/db-audit-findings/ folder seeded by PR #491 and
is idempotent against its hand-written stubs — the existing add-invoices-tenant-index.md (and
any other manual stub) is refreshed in place by finding identity, never duplicated./pipeline new pipeline/intake/db-audit-findings/<finding-slug>.md spins a finding out exactly
like a feature stub — no /pipeline router changes required.db-auditor skill doc describes the triage pass and the db-audit-findings epic./pipeline subcommand — the existing db-auditor skill plus /pipeline new already cover it.db-audit-findings folder + backlog +
first stub), merged separately. This feature automates maintaining that folder; it does not
re-create or discard #491's stubs.db:audit is used only where the DB is reachable.)02_build/output/notes.mdfeat: db-findings-intake — machine-readable audit report + structured finding targetfeat: db-findings-intake — db-auditor triage pass maintains db-audit-findings intakepackages/services/src/db/audit/index.ts: added a discrete target field to AuditFinding (the
index name / field a finding is about, or "" for collection-wide) and populated it at all six
push sites. This gives every finding a stable machine-readable identity (kind + collection + target) without parsing the prose message — the basis for stable stub slugs.packages/services/scripts/db-audit.ts: added a JSON export. db:audit --json <path> (or
--json=<path> / DB_AUDIT_JSON_PATH) writes the full AuditReport to a file. It's emitted before
the exit-code branch, so the triage gets the complete picture (inspected, skipped, findings) even on
an incomplete audit. The honest exit-code behaviour is unchanged..claude/skills/db-auditor/SKILL.md: extended the skill (v2) with the triage pass — mirrors
/pipeline decompose. Documents: getting a findings report without a live DB (the JSON export); the
db-audit-findings epic layout (breakdown.md + per-finding stubs + _done/); the stable
finding-key identity (<kind>/<collection>/<target>) and slug derivation; idempotency, _done/
skipping and pruning; "what is actionable" (follow the breakdown's prioritisation, don't
batch-generate); read-only-against-DB guarantee; and the /pipeline new hand-off (no router change).pipeline/intake/db-audit-findings/add-invoices-tenant-index.md: added a - finding-key: missing-tenant-index/invoices/tenantId line so the triage matches #491's hand-written stub by
identity and refreshes it in place — preserving its human-friendly filename, never duplicating it.pipeline/intake/db-audit-findings/breakdown.md: recorded the stub's finding-key and added a
"Triage maintenance" section describing how the db-auditor triage maintains the backlog.pipeline/intake/db-audit-findings/ exists with a breakdown.md in the standard format — seeded
by #491 (merged into this branch); the triage adopts and maintains it.admin,
carrying the initiative/objective link — documented as the triage pass; the seed stub demonstrates
the format.touches: hint —
enforced by the stub format + the triage's "independently shippable" rule.finding-key is the match key; target is now a discrete field, so the identity is derivable
without parsing prose._done/ and prunes findings no longer reported — specified in the
idempotency/pruning procedure.add-invoices-tenant-index.md now carries its finding-key and is matched by identity, not
filename.db:audit --json <path>
emits the AuditReport JSON the triage consumes./pipeline new pipeline/intake/db-audit-findings/<finding-slug>.md spins a finding out like a
feature stub — stubs use the standard intake format, so no /pipeline router change is needed.db-auditor skill doc describes the triage pass and the db-audit-findings epic.target field is required on AuditFinding
and is set at all six push sites + the type, so the typecheck should stay green.decompose. The only
runtime code change is the JSON export + the target field; the rest is the skill contract and the
intake folder it maintains. This keeps the surface minimal (no new abstraction) per CONVENTIONS.AuditReport returned by auditDatabase().03_release/output/release.mdapps/docs/app/technical/development/database/page.mdx — documented the db:audit --json export, the discrete finding target, and the triage → pipeline/intake/db-audit-findings/ bridge. No further ci-cd impact (the audit/migrate CI workflows are unchanged).packages/services/src/db/audit/index.ts — target added to AuditFinding and populated at all six push sites; required field, set everywhere, so the type stays sound. Internal-only, no behaviour change to the existing report.packages/services/scripts/db-audit.ts — JSON export resolves the path from --json <path> / --json=<path> / DB_AUDIT_JSON_PATH, writes the full AuditReport, emitted before the exit-code branch so the report is complete even on an incomplete audit. Honest exit codes unchanged. Exercised indirectly: the Migrate-preview CI job ran the updated package against the preview DB and succeeded..claude/skills/db-auditor/SKILL.md, pipeline/intake/db-audit-findings/** — skill + intake docs; no runtime surface.type, named imports).pipeline/intake/db-audit-findings/ exists with breakdown.md — seeded by #491, adopted here.touches: hint — enforced by the stub format and the triage rules.finding-key = <kind>/<collection>/<target>; target now discrete._done/, prunes resolved findings — specified in the idempotency/pruning procedure.add-invoices-tenant-index.md tagged with its finding-key, matched by identity not filename.db:audit --json <path> emits the AuditReport./pipeline new <stub> spins out like a feature — standard intake format, no router change.db-audit-findings epic.