Skip to content

fix(work-items): make every lane escalation reach attend-queue - #9558

Merged
kyle-sexton merged 6 commits into
mainfrom
fix/attend-queue-escalation-authors
Oct 24, 2026
Merged

kyle-sexton merged 6 commits into
mainfrom
fix/attend-queue-escalation-authors

Conversation

@kyle-sexton

@kyle-sexton kyle-sexton commented Oct 24, 2026 •

Copy link
Copy Markdown
Member

No related issue: lane escalations must reach attend-queue (lane-stop audit 2026-10-24)

Summary

Some lane escalations never reached /work-items:attend-queue, for three reasons:

  • The rule says attend-queue "matches on author and marker prefix", but nothing named which authors count. The CI lanes post as melodic-automation-lanes[bot], which is not the operator's session login.
  • The github adapter's item listing returns issues only, so an escalated pull request was never listed. This repository has 5 open pull requests with needs-human right now.
  • work-resolve-issue's report-outcome added needs-human but posted no work-items:escalation marker.

Fix

  • plugins/work-items/reference/escalation-marker.md gets a "Trusted escalation authors" section, the one definition of who counts: the session's write identity, the target's merge.agent-identity from docs/conventions/pr-pipeline.yaml (read from the default branch), and <lane_app_slug>[bot] when that option is set. A marker from anyone else is reported as a suspected spoof. item-content-trust.md, attend-queue's SKILL.md and the parked-decision prompt in prompts/loops/loop-lane-prompts.md point at it. Writers still suppress duplicates on their own write identity only.
  • The github adapter README gets a "List pull requests" operation. attend-queue lists open pull requests that carry the human-gated label beside issues. On a pull request row it removes the human-gated label alone: never the autonomous-eligible role, never a work-class: label, and it never merges.
  • report-outcome adds the first line <!-- work-items:escalation lane=work-resolve-issue kind=escalated --> to every comment that adds the human-gated label: pushback, stopped, a refused patch, a dimension skip, and a turn cap with no restart left. The existing outcome marker moves to line two. parseOutcomeMarker accepts that one exact line before the outcome marker, so issue-prior, work-unblock and the monitor signals still read it. The pr-pipeline docs describing the marker are updated to match.
  • New changelog fragments for work-items and pr-pipeline.

Verification

  • node --test on report-outcome.test.mjs, label-unblocked.test.mjs, collect.test.mjs and cleanup.test.mjs: 364 passed, 0 failed.
  • Two new report-outcome tests:
    • Every hand-back opens with the escalation marker, and the plans that keep agent-ready (limited, funding, turn-cap restart) carry none.
    • The parser reads the outcome marker after the exact escalation line, and returns nothing after another lane's marker or a quoted one.
  • With the marker helper sabotaged to a no-op, 11 tests fail. They pass again once it is restored.
  • New attend-queue evals: 10 (markers count from the lane identity and the session login, not from a drive-by commenter) and 11 (an escalated pull request is listed and answered without the issue flip).
  • scripts/check-affected.sh --uncommitted: 10 passed, 6 skipped. After the review fixes and a merge of main, scripts/check-affected.sh --tests on 00c2f539: 12 passed, 2 skipped.
  • Fresh-context code and security reviews ran locally, because no CI review lane was healthy. Their findings were fixed in the third commit:
    • The lane identity is read through the forge, never a local checkout.
    • No pull request takes a role-label flip or a body update, whatever its row kind.
    • An untrusted marker counts for nothing instead of demoting the item.
    • The read-failure rule points at the loop-lane convention.
    • The pr-run-activity hand-back wording is corrected.
  • Review findings not fixed, with reasons:
    • report-outcome's hand-back has no once-per-run guard, so a rerun posts a second comment and so a second escalation marker. Labels go in separate calls. Both behaviours were here before this change. A duplicate marker still lists the item once, so it is left for a separate change.
    • The parked-decision prompt keeps its inline copy of the trusted authors. That prompt invokes no skill and states every contract inline by design. It now names its source section and compares case-insensitively.
    • The MARKER regex repeats the ESCALATION_MARKER literal. The marker holds no regex metacharacters, and the tests pin both against an independent literal.

Left out: running the attend-queue evals through claude plugin eval, which is a paid run. The changed-skills check, which check-affected skips locally; CI runs it.

Related

