Skip to content

feat(planning): restate every open item in full when async work lands mid-round - #11888

Closed
melodic-automation-lanes[bot] wants to merge 1 commit into
mainfrom
work-resolve-issue/issue-8466-41281442798-1
Closed

melodic-automation-lanes[bot] wants to merge 1 commit into
mainfrom
work-resolve-issue/issue-8466-41281442798-1

Conversation

@melodic-automation-lanes

Copy link
Copy Markdown
Contributor

Closes #8466

Summary

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

Adds the cross-plugin contract docs/contracts/async-round-presentation/README.md. When a skill has shown open items and dispatched work returns before the user answers, the next message that presents anything ends with one block restating every open item in full, with the changed item marked. Items that wait on a pending result may be held, and status lines are allowed. /planning:interview's out-of-band drift rule now uses this full restate in place of 'Re-present narrowly'. It keeps 'This does not hold the round', so questions that do not wait on a lookup are still asked at once. discovery research, discovery explore and review fanout each point to the contract. Placement: the issue named docs/conventions/async-round-presentation/, but the repository moved cross-plugin contracts to docs/contracts/<name>/ and keeps only settings files in docs/conventions/ (ADR 0064 Decision 6, amended 2026-10-27; AGENTS.md:112). So the contract lives in docs/contracts/ with no stub under docs/conventions/. Review found that the recommendation-basis contract still required the narrow one-line form. Its re-emit section now defers to the new contract for dispatched-work returns (contract 3.0.0), and the convention registry lists the new contract.

Not verified

  • The test suites (plugins/planning/tests/interview-defenses.test.sh, plugins/discovery/scripts/contract.test.sh) were not run: this lane runs only the lint tier. They are left to the PR's CI. The digests were recomputed with repin-digests.sh and the byte window was measured as above.
  • The issue's criterion names docs/conventions/async-round-presentation/README.md. The contract was put at docs/contracts/async-round-presentation/README.md because ADR 0064 Decision 6 (amended 2026-10-27) and AGENTS.md:112 keep cross-plugin contracts in docs/contracts/. No stub was added under docs/c
  • The plugin-shipped copies of the recommendation-basis contract (plugins/discipline/context/recommendation-basis.md and about 11 byte-identical copies listed in scripts/cross-plugin-source-registry.txt) still say 'name the unchanged ones in one line' with no exception for dispatched-work returns. Upd
  • Tidy was not run: the change has 14 files across more than one area (docs/contracts, docs, plugins/planning, plugins/discovery, plugins/review), over the 10-file and 1-area cutoffs.
  • review-venue.txt was absent, so the review ran locally in a fresh-context subagent. The repository's CI code-review lane will still review the PR.
  • git status lists untracked root dotfiles (.bashrc, .gitconfig, .mcp.json, .idea, .vscode and others) that exist only inside the command sandbox; the file tools see none of them. They are not part of this change and should not go into the patch.

Fix

  • docs/contracts/async-round-presentation/README.md: new contract with the rule, the hold and status-line allowances, the reason, what it does not require (no serialized round), and the adopters
  • plugins/planning/skills/interview/context/loop.md: 'Re-present narrowly' is now 'Restate every open row in full': when outcome 2 or 3 moved a row, the next message that presents a question before the reply ends with every open and superseded-by-plan row in full, the moved row marked, and it points t
  • plugins/planning/skills/interview/SKILL.md: the out-of-band paragraph now asks for the full restate with the moved row marked and points to the contract; 'never hold the round' is kept
  • plugins/planning/tests/interview-defenses.test.sh: the phrase pin on 'Re-present narrowly.' now pins 'Restate every open row in full.', and the 'does not hold the round' pin is kept; four digest pins (SKILL.md Stance section, loop.md open-question register section, case 25, eval roster) re-p
  • plugins/planning/skills/interview/evals/evals.json: new case 43 late-return-restates-every-open-question-in-full; case 25's expected output and its narrow-restate expectation now require the full restate with Q3 marked
  • plugins/discovery/skills/research/SKILL.md: pointer line to the contract in 'Outcome gate (run before presenting)', placed after the gate table
  • plugins/discovery/skills/explore/SKILL.md: pointer line to the contract in 'Outcome gate (before EXPLORE.md handoff)'
  • plugins/review/skills/fanout/SKILL.md: pointer line to the contract in 'Step 2: Normalize'
  • docs/contracts/recommendation-basis/README.md: the re-emit section defers to async-round-presentation when dispatched work moved a recommendation; dropped the dangling 'Re-present narrowly' reference and the stale loop.md line numbers
  • docs/contracts/recommendation-basis/CHANGELOG.md: 3.0.0 entry (the contract's own rule makes any re-emit shape change a major bump)
  • docs/plugin-philosophy.md: Convention registry row for the new contract
  • .changes/planning/work-resolve-issue-issue-8466-3f9c1a7e.md: minor fragment
  • .changes/discovery/work-resolve-issue-issue-8466-b52e8d04.md: patch fragment
  • .changes/review/work-resolve-issue-issue-8466-6a1d73c9.md: patch fragment

Verification

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

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

The run reports:

  • /home/runner/work/claude-code-plugins/claude-code-plugins/.lane/checks/bin/check-changelog-fragments: all 47 fragments valid (run after the last edit)
  • /home/runner/work/claude-code-plugins/claude-code-plugins/.lane/checks/bin/check-affected: 12 passed, 6 skipped (typos not installed; checks that run the checked tree's own code), over 14 changed files (run after the last edit)
  • check-evals-quality plugins/planning/skills/interview/evals/evals.json: PASS, exit 0; the one warning is on existing case 14 (Q4 prose path), not on a changed case
  • cant-fail-scan --file plugins/planning/tests/interview-defenses.test.sh --check: PASS, no gating findings
  • repin-digests: four pins re-pinned, exit 0 (Stance 4f2aaa25 -> 564de96c, register 83310a75 -> fcd6bc75, case 25 60964b5d -> 186a511b, roster 68cb522d -> c6aa3fa2)
  • Byte-window check for plugins/discovery/scripts/contract.test.sh 8b, done with a bounded multiline regex because wc cannot run here: 'The Effort row is the ceiling over discipline 8' and 'Research the following topic: $ARGUMENTS' both start inside the first 20,000 bytes of research/SKILL.md; the Eff
  • Grep: 'Re-present narrowly' no longer appears in loop.md or SKILL.md; 'does not hold the round' (loop.md) and 'never hold the round' (SKILL.md) remain; each of the five skill files names docs/contracts/async-round-presentation/README.md
  • Fresh-context subagent review of the whole diff: 2 high, 4 medium and 6 low findings. Fixed: the stale digest pins, the recommendation-basis conflict, the unscoped SKILL.md/loop.md wording, the missing registry row, the research pointer placement, the explore wording, case 43's session state, and th
  • The lane run: https://github.com/melodic-software/claude-code-plugins/actions/runs/41281442798

Left out: the items under Not verified.

Related

#8466

Lane-Activity: work-resolve-issue/resolve-issue
@melodic-automation-lanes

Copy link
Copy Markdown
Contributor Author

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

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

@github-actions

github-actions Bot commented Nov 1, 2026

Copy link
Copy Markdown
Contributor

claude-security-review reviewed eb440e4fa82f69611fcdb06fc4721389775b6b1b: read 14 of 14 changed file(s); 0 finding(s), 0 as inline comments.

Security review: PR #11888

I found no security issues.

critical-findings: 0

Scope. I read every hunk of all 14 changed files in .claude-lane/pr.diff:

  • 3 changelog fragments
  • the new docs/contracts/async-round-presentation/README.md
  • the recommendation-basis README and its CHANGELOG
  • docs/plugin-philosophy.md
  • the discovery research and explore SKILL.md files
  • the interview SKILL.md, context/loop.md and evals/evals.json
  • interview-defenses.test.sh
  • the review fanout SKILL.md

None of them matches a listed trusted-path glob. plugins/review/skills/fanout/** is outside plugins/review/skills/security-review/**. The diff touches no trust control: no trusted-trigger or trusted-actor list, lane token scope, kill switch, resolve-config or broker file, merge hold, workflow, or plugin manifest (plugin.json / marketplace.json). It changes no userConfig key.

Instruction-surface lens. One standing instruction is replaced: /planning:interview's "Re-present narrowly" rule in loop.md and SKILL.md. The new rule restates every open item in full after dispatched work returns. I checked it by consequence. The old rule only limited how much of a round was printed again. Removing it lets no request reach an action that a check used to stop. These guardrails stay in place, and the test still pins them:

  • the no-hold rule ("This does not hold the round", "never hold the round")
  • the outcome that a superseded recommendation is restated, never resolved
  • the environment-resolve outcome
  • the floor at the next reply

The new eval case 43 and the rewritten case 25 both still require that no row is recorded as answered without the user. The re-pinned digests in interview-defenses.test.sh cover the Stance section, the register section, case 25 and the eval roster. Each re-pin matches a visible text change in this diff, and the no-silent-resolve, gap and blocker lines inside those sections are unchanged. I did not consult the protected-class list in docs/contracts/instruction-exception-register/README.md, because this lane has no shell and the change is a presentation rule. I judged it by consequence alone.

PR context. The description and the issue comments hold no text telling the lane to pass the PR, skip a check, or drop a finding.

Spend. Small token spend only: a full restate makes interview, research and fanout messages after an async return somewhat longer. It needs no hold.

@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 eb440e4fa82f69611fcdb06fc4721389775b6b1b; the summary is in this lane's pull request comment.

claude-lane: claude-review

Comment on lines +101 to +103
unchanged in one line. When the evidence is dispatched work that returned while open items wait on
the user, [async-round-presentation](../async-round-presentation/README.md) governs instead: the
message ends with every open item in full, the moved one marked. A pending recommendation the

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.

This bumps the contract's re-emit shape to 3.0.0, but the plugin copies still give the old shape, so the shipped planning plugin contradicts itself.

This section's own "Plugin-shipped copies" rule (L118-125) says each adopting plugin must state the re-emit shape in its own shipped text, because installed plugins cannot read docs/. The canonical copy plugins/discipline/context/recommendation-basis.md and its 11 byte-identical copies were not updated. For example, plugins/planning/context/recommendation-basis.md:34-36 still says:

When evidence changes a pending recommendation, restate it as old → new → why … name the unchanged ones in one line.

It has no exception for dispatched work. /planning:interview points at that shipped copy as "the contract this plugin ships" (SKILL.md:205, and SKILL.md:201 for re-emitting). In-flight lookups are exactly the dispatched work that now needs a full restate, so the interview's two rules disagree: loop.md says restate every open row in full, the shipped contract says one line. The new 3.0.0 CHANGELOG entry admits the copies are stale. The drift check (check-cross-plugin-source-drift.sh) only compares the copies with each other, so CI will not catch this.

Fix: add the dispatched-work exception (with its absolute-URL pointer to async-round-presentation) to plugins/discipline/context/recommendation-basis.md and sync the copies listed in scripts/cross-plugin-source-registry.txt. Or, if this is a deliberate follow-up, track it in an issue and drop "have not yet been updated" from a released major entry.

claude-lane: claude-review

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

pr-unblock / address-feedback: UNCERTAIN, left open

Evidence: docs/contracts/recommendation-basis/README.md:100, plugins/discipline/context/recommendation-basis.md:34, plugins/planning/context/recommendation-basis.md:34, docs/contracts/recommendation-basis/CHANGELOG.md:13

The finding is accurate. The contract's re-emit section now hands dispatched work to async-round-presentation (README.md:100-103), and the CHANGELOG 3.0.0 entry calls that a re-emit shape change and says the plugin-shipped copies have not yet been updated (CHANGELOG.md:13-14). The canonical copy plugins/discipline/context/recommendation-basis.md:34-36 and its byte-identical copies in 12 other plugins (architecture, code-tidying, debugging, developer-experience, github, harness-ops, naming, planning, session-flow, source-control, user-experience, work-items) still give the one-line form with no dispatched-work exception. The README's own Plugin-shipped copies rule (README.md:120-125) requires the re-emit shape in each copy. The fix is to add the exception, with an absolute-URL pointer to async-round-presentation, to the canonical copy and sync all 13 files. This lane's path check refused every one of those 13 files as outside this thread's scope, so I made no edit. The other option the reviewer offers, filing a follow-up issue and rewording the CHANGELOG entry, needs a tracker item, which this lane cannot file. Left open for a person to choose between syncing the copies in this PR and deferring to a tracked issue.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

pr-unblock / adjudicate-feedback: the finding stands

A fresh-context adjudicator read the review comment, the locations both sides cited and the code at eb440e4fa82f69611fcdb06fc4721389775b6b1b, without the fixing lane's reasoning, and found that the finding holds. The next address-feedback round fixes it; a round that leaves this thread open again ends the lane in a failing status.

Evidence: docs/contracts/recommendation-basis/README.md:100, plugins/discipline/context/recommendation-basis.md:34, plugins/planning/context/recommendation-basis.md:34, docs/contracts/recommendation-basis/CHANGELOG.md:13

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. Add the dispatched-work exception, with its absolute-URL pointer to docs/contracts/async-round-presentation/README.md, to plugins/discipline/context/recommendation-basis.md (re-emit text at lines 34-36), and sync every byte-identical copy listed in scripts/cross-plugin-source-registry.txt in this PR. Then drop "have not yet been updated" from the 3.0.0 entry in docs/contracts/recommendation-basis/CHANGELOG.md.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

pr-unblock / address-feedback: UNCERTAIN, left open

Evidence: plugins/discipline/context/recommendation-basis.md:34, plugins/planning/context/recommendation-basis.md:34, docs/contracts/recommendation-basis/README.md:100, docs/contracts/recommendation-basis/CHANGELOG.md:13, scripts/cross-plugin-source-registry.txt:123

The direction asks for three edits. First, add the dispatched-work exception, with an absolute-URL pointer to the async-round-presentation contract, to the re-emit text of the canonical copy plugins/discipline/context/recommendation-basis.md (lines 34-36). Second, sync the byte-identical copies registered at scripts/cross-plugin-source-registry.txt:123: architecture, code-tidying, debugging, developer-experience, github, harness-ops, naming, planning, session-flow, source-control, user-experience and work-items. Third, drop 'have not yet been updated' from the 3.0.0 CHANGELOG entry. The finding still holds at this head: the canonical copy and the 12 others still state only the one-line form, and README.md:100-103 now hands dispatched work to async-round-presentation. This lane's path check refused all 13 context/recommendation-basis.md files as outside the kept thread's scope. Those files are not among the pull request's changed files, and the fix request did not add them as named paths. Only the CHANGELOG is in scope, and editing it alone would claim the copies were updated when they were not, so I made no edit. This needs either a person to make the 13-file sync in this PR, or the copies added to the PR's changed files (for example by pushing the canonical edit) so that a later round can sync the rest.

@github-actions

github-actions Bot commented Nov 1, 2026

Copy link
Copy Markdown
Contributor

claude-review reviewed eb440e4fa82f69611fcdb06fc4721389775b6b1b: read 14 of 14 changed file(s); 2 finding(s), 2 as inline comments.

Code review: PR #11888 (async round presentation)

I read all 14 changed files in .claude-lane/pr.diff, along with the PR context, AGENTS.md, the recommendation-basis contract and the planning plugin's shipped copy of it.

The PR replaces the interview's "Re-present narrowly" rule with a full restate in loop.md and SKILL.md. It keeps "does not hold the round" and "never hold the round". The test pin moves to **Restate every open row in full.** and keeps the hold-refusal pin. Case 25 changes and case 43 is new; both grade the full restate with the changed question marked. The discovery and fanout skills each get a pointer line, and all three plugins get a changelog fragment. Grep finds no "Re-present narrowly" left outside historical CHANGELOG entries.

Findings

  1. The plugins still ship the old re-emit rule (inline comment on docs/contracts/recommendation-basis/README.md). The contract goes to 3.0.0 for a change to its re-emit shape, but the plugin copies still tell the model to name unchanged recommendations in one line. The installed planning plugin now gives /planning:interview two conflicting rules.
  2. The contract is not at the path the acceptance criterion names (inline comment on the new contract README). The criterion asks for docs/conventions/async-round-presentation/README.md; the file is at docs/contracts/.... AGENTS.md:112 supports the move, but an owner should confirm the criterion is met.

Closing issue #8466: acceptance criteria

  • Contract exists and the five skill files name it: met, except for the path (finding 2).
  • loop.md and SKILL.md no longer contain "Re-present narrowly", and the "does not hold the round" and "never hold the round" text is kept: met. I checked this with Grep.
  • interview-defenses.test.sh pins the new sentence and keeps the hold pin: met in the diff. The four re-pinned digests and "exits 0" are the author's claim; I did not run the test, and the PR says it was not run either.
  • New eval case 43: present and matches the criterion. That check-evals-quality passed is the author's claim; I did not check it.
  • Fragments for planning, discovery and review: present. That check-changelog-fragments and check-affected passed is the author's claim; I did not check it.

Other

  • The PR body and issue text contain no embedded instructions aimed at this lane.
  • No plugin.json or marketplace.json changes, so I ran no manifest checks.
  • No extra spend: the change only edits skill wording.

@melodic-automation-lanes

Copy link
Copy Markdown
Contributor Author

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

@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 what the change is meant to do, which a person decides.

  • Reason: feedback-question-intent
  • Resume key: eb440e4fa82f69611fcdb06fc4721389775b6b1b (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=11888 and activity=address-feedback:

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

@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
@melodic-automation-lanes

Copy link
Copy Markdown
Contributor Author

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

@melodic-automation-lanes

Copy link
Copy Markdown
Contributor Author

pr-unblock / address-feedback finished round 2 of max 4 on eb440e4.

@melodic-automation-lanes

Copy link
Copy Markdown
Contributor Author

The pr-unblock lane stopped address-feedback on this pull request: an adjudicator found a review finding stands, and the next round left it open again. 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=11888 -f activity=address-feedback

@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 edit the registered copies the open finding needs. Releases when: the replacement merges and this PR is closed.

@kyle-sexton

Copy link
Copy Markdown
Member

Superseded by #11913, which carries this change plus the recommendation-basis copy fix the lane could not make.

@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.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(planning): present every open item once when async work could change the round

1 participant