Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions .agents/completed/issue-index.md

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
ID: ISSUE-LOCAL-01M3NR65JDEV0NH28W5ZPQDPYC
Title: the frozen archive dropped 27 rows its own evidence records still cite
Row: GATE-ISSUE-ARCHIVE-RESTORE
State: OPEN
Kind: bug
GitHub: -
Mirror: PENDING
Availability: FULL
Created: 2026-09-29
Updated: 2026-09-29
Closed: -

## Problem

Commit 2e84a073b deleted .agents/completed/issue-index.md wholesale (913 lines) and e3539d994 restored a hand-picked 886-line copy that dropped 27 archived rows. Those 27 rows are exactly what 43 frozen-evidence records cite: 24 cite a line past the restored file's end, 19 cite a line that now holds a different row. No gate sees any of that today: the frozen-evidence comparison runs only in the _intake branch, whose 9 records all cite surviving lines, so all 43 stale quotes are row-owned records that validate untouched. But every one of those 43 quotes is byte-true to the pre-deletion archive, so no edit to any record can repair them against a truncated archive; the defect is in the archive, not in the quoting. Measured: re-inserting the deleted lines at the positions difflib reports leaves the file byte-identical to the pre-deletion archive except line 406, which keeps e3539d994's own deliberate link re-point; the 831-quote census moves from 350 byte-equal to 373, and check-agent-record stays green with unchanged row counts. With the #3350 relative-link comparison the restored archive resolves all 831 quotes, 0 failing. Fix: splice the 27 rows back at their original positions, re-pointing any link that does not resolve from .agents/completed/ (measured: none needed). Prerequisite for the stacked checker change that enforces the comparison outside _intake.

## Resolution

-
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
ID: ISSUE-LOCAL-01M3NSTDJSHREP8HCX83K5KXV0
Title: the frozen-evidence contract is not enforced outside _intake
Row: GATE-ISSUE-ARCHIVE-RESTORE
State: OPEN
Kind: bug
GitHub: -
Mirror: PENDING
Availability: FULL
Created: 2026-09-29
Updated: 2026-09-29
Closed: -

## Problem

