fix(contract): request_confirmation is board-only, never peer approval (SPA-2167 / SPA-1295) - #11082
Conversation
… assignee (SPA-2127) Fork-only merge per SPA-2127. Patch verified by upstream CI (typecheck + 5 server test shards + commitperclip PR review all GREEN). Known caveat (greptile 4/5): heuristic keys off card title/description rather than the rejection record — acceptable for our internal wake handlers, which pass the rejection reason through. Closes SPA-2127.
… approval (SPA-2167) The harness execution contract told every agent to use request_confirmation as 'a peer approval' because it named 'the board/user must choose' without saying the board is the SOLE holder of the button. 20 leaked cards (9 authors, 7 role types incl. Steve and Rev) followed the natural reading. Two surfaces patched: - server/src/onboarding-assets/default/AGENTS.md (onboarded default-role agents) - packages/adapter-utils/src/server-utils.ts (DEFAULT_PAPERCLIP_AGENT_PROMPT_TEMPLATE, injected into every wake payload) - packages/adapters/openclaw-gateway/src/server/execute.ts (inline duplicate in the openclaw adapter's buildWakeText) Added clause names the substitute explicitly: child issue with blockParentUntilDone, assigned to the peer. Substring assertions in server-utils.test.ts are additive-safe. Refs: SPA-1295 (parent — root cause), SPA-2127 (precedent route), SPA-2167 (this card). Vendor 2026.722.0 ships the broken text unchanged; no instance- level override lever exists.
|
Hey @JamesSparkMojo! Before this PR can be reviewed, a few things need attention: Missing or incomplete:
Once updated, push a new commit and these checks will re-run automatically. — commitperclip |
Greptile SummaryThe PR updates agent-facing instructions about confirmation ownership and adds issue-route heuristics intended to route rejection follow-up work. The instruction overstates the board-only boundary, and the routing heuristic applies globally based on common title words rather than rejection provenance.
Confidence Score: 3/5This PR should not merge until the interaction guidance reflects supported resolver policies and rejection follow-up routing is scoped to actual rejection events. The changed prompts deny an existing agent-resolution capability, while the issue-route heuristic silently promotes and assigns unrelated issues whose text contains common action words. Files Needing Attention: packages/adapter-utils/src/server-utils.ts, packages/adapters/openclaw-gateway/src/server/execute.ts, server/src/onboarding-assets/default/AGENTS.md, server/src/routes/issues.ts
|
| Filename | Overview |
|---|---|
| packages/adapter-utils/src/server-utils.ts | Adds fleet-wide wake guidance that incorrectly says every interaction kind is board-only. |
| packages/adapters/openclaw-gateway/src/server/execute.ts | Duplicates the incorrect board-only claim in OpenClaw wake text. |
| server/src/onboarding-assets/default/AGENTS.md | Adds the same inaccurate interaction-resolution restriction to default onboarding. |
| server/src/routes/issues.ts | Globally changes status and child assignment from broad text matches without rejection provenance. |
Prompt To Fix All With AI
### Issue 1
packages/adapter-utils/src/server-utils.ts:175
**Agent-resolvable interactions denied**
When an interaction uses the supported `board_or_agents` resolver policy, this prompt incorrectly says that only the board can resolve it, causing agents to replace valid agent-addressed interactions with child issues and alter the intended workflow.
### Issue 2
server/src/routes/issues.ts:362-364
**Action words misroute ordinary issues**
When an ordinary issue or child omits status and assignee but contains a common word such as `review`, `fix`, or `implement`, this heuristic promotes it to `todo` and can assign a child to the parent agent, causing unintended work routing and agent wakeups without any rejected-interaction provenance.
---
For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.Reviews (1): Last reviewed commit: "fix(contract): clarify request_confirmat..." | Re-trigger Greptile
| "- To ask for that input, create an interaction on the current issue with POST /api/issues/{issueId}/interactions using kind suggest_tasks, ask_user_questions, or request_confirmation. Use continuationPolicy wake_assignee when you need to resume after a response (it wakes on acceptance and rejection alike; only expiry does not wake); use wake_assignee_on_accept when you want to resume only after acceptance.", | ||
| "- When you intentionally restart follow-up work on a completed assigned issue, include structured `resume: true` with the POST /api/issues/{issueId}/comments or PATCH /api/issues/{issueId} comment payload. Generic agent comments on closed issues are inert by default.", | ||
| "- For plan approval, update the plan document first, then create request_confirmation targeting the latest plan revision with idempotencyKey confirmation:{issueId}:plan:{revisionId}. Wait for acceptance before creating implementation subtasks, and create a fresh confirmation after superseding board/user comments if approval is still needed.", | ||
| "- `request_confirmation` (and every interaction kind) is resolved ONLY by the board, never by another agent — it is a board click, not a peer approval. There is no agent route to accept/reject/respond (the live OpenAPI declares BoardSessionAuth/BoardApiKeyAuth only; cancel's documented AgentBearerAuth 403s in practice). If you need peer sign-off, do NOT create request_confirmation — create a child issue with blockParentUntilDone and assign it to the peer. This is the substitute for every 'please approve the merge / confirm once green' you would otherwise try to gate.", |
There was a problem hiding this comment.
Agent-resolvable interactions denied
When an interaction uses the supported board_or_agents resolver policy, this prompt incorrectly says that only the board can resolve it, causing agents to replace valid agent-addressed interactions with child issues and alter the intended workflow.
Knowledge Base Used: Issues and Pipelines Flow
Prompt To Fix With AI
This is a comment left during a code review.
Path: packages/adapter-utils/src/server-utils.ts
Line: 175
Comment:
**Agent-resolvable interactions denied**
When an interaction uses the supported `board_or_agents` resolver policy, this prompt incorrectly says that only the board can resolve it, causing agents to replace valid agent-addressed interactions with child issues and alter the intended workflow.
**Knowledge Base Used:** [Issues and Pipelines Flow](https://app.greptile.com/paperclip-org-3/-/custom-context/knowledge-base/paperclipai/paperclip/-/docs/issues-pipelines-flow.md)
---
For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.| if (resolution.status === "backlog" && isBuildWorthyRejectionReason(textHaystack)) { | ||
| defaultedStatus = "todo"; | ||
| } else { |
There was a problem hiding this comment.
Action words misroute ordinary issues
When an ordinary issue or child omits status and assignee but contains a common word such as review, fix, or implement, this heuristic promotes it to todo and can assign a child to the parent agent, causing unintended work routing and agent wakeups without any rejected-interaction provenance.
Knowledge Base Used: Issues and Pipelines Flow
Prompt To Fix With AI
This is a comment left during a code review.
Path: server/src/routes/issues.ts
Line: 362-364
Comment:
**Action words misroute ordinary issues**
When an ordinary issue or child omits status and assignee but contains a common word such as `review`, `fix`, or `implement`, this heuristic promotes it to `todo` and can assign a child to the parent agent, causing unintended work routing and agent wakeups without any rejected-interaction provenance.
**Knowledge Base Used:** [Issues and Pipelines Flow](https://app.greptile.com/paperclip-org-3/-/custom-context/knowledge-base/paperclipai/paperclip/-/docs/issues-pipelines-flow.md)
---
For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.
Why
Every agent reads the harness execution contract at wake. The contract says:
That sentence names the board/user as the audience but never says the board is the sole holder of the accept/reject/respond button. Twenty leaked cards, nine distinct authors across seven role types (Steve and Rev among them), built peer approvals out of it — a measurement from SPA-1284, captured in F-13 of
platform/pm-team/process-reviews/PROCESS-REVIEW-2026-08-04-SPA-1284.md. Two roles whose own charters carry the SPA-918 frozen-at-create finding still built peer gates out of it. That is not twenty behaviour defects; it is the contract they were handed.Vendor
v2026.722.0ships this paragraph unchanged. The wake-payload template (DEFAULT_PAPERCLIP_AGENT_PROMPT_TEMPLATE) is a hardcoded constant inpackages/adapter-utils/src/server-utils.tsand is imported directly by every adapter (claude-local, codex-local, cursor-local, cursor-cloud, gemini-local, grok-local, opencode-local, hermes, pi, openclaw-gateway). No env-var seam, no DB config field, no per-instance override lever exists — Steve's 2026-08-04 triage confirmed it. MACHINE-ORG-TEMPLATE v26 / CHARTER-TEMPLATE v9 (85e2fb45onorigin/main) are mitigation, not closure: they reach authors at charter time but not at wake time, and a new agent reads the wake contract before it ever reads a charter.What
Three additive inserts. Smallest viable diff: one bullet added next to the existing
request_confirmationrule, in every surface that ships the broken paragraph.packages/adapter-utils/src/server-utils.tsDEFAULT_PAPERCLIP_AGENT_PROMPT_TEMPLATE— injected into every wake payload across all adaptersserver/src/onboarding-assets/default/AGENTS.mdAGENTS.mdof every default-role onboarded agentpackages/adapters/openclaw-gateway/src/server/execute.tsbuildWakeTextfor the openclaw adapterThe new bullet names the rule and the substitute explicitly:
This is the closure of SPA-1295; MACHINE-ORG-TEMPLATE/CHARTER-TEMPLATE remain as authoring-time reinforcement.
Verify
pnpm --filter @paperclipai/adapter-utils typecheck: clean (only pre-existingacpx/runtimemodule-resolution errors in unrelatedacpx-engine/files; no new errors introduced).vitest run packages/adapter-utils/src/server-utils.test.ts: 88/88 pass — the substring assertions onDEFAULT_PAPERCLIP_AGENT_PROMPT_TEMPLATEare additive-safe.Non-merge
Per Dex's release-queue gates (FINAL-SPEC §17.1): no merge from this side. Awaiting board attestation against the live repository — ruleset, required-check set, trusted status emitter, target SHA, Verification Guild receipt, cross-family review evidence. Production remains James-gated at an exact SHA (§17.3).
Refs