🤖 Generated with Claude Code

kyle-sexton and others added 5 commits October 23, 2026 23:31
…lated PRs

escalation-marker.md now defines the trusted escalation authors once: the
session's write identity, the target's merge.agent-identity, and
<lane_app_slug>[bot] when set. attend-queue, item-content-trust.md and the
parked-decision prompt point at it. attend-queue also lists open pull
requests carrying the human-gated label through the github adapter's new
"List pull requests" operation, since list-items returns issues only.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…utcome hand-backs

Every report-outcome comment that adds the human-gated label now opens with
<!-- work-items:escalation lane=work-resolve-issue kind=escalated -->, then
the outcome marker, so /work-items:attend-queue lists the issue as
escalated. parseOutcomeMarker reads the outcome marker after that exact
line, so issue-prior, work-unblock and the monitor signals still see it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Read the lane identity through the forge, never a local checkout; make an
untrusted marker count for nothing instead of demoting the item; keep pull
requests out of every role-label flip and body update; defer the read-failure
rule to the loop-lane convention; fix the pr-run-activity hand-back wording.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@kyle-sexton
kyle-sexton marked this pull request as ready for review October 24, 2026 03:52
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 24, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-24T03:54:15.789856Z 00c2f53 Draft marked ready
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@github-actions

github-actions Bot commented Oct 24, 2026 •

Copy link
Copy Markdown
Contributor

claude-security-review reviewed eed2893ec4e8277afcafccce3a6d1a64a37d8624: 0 finding(s), 0 as inline comments.

Incremental security review of plugins/work-items/skills/attend-queue/SKILL.md (since 00c2f53). I found no security issues.

The change adds one rule. A [ratify] row that comes from a lanes App marker, of either ratify kind, only prompts the operator. Only the operator's own ratification in the session ratifies, and an App comment never does. This tightens a control: it closes a path where a bot-authored marker, now a trusted author under the PR's "Trusted escalation authors" section, could be read as ratification ending the first-drain period. No standing instruction is deleted or softened, so the instruction-surface lens finds nothing.

Both referenced files exist in the tree: skills/work-loop/reference/first-drain-ratification.md and skills/work-loop/reference/c3-ratification-queue.md. I did not review the other 11 files in this pull request. They are unchanged since the last review and were covered then. There are no manifest changes in this increment.

critical-findings: 0

@github-actions

github-actions Bot commented Oct 24, 2026 •

Copy link
Copy Markdown
Contributor

claude-review reviewed eed2893ec4e8277afcafccce3a6d1a64a37d8624: 0 finding(s), 0 as inline comments.

Incremental review of plugins/work-items/skills/attend-queue/SKILL.md since 00c2f53: no findings.

The change adds one paragraph at lines 87-91. A [ratify] row from a lanes App marker, of either ratify kind, only prompts the operator, and the operator's own ratification in the session is what ratifies. It points to the two work-loop references for who may end the period and what counts as ratification.

I checked three things:

  • Link targets: Both exist: skills/work-loop/reference/first-drain-ratification.md and skills/work-loop/reference/c3-ratification-queue.md. The ${CLAUDE_PLUGIN_ROOT}/skills/... link style is already used in this plugin's skills (101 occurrences across 19 files).
  • Consistency with the references: first-drain-ratification.md says a label applied by a Bot or App actor doesn't count, so a lane running under an App token can't ratify itself. The new text agrees. It also agrees with c3-ratification-queue.md, which treats body-recorded ratification as context for the operator rather than dispatch authority.
  • Fit with the surrounding rule: The new paragraph doesn't conflict with the trusted-author rule at lines 62-64. An App marker is still listed as a row, and it only prompts the operator.

I did not run the attend-queue evals or any tests. The PR's verification claims in its description are the author's and I did not confirm them. No manifest files changed in this increment, and no hold class applies.

Now that merge.agent-identity is a trusted escalation author, a [ratify]
row can come from an App marker. State that such a row only prompts: the
operator's own ratification ratifies, never an App comment, pointing at the
work-loop ratification references.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@kyle-sexton
kyle-sexton added this pull request to the merge queue Oct 24, 2026
Merged via the queue into main with commit bc2c5ef Oct 24, 2026
35 checks passed
@kyle-sexton
kyle-sexton deleted the fix/attend-queue-escalation-authors branch October 24, 2026 04:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant