Problem
LinkObject structure has architectural inconsistency between source and target properties, with source metadata scattered across multiple locations.
Current State - Redundancy & Asymmetry
// ParserOutputContract root level:
{
"filePath": "/project/file.md", // ← Source file path at root
"links": [{
"source": {
"path": { "absolute": "/project/file.md" } // ← DUPLICATE of filePath!
},
"target": {
"path": { "raw": "...", "absolute": "...", "relative": "..." },
"anchor": "header"
},
// Source metadata scattered outside source object:
"text": "Link Text", // ← Source link text
"fullMatch": "[...]", // ← Source full match string
"line": 5, // ← Source position
"column": 3 // ← Source position
}]
}
Issues
- Data Duplication:
source.path.absolute duplicates ParserOutputContract.filePath
- Architectural Asymmetry:
target groups all target info, but source metadata (text, fullMatch, line, column) scattered at link root level
- No Clear Relationship Model: Link object doesn't clearly express "source → target" relationship
- Future-Proofing Gap: If we need additional source metadata (e.g., context lines, parent heading), no clear place to add it
Better Architecture
{
"linkType": "markdown",
"scope": "cross-document",
"anchorType": "header",
"source": {
"path": { "absolute": "/project/file.md" },
"text": "Link Text",
"fullMatch": "[Link Text](target.md#anchor)",
"line": 5,
"column": 3
},
"target": {
"path": { "raw": "...", "absolute": "...", "relative": "..." },
"anchor": "header"
}
}
Benefits
- ✅ Clear source/target symmetry - relationship model explicit
- ✅ Eliminates duplication - no redundant
filePath copy
- ✅ Logical grouping - all source data in
source, all target data in target
- ✅ Future extensibility - clear place for additional source metadata
Migration Cost
High - Breaking change to public API contract. Requires refactoring:
MarkdownParser.extractLinks() (6 link pattern constructions)
CitationValidator (accesses link.text, link.line, etc.)
- All test files
- Any downstream consumers
Recommendation
- Document as architectural debt (this issue)
- Prioritize for future refactoring epic when planning breaking changes
- Batch multiple breaking changes into single migration to minimize disruption
Related Issues
#28 (Double-Parse) - both could be addressed in same refactoring epic
Discovery Date: 2025-10-17
Priority: Medium (architectural improvement, not blocking functionality)
Source: Markdown Parser Implementation Guide - Issue 4
Problem
LinkObject structure has architectural inconsistency between
sourceandtargetproperties, with source metadata scattered across multiple locations.Current State - Redundancy & Asymmetry
Issues
source.path.absoluteduplicatesParserOutputContract.filePathtargetgroups all target info, but source metadata (text,fullMatch,line,column) scattered at link root levelBetter Architecture
{ "linkType": "markdown", "scope": "cross-document", "anchorType": "header", "source": { "path": { "absolute": "/project/file.md" }, "text": "Link Text", "fullMatch": "[Link Text](target.md#anchor)", "line": 5, "column": 3 }, "target": { "path": { "raw": "...", "absolute": "...", "relative": "..." }, "anchor": "header" } }Benefits
filePathcopysource, all target data intargetMigration Cost
High - Breaking change to public API contract. Requires refactoring:
MarkdownParser.extractLinks()(6 link pattern constructions)CitationValidator(accesseslink.text,link.line, etc.)Recommendation
Related Issues
#28 (Double-Parse) - both could be addressed in same refactoring epic
Discovery Date: 2025-10-17
Priority: Medium (architectural improvement, not blocking functionality)
Source: Markdown Parser Implementation Guide - Issue 4