An FPC-seed-canary RED cited line numbers that cannot contain the identifier
- Type: bug (false RED, not reproduced) — Track T (
tools/gate.shis T's; filed by Track A, not fixed here) - Status: backlog
- Opened: 2026-08-21
What happened
tools/gate.sh quick, log dir /tmp/pxx-gate-3976445:
FAIL FPC seed canary (concurrent) /tmp/pxx-gate-3976445/fpc-seed.log
symtab.inc(5934,30) Error: Identifier not found "ByRefArgNeedsLvalue"
symtab.inc(5935,6) Error: Identifier not found "ByRefArgNeedsLvalue"
The working tree at that moment (and now) says otherwise:
compiler/symtab.inc:5934is insideRegisterProc's parameter-compare loop and contains no such identifier;ByRefArgNeedsLvalueis DEFINED atsymtab.inc:6099and used at6185/6186— after its definition, which is why FPC is happy with it;- the tree was clean apart from my own edits, none of them in
symtab.inc(git statuschecked at the time).
Immediately after, on the identical tree:
fpc -Mobjfpc -O2 -Tlinux -Px86_64 ... compiler/compiler.pasby hand: rc=0;- the next
tools/gate.sh quick: GREEN, canary included.
So the canary compiled something that was not the tree it named — the file it read had that call roughly 165 lines earlier than the current file does.
Why it is worth a ticket even though it did not reproduce
The canary's failure text tells the reader to add a forward declaration. Acting
on that would have meant editing a file that was already correct. What it cost
in practice was an investigation: grep, git log, a hand FPC compile, and a
second gate run, before the RED could be dismissed — on a night where the same
box had already produced a false DOWN
([[bug-t-twatch-status-says-down-while-the-daemon-is-alive-and-testing]]).
The failure class is one this tooling already knows about.
tools/selfhost_fixedpoint.sh carries a comment about exactly it: "any
concurrent make in the same clone replaces it mid-check — observed on plexus
with 17 other build processes on the box, reported as a self-host FAIL when
nothing was wrong", and it fixed that by snapshotting the artefact and
hash-verifying the copy. The canary reads the SOURCE tree, concurrently with
the fixedpoint build and testmgr --tier quick, with no such protection.
Suggested shape (T's call)
- On a canary FAIL, re-run it once serially before reporting RED. A real forward-declaration drift is deterministic and survives the re-run; a stale-read does not. The cost is paid only on failure.
- Or make the canary compile from a snapshot of
compiler/taken at one instant, mirroring whatselfhost_fixedpoint.shdoes for the binary. - Either way, when the reported error's line does not contain the reported identifier, say so rather than printing the "add a forward" advice, which is wrong exactly when this happens.
What is NOT claimed
No root cause. Nothing else on the box wrote compiler/symtab.inc (the Track T
watcher runs in /home/neo/trackt-watch, its own clone, verified by
/proc/<pid>/cwd), and I could not construct a repro. This ticket is the
EVIDENCE, deliberately not a theory — recording a plausible mechanism as the
cause is how this repo has bought wrong root causes before.
Deprioritised 2026-09-02 — the Track T tooling backlog was cut as a pile
This ticket is not being called wrong. It was moved as part of a pile, not judged individually, and nothing here disputes its finding.
Owner decision. 73 of the 74 open track: T tickets were filed between
2026-08-31 and 2026-09-02, 58 on one day. The pile was too large to work through
and returned almost nothing, and a ticket nobody will fix does not sit neutrally
— it stays in the ranker forever at zero value, which is the argument CLAUDE.md
already makes for a terminal folder over a low prio.
Four were kept in the ranker on a purely structural test — an active umbrella or
a hard blocked-by: edge from live work:
umbrella-one-full-tier-run-with-no-red-tier,
feature-t-freebsd-image-and-runner, and the two regression-test-core-* reds
that block the umbrella.
Kept, not deleted, for two reasons: so the finding is not rediscovered and refiled from scratch by the next agent who trips over it, and so it can be pulled back if what it touches becomes load-bearing.
To revive it: move it to the owning lane's backlog, set status: backlog,
and say in the ticket WHAT CHANGED to make it matter now. Restoring it because it
reads well is how the pile comes back.