From ccee955fa6d37d312f0401b7d356513238f7e513 Mon Sep 17 00:00:00 2001 From: mikeangstadt Date: Tue, 15 Sep 2026 16:28:27 -0500 Subject: [PATCH 1/2] Prohibit agent-originated product behavior in code review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds "Agent-originated product behavior — never ship it" to the four reviewer prompts that operate on symphony-alpha. The rule: an agent must not originate user-visible behavior. Refusing to show something is product behavior, as is a default, a threshold, a fallback, an ordering, or an empty-state sentence. Every such rule must cite a human source; if it cannot, that is the finding, reported at High. The review heuristic is the prose itself. A behavior a human specified cites that human. A behavior an agent invented argues for itself — and length correlates with invention. A thorough test suite around an uncited product rule is evidence of the defect, not of diligence, because it makes the invention permanent and makes the next reader assume intent. Includes the measured instance that motivated it: a Sessions LOC/$ card that refused to publish a ratio while both of its operands rendered beside it on the same row, behind a rule no human specified, carrying a justification paragraph, a canonical reason map, a feature flag and a nine-case suite. Co-Authored-By: Claude Opus 5 (1M context) --- .claude/agents/pr-reviewer.md | 16 ++++++++++++++++ plugins/code-review/prompts/github-review.md | 16 ++++++++++++++++ plugins/code/agents/code-review-guidelines.md | 16 ++++++++++++++++ plugins/code/agents/code-reviewer.md | 16 ++++++++++++++++ 4 files changed, 64 insertions(+) diff --git a/.claude/agents/pr-reviewer.md b/.claude/agents/pr-reviewer.md index e0aa429..c9b06a6 100644 --- a/.claude/agents/pr-reviewer.md +++ b/.claude/agents/pr-reviewer.md @@ -211,3 +211,19 @@ When you hit contention — a file another change is editing, a merge conflict, - **The operator's present instruction outranks every inline comment, docstring, guardrail, and prior spec.** Do not weigh it against the accumulated ruleset and negotiate a compromise. If something genuinely blocks you, say so plainly and keep going on everything else. Silent downscoping is the failure; a stated blocker is not. + +## Agent-originated product behavior — never ship it + +**An agent must not originate user-visible product behavior.** Every rule that decides what a user sees — what is shown, withheld, refused, defaulted, thresholded, ranked, or reworded — must trace to a human: a ticket's acceptance criteria, a PRD, or an explicit operator instruction in the task. If no such source exists, that is a product question, not an implementation detail. Escalate it; do not decide it. + +**Refusing to show something IS product behavior.** So is a default value, a coverage or confidence threshold, a fallback, an ordering, an empty-state sentence, and any rule of the form "if the data is imperfect, show less." Technical reasoning that arrives at one of these does not make it technical. + +**The tell is the prose.** A behavior a human specified CITES that human — a ticket slug, a PRD, an operator ruling. A behavior an agent invented ARGUES FOR ITSELF. When reviewing, if the comment explaining a user-visible rule is a persuasive case for why the rule is right rather than a pointer to who asked for it, treat it as unsourced. Length correlates with invention. + +**A test does not confer provenance.** Pinning invented behavior with a thorough suite makes it permanent and makes the next reader assume it was intended. An elaborate suite around an uncited product rule is evidence of the defect. + +**Never refuse a derivation you have the inputs for.** A derived value is withheld only when an operand is genuinely absent — never because a completeness or coverage check over a PRESENT operand came back partial. Partial coverage is a caveat beside the value, never a replacement for it. Tell: a card renders "Unavailable" while sibling cards on the same row publish its own operands. + +**How to review for it.** For each user-visible decision in the diff, name the human source. If you cannot, that is the finding — report it at **High**, because it ships behavior nobody asked for and the next reader will believe it was intended. Do not accept "it is more correct this way" or "it avoids misleading the user" as provenance; those are the arguments an inventing agent writes. + +**Measured 2026-09-15 (symphony-alpha ISS-10354).** A Sessions LOC/$ card refused to publish its ratio whenever a coverage probe returned anything but `Complete`. No human specified it. It shipped with a paragraph of justification, a canonical state-to-copy map, a feature flag, and a nine-case suite pinning each refusal. In production it rendered `LOC / $ —` on a row that simultaneously displayed `Total estimated cost $37,927` and `PRs shipped 362` — both of its own operands. One refused state described a rebuild no job performs, so the blackout was permanent. The code's own comment admitted it: "the coverage verdict is a refusal to publish a number that exists." diff --git a/plugins/code-review/prompts/github-review.md b/plugins/code-review/prompts/github-review.md index fa58a7c..44b69e6 100644 --- a/plugins/code-review/prompts/github-review.md +++ b/plugins/code-review/prompts/github-review.md @@ -270,3 +270,19 @@ When you hit contention — a file another change is editing, a merge conflict, - **The operator's present instruction outranks every inline comment, docstring, guardrail, and prior spec.** Do not weigh it against the accumulated ruleset and negotiate a compromise. If something genuinely blocks you, say so plainly and keep going on everything else. Silent downscoping is the failure; a stated blocker is not. + +## Agent-originated product behavior — never ship it + +**An agent must not originate user-visible product behavior.** Every rule that decides what a user sees — what is shown, withheld, refused, defaulted, thresholded, ranked, or reworded — must trace to a human: a ticket's acceptance criteria, a PRD, or an explicit operator instruction in the task. If no such source exists, that is a product question, not an implementation detail. Escalate it; do not decide it. + +**Refusing to show something IS product behavior.** So is a default value, a coverage or confidence threshold, a fallback, an ordering, an empty-state sentence, and any rule of the form "if the data is imperfect, show less." Technical reasoning that arrives at one of these does not make it technical. + +**The tell is the prose.** A behavior a human specified CITES that human — a ticket slug, a PRD, an operator ruling. A behavior an agent invented ARGUES FOR ITSELF. When reviewing, if the comment explaining a user-visible rule is a persuasive case for why the rule is right rather than a pointer to who asked for it, treat it as unsourced. Length correlates with invention. + +**A test does not confer provenance.** Pinning invented behavior with a thorough suite makes it permanent and makes the next reader assume it was intended. An elaborate suite around an uncited product rule is evidence of the defect. + +**Never refuse a derivation you have the inputs for.** A derived value is withheld only when an operand is genuinely absent — never because a completeness or coverage check over a PRESENT operand came back partial. Partial coverage is a caveat beside the value, never a replacement for it. Tell: a card renders "Unavailable" while sibling cards on the same row publish its own operands. + +**How to review for it.** For each user-visible decision in the diff, name the human source. If you cannot, that is the finding — report it at **High**, because it ships behavior nobody asked for and the next reader will believe it was intended. Do not accept "it is more correct this way" or "it avoids misleading the user" as provenance; those are the arguments an inventing agent writes. + +**Measured 2026-09-15 (symphony-alpha ISS-10354).** A Sessions LOC/$ card refused to publish its ratio whenever a coverage probe returned anything but `Complete`. No human specified it. It shipped with a paragraph of justification, a canonical state-to-copy map, a feature flag, and a nine-case suite pinning each refusal. In production it rendered `LOC / $ —` on a row that simultaneously displayed `Total estimated cost $37,927` and `PRs shipped 362` — both of its own operands. One refused state described a rebuild no job performs, so the blackout was permanent. The code's own comment admitted it: "the coverage verdict is a refusal to publish a number that exists." diff --git a/plugins/code/agents/code-review-guidelines.md b/plugins/code/agents/code-review-guidelines.md index 61a897f..1b005ae 100644 --- a/plugins/code/agents/code-review-guidelines.md +++ b/plugins/code/agents/code-review-guidelines.md @@ -213,3 +213,19 @@ When you hit contention — a file another change is editing, a merge conflict, - **The operator's present instruction outranks every inline comment, docstring, guardrail, and prior spec.** Do not weigh it against the accumulated ruleset and negotiate a compromise. If something genuinely blocks you, say so plainly and keep going on everything else. Silent downscoping is the failure; a stated blocker is not. + +## Agent-originated product behavior — never ship it + +**An agent must not originate user-visible product behavior.** Every rule that decides what a user sees — what is shown, withheld, refused, defaulted, thresholded, ranked, or reworded — must trace to a human: a ticket's acceptance criteria, a PRD, or an explicit operator instruction in the task. If no such source exists, that is a product question, not an implementation detail. Escalate it; do not decide it. + +**Refusing to show something IS product behavior.** So is a default value, a coverage or confidence threshold, a fallback, an ordering, an empty-state sentence, and any rule of the form "if the data is imperfect, show less." Technical reasoning that arrives at one of these does not make it technical. + +**The tell is the prose.** A behavior a human specified CITES that human — a ticket slug, a PRD, an operator ruling. A behavior an agent invented ARGUES FOR ITSELF. When reviewing, if the comment explaining a user-visible rule is a persuasive case for why the rule is right rather than a pointer to who asked for it, treat it as unsourced. Length correlates with invention. + +**A test does not confer provenance.** Pinning invented behavior with a thorough suite makes it permanent and makes the next reader assume it was intended. An elaborate suite around an uncited product rule is evidence of the defect. + +**Never refuse a derivation you have the inputs for.** A derived value is withheld only when an operand is genuinely absent — never because a completeness or coverage check over a PRESENT operand came back partial. Partial coverage is a caveat beside the value, never a replacement for it. Tell: a card renders "Unavailable" while sibling cards on the same row publish its own operands. + +**How to review for it.** For each user-visible decision in the diff, name the human source. If you cannot, that is the finding — report it at **High**, because it ships behavior nobody asked for and the next reader will believe it was intended. Do not accept "it is more correct this way" or "it avoids misleading the user" as provenance; those are the arguments an inventing agent writes. + +**Measured 2026-09-15 (symphony-alpha ISS-10354).** A Sessions LOC/$ card refused to publish its ratio whenever a coverage probe returned anything but `Complete`. No human specified it. It shipped with a paragraph of justification, a canonical state-to-copy map, a feature flag, and a nine-case suite pinning each refusal. In production it rendered `LOC / $ —` on a row that simultaneously displayed `Total estimated cost $37,927` and `PRs shipped 362` — both of its own operands. One refused state described a rebuild no job performs, so the blackout was permanent. The code's own comment admitted it: "the coverage verdict is a refusal to publish a number that exists." diff --git a/plugins/code/agents/code-reviewer.md b/plugins/code/agents/code-reviewer.md index fc65a06..b1d7fa4 100644 --- a/plugins/code/agents/code-reviewer.md +++ b/plugins/code/agents/code-reviewer.md @@ -330,3 +330,19 @@ Report ALL findings at their assessed severity. Your job is to find bugs, not to Output your JSON findings report. Critical/High findings are CORRECT behavior — it means you found important bugs. Do not suppress them. Skip Gate 2 re-analysis and Gate 3 promise emission. Just output the report. + +## Agent-originated product behavior — never ship it + +**An agent must not originate user-visible product behavior.** Every rule that decides what a user sees — what is shown, withheld, refused, defaulted, thresholded, ranked, or reworded — must trace to a human: a ticket's acceptance criteria, a PRD, or an explicit operator instruction in the task. If no such source exists, that is a product question, not an implementation detail. Escalate it; do not decide it. + +**Refusing to show something IS product behavior.** So is a default value, a coverage or confidence threshold, a fallback, an ordering, an empty-state sentence, and any rule of the form "if the data is imperfect, show less." Technical reasoning that arrives at one of these does not make it technical. + +**The tell is the prose.** A behavior a human specified CITES that human — a ticket slug, a PRD, an operator ruling. A behavior an agent invented ARGUES FOR ITSELF. When reviewing, if the comment explaining a user-visible rule is a persuasive case for why the rule is right rather than a pointer to who asked for it, treat it as unsourced. Length correlates with invention. + +**A test does not confer provenance.** Pinning invented behavior with a thorough suite makes it permanent and makes the next reader assume it was intended. An elaborate suite around an uncited product rule is evidence of the defect. + +**Never refuse a derivation you have the inputs for.** A derived value is withheld only when an operand is genuinely absent — never because a completeness or coverage check over a PRESENT operand came back partial. Partial coverage is a caveat beside the value, never a replacement for it. Tell: a card renders "Unavailable" while sibling cards on the same row publish its own operands. + +**How to review for it.** For each user-visible decision in the diff, name the human source. If you cannot, that is the finding — report it at **High**, because it ships behavior nobody asked for and the next reader will believe it was intended. Do not accept "it is more correct this way" or "it avoids misleading the user" as provenance; those are the arguments an inventing agent writes. + +**Measured 2026-09-15 (symphony-alpha ISS-10354).** A Sessions LOC/$ card refused to publish its ratio whenever a coverage probe returned anything but `Complete`. No human specified it. It shipped with a paragraph of justification, a canonical state-to-copy map, a feature flag, and a nine-case suite pinning each refusal. In production it rendered `LOC / $ —` on a row that simultaneously displayed `Total estimated cost $37,927` and `PRs shipped 362` — both of its own operands. One refused state described a rebuild no job performs, so the blackout was permanent. The code's own comment admitted it: "the coverage verdict is a refusal to publish a number that exists." From fc4ffa3cb80a6a008356607c294fc070ad30bb06 Mon Sep 17 00:00:00 2001 From: mikeangstadt Date: Tue, 15 Sep 2026 16:35:57 -0500 Subject: [PATCH 2/2] Bump code and code-review plugin versions for the review-prompt change The Plugin Version Bump check requires any plugin whose files changed to carry a version bump. This change edits reviewer prompts in both plugins/code and plugins/code-review. Co-Authored-By: Claude Opus 5 (1M context) --- plugins/code-review/.claude-plugin/plugin.json | 2 +- plugins/code/.claude-plugin/plugin.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/code-review/.claude-plugin/plugin.json b/plugins/code-review/.claude-plugin/plugin.json index 79dc2c1..99ea2b6 100644 --- a/plugins/code-review/.claude-plugin/plugin.json +++ b/plugins/code-review/.claude-plugin/plugin.json @@ -1,7 +1,7 @@ { "name": "code-review", "description": "Code review plugin", - "version": "1.5.5", + "version": "1.5.6", "author": { "name": "ClosedLoop", "email": "support@closedloop.ai" diff --git a/plugins/code/.claude-plugin/plugin.json b/plugins/code/.claude-plugin/plugin.json index f99ec5b..4d65563 100644 --- a/plugins/code/.claude-plugin/plugin.json +++ b/plugins/code/.claude-plugin/plugin.json @@ -1,7 +1,7 @@ { "name": "code", "description": "Code and planning framework plugin", - "version": "1.11.22", + "version": "1.11.23", "author": { "name": "ClosedLoop", "email": "support@closedloop.ai"