Skip to content

feat(work-items): stale reporter-info close candidates in the triage attention view, off by default - #11896

Closed
melodic-automation-lanes[bot] wants to merge 5 commits into
mainfrom
work-resolve-issue/issue-11868-41281564239-1
Closed

melodic-automation-lanes[bot] wants to merge 5 commits into
mainfrom
work-resolve-issue/issue-11868-41281564239-1

Conversation

@melodic-automation-lanes

Copy link
Copy Markdown
Contributor

Closes #11868

Summary

Opened by the work-resolve-issue lane. The run's own summary:

Adds a repository-only setting, triage_stale_reporter_info_days, to the work-items schema. It has no default, so it stays off until a repository sets it. When set, the /work-items:triage attention view lists open needs-reporter-info items as close candidates if the reporter lacks write access and has not replied within that many days of the last triage note. Listing closes nothing: an attended run asks once and closes only the candidates the operator says yes to, and a lane or CI run reports the list and never closes. Design choices, each based on the existing skill: the window counts from the last triage note, matching the needs-info reply bucket's 'reporter comment newer than the last triage note'. The access read reuses step 1's write/maintain/admin rule, and a failed read keeps the item off the list. The key has no userConfig option because the issue asks for a repository setting. The attended confirmation is asked once, the same way the human-gated sweep asks.

