Skip to content

fix(frontmatter): keep the last character of a bare scalar that ends in a quote - #183

Merged
drewstone merged 1 commit into
mainfrom
fix/frontmatter-unmatched-trailing-quote
Sep 1, 2026
Merged

fix(frontmatter): keep the last character of a bare scalar that ends in a quote#183
drewstone merged 1 commit into
mainfrom
fix/frontmatter-unmatched-trailing-quote

Conversation

@drewstone

Copy link
Copy Markdown
Contributor

What breaks

unquote in src/frontmatter.ts strips a leading or a trailing quote independently:

function unquote(value: string): string {
  return value.replace(/^['"]|['"]$/g, '')
}

So a bare scalar that merely ends in a quote loses its last character.

written read back
check: python3 -c "print(1)" python3 -c "print(1)
title: the symbol '7' the symbol '7

A truncated check is an unterminated shell quote. Every claim graded by re-executing it records unrunnable whatever the claim proved.

Why the writer never produced it, and who pays

formatYamlScalar already refuses the shape — stringNeedsJsonEncoding returns true for a value matching /["']$/ — so no page this package wrote was ever affected. The loss falls entirely on frontmatter written by another hand, which is the normal case for a store a product already had.

Measured on one such corpus (Discovery Lab, 3,655 shared pages): 1,378 pages lost a character, 1,376 of them in check, 2 in title, 1 in expect.

The fix

Strip a matched pair, which is what the writer's own encoder assumes. A quoted value still unwraps; an unmatched quote is data.

Proof

  • The new case in src/frontmatter.test.ts fails on the previous rule (Tests 1 failed | 4 passed) and passes on this one.
  • npx vitest run src/ — 24 files, 222 of 222 tests pass.

…in a quote

`unquote` stripped a leading OR a trailing quote independently, so a value that
merely ended in one lost its last character. `check: python3 -c "print(1)"` read
back as `python3 -c "print(1)` — an unterminated shell quote — and a title ending
in `'7'` lost the closing mark.

`formatYamlScalar` already refuses to write that shape: `stringNeedsJsonEncoding`
returns true for a value matching /["']$/. So no page this writer produced was
ever affected, and the loss fell entirely on frontmatter written by another hand.
Measured on one such corpus: 1,378 of 3,655 pages, 1,376 of them in a `check`
field, which is the command a claim is re-executed by.

The rule is now a matched pair, which is what the writer's own encoder assumes.
A quoted value still unwraps; an unmatched quote is data.

The new test fails on the previous rule and passes on this one; 222 of 222 tests
under src/ pass.

@tangletools tangletools left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Auto-approved drewstone PR — 60007061

This PR was opened by the trusted drewstone account.
The full PR reviewer audit still runs separately and will publish findings if it detects issues.

This approval is provisional. It rests on the audit running. If the audit cannot run — for example the CLI bridge rejects it — this approval is dismissed rather than left standing, so an unrun check never reads as a passing one.

tangletools · auto-approval · reason: drewstone_author · 2026-09-01T17:47:53Z

@drewstone
drewstone merged commit b922275 into main Sep 1, 2026
2 checks passed
@drewstone
drewstone deleted the fix/frontmatter-unmatched-trailing-quote branch September 1, 2026 18:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants