Port the pr-explain report validator to Go (parse-shaped carve-off) #142

Open
opened 2026-08-18 14:38:54 +01:00 by vnprc-agent · 0 comments
Contributor

User story: So that every new report-grammar rule is a tokenizer visitor instead of a hand-built awk parser, the PR explanation validator should migrate to Go alongside the other program-shaped bash tools.

Part of the "Migrate program-shaped bash tools to Go" arc — refs #98, which predates this tool and does not list it.


pr-explain/lib.sh is now ~2,400 lines, and nearly all of it is one program shape: a parser-linter that enforces a deliberately narrow HTML grammar with grep/awk over raw bytes. It is the single largest bash-tax payer in the repo, and the redesign on #141 is still adding rules (objective coverage, layer ordering, slop linting), each one a fresh chance to write a subtly wrong regex.

The evidence is already on the branch: the first attended v2 run explained #141 itself and was rejected by its own validator, because the report quoted PR_EXPLAIN_PROVIDER_PID="" inside a codewalk and the E3 identifier census, grepping raw bytes case-insensitively, counted PID="" as an id attribute. The body was valid; the validator was wrong. The fix was to hand-build a tag tokenizer in awk — that is, to start writing the Go program in the wrong language. A real tokenizer deletes that bug class instead of patching one instance of it.

Scope:

  • Port the validation core (pr_explain_validate_report and its helpers) and the validate-report entry point to a Go binary, standard library only. Build a strict tokenizer for the one-tag-per-line grammar; do not use a lenient HTML parser that normalizes what the validator exists to reject.
  • Preserve the contract exactly: the validate-report CLI (3- and 9-argument forms), the allod pr _validate-report surface, one diagnostic per line with the E*/W* codes, warnings-versus-errors semantics, and exit codes. The ~104-probe conformance suite in tests/pr-explain/validation.sh must pass unchanged against the binary; that suite is the port's acceptance test.
  • Out of scope: the orchestration cage in pr-explain/explain (env sanitization, traps, snapshot verification, provider invocation). That is pipeline-shaped bash and stays bash, per the #98 boundary.

Sequencing: after the #141 redesign slices land. The grammar is still moving; porting a moving target buys a merge conflict, not a tokenizer. Reasonable slot: alongside or after #98 Phase 1 (forge), since the two ports share no code and can proceed independently.

Implementation PRs should use Refs allod/tools#<this>; the cutover PR that switches allod pr _validate-report to the binary carries the closing keyword.

**User story:** So that every new report-grammar rule is a tokenizer visitor instead of a hand-built awk parser, the PR explanation validator should migrate to Go alongside the other program-shaped bash tools. _Part of the "Migrate program-shaped bash tools to Go" arc — refs #98, which predates this tool and does not list it._ --- `pr-explain/lib.sh` is now ~2,400 lines, and nearly all of it is one program shape: a parser-linter that enforces a deliberately narrow HTML grammar with grep/awk over raw bytes. It is the single largest bash-tax payer in the repo, and the redesign on #141 is still adding rules (objective coverage, layer ordering, slop linting), each one a fresh chance to write a subtly wrong regex. The evidence is already on the branch: the first attended v2 run explained #141 itself and was rejected by its own validator, because the report quoted `PR_EXPLAIN_PROVIDER_PID=""` inside a codewalk and the E3 identifier census, grepping raw bytes case-insensitively, counted `PID=""` as an id attribute. The body was valid; the validator was wrong. The fix was to hand-build a tag tokenizer in awk — that is, to start writing the Go program in the wrong language. A real tokenizer deletes that bug class instead of patching one instance of it. Scope: - Port the validation core (`pr_explain_validate_report` and its helpers) and the `validate-report` entry point to a Go binary, standard library only. Build a strict tokenizer for the one-tag-per-line grammar; do not use a lenient HTML parser that normalizes what the validator exists to reject. - Preserve the contract exactly: the `validate-report` CLI (3- and 9-argument forms), the `allod pr _validate-report` surface, one diagnostic per line with the `E*`/`W*` codes, warnings-versus-errors semantics, and exit codes. The ~104-probe conformance suite in `tests/pr-explain/validation.sh` must pass unchanged against the binary; that suite is the port's acceptance test. - Out of scope: the orchestration cage in `pr-explain/explain` (env sanitization, traps, snapshot verification, provider invocation). That is pipeline-shaped bash and stays bash, per the #98 boundary. Sequencing: after the #141 redesign slices land. The grammar is still moving; porting a moving target buys a merge conflict, not a tokenizer. Reasonable slot: alongside or after #98 Phase 1 (`forge`), since the two ports share no code and can proceed independently. Implementation PRs should use `Refs allod/tools#<this>`; the cutover PR that switches `allod pr _validate-report` to the binary carries the closing keyword.
Sign in to join this conversation.
No description provided.