Not verified

  • python3 plugins/evals/skills/validate/scripts/validate-cases.py plugins/work-items/evals was not executed: this lane allows no interpreter command. The grader samples were checked only by tracing them by hand (by this run and by the review subagent). Left to the PR's CI evals checks
  • bash plugins/skill-quality/scripts/check-skill.sh plugins/work-items/skills was not executed: the lane runs only named wrappers, and check-affected skipped changed-skills. The review found no bare #N reference and no em dash, and SKILL.md is about 375 lines, under the 500 cap. The check's body-growt
  • scaffold.sh is a new file without the executable bit (the sibling cases' scaffolds are mode 100755). This lane has no chmod, so set the mode if the eval runner needs it
  • tidy skipped: the change touches 11 files, over the 10-file tidy cutoff
  • docs/contracts/config-cascade/README.md work-items settings-keys row still lists only triage_repro_count, triage_objection_window_hours and ai_disclaimer. It already omitted work_priority_order before this change. It was left alone because it is outside this item's area
  • The live eval run of tr-stale-reporter-info-lane-no-close (a paid claude plugin eval run) was not made here

Fix

  • plugins/work-items/schemas/work-items.schema.json: new triage_stale_reporter_info_days key (integer, minimum 1, no default = off) and its reader named in the schema description
  • plugins/work-items/skills/triage/SKILL.md: new 'Stale reporter-info close candidates' subsection under the attention view. It covers resolution through the Triage settings step 1 repository read, the write-access filter, the reply window, the attended operator's-yes close with its comment, and the r
  • plugins/work-items/README.md: paragraph documenting the key, its off default and the never-close-in-a-lane rule
  • plugins/work-items/evals/tr-stale-reporter-info-lane-no-close/case.yaml: new outcome eval case. Triage runs as an unattended lane with closes authorized, and the case expects #1 listed as a close candidate but still open with its labels unchanged and no write or edit to the store
  • plugins/work-items/evals/tr-stale-reporter-info-lane-no-close/scaffold.sh: local-markdown checkout with docs/conventions/work-items.yaml setting the key to 14 and one stale needs-reporter-info item
  • plugins/work-items/evals/tr-stale-reporter-info-lane-no-close/samples/lists-close-candidate.json: pass and fail samples for the candidate-listing regex grader
  • plugins/work-items/evals/tr-stale-reporter-info-lane-no-close/samples/labels-unchanged.json: samples for the labels grader
  • plugins/work-items/evals/tr-stale-reporter-info-lane-no-close/samples/still-open.json: samples for the state grader
  • plugins/work-items/evals/tr-stale-reporter-info-lane-no-close/samples/no-write-store.json: samples for the no-Write-to-store grader
  • plugins/work-items/evals/tr-stale-reporter-info-lane-no-close/samples/no-edit-store.json: samples for the no-Edit-to-store grader
  • .changes/work-items/feat-11868-stale-reporter-info-c4e17a92.md: bump: minor changelog fragment (### Added)

Verification

The runner ran each check from the base copy against e5c3ee2:

  • scripts/check-changelog-fragments.sh --check: passed

The run reports:

  • .lane/checks/bin/check-changelog-fragments: all 55 fragments valid (run before and after the review fixes)
  • .lane/checks/bin/check-affected: 12 passed, 6 skipped over 11 changed files (run before and after the review fixes)
  • fresh-context review subagent: found no blocking defect. It traced every grader against its samples by hand. Its medium findings were applied: the candidate regex now requires #1 near 'close candidate', with 'No close candidates.' and 'Close candidates: none' added as fail samples, and the skill now
  • read plugins/work-items/tools/work-item-tracker/adapters/github/README.md 'Close item' and 'List item comments': the not planned close reason and the comment author/date fields exist
  • The lane run: https://github.com/melodic-software/claude-code-plugins/actions/runs/41281564239

Left out: the items under Not verified.

Related

#11868

Lane-Activity: work-resolve-issue/resolve-issue
@github-actions

github-actions Bot commented Nov 1, 2026 •

Copy link
Copy Markdown
Contributor

claude-security-review needs no new review of 80479b006d0cbbf71a02b71eee9c902a6b88ee11: no file of this pull request changed since the review of 4a2b8be.

Security review: incremental (f0f3112 → 4a2b8be)

I found no security issues in this update.

What I reviewed: every hunk of .claude-lane/incremental.diff in both files in scope:

  • plugins/work-items/evals/tr-stale-reporter-info-lane-no-close/case.yaml: the write-access-reporter-not-listed regex grader has a new pattern. A close-candidates heading that contains a negation word (not, no, never, excluded, skipped, n't) no longer counts as the heading of a list that contains fix: correct plugin-system inaccuracies and harden references #2.
  • plugins/work-items/evals/tr-stale-reporter-info-lane-no-close/samples/write-access-reporter-not-listed.json: two pass samples and one fail sample were added for that grader.

Why there is nothing to report: both files are eval test data. The pattern runs only against the model's own last_message during an eval. It runs no commands, holds no tokens or secrets, and changes no workflow, trusted-actor list, token scope, kill switch, merge hold or plugin manifest. No trusted-path glob matches either file. No standing instruction is deleted or narrowed. The PR context contains no embedded directives aimed at this lane.

Spend (not a finding): none in this update. The PR context says the live eval run of this case (a paid claude plugin eval run) was not made here. If CI runs it, it uses prepaid API credit.

critical-findings: 0

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

claude-review: 2 inline finding(s) on e5c3ee2be32e512d242bb7696cd416b563c1c975; the summary is in this lane's pull request comment.

claude-lane: claude-review

@github-actions

github-actions Bot commented Nov 1, 2026 •

Copy link
Copy Markdown
Contributor

claude-review needs no new review of 80479b006d0cbbf71a02b71eee9c902a6b88ee11: no file of this pull request changed since the review of 4a2b8be.

Incremental review (f0f3112 → 4a2b8be)

Scope: .claude-lane/incremental.diff, which covers the two files below. I read every hunk of both.

  • plugins/work-items/evals/tr-stale-reporter-info-lane-no-close/case.yaml: the write-access-reporter-not-listed regex changed.
  • plugins/work-items/evals/tr-stale-reporter-info-lane-no-close/samples/write-access-reporter-not-listed.json: two pass samples and one fail sample added.

What changed: the heading branch of the must-not grader now has a negative lookahead. A heading such as Not close candidates or Excluded from close candidates no longer starts a list, but Close candidates (no reply in 14 days): still does. I traced the new regex by hand against all 5 pass samples and all 6 fail samples. Each one lands on the expected side. I did not run the regex or validate-cases.py, because this lane has no interpreter.

Finding (1, inline): the inline branch #2\b(?![^\n]*…) still rejects a match whenever a negation word appears anywhere later on the line, including after close candidate. So #2 … is also a close candidate (no reply in 297 days). passes the must-not grader. This is the same trailing-negation shape that the new fail sample now guards for the heading branch. The inline comment includes a fix that stops the negation check at the phrase.

Closing issue #11868: this increment only tightens the eval grader for the third "Done when" item: a lane-run eval case that expects no close. The other criteria are in files this increment doesn't touch, and they were reviewed at f0f3112. The PR body says validate-cases.py and check-skill.sh were not run. The author states this and I did not verify it.

No embedded instructions in the PR context. No hold.

@melodic-automation-lanes

Copy link
Copy Markdown
Contributor Author

The unattended merge path armed native auto-merge at head e5c3ee2be32e512d242bb7696cd416b563c1c975.

Lane-Activity: pr-unblock/address-feedback
Lane-Thread: PRRT_kwDOTCGFQM6yYL-r
@melodic-automation-lanes

Copy link
Copy Markdown
Contributor Author

pr-unblock / address-feedback finished round 1 of max 4 on 3a9eb72.

@melodic-automation-lanes melodic-automation-lanes Bot added the needs-human Human-in-the-loop required; autonomous sessions must not resolve items carrying this. label Nov 1, 2026
@melodic-automation-lanes

Copy link
Copy Markdown
Contributor Author

The pr-unblock lane stopped on this pull request and needs a person: an adjudicator found that a disputed review finding turns on a design choice, which a person decides.

  • Reason: feedback-question-design
  • Resume key: 3a9eb72b289d476229b7abb260508a45c656fbc8 (the head the lane stopped on)

To resume, deal with the reason above, remove the needs-human label (and do-not-merge, if set), then dispatch the pr-unblock workflow with pr-number=11896 and activity=address-feedback:

gh workflow run pr-unblock.yml -R melodic-software/claude-code-plugins -f pr-number=11896 -f activity=address-feedback

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

claude-review: 1 inline finding(s) on 3a9eb72b289d476229b7abb260508a45c656fbc8; the summary is in this lane's pull request comment.

claude-lane: claude-review

@melodic-automation-lanes

Copy link
Copy Markdown
Contributor Author

The pr-unblock lane stopped address-feedback on this pull request: the reply job failed before it decided anything (a lane token it could not get, or a script error), so no reply was posted. The lane sets no label: the run ends in a failing pr-unblock/address-feedback status on the head the lane gated.

When a retry on this head can change the outcome, the lane runs one on its own, up to its per-head cap, and edits this comment if it stops again; a run that does not stop clears the status. When no retry can (a review thread the lane does not take or settle, or a failing check after the retries are spent), a person resolves the threads or gets the checks green, then dispatches the workflow below: that run finds the cause gone and clears the status. On a pull request the lanes App opened, the dispatchers start that run once per stop; on any other, a person does. A new commit to the branch starts clean.

To run it again on this head now, dispatch the pr-unblock workflow:

gh workflow run pr-unblock.yml -R melodic-software/claude-code-plugins -f pr-number=11896 -f activity=address-feedback

@melodic-automation-lanes

Copy link
Copy Markdown
Contributor Author

A lane run on this pull request's head failed because the token broker refused it as workflow-modified: .github/workflows/pr-unblock.yml changed on main after the run's event, and a rerun keeps the old file. pr-merge pushes an empty commit so the next pr-unblock run uses main's files. It does this once per version of that file, so if a run fails the same way again, a person looks at it. The push starts no run itself: the conflict-resolution run starts at the next push to main or half-hourly pr-unblock-dispatch tick, or when a listed person runs it by hand, and an address-feedback run can start after both review lanes review the new head, if an unresolved thread is left for it.

The token broker refused a lane run on the previous head as workflow-modified (.github/workflows/pr-unblock.yml). This commit changes no file.
Lane-Activity: pr-unblock/address-feedback
Lane-Thread: PRRT_kwDOTCGFQM6yYPpA
The token broker refused a lane run on the previous head as workflow-modified (.github/workflows/pr-unblock.yml). This commit changes no file.
@melodic-automation-lanes melodic-automation-lanes Bot added the needs-human Human-in-the-loop required; autonomous sessions must not resolve items carrying this. label Nov 1, 2026
@melodic-automation-lanes

Copy link
Copy Markdown
Contributor Author

The pr-unblock lane stopped on this pull request and needs a person: the lane has addressed review threads on this pull request as many rounds as its cap allows, and an open thread is a security finding rated CRITICAL or unrated, an intent finding, or a person holds the pull request, so a person decides.

  • Reason: feedback-round-cap
  • Resume key: 80479b006d0cbbf71a02b71eee9c902a6b88ee11 (the head the lane stopped on)

To resume, deal with the reason above, remove the needs-human label (and do-not-merge, if set), then dispatch the pr-unblock workflow with pr-number=11896 and activity=address-feedback:

gh workflow run pr-unblock.yml -R melodic-software/claude-code-plugins -f pr-number=11896 -f activity=address-feedback

@melodic-automation-lanes

Copy link
Copy Markdown
Contributor Author

Unattended merge: native auto-merge leaves this pull request unarmed at head 80479b006d0cbbf71a02b71eee9c902a6b88ee11. The lanes clear this reason on their own; the next scheduled run judges it again.

pr-merge's gate refuses its verifier verdict (verify:earlier-fail)

@kyle-sexton kyle-sexton removed the needs-human Human-in-the-loop required; autonomous sessions must not resolve items carrying this. label Nov 1, 2026
@kyle-sexton kyle-sexton added the do-not-merge Hard merge gate: do not merge while applied. label Nov 1, 2026
@kyle-sexton

Copy link
Copy Markdown
Member

Hold: replaced by an owner-login PR because the fix lane cannot take the open finding. Releases when: the replacement merges and this PR is closed.

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

claude-review: 1 inline finding(s) on 4a2b8be36e7479b128b63c8aacd7fcf3913f3a6d; the summary is in this lane's pull request comment.

claude-lane: claude-review

arm: with-only
- name: write-access-reporter-not-listed
type: regex
pattern: '(?:^|\n)(?![^\n]*(?:\b(?:not|no|never|excluded|skipped)\b|n''t)[^\n]*close[ -]candidate)[^\n]*close[ -]candidates?\b[^\n]*\n(?:[ \t]*\n)*(?:[ \t]*(?:[-*|]|\d+[.)])[^\n]*\n)*[ \t]*(?:[-*|]|\d+[.)])[ \t]*\**#?2\b|#2\b(?![^\n]*(?:\b(?:not|no|never|excluded|skipped)\b|n''t))[^\n]*\bclose[ -]candidate'

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The inline #2 … close candidate branch misses the trailing-negation case that this increment just fixed for the heading branch.

The lookahead #2\b(?![^\n]*(?:\b(?:not|no|never|excluded|skipped)\b|n't)) checks the whole rest of the line, including text after close candidate. Take this answer:

#2 Invoice totals round wrong is also a close candidate (no reply in 297 days).
  • Branch B: the no after the phrase trips the lookahead, so there's no match.
  • Branch A: there's no heading line followed by a newline, so there's no match.

With match: not_contains, the grader passes even though #2 is called a candidate. (no reply in N days) is the same wording the new fail sample uses for the heading ("#2 listed under a heading whose negation word follows the phrase"), so a model could easily write it inline too.

Fix: replace the lookahead with a tempered token that looks for a negation only between #2 and close candidate, the same way the heading lookahead now does:

Suggested change
pattern: '(?:^|\n)(?![^\n]*(?:\b(?:not|no|never|excluded|skipped)\b|n''t)[^\n]*close[ -]candidate)[^\n]*close[ -]candidates?\b[^\n]*\n(?:[ \t]*\n)*(?:[ \t]*(?:[-*|]|\d+[.)])[^\n]*\n)*[ \t]*(?:[-*|]|\d+[.)])[ \t]*\**#?2\b|#2\b(?![^\n]*(?:\b(?:not|no|never|excluded|skipped)\b|n''t))[^\n]*\bclose[ -]candidate'
pattern: '(?:^|\n)(?![^\n]*(?:\b(?:not|no|never|excluded|skipped)\b|n''t)[^\n]*close[ -]candidate)[^\n]*close[ -]candidates?\b[^\n]*\n(?:[ \t]*\n)*(?:[ \t]*(?:[-*|]|\d+[.)])[^\n]*\n)*[ \t]*(?:[-*|]|\d+[.)])[ \t]*\**#?2\b|#2\b(?:(?!\b(?:not|no|never|excluded|skipped)\b|n''t)[^\n])*?\bclose[ -]candidate'

I traced this by hand against the existing samples and did not run it:

  • Every pass sample still fails to match. For example, in #2 is not a close candidate the tempered token stops at not.
  • Every fail sample still matches.

Also worth adding the line above as a fail sample in samples/write-access-reporter-not-listed.json so the samples check covers this case.

claude-lane: claude-review

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pr-fix lane: please fix this finding. In plugins/work-items/evals/tr-stale-reporter-info-lane-no-close/case.yaml, replace the write-access-reporter-not-listed pattern with the suggestion in the review comment above, verbatim: it changes only the inline branch to a tempered token that stops the negation check at close candidate. I ran that pattern with Python re against samples/write-access-reporter-not-listed.json at 80479b0: all 5 pass samples stay unmatched, all 6 fail samples match, and the line #2 Invoice totals round wrong is also a close candidate (no reply in 297 days). now matches (the current pattern misses it). Add that line as a fail sample in samples/write-access-reporter-not-listed.json, why: #2 called a candidate inline with a negation word after the phrase.

@melodic-automation-lanes

Copy link
Copy Markdown
Contributor Author

A lane run on this pull request's head failed because the token broker refused it as workflow-modified: .github/workflows/pr-unblock.yml changed on main after the run's event, and a rerun keeps the old file. pr-merge pushes an empty commit so the next pr-unblock run uses main's files. It does this once per version of that file, so if a run fails the same way again, a person looks at it. The push starts no run itself: the conflict-resolution run starts at the next push to main or half-hourly pr-unblock-dispatch tick, or when a listed person runs it by hand, and an address-feedback run can start after both review lanes review the new head, if an unresolved thread is left for it.

@kyle-sexton

Copy link
Copy Markdown
Member

Superseded by #11920, which merged with this change plus the inline-branch negation fix.

@kyle-sexton kyle-sexton closed this Nov 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

do-not-merge Hard merge gate: do not merge while applied. needs-human Human-in-the-loop required; autonomous sessions must not resolve items carrying this.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(work-items): stale reporter-info setting, default off, closes only on the operator's yes

1 participant