Conversation
…ontmatter Codex's post-merge schema-overlap audit flagged that ExtractedConcept and WikiFrontmatter independently re-declared the same four optional fields (confidence, provenanceState, contradictedBy, inferredParagraphs). They are intentionally a pipeline-boundary pair — extraction-time concept records vs. on-disk page frontmatter — but the lack of a shared shape meant any future field addition or rename risked drifting one surface from the other. Define a single exported `ProvenanceMetadata` interface in src/utils/types.ts and compose both surfaces from it via interface extension. TypeScript erases the indirection at compile time, so the JSON shapes serialised on disk and over the LLM tool boundary stay byte-identical to the previous flat layout — pure refactor, no behaviour change. Also drops the duplicate private `ProvenanceMetadata` interface that lived in src/utils/markdown.ts (used by parseProvenanceMetadata and the lint rules) and re-uses the canonical exported type instead, so the lint surface tracks the same shared shape. A new compile-time pin in test/provenance-metadata-shape.test.ts asserts that both ExtractedConcept and WikiFrontmatter remain assignable to ProvenanceMetadata; future drift would fail `npx tsc --noEmit` rather than silently re-creating the gap.
…-level pin Codex review on PR #51 flagged two low-priority wording / strength issues: 1. The ProvenanceMetadata jsdoc said "Composed (not extended) into …" but the implementation uses `interface … extends ProvenanceMetadata`. Comment now reads "Extended by … via `interface … extends ProvenanceMetadata`" so it matches the code. 2. The previous test assertion (`const x: ProvenanceMetadata = concept`) was weaker than its own comment claimed: every ProvenanceMetadata field is optional, so the assignment alone wouldn't have caught a future drop of a key from ExtractedConcept / WikiFrontmatter. Adds two type-level conditional assertions that compile only when every key on ProvenanceMetadata remains present on each of the consumer interfaces — a removal would break `npx tsc --noEmit`. Comment updated to match the new guarantee.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Second of four pre-0.6.0 audit-fix PRs.
What
ExtractedConceptandWikiFrontmatterindependently re-declared the same four optional fields (confidence,provenanceState,contradictedBy,inferredParagraphs). They are intentionally a pipeline-boundary pair — extraction-time concept records vs. on-disk page frontmatter — but the lack of a shared shape meant any future field addition or rename risked drifting one surface from the other.Define a single exported
ProvenanceMetadatainterface insrc/utils/types.tsand compose both surfaces from it via interface extension. TypeScript erases the indirection at compile time, so the JSON shapes serialised on disk and over the LLM tool boundary stay byte-identical to the previous flat layout — pure refactor, no behaviour change.Also drops the duplicate private
ProvenanceMetadatainterface that lived insrc/utils/markdown.ts(used byparseProvenanceMetadataand the lint rules) and re-uses the canonical exported type instead, so the lint surface tracks the same shared shape.Test plan
test/provenance-metadata-shape.test.tsasserts that bothExtractedConceptandWikiFrontmatterremain assignable toProvenanceMetadata— future drift failsnpx tsc --noEmitrather than silently re-creating the gapnpx tsc --noEmitcleannpm run buildsucceedsnpm test— 632 pass / 3 skipped (smoke), no regressionsnpm run fallow:ci— 0 issues above thresholdUp next (remaining audit follow-ups)
inferredParagraphsfrom rendered page bodies/citations rather than trusting extraction-time metadatacheckSchemaCrossLinks/checkPageCrossLinksshared logic (lower priority)generation.pagesso downstream consumers know they changed (lower priority)