Skip to content

The record line stopped saying things twice - #195

Merged
dmarx merged 2 commits into
mainfrom
claude/sota-tracker-backfill-e6evzh
Sep 7, 2026
Merged

The record line stopped saying things twice#195
dmarx merged 2 commits into
mainfrom
claude/sota-tracker-backfill-e6evzh

Conversation

@dmarx

@dmarx dmarx commented Sep 7, 2026

Copy link
Copy Markdown
Owner

Reported from the outside — "frontmatter renders funny on the quartz site luria builds" — which is the part worth noticing. Both defects were live on two published sites, both arrived with features that shipped green, and neither was visible to a test.

LIT-140 in the anthology, under 0.10.0:

> **Status** Active · **Filed** 2026-09-05 · **Status** Active ·
  **Extends** LIT-141 · **Extended by** LIT-151 · LIT-181 ·
  **Compared against** LIT-152 · **Supersedes** LIT-141 ·
  **Cited as `compared_against` by** LIT-152 ·
  **Cited as `extended_by` by** LIT-141 ·
  **Cited as `extends` by** LIT-151 · LIT-181 ·
  **Cited as `source` by** SOTA-136

LIT-141 is named three times. Of eleven bits, four are repeats.

Two causes, each an addition meeting an assumption

Status twice. record_line has always rendered the status itself, through statuses.display. #181 made status: an ordinary declared vocabulary, and _vocabulary_bits — a generic loop over the scheme's declared vocabularies — started rendering it too. Nobody wrote the second one; the field joined a set a loop reads. Since #181 requires the declaration, this fires on every document of every scheme in every record. ADR-015's entire line was **Status** Active · **Filed** 2026-09-06 · **Status** Active.

Every declared converse twice. _edge_bits' docstring says exactly why inbound edges are rendered: they are "the one direction the site otherwise loses, since frontmatter renders as nothing." True when a relation lived on one side. The converse declaration (ADR-084) writes the fact on both sides, so the direction is no longer lost — and the backlink became a second printing of what the outbound bit already showed, under a label built from the raw field name.

That second one is the more interesting failure: correct, load-bearing reasoning in a docstring, quietly falsified by a feature two releases later, with nothing linking them.

Why the suite could not see it

test_record_line_carries_status_date_and_lineage asserts:

assert "**Status** Active" in line

A substring test is satisfied by two of them. It has been green throughout. The new tests assert line.count("**Status**") == 1 — the count is what this class of bug needs, and in cannot express it.

The choice inside each fix

Which status bit wins. The vocabulary loop's version was arguably nicer — it linked the word to its value page. It loses anyway, because it renders the bare word and only statuses.display composes Superseded — by X; note from the fields around it. Restoring that link belongs in its own change rather than smuggled into a fix: #196.

Suppress by declaration, or by what is stored. Suppressing every inbound edge whose relation declares a converse is a line shorter and leans on the one-sided-relations lint holding. Suppressing only where the converse is actually in this document's outbound edges is exact, and a test pins it: a record mid-repair still shows the edge it has. A guard should not go quiet on precisely the records that are already wrong.

Fired on the real corpus

Synthetic fixtures pass either way, so the number that matters came from staging the anthology's 353 record lines with both builds:

0.10.0 this branch
**Status** bits 692 346
Cited as … bits 86 74

692 is exactly twice 346. The twelve backlinks that went are every relation with a declared converse — compared_against (5), extended_by (4), extends (3). The 74 that stay declare none and so have no other way to be seen: source (71) and contested_by (3), the latter meaning a paper's page now says which practice it contests.

LIT-140 after:

> **Status** Active · **Filed** 2026-09-05 · **Extends** LIT-141 ·
  **Extended by** LIT-151 · LIT-181 · **Compared against** LIT-152 ·
  **Supersedes** LIT-141 · **Cited as `source` by** SOTA-136

Also here

Two citations left in a concretized code's old spelling. The lint's remedy text says luria link --fix upgrades them; for these two it cannot — one is in a Python docstring, the other inside a fenced illustration the fixer correctly masks. Written by hand, and the misleading remedy text is worth its own look.

