Skip to content

A matrix row without a leading pipe is invisible to every gate #115

Description

@rookslog

readMatrix reads a matrix table so that the column a reader sees is the
column that counts. ADR-0028 records the design, and LOOKS_LIKE_ROW at
src/ground.js:58 is what decides which lines are candidate rows.

const LOOKS_LIKE_ROW = /^\s*>?\s*\|/;

It requires a LEADING pipe. GFM does not. A row whose first cell simply begins
without one renders as an ordinary row, and here it is nothing at all: not a
row, not a stray, not unread-matrix-row. Every gate built for those cells is
bypassed at once, and the coverage note reports over a denominator that no
longer describes the file.

This is the denominator shrink the blockquote and indentation rules were
written for, through the one door that regular expression leaves open.

What reproduces

Verified on main at a7444f0. Note the missing leading pipe on G-02, and
nothing else unusual about it.

| ID | Our guidance | Our anchor | Source rule | Source text | Source location | Audited |
|---|---|---|---|---|---|---|
| N-01 | S | S |  |  |  |  |
| N-02 | Rules | Rules |  |  |  |  |
| G-01 | Always wear the harness. | Rules | Rule 5.1 | unquoted | p. 12 | unaudited |
G-02 | A rule nobody wrote. | Rules | Rule 9.9 | "Invented rule text nobody sanctioned." | p. 99 | 2099-08-01 deadbeef |

Against a skill carrying one heading and one directive, checkSkill returns:

rows a READER sees: 4 ["N-01","N-02","G-01","G-02"]
rows readMatrix sees: [ 'N-01', 'N-02', 'G-01' ]
findings:
   note audit-coverage | 0 of 1 G rows record a person reading them against the source.
   note quote-coverage | 0 of 1 G rows carry the source's own words.

Zero errors and zero warnings. The rendered row count comes from micromark
through test/gfm.js, so the four is what a reader sees rather than a reading
of the specification.

G-02 carries three things this repository gates hardest, and none of them
fires:

  • A quotation in a matrix declaring **Quotation:** forbidden, which ADR-0020
    says must be refused even when the quotation is well formed and real. This
    one is fabricated.
  • An audit dated 2099-08-01, which the future-date rule exists to refuse.
  • A digest that matches nothing, which the stale-audit rule exists to catch.

The coverage note then prints 0 of 1 over a matrix a reader sees carrying two
G rows, so the one number offered as the answer to a green run over an
unread matrix is itself computed over a file nobody has.

Notes for whoever takes this

The fix is not only to drop >?\s* and the leading \|. LOOKS_LIKE_ROW is
the candidate test, and widening it changes what counts as a stray, what counts
as unread-matrix-row, and where the table is bound. AGENTS.md already states
that a row must begin at column 0, that fenced content is skipped, and that an
unread line is named rather than dropped, and each of those has to keep holding
against the wider test.

test/gfm-render.test.js holds the parser oracle. The property to assert is
the one already written there: wherever a table stands to a reader, the checker
reads no row that reader does not see. That test compares identifiers taken
from the render, so a row invisible to readMatrix should already fail it once
the fixture carries this shape.

Found by an independent product review of src/ground.js during PR #112, and
verified on main before that branch existed. PR #112 does not touch
readMatrix.

Metadata

Metadata

Assignees

No one assigned

    Labels

    defectSomething behaves wronglyengineThe CLI, install, update, uninstall, doctor

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions