Route mutations to publish or proposal automatically and report the outcome #238
Description
Outcome
An agent states its intent once. The server decides between publishing and opening a proposal from effective permission, and the response says which happened. No permission lookup, no error-string parsing, and the same content is never sent twice.
Decision: tasks are excluded
Review applies to shared knowledge only — project memories and Project Instructions. Tasks are work organization, not a reviewed knowledge state: write permission edits them directly, including creating them. Traceability for tasks comes from history instead of review, tracked in #247.
Delivered
| Commit | Change |
|---|---|
729f7d7 |
Removed the authorship check in Review. IsModerator via Access(..., moderate: true) is the only gate, so an owner can decide on their own agent's submission. |
8d88b00 |
Task proposals can create a task. Superseded by the decision above; removed with #247. |
f258099 |
memory_store and project_instructions_update publish or submit for review from one call. Response carries outcome; review=require forces review. |
175487e |
memory_update exposes the existing KnowledgeService.Store(memoryId, baseRevisionId) path, which no MCP tool reached. Guide raised to v18. |
6476e78 |
memory_store_many submits a whole batch for review in one Serializable transaction and reuses the MemoryWriteBatch idempotency record, so a replayed key returns the original result instead of duplicating proposals. |
43e017a |
Missing write permission answers with outcome: denied, reason: missing_permission and the missing capability instead of exception prose. |
Acceptance
- An owner approves a proposal submitted by their own agent, and that publishes it.
- Someone with write but not moderate cannot approve anything there, including their own proposal.
- Removing the authorship check widens nothing: every review still passes the moderator check.
- The same call publishes for a moderator and submits for review otherwise, differing only in
outcome. - A contributor creates or edits a memory or Project Instructions in one call; no second call repeats the content.
- Approval publishes exactly the submitted payload; rejection discards it and publishes nothing.
-
review=requireasks for review even when the caller could publish. - A read-only key receives a machine-readable
deniedand creates nothing. -
memory_store_manyfollows the same rule and stays atomic and idempotent on both paths.
Follow-up
proposal_create is now redundant for memories and Project Instructions. It is removed together with the task proposal paths in #247, leaving proposal_get, proposal_list, proposal_review and proposal_withdraw as the review surface.
Constraints
Pre-release, no live users: the old paths were replaced outright. No migration, no compatibility shim, no parallel versioned variant.