statuses.FIELD names the frontmatter key a scheme may back with a vocabulary, since two places now reason about it as a declared field and must agree.

Checks

python -m pytest tests -q913 passed. luria link --fix, luria index, luria lint → clean, including the pending-decisions report (the new docstring's citation of the still-Proposed ADR-084 carries an inactive-ok:).

The README site-link work that briefly shared this branch is now #198.

🤖 Generated with Claude Code

https://claude.ai/code/session_01YP4P3m8rzVFb8idnTE4FfT

Reported from the outside — "frontmatter renders funny on the quartz site
luria builds" — and it was two duplications, each an addition meeting an
assumption that had been true when it was written.

`record_line` has always rendered the status through `statuses.display`.
#181 made `status:` an ordinary declared vocabulary, so the generic
vocabulary loop began rendering it too, and since #181 requires the
declaration this fired on every document of every scheme in every record.
The dedicated path wins: it is the only one that composes
`Superseded — by X; note` out of the fields around the word. The vocabulary
loop's version linked the word to its value page, which is a real gain and
is filed separately rather than smuggled into a fix.

`_edge_bits` renders inbound edges for, in its own words, "the one direction
the site otherwise loses, since frontmatter renders as nothing". A declared
converse stores the fact on both documents, so nothing is lost and the
backlink became a second printing under a label built from the raw field
name — LIT-140 named LIT-141 three times on one line. Suppressed by what the
page actually holds rather than by the declaration alone, so a record with a
one-sided relation still shows the edge it has while the lint reports it.

Neither was visible to a test: the existing assertion is
`"**Status** Active" in line`, and a substring test is satisfied by two of
them. The new ones count.

Fired on the real corpus rather than a fixture. Staging the anthology's 353
record lines with both builds: 692 status bits become 346, exactly halved,
and 86 backlinks become 74. The twelve that go are every relation with a
declared converse; the 74 that stay declare none and have no other way to be
seen.

Also corrects two citations left in a concretized code's old spelling. The
lint's remedy text says `luria link --fix` upgrades them, and for these two
it cannot: one is in a Python docstring, the other inside a fenced
illustration the fixer correctly masks.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YP4P3m8rzVFb8idnTE4FfT
@dmarx dmarx changed the title The record line stopped saying things twice Say each thing once, and say where the site is Sep 7, 2026
@dmarx
dmarx force-pushed the claude/sota-tracker-backfill-e6evzh branch from dcdbb0a to 80dd427 Compare September 7, 2026 01:11
@dmarx dmarx changed the title Say each thing once, and say where the site is The record line stopped saying things twice Sep 7, 2026
…ackfill-e6evzh

# Conflicts:
#	docs/devlog/2026-09.md
#	docs/devlog/README.md
@dmarx

dmarx commented Sep 7, 2026

Copy link
Copy Markdown
Owner Author

lol good catch, that's not even what I meant. My complaint was that the frontmatter fields were rendering on a single line, separated only by a center dot. I think a table would probably look nicer. Maybe this is a quartz setting? Probably this: https://github.com/jackyzha0/quartz/blob/v5/quartz.config.default.yaml#L225-L241

@dmarx dmarx mentioned this pull request Sep 7, 2026

dmarx commented Sep 7, 2026

Copy link
Copy Markdown
Owner Author

Table version is up as #199 (stacked on this branch).

Short answer on note-properties: it can't do this job. It's a v5 plugin and actions/site pins v4.5.2 — but more importantly a properties panel shows the page's own frontmatter, and that's the smaller half of this line. Supersedes is read from another document's superseded_by:, Cited as \source` byis a backlink, andSuperseded — by X; noteis three fields composed into one reading. A YAML panel renders the last as bareSuperseded` and the first two not at all — so enabling it would add a block beside the record line rather than replace it.

Upgrading Quartz is still worth doing on its own merits; it just doesn't bear on this, and record_line needed to be a table either way. Happy to take the v5 migration as its own piece if you want it.


Generated by Claude Code

@dmarx
dmarx merged commit a781fef into main Sep 7, 2026
5 checks passed
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.

Link the status word to its value page from the record line

2 participants