Skip to content

test(agents): agent write path refuses every card kind except ui (TASK-657) - #3061

Merged
lilyshen0722 merged 1 commit into
mainfrom
task-657-card-kind-refusal
Oct 31, 2026
Merged

lilyshen0722 merged 1 commit into
mainfrom
task-657-card-kind-refusal

Conversation

@lilyshen0722

Copy link
Copy Markdown
Contributor

Written by Dart, a Commonly agent — https://commonly.me/v2/pods/6a692a1be833c668acdb84cf

TASK-657. Pins the lane split from CTO's ruling on #2892: the agent write path must refuse every payload kind except ui, so a connector card cannot be forged.

  • New service-tier test (backend/__tests__/service/agentsRuntime.cardKindBoundary.test.js, real Mongo/PG) posts through POST /api/agents/runtime/pods/:podId/messages, the route the MCP commonly_post_message tool uses.
  • Refused kinds (approval, connector, system, UI, ui-connector, missing) are checked against the stored message list, not just the status code.
  • A valid kind: "ui" card is still accepted, so the refusals cannot pass by refusing everything.
  • Mutant check: letting connector through makes the refusal cases fail (2 failed, 6 passed).
  • Each test uses a fresh pod, because the runtime's consecutive-post cap returns 200 with refused: true and would otherwise mask the accept case.
  • No behaviour change.

Not covered here: the /bot/pods/:podId/messages route, which calls the same validator and has unit coverage in agentsRuntime.post-message.config.test.js.

🤖 Generated with Claude Code

…K-657)

Pins the lane split from CTO's ruling on #2892: connector results carry
server-written payloads, and agent-authored OpenUI stays on kind "ui". The
agent write path must refuse every other kind, so a connector card cannot
be forged by an agent.

Service tier, real Mongo/PG, through the runtime message route that the MCP
commonly_post_message tool posts through. Each refused kind is checked
against the stored message list, not only the response code. A valid kind
"ui" card is still accepted, so the refusals cannot pass by refusing
everything.

Mutant check: letting kind "connector" through fails the refusal cases.
No behaviour change.

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-authored-by: dart <WyJkYXJ0IiwiZGVmYXVsdCJd@agents.commonly.invalid>
Agent-Model: claude/claude-haiku-5-5/default
@coderabbitai

coderabbitai Bot commented Oct 31, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

No actionable comments were generated in the recent review.

Recent review info
Run configuration
Commits

Reviewing files that changed from the base of the PR and between ac4b0af and d28e116.

Files selected for processing: 1
  • backend/__tests__/service/agentsRuntime.cardKindBoundary.test.js

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 0 remain after this review.

Walkthrough

This change adds database-backed integration tests for agent runtime card messages. The tests check that unsupported kinds return HTTP 400 without storing a message, while a valid ui card returns HTTP 200 and adds one stored message.

Changes: Runtime card-kind boundary

Layer / File(s) Summary
Card-kind boundary coverage
backend/__tests__/service/agentsRuntime.cardKindBoundary.test.js
Sets up an agent runtime test environment and checks responses and stored-message counts for refused card kinds and a valid ui card.

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Other

Possibly related PRs

  • Team-Commonly/commonly#2675: Adds validation for the same agent message routes; this change adds integration coverage for that validator boundary and its persistence effects.
Merge Risk: Minimal · up to d28e1

The change adds card-kind tests without changing production behavior. No merge-blocking risk was identified.

Pre-merge checks: Passed 4
Check name Status Explanation
Title check Passed The title clearly and concisely describes the main change: a test that verifies the agent write path rejects all card kinds except ui.
Description check Passed The description directly explains the new service-tier test, the refused and accepted card kinds, the storage assertions, and the test isolation strategy.
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Finishing Touches
Generate docstrings
  • Commit to this branch
  • Create a new PR
Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

@lilyshen0722 lilyshen0722 left a comment

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.

Independent subagent review of the new service test at d28e116. Checked against the code, not the PR text.

  • Refusal is real: the route calls validateAgentCardPayload before anything is stored, and the 400 comes back through the catch.
  • The store check is real: the GET returns messages, and the accept case shows the read does see new rows, so the refusal counts are not vacuous.
  • The consecutive-post cap returns 200 with refused: true, and the fresh pod per test keeps each case at run 0.
  • Each refused case differs from the valid envelope only in kind, so the 400 comes from the kind check.
  • The mutant that lets connector through fails the refusal cases. I reproduced this: 2 failed, 6 passed.
  • No flakiness risk found; ids come from Mongo and beforeEach resets installations and tokens.

Non-blocking nits, not changed at this head:

  • The refusal assertion checks only the status. Matching the 400 body to /Expected {kind/ would tie each refusal to the kind check.
  • Each beforeEach leaves its pod behind. Harmless, but pod cleanup would make the file easier to read.

Written by Dart, a Commonly agent — https://commonly.me/v2/pods/6a692a1be833c668acdb84cf

GATE: PASS

@lilyshen0722
lilyshen0722 added this pull request to the merge queue Oct 31, 2026
Merged via the queue into main with commit 23dd3df Oct 31, 2026
38 checks passed
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