Skip to content

fix(work-items): reconcile triage step-2 wait-gate with autonomous mode (#459) - #564

Merged
kyle-sexton merged 1 commit into
mainfrom
fix/459-triage-autonomous-gate-contradiction
Jul 20, 2026
Merged

fix(work-items): reconcile triage step-2 wait-gate with autonomous mode (#459)#564
kyle-sexton merged 1 commit into
mainfrom
fix/459-triage-autonomous-gate-contradiction

Conversation

@kyle-sexton

@kyle-sexton kyle-sexton commented Jul 19, 2026

Copy link
Copy Markdown
Contributor

Summary

The triage skill contradicted itself for autonomous/agent sessions. Step 2 ("Recommend category + state") ended with a flat "Wait for the user's direction before mutating anything," while the "AI disclaimer" section explicitly presupposed the opposite — sessions that "[create] comments or items during autonomous/agent triage sessions", i.e. mutate without a human turn. No branch selected between them, so an operator following step 2 literally could not triage autonomously, and an autonomous lane necessarily violated step 2.

Fix

Replace the single wait-line at the end of step 2 with an explicit, checkable two-branch direction gate:

  • Interactive session — a human operator is present and no standing lane rules were supplied. Keep the wait-gate: present the recommendation and wait for explicit user direction before mutating. This is the default.
  • Autonomous lane — triage runs unattended as a /loop / /schedule AFK session whose standing rules (the directive supplied with the invocation) already authorize triage mutations. Those standing rules are the direction the gate requires: the gate is treated as satisfied and triage proceeds without a human turn, prefixing every comment and item with the AI disclaimer. Blocking here would deadlock the lane, so the gate is met by the lane's mandate rather than silently ignored.

A closing sentence names the autonomous branch as the exact mode the AI disclaimer already anticipates, so the two sections read as one mode instead of a contradiction. This is the minimal reconciliation the issue asks for — the interactive gate is preserved verbatim; only the autonomous carve-out is added. It uses the plugin family's existing vocabulary (/loop, /schedule, AFK, standing rules, interactive vs unattended) rather than inventing new terms, and points at the real operative signal (standing rules supplied with the invocation) rather than a userConfig/session flag the plugin does not ship.

An eval (triage-autonomous-lane-treats-standing-rules-as-direction) guards the new branch against regression; the existing interactive-PR eval (which asserts the wait-gate) is unchanged.

Verification

Repo lint gates, run against the changed files in the worktree (all pass):

$ markdownlint-cli2 plugins/work-items/skills/triage/SKILL.md plugins/work-items/CHANGELOG.md
Linting: 2 file(s)
Summary: 0 error(s)

$ typos plugins/work-items/skills/triage/ plugins/work-items/CHANGELOG.md plugins/work-items/.claude-plugin/plugin.json
(exit 0, no output)

$ editorconfig-checker plugins/work-items/skills/triage/SKILL.md plugins/work-items/CHANGELOG.md plugins/work-items/.claude-plugin/plugin.json plugins/work-items/skills/triage/evals/evals.json
(exit 0, no output)

plugins/work-items/.claude-plugin/plugin.json bumped 0.12.20.12.3 (patch — documentation/behavioral clarification, no new capability) with a matching CHANGELOG.md entry. No other file pins the version (marketplace.json references the plugin by source path, not version).

Closes #459

Related

🤖 Generated with Claude Code

https://claude.ai/code/session_011V31qpAHP3jfs76B9d5Rfo

…de (#459)

Step 2 ("Recommend category + state") ended with a flat "Wait for the
user's direction before mutating anything," while the AI disclaimer
section presupposed the opposite — autonomous/agent sessions that mutate
without a human turn. No branch selected between them, so an operator
following step 2 could not triage autonomously and an autonomous lane
necessarily violated step 2.

Replace the single wait-line with an explicit two-branch direction gate:
interactive sessions (a human present, no standing lane rules) keep the
wait-gate; autonomous /loop / /schedule AFK lanes treat their standing
rules as the direction the gate requires and proceed without a human
turn — the mode the AI disclaimer already anticipates — so the gate is
satisfied by the lane's mandate rather than silently ignored.

Add an eval covering the autonomous-lane branch, bump plugin version to
0.12.3, and record the change in the changelog.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@kyle-sexton kyle-sexton added the automated Opened by automation. label Jul 19, 2026
@claude

claude Bot commented Jul 19, 2026

Copy link
Copy Markdown

Claude finished @kyle-sexton's task in 1m 58s —— View job


PR Review

  • Gather PR context and changed files
  • Review SKILL.md changes (triage gate logic)
  • Review evals.json changes (new eval coverage)
  • Review plugin.json version bump
  • Review CHANGELOG.md entry
  • Synthesize findings and post review

Overall Assessment

This is a clean, minimal, well-targeted fix. The logic is sound, the contradiction is correctly diagnosed, and the resolution uses the plugin family's existing vocabulary without inventing new terms. No correctness bugs, security issues, or architectural problems. The findings below are minor nits.


SKILL.md — Direction gate

The two-branch gate is well-structured. The critical phrasing "the gate is met by the lane's mandate, not skipped" is important — it correctly distinguishes authorization-via-mandate from silent bypass, and the closing sentence ties the AI disclaimer section to the autonomous branch precisely.

Minor — "standing rules" is not yet defined in this plugin's own vocabulary. The parenthetical "the directive supplied with its /loop / /schedule invocation" adequately explains the term in-place, so a reader landing here cold is not lost. However, the term appears only in the re-anchor plugin elsewhere in the codebase (in a different sense: project-configured rules, not invocation directives). A future reader could benefit from a pointer — e.g., "the directive supplied with its /loop / /schedule invocation (see CLAUDE.md or the loop's standing prompt)" — but this is a documentation nit, not a correctness issue, and keeping it concise is reasonable.

Minor — the autonomous branch adds an implicit double condition. The gate triggers when (a) running via /loop or /schedule AND (b) the invocation directive "already authorize[s] triage mutations." Both conditions are sensible, but the skill gives no guidance on what counts as sufficient authorization if the standing directive is general (e.g., "handle all routine work"). The model is expected to use judgment here, which is consistent with the plugin family's design, but an edge-case reader might wonder whether broad authorization counts. Not a bug — just worth noting as a potential ambiguity that could surface in practice.


evals.json — New eval #6

The new eval triage-autonomous-lane-treats-standing-rules-as-direction covers the key behaviors correctly:

  • Autonomous branch selected (standing rules satisfy the gate)
  • No wait for user direction
  • AI disclaimer prefixed on all created content
  • Adapter routing respected (no inline provider commands)

The prompt explicitly states authorization ("standing rules authorize triage label and comment mutations"), making the expected behavior unambiguous. The existing interactive eval (#1) remains valid — its prompt carries no autonomous context, so "waits for user direction" in its expected_output is still correct for the default path.

Acceptable gap — no eval for the ambiguous middle case (a /loop session whose standing rules don't explicitly authorize triage mutations). The PR description explicitly frames this as a minimal reconciliation, so the missing edge-case coverage is a conscious choice, not an oversight.


plugin.json and CHANGELOG.md

Version bump 0.12.20.12.3 is the correct semver level — this is a behavioral clarification (documentation + gate semantics), not a new capability. The changelog entry under ### Fixed is accurate and thorough, matches Keep a Changelog format, and covers both branches of the fix.


Summary

No blockers. Two minor documentation nits (the undefined "standing rules" term and the unguarded general-authorization case) are consistent with the plugin family's convention of relying on model judgment, and the minimal-fix scope deliberately sidesteps the edge case. The eval coverage is appropriate for what changed. Good to merge.

@kyle-sexton

Copy link
Copy Markdown
Contributor Author

Post-green review pass (work lane)

Finding Classification Disposition
"standing rules" undefined in this plugin's own vocabulary; collides with re-anchor's different sense of the term Valid, deferred (documentation nit, not blocking) Filed #570
Autonomous branch's implicit double condition has no guidance for the ambiguous general-authorization middle case Valid, deferred (documentation nit, not blocking) Filed #570

Bot review concluded "no blockers... good to merge" — both findings are non-blocking documentation nits, consistent with the PR's deliberately minimal scope. Moving this out of draft.

🤖 Generated with Claude Code

@kyle-sexton
kyle-sexton marked this pull request as ready for review July 19, 2026 23:57
@claude

claude Bot commented Jul 19, 2026

Copy link
Copy Markdown

Claude finished @kyle-sexton's task in 1m 49s —— View job


PR Review

  • Gather PR diff and changed files
  • Review SKILL.md changes (triage gate logic)
  • Review evals.json changes (new eval coverage)
  • Review plugin.json version bump
  • Review CHANGELOG.md entry
  • Synthesize findings and post review

Overall Assessment

Clean, minimal, and correct. The contradiction is accurately diagnosed and resolved with minimal scope: the interactive gate is preserved verbatim; only the autonomous carve-out is added. No correctness bugs, security issues, or architectural concerns. The two findings from the previous bot pass are confirmed as non-blocking nits (both filed as #570); I have one additional minor observation below.


SKILL.md — Direction gate (L89–L94)

The two-branch structure is logically sound. The operative signal — "standing rules supplied with the invocation" — is the correct one to use, not a userConfig flag or a session heuristic the plugin does not ship.

The phrase "the gate is met by the lane's mandate, not skipped" at line 92 does important work: it distinguishes authorized-by-mandate from silent bypass, which is the core of the fix. The closing bridge sentence at line 94 ties the AI disclaimer section to the autonomous branch directly, closing the contradiction at both ends.

Two previously identified nits (confirmed valid, deferred to #570):

  • "standing rules" is not defined in this plugin's own vocabulary; the parenthetical explains it in-place adequately for now.
  • The interactive condition ("no standing lane rules were supplied") and the autonomous condition ("standing rules already authorize triage mutations") are not strict complements — there is an implicit middle case (a /loop session whose standing rules don't explicitly cover triage). The model is expected to exercise judgment, which is consistent with the plugin family's design. Still worth a follow-up.

New minor observation — eval #6 prompt pre-asserts verification success (#71 is an external bug report you have just reproduced). That is the right setup for testing the direction gate specifically (the gate governs mutation, and mutation follows verification), but it means there's no eval covering the verification attempt itself in an autonomous lane — e.g., whether the AI disclaimer is correctly prefixed on a needs-info comment written by an autonomous session that could not reproduce the bug. Not blocking; the happy-path write path is what the new gate text governs. Worth noting for future eval expansion.


evals.json — Eval #6 (L72–L83)

The four expectations are correctly scoped:

  1. Selects autonomous-lane branch (standing rules satisfy direction requirement → no human-turn wait)
  2. Explicitly does NOT wait — and names why ("blocking here would deadlock the lane")
  3. AI disclaimer applied to all created content
  4. Adapter routing respected (no inline provider commands)

The prompt's explicit authorization signal ("standing rules authorize triage label and comment mutations") makes the expected behavior unambiguous and avoids dependence on implicit context. Eval #1's expected_output still correctly asserts "waits for user direction" for the interactive path — unchanged and valid.


plugin.json and CHANGELOG.md

0.12.20.12.3 is the correct semver level (behavioral clarification, not new capability). The changelog entry under ### Fixed is accurate, complete, and consistent with the format used in prior entries — including the no-comparison-link convention the file uses throughout.


Summary

No blockers. The previous review's two nits are confirmed; I add one minor note on the autonomous-lane needs-info path not being covered in evals (conscious minimal-scope choice, not an oversight). Good to merge.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

automated Opened by automation.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

work-items(triage): step-2 "wait for user direction" gate contradicts the skill's own autonomous/agent triage mode

1 participant