Description
Two of evaluate-relevance.sh's five evidence shapes test string presence in place of a semantic relationship, and both produce confident CLOSE verdicts on tickets that must stay open. Verified present at upstream HEAD (packages/itil/scripts/evaluate-relevance.sh, 530 lines).
Shape 2 (ADR-shipped-confirmed), line 300. The ADR match is a bare grep -oE '\bADR-[0-9]{3}\b', and the number is resolved against the consuming repo's docs/decisions/<NNN>-*.md with no repo or namespace qualification. Downstream tickets routinely cite agent-plugins ADR numbers, and both repos number their ADRs from 001, so a citation of an upstream decision is reported as evidence that an unrelated local decision shipped.
Shape 5 (driver-child-ticket-closed), lines 418 to 445. The ## Related section is parsed for P<NNN> refs and any closed one is counted as a closed "driver". Nothing checks whether the ticket declared that ref as a driver. ## Related is a mixed section by design, carrying drivers, siblings, supersessions and capture provenance, so presence there carries no directional information. A ticket that explicitly says "composes with P040, distinct concerns" has P040 counted as its closed driver.
The A1 guard at lines 448 to 471 (suppress shape 5 when the child names an unbuilt SKILL or agent) is a narrow patch on the same gap: it catches one way a non-driver relationship shows up, not the general case.
Symptoms
Two independent witnesses in one downstream repo on 2026-08-08, through the two different shapes, both reproduced by running the script directly.
Witness A, /wr-itil:review-problems Step 4.6. 24 candidates surfaced, 0 survived verification, nothing closed. Two examples: a ticket citing the upstream Decision-Delegation Contract ADR-044 was credited with the local 044-cross-edition-shape-as-a-fresh-context-subagent-gate.proposed.md, a newsletter gate with no relationship to it; a ticket citing upstream ADR-013/014/032 was credited with the local 013-no-automated-linkedin-scraping.proposed.md and 014-wardley-mapping-as-strategic-lens.proposed.md.
Witness B, /wr-itil:work-problems Step 3.6. A live, reproduced bug returned CLOSE-CANDIDATE-WITH-CAVEAT citing three tickets as closed drivers. The ticket lists all three under "Composes with ... same publish/draft-lifecycle area, distinct concerns", and its own ## Related line says the dedup pass surfaced them as "newsletter-adjacent but distinct". The orchestrator overrode the verdict; the ticket was then fixed as a genuine defect in the same session.
Both surfaces consume the same script, so the same false positive can arrive during an interactive review and during an AFK loop.
Workaround
Read the cited evidence back against the ticket body before acting on any CLOSE verdict. Check that each cited ADR is the one the ticket meant, local or upstream, and that each cited P<NNN> was declared as a driver rather than a sibling.
Affected plugin / component
@windyroad/itil, packages/itil/scripts/evaluate-relevance.sh, shapes 2 and 5. Consumed by /wr-itil:review-problems Step 4.6 and /wr-itil:work-problems Step 3.6.
Frequency
Both consuming surfaces, every pass. One review pass produced 24 false positives out of 24 candidates.
Versions
- Local plugin:
@windyroad/itil@0.59.2
- Upstream package:
@windyroad/itil@0.61.1 (defect confirmed present in the HEAD copy of the script fetched from this repo)
- Claude Code CLI: 2.1.224 (Claude Code)
- Node: v24.16.0
- OS: Darwin 25.3.0 arm64
Evidence
Both verdicts reproduce by invoking the script directly against the affected ticket files. The two failures are independent, so a fix for one does not cover the other.
Suggested fix shape:
- Qualify shape 2's ADR match. Require a repo or namespace marker adjacent to the reference, or restrict matching to ADRs the ticket cites in a local-path form (
docs/decisions/<NNN>-...), or drop bare-number matching. A bare ADR-NNN is not a unique identifier once a consuming repo keeps its own decision log.
- Gate shape 5 on the relationship the ticket declares rather than on presence in
## Related. Parse the Blocked by line or explicit driver phrasing, and treat Composes with as explicitly non-qualifying.
- Cover both witnesses in
packages/itil/scripts/test/evaluate-relevance.bats: an upstream-ADR-number collision, and a closed Composes with sibling.
Related issues in the same script, cross-referenced for context rather than as duplicates:
Cross-reference
Reported from a downstream project's docs/problems/open/132-relevance-evaluator-emits-close-verdicts-from-syntax-only-adr-number-and-driver-matching.md.
This issue is tracked locally as P132 in the downstream project's docs/problems/ directory.
Description
Two of
evaluate-relevance.sh's five evidence shapes test string presence in place of a semantic relationship, and both produce confident CLOSE verdicts on tickets that must stay open. Verified present at upstream HEAD (packages/itil/scripts/evaluate-relevance.sh, 530 lines).Shape 2 (
ADR-shipped-confirmed), line 300. The ADR match is a baregrep -oE '\bADR-[0-9]{3}\b', and the number is resolved against the consuming repo'sdocs/decisions/<NNN>-*.mdwith no repo or namespace qualification. Downstream tickets routinely cite agent-plugins ADR numbers, and both repos number their ADRs from 001, so a citation of an upstream decision is reported as evidence that an unrelated local decision shipped.Shape 5 (
driver-child-ticket-closed), lines 418 to 445. The## Relatedsection is parsed forP<NNN>refs and any closed one is counted as a closed "driver". Nothing checks whether the ticket declared that ref as a driver.## Relatedis a mixed section by design, carrying drivers, siblings, supersessions and capture provenance, so presence there carries no directional information. A ticket that explicitly says "composes with P040, distinct concerns" has P040 counted as its closed driver.The
A1guard at lines 448 to 471 (suppress shape 5 when the child names an unbuilt SKILL or agent) is a narrow patch on the same gap: it catches one way a non-driver relationship shows up, not the general case.Symptoms
Two independent witnesses in one downstream repo on 2026-08-08, through the two different shapes, both reproduced by running the script directly.
Witness A,
/wr-itil:review-problemsStep 4.6. 24 candidates surfaced, 0 survived verification, nothing closed. Two examples: a ticket citing the upstream Decision-Delegation Contract ADR-044 was credited with the local044-cross-edition-shape-as-a-fresh-context-subagent-gate.proposed.md, a newsletter gate with no relationship to it; a ticket citing upstream ADR-013/014/032 was credited with the local013-no-automated-linkedin-scraping.proposed.mdand014-wardley-mapping-as-strategic-lens.proposed.md.Witness B,
/wr-itil:work-problemsStep 3.6. A live, reproduced bug returnedCLOSE-CANDIDATE-WITH-CAVEATciting three tickets as closed drivers. The ticket lists all three under "Composes with ... same publish/draft-lifecycle area, distinct concerns", and its own## Relatedline says the dedup pass surfaced them as "newsletter-adjacent but distinct". The orchestrator overrode the verdict; the ticket was then fixed as a genuine defect in the same session.Both surfaces consume the same script, so the same false positive can arrive during an interactive review and during an AFK loop.
Workaround
Read the cited evidence back against the ticket body before acting on any CLOSE verdict. Check that each cited ADR is the one the ticket meant, local or upstream, and that each cited
P<NNN>was declared as a driver rather than a sibling.Affected plugin / component
@windyroad/itil,packages/itil/scripts/evaluate-relevance.sh, shapes 2 and 5. Consumed by/wr-itil:review-problemsStep 4.6 and/wr-itil:work-problemsStep 3.6.Frequency
Both consuming surfaces, every pass. One review pass produced 24 false positives out of 24 candidates.
Versions
@windyroad/itil@0.59.2@windyroad/itil@0.61.1(defect confirmed present in the HEAD copy of the script fetched from this repo)Evidence
Both verdicts reproduce by invoking the script directly against the affected ticket files. The two failures are independent, so a fix for one does not cover the other.
Suggested fix shape:
docs/decisions/<NNN>-...), or drop bare-number matching. A bareADR-NNNis not a unique identifier once a consuming repo keeps its own decision log.## Related. Parse theBlocked byline or explicit driver phrasing, and treatComposes withas explicitly non-qualifying.packages/itil/scripts/test/evaluate-relevance.bats: an upstream-ADR-number collision, and a closedComposes withsibling.Related issues in the same script, cross-referenced for context rather than as duplicates:
file-no-longer-existsfalse positives on upstream-plugin paths. Same script, different shape, and the same underlying theme of a path or identifier meaning something different in the consuming repo.Cross-reference
Reported from a downstream project's
docs/problems/open/132-relevance-evaluator-emits-close-verdicts-from-syntax-only-adr-number-and-driver-matching.md.This issue is tracked locally as P132 in the downstream project's
docs/problems/directory.