fix(mcp): server-derive artifact sender; default item(list) filter to identity (#75) - #207
Merged
Merged
Conversation
… identity (#75) Stop trusting caller-supplied identity strings for authorship/scoping. - artifact publish: remove ArtifactRequest.sender; always attribute to the server-derived identity (self.agent). Dropping the field makes sender spoofing unrepresentable at the type level rather than relying on a runtime override-ignored check. - item(list): default assignee_agent to the server identity when omitted so a bare list behaves like an inbox (mine + unassigned) instead of dumping every item; an explicit value is still honored (read-only visibility filter). - review submit: document why the finder `agent` stays caller-settable by design (local per-repo DB; /code-review orchestrator legitimately submits on behalf of many finder sub-agents; consensus counts distinct finder names). - tests: add item(list) default + explicit-override regression; drop the now- vacuous artifact "explicit sender wins" cases.
📝 WalkthroughWalkthroughMCP artifact publishing now always assigns the server identity as sender. Item listing defaults omitted assignee filters to the server identity while preserving explicit filters and unassigned items. ChangesMCP identity and filtering
Estimated code review effort: 3 (Moderate) | ~20 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
4 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What & why
Implements flare tracker item #75 (agent-identity hardening) — this is the agentflare item tracker, not GitHub issue #75 (an unrelated, already-closed ponytail item), so no GitHub close-keyword is used here. Stops trusting caller-supplied identity strings for authorship/scoping. The server already knows the calling agent non-spoofably (
self.agent/claims::owner_id()); claim/heartbeat/release/done/comment/handoff already use it. This closes the two request fields that let a caller override it.Full audit (item step 3)
Every caller-suppliable "which agent is acting" field on the MCP surface:
senderArtifactRequest(publish)self.agentassignee_agentItemRequest(list)assignee_agentItemRequest(create/update)agentReviewRequest(submit)Changes
artifactpublish — droppedArtifactRequest.sender; authorship is always the server-derived identity. Removing the field makes the spoof unrepresentable at the type level, which is stronger than a runtime "override is ignored" check (and makes such a check vacuous — so the old test cases that setsender:were removed).item(list)— a barelistnow defaultsassignee_agentto the server identity, so it behaves like an inbox (mine + unassigned) instead of dumping every item, matching what the/handoff inboxprompt already tells callers to do manually. An explicit value is still honored — this is a read-only visibility filter (viewing a teammate's queue), not an authorization boundary. Falls back to no filter only when identity is undetected.reviewsubmit —agent(finder name) stays caller-settable by design, now with a documentedSECURITY / step-3rationale instead of an implicit fallback.Tests
item_list_defaults_assignee_filter_to_server_identity— proves the new default and that an explicitassignee_agentstill works.artifact_publish_defaults_sender_to_agent_identity/artifact_list_filters_by_recipient_and_thread— updated for the removed field.Verification
cargo test --workspace— 496 bin tests + all crates passcargo clippy --workspace --all-targets -- -D warnings -A unsafe_code -A clippy::pedantic— cleancargo fmt --check— cleanDesign decision:
ReviewRequest.agentstays caller-settable (resolved)The original hand-off audit dismissed this field as "server fallback exists → leave as-is." That reasoning was wrong (the fallback is the hole), but the outcome is correct for a concrete reason:
/code-revieworchestrator legitimately submits on behalf of many finder sub-agents, andconsensus()counts distinct finder names — forcing one server identity would collapse them and break consensus, the feature's whole purpose.So it's kept, with the classification documented in code. Unlike
ArtifactRequest.sender(cross-agent handoff attribution another agent trusts), this is not an authorization boundary.