Why
listSpecSections already reports, per CSI MasterFormat section, whether a spec exists in the
database (inDatabase) — half of a MasterFormat alignment audit. The other half is missing:
a spec whose section number matches MasterFormat but whose title has drifted from the canonical
title, and a spec whose section number doesn't exist in the MasterFormat reference at all.
Clients running periodic alignment reviews (masters on a cadence, projects at kickoff) currently
diff titles themselves.
What
- Extend the sections listing (
GET sections / MCP list_sections) rows with:
canonicalTitle (from spec_sections), actualTitle (from the stored spec),
titleMatches (normalized comparison: case, whitespace, punctuation).
- New companion signal: specs whose
section is absent from spec_sections
(unknownSection: true on the spec listing row, or a small dedicated rollup — decide in review).
- Normalization rules documented in the test file; genuinely ambiguous title comparisons get
// KNOWN AMBIGUITY cases rather than silent behavior.
Tasks
Acceptance criteria
- A client can produce a MasterFormat alignment report (missing / present / title-drifted /
unknown-number) from a single listing call, no client-side diffing.
Why
listSpecSectionsalready reports, per CSI MasterFormat section, whether a spec exists in thedatabase (
inDatabase) — half of a MasterFormat alignment audit. The other half is missing:a spec whose section number matches MasterFormat but whose title has drifted from the canonical
title, and a spec whose section number doesn't exist in the MasterFormat reference at all.
Clients running periodic alignment reviews (masters on a cadence, projects at kickoff) currently
diff titles themselves.
What
GETsections / MCPlist_sections) rows with:canonicalTitle(fromspec_sections),actualTitle(from the stored spec),titleMatches(normalized comparison: case, whitespace, punctuation).sectionis absent fromspec_sections(
unknownSection: trueon the spec listing row, or a small dedicated rollup — decide in review).// KNOWN AMBIGUITYcases rather than silent behavior.Tasks
src/db/queries/search.ts(listSpecSections): title join + normalized comparisonopenapi.yamlsame PR; MCPlist_sectionsparityAcceptance criteria
unknown-number) from a single listing call, no client-side diffing.