T-19PE-converge-audit-frontmatter-parsing
Status: closed/done · Impact: medium · Complexity: medium
The rewire (PR #490) routed validate.ts through the contract and dropped its
coercion, but audit.ts was left parsing frontmatter its own way. As a result
frontmatter is parsed two different ways across the two ops: audit.ts still
keeps its own coerceForSchema (live, defined around plugin/lib/model/ops/audit.ts:128
and called at ~130/135/161 inside parseFrontmatter) and YAML-parses frontmatter
itself, while validate.ts consumes the contract’s frontmatter result. Converge
audit onto the contract path so frontmatter is parsed exactly one way.
| Location | Role today |
|---|---|
plugin/lib/model/ops/audit.ts | Parses frontmatter its own way — coerceForSchema (128) + a local parseFrontmatter (144), called at 356 to feed report.frontmatter (363) and the closed-status check (367). Separately already runs contract.validate(text) for drift (383-394) |
plugin/lib/model/ops/validate.ts | The other op’s parse — parseFrontmatter (71), raw YAML, no coercion (coercion was dropped in the rewire). The one-way target |
Approach
Section titled “Approach”Make both ops parse frontmatter one way — raw YAML, no coercion — then delete audit’s coercion.
- Factor a single text→
{ fm, parseError }raw-YAML parse shared by both ops.validate.ts:71is path-based, so extract its core to accept text; audit already holdstext/reland can call it. - Point
audit.ts:356at the shared parse; deletecoerceForSchema(128-142) and audit’s localparseFrontmatter(144-164). report.frontmatterand thefm["status"]check now see raw YAML (numbers and dates uncoerced). Confirm the closed-status check and the separate schema_version-drift computation are unaffected — they key on string values.- Drift findings still come from
contract.validate(383-394), untouched, so the audit drift output stays byte-stable.
Files to touch
Section titled “Files to touch”| Location | Kind | Change |
|---|---|---|
plugin/lib/model/ops/audit.ts | modify | Delete coerceForSchema (128-142) and the local parseFrontmatter (144-164); consume the shared raw parse at 356 |
plugin/lib/model/ops/validate.ts | modify | Factor parseFrontmatter (71) into a text-based core both ops share — the single frontmatter parse |
Acceptance criteria
Section titled “Acceptance criteria”- AC-1:
audit.tsconsumes the contract’s frontmatter result (or a single shared helper) so frontmatter is parsed one way acrossvalidate.tsandaudit.ts. - AC-2: The duplicate
coerceForSchemainaudit.ts(around line 128) is removed. - AC-3:
audit’s drift output is unchanged — the audit op suite stays green and the CLI markers/exit codes are byte-stable.
Out of scope
Section titled “Out of scope”- Changing audit’s drift semantics (what it flags as drift) — this is a parsing-path convergence only.