validate_issue_record runs the frozen-evidence comparison (the quoted archive line must be byte-equal to the declared line, and must name the record's own GitHub number) only in the _intake branch. Row-owned and _owed records that carry a Frozen archive evidence block are never compared: any of the 822 non-intake blocks could drift from the archive, swap a URL, or quote another issue's row, and every gate stays green. Measured on the restored archive (#3351 data half): 831 records carry a block, 831 resolve under the #3350 comparison with the record directory as base, 831 quote a line carrying their own issue number, 0 violations, so enforcing the same rule outside _intake adds no new red today while closing the drift door. Absence of the block stays legal outside _intake (456 row-owned records legitimately have none); presence is not. Fix: hoist the comparison into a shared helper and apply it in the _owed and row-owned branches, and strip a trailing CR from the archived line so a CRLF Windows working copy compares equal to the LF committed blob.

## Resolution

-
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
ID: ISSUE-LOCAL-01M3NC14GE995V9E6F7GTYSQJ3
Title: record checkers stop at the first invalid input and hide the rest
Row: GATE-ISSUE-INDEX-TABLE-SHAPE
State: OPEN
Kind: bug
GitHub: -
Mirror: PENDING
Availability: FULL
Created: 2026-09-28
Updated: 2026-09-28
Closed: -

## Problem

Both record validators abort on the first invalid input, so one run reveals only one defect and each fix exposes the next only after a new run (this masked three separate defects behind each other in the ORPHAN-MODEL-ROWS repair). scripts/agent-issue-index.py load_local_files raises IssueRecordError at the first file whose record fails validate_issue_record, so ten broken issue files report one error and --check shows only that one. scripts/check-agent-record.py parse_claim_rows drops any row whose cell count or state cell is malformed (bare continue), which both corrupts the matrix counts AND silently removes the row from every downstream contract check (owner/claim, anchors, spec) - a row with one missing cell reports a pipe-count error and nothing else, exactly the MODEL-DSV41 shape.

## Resolution

-
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
ID: ISSUE-LOCAL-01M3NH23E78PEXCJF4HW1XHQQ3
Title: frozen-evidence byte equality and record link resolution cannot both hold
Row: POLICY-ISSUE-INTAKE
State: OPEN
Kind: bug
GitHub: -
Mirror: PENDING
Availability: FULL
Created: 2026-09-28
Updated: 2026-09-28
Closed: -

## Problem

An _intake record's Problem must quote the frozen archive line byte for byte, but check-agent-record's check_links requires every link in a record to resolve from the record's own directory. The archive lives at .agents/completed/issue-index.md, one level under .agents, so a link to a spec is spelled ../specs/x.md there; the record that QUOTES the row lives at .agents/issues/<owner>/, two levels down, so the same link must be spelled ../../specs/x.md from there. One string cannot satisfy both. Commit e3539d994 re-pointed the ISSUE-GH-1033 quote to the record-relative spelling to fix the dangling link, which broke the byte comparison: first divergence at column 2191 of archive line 350, archive 2237 chars against evidence 2240. Measured over all 831 records that carry a Frozen archive evidence block, 350 are byte-equal, 438 differ from the cited line ONLY by a relative link rebase, and 43 cite a line the archive no longer has (24 past its 886 lines after the delete and re-add, 19 naming a row that moved). Restoring the archive spelling makes check-links red instead. Fix: compare the quote against the cited line with each side's relative link targets resolved to the file they denote, so the check asks whether the quote IS the archived row rather than which directory holds the quote.

## Resolution

-
83 changes: 83 additions & 0 deletions .agents/specs/gate-issue-archive-restore.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
# Spec — the frozen archive dropped 27 rows its own evidence records still cite

Row: `GATE-ISSUE-ARCHIVE-RESTORE` (unplaced record/gate defect; the completed
archive is a record surface, not a matrix row)
State: `ACTIVE`

## Scope

`.agents/completed/issue-index.md` is the frozen archive every
`### Frozen archive evidence` block quotes. It is not frozen in the way the
name claims:

1. Commit `2e84a073b` deleted the file wholesale — 913 lines — alongside its
(legitimate) spec addition.
2. Commit `e3539d994` restored a hand-picked copy: "The last pre-retirement
revision is restored at `.agents/completed/issue-index.md`, with its
internal links re-pointed." The restore measured 886 content lines: 27
archived rows came back missing, and one surviving line (406) was
deliberately re-pointed.

The 27 dropped rows are not idle history. Exactly 43 records under
`.agents/issues/` cite them: 24 cite a line past the restored file's end, 19
cite a line that now holds a different row. No gate sees any of that today:
the frozen-evidence comparison runs only in the `_intake` branch of
`validate_issue_record`, whose 9 records all cite surviving lines, so all 43
stale quotes are row-owned records that validate untouched. But every one of
those 43 quotes is byte-true to the pre-deletion archive, so no edit to any
record can repair them against a truncated archive. The defect is in the
archive, not in the quoting.

Measured over all 831 records that carry a frozen-evidence block, against
the committed LF blob:

- before the restore: 350 byte-equal, 458 failing under this base's
byte-only comparison (481 under the #3350 link-rebase comparison);
- after re-inserting the 27 lines at the positions `difflib` reports
between `2e84a073b~1` and the restored file: the file is byte-identical
to the pre-deletion archive except line 406, which keeps `e3539d994`'s own
deliberate re-point; 373 byte-equal, and under #3350's comparison all 831
resolve, 0 failing.

`scripts/check-agent-record.py` stays green with unchanged row counts
(ENGINE=179 MODEL=384 QUANT=87 KERNEL=60 BACKEND=90); none of the re-pointed
links in the restored lines dangle from `.agents/completed/`, so nothing
needed re-pointing beyond what `e3539d994` already did.

In scope:

1. Splice the 27 dropped rows back at their original positions.
2. Re-point any restored link that does not resolve from
`.agents/completed/` (measured: none).
3. The red-before / green-after census in the commit message.

Out of scope, each for its own reason:

1. **Editing any record.** The 43 quotes are correct; "repairing" them would
re-anchor records onto a truncated archive and make the falsification
load-bearing.
2. **Changing any checker.** Widening or narrowing a gate to make a red go
green is what AGENTS.md forbids; the archive, not the gate, is wrong.
3. **Enforcing the frozen-evidence comparison outside `_intake`.** That is
the checker half of this pair and lands as its own stacked PR (#3350 is
the comparison it needs; this restore is the data it needs).
4. **The 4 row-cell anomalies in the ROW bucket** — 3 records whose archived
cell is the em-dash placeholder (`ISSUE-GH-83`, `ISSUE-GH-606`,
`ISSUE-GH-408`) and 1 genuine cross-row citation (`ISSUE-GH-298` cites a
`PERF-27B-LMHEAD-DSR` line while living under `PERF-27B-LMHEAD-FP4`).
They are pre-existing record-content questions, orthogonal to line
existence, and every one of them still resolves after the restore.

## Enforcement (the stacked checker PR)

With the rows restored and #3350's relative-link comparison landed, the
frozen-evidence contract is enforced wherever the block appears, in every
owner directory: a record that QUOTES an archived row must quote the line it
declares, modulo exactly the relative-link rebase the record's directory
forces, and the quoted line must carry the record's own GitHub number.
Absence of the block stays legal everywhere except `_intake`; presence is
not. Measured over the corpus on the restored archive: 831 records carry a
block, 831 resolve, 831 identify their own issue, 0 violations -- the
ratchet adds no new red. Working-copy EOL no longer changes the answer: the
comparison strips a trailing CR from the archived line, because the
committed blob is LF and a Windows checkout is not.
32 changes: 23 additions & 9 deletions scripts/agent-issue-index.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,23 +65,37 @@ def load_local_files(
owed: issue_records.OwedLookup | None = None,
frozen_archive: bytes | None = None,
) -> list[issue_records.IssueRecord]:
"""Parse and validate every canonical issue file without network access."""
"""Parse and validate every canonical issue file without network access.

Every invalid file is reported in one run. Stopping at the first failure
is what let three separate defects hide behind one another in the
ORPHAN-MODEL-ROWS repair (ISSUE-LOCAL-01M3NC14GE995V9E6F7GTYSQJ3): each
fix exposed the next only after another run, and the first failure was
always an _intake record nobody was editing.
"""

effective_rows = issue_records.canonical_rows(ROOT) if rows is None else rows
effective_owed = issue_records.owed_issue_counts(ROOT) if owed is None else owed
if frozen_archive is None:
frozen_archive = FROZEN_ARCHIVE.read_bytes()
records: list[issue_records.IssueRecord] = []
failures: list[str] = []
for path in sorted(issues_root.glob("**/*.md")):
record = issue_records.parse_issue_file(path)
issue_records.validate_issue_record(
record,
path,
effective_rows,
effective_owed,
frozen_archive=frozen_archive,
)
try:
record = issue_records.parse_issue_file(path)
issue_records.validate_issue_record(
record,
path,
effective_rows,
effective_owed,
frozen_archive=frozen_archive,
)
except (OSError, issue_records.IssueRecordError) as error:
failures.append(f"{path}: {error}")
continue
records.append(record)
if failures:
raise issue_records.IssueRecordError("; ".join(failures))
issue_records.validate_issue_collection(records)
return records

Expand Down
19 changes: 18 additions & 1 deletion scripts/check-agent-record.py
Original file line number Diff line number Diff line change
Expand Up @@ -587,19 +587,36 @@ def parse_claim_rows(path: Path, errors: list[str]) -> list[ClaimRow]:
item_id = cells[0].strip().strip("`")
if not ID_RE.fullmatch(item_id):
continue
# A row that fails its shape check is REPORTED and still parsed, never
# dropped: dropping it hid every downstream contract defect behind the
# shape error and corrupted the matrix ratchet counts, so each fix
# exposed the next defect only after another run (three defects masked
# this way in the ORPHAN-MODEL-ROWS repair;
# ISSUE-LOCAL-01M3NC14GE995V9E6F7GTYSQJ3). The one error list reports
# the shape and the contracts in the same run.
malformed = False
if len(cells) != len(header):
errors.append(
f"{path.relative_to(ROOT)}:{line_no}: {item_id} has {len(cells)} cells; "
f"header has {len(header)}"
)
continue
malformed = True
state_index = field_index(header, "state")
state_cell = cells[state_index] if state_index is not None else ""
state_matches = STATE_RE.findall(state_cell)
if len(state_matches) != 1:
errors.append(
f"{path.relative_to(ROOT)}:{line_no}: {item_id} must have exactly one canonical state"
)
malformed = True
if malformed:
# Parsed with an empty state so the ratchet, duplicate detection
# and the summary rollups still see the row; no state-conditional
# contract can fire on the empty state, so the reported defects
# stay the shape ones.
rows.append(
ClaimRow(path, line_no, item_id, state_matches[0] if state_matches else "", header, tuple(cells), line)
)
continue
rows.append(
ClaimRow(path, line_no, item_id, state_matches[0], header, tuple(cells), line)
Expand Down
Loading
Loading