mirror of
https://github.com/nexu-io/open-design.git
synced 2026-10-27 09:51:12 +01:00
* fix(web): parse Provenance with Markdown-bold labels (#1580) The daemon's finalize synthesis prompt at apps/daemon/src/finalize-design.ts:560-565 lists the five Provenance fields without pinning field-label syntax, so Claude renders them with Markdown-bold labels per Markdown convention (`- **Field:** value`). The parser at apps/web/src/lib/parse-provenance.ts:32-36 uses `[:\s]+` as its label/value separator, which stops at the trailing `**` after the colon; the capture group then slurps the `**` and any following whitespace into the value. Downstream of that, transcriptMessageCount and generatedAt parse as null because the captured tokens don't start with digits or a valid ISO 8601 prefix, and the Continue in CLI clipboard prompt shows `Design system: ** ...`, `Transcript message count when DESIGN.md was generated: unknown`, `DESIGN.md generated at: unknown`. Fix: strip leading and trailing Markdown emphasis (`*`, `_`, whitespace) from every captured value via a single helper threaded through extractField / extractFieldOrNone / extractNumber / extractDate. Widen the transcriptMessageCount regex's capture from `(\d+)` to `([^\n]+)` so the strip step gets a chance to run on `** 4`. Add `[^:]*` between `count` and `[:\s]+` to mirror the other label-walking regexes for bolded label variants. Defense-in-depth: tell the synthesis prompt to emit plain `- Field: value` bullets with no emphasis on the labels. The parser hardening is the load-bearing fix; this is belt-and-suspenders for new model variants. Red-Green-Refactor: - Phase 1 (Red): 3 new parse-provenance tests covering bold labels with backticked values, bold labels with a short `Generated:` form, and bold labels with `none` sentinels. All 3 failed against pre-fix source. - Phase 2 (Green): strip + regex widening. All 7 parse-provenance tests + 1158 web tests pass. - Phase 3: empirically verified against a live finalized DESIGN.md — all five fields now parse correctly. - Phase 4 (defense-in-depth): one-line addendum to synthesis prompt. - Phase 5: bold-labelled Provenance fixture added to the hook test (useDesignMdState.test.tsx) so the round-7 `unknown-provenance` fail-closed path is regression-pinned end-to-end. Backticks in field values are intentionally kept (out of scope per the issue spec; rendered clipboard text reads fine with them). The variant `- **Field**: value` (colon outside emphasis) is not in the issue enumeration and is not handled. Fixes #1580 * fix(web): narrow Provenance strip to Markdown residue only Round-2 fix per lefarcen's review on PR #1584. The round-1 helper used `^[\s*_]+` / `[\s*_]+$`, which stripped a literal leading or trailing `*`/`_` from any captured value — `_draft.html` corrupted to `draft.html`, and a build id like `build_id_v1_` lost its trailing underscore. Narrow stripMarkdownEmphasis to three explicit passes: 1. Leading `*`/`_` tokens FOLLOWED BY WHITESPACE — only matches the `** ` residue left after `- **Field:** value` is captured starting at the `*`. 2. Trailing WHITESPACE followed by `*`/`_` tokens — mirror of (1) if the value closes with emphasis after whitespace. 3. A single balanced wrap around the remaining value (`**X**` / `*X*` / `__X__` / `_X_`) — handles the `- **Field:** **value**` shape and any plain-label `**value**` form. Asymmetric literal `*`/`_` characters in the value (no whitespace separator, no balanced closing token) are preserved by construction. Added regression tests: - plain label + `_draft.html` value - plain label + `build_id_v1_` value (trailing underscore) - bold label + `_draft.html` value (residue stripped, literal leading underscore preserved) - plain label + `**wrapped-id**` value (balanced residue stripped) All 11 parse-provenance tests + 1162 web tests pass. Empirically re-verified against a live finalized DESIGN.md — all five fields still parse correctly. --------- Co-authored-by: DevForgeAI CI/CD Engineer <devforge-ai@development.ai>