Skip to content

feat(agent-org): [7/10] add multi-Writer mutations, Tool Call idempotency, and Idle activation #762

Description

@ShiboSheng

Effort

Delivery boundary P50 P90 Substantive files
Writer LWW, call_id receipt, Idle activation, and cancellation/reassignment stale-result gate 3,000 review lines 5,000 review lines 22–34

Delivery contract

Dependency and single goal

Strictly stack on PR 6. This is the heaviest formal control-plane layer. Activate only the Writer capabilities persisted by PR 2 and add LWW, Tool Call idempotency, and Idle activation on top of PR 3 Turn identity, PR 4 Task hard gates, and PR 5/6 Team fences. Do not open Member direct or Group entry points in this PR.

State after merge

The Coordinator and Members granted capability by a real user can modify the same formal Task graph. Graph-admin sparse patches no longer require rereading because of stale updated_at: different fields are preserved, and the last legal commit wins for the same field. Every Agent Org state-writing Tool Call produces at most one durable side effect using the existing CallContext.call_id. The first formal Tasks in Idle, Team → Working, generation, history/outbox, and receipt commit together. Adding work while already Working does not bump activation generation. Cancellation/reassignment does not force-stop old execution, but PR 4 Store gates always reject a late formal result from the old owner.

Primary files

src-tauri/crates/agent-core/src/core/coordination/agent_org_tool_call_receipts.rs
src-tauri/crates/agent-core/src/core/coordination/agent_org_tasks/*
src-tauri/crates/agent-core/src/core/tools/impls/orchestration/agent_org/{task_create,task_graph_create,task_update,tasks}.rs
src-tauri/crates/agent-core/src/state/commands/session/org_tasks/*

Implementation steps and authoritative entry points

  1. At execution time, derive TaskGraphWriterAdmin from PR 3 persisted context and the PR 2 launch snapshot. The Coordinator is inherent. An additional Member must be present in the frozen allowlist. Links, Prompts, job titles, and model parameters cannot elevate privilege.
  2. Change graph-admin update to a sparse patch. Inside the transaction, reread the latest Task/graph and apply fields individually. Metadata merges only through explicit subkeys/merge-patch; reserved fields cannot be hidden in metadata and overwritten. Remove graph-admin updated_at CAS/stale-reload branches while retaining PR 4 cycle, terminal, in-progress, and owner hard gates.
  3. Every Agent Org state-writing Tool obtains a nonempty CallContext.call_id from the Provider tool ID. The receipt key is (org_run_id, session_id, turn_intent_id, call_id) and stores Tool/operation, canonical request digest, and deterministic result.
  4. The same key and same digest returns the first result. The same key with a different digest or Tool returns a typed conflict. Different call_id values in the same Turn are separate legal operations. Do not mechanically create receipts for read-only Tools.
  5. The path is Provider tool ID → typed Store IMMEDIATE transaction → receipt plus Task/history/assignment outbox/work_revision/required Team activation in one commit. Provider/Wake occurs only after commit.
  6. The Idle first-work transaction validates Writer and Team fences, creates every pending Task and dependency, commits Idle → Working, generation +1, history/outbox, and receipt together. Of two concurrent Writers, only the first bumps activation generation; the second sees the latest Working state and adds work normally.
  7. Task cancellation/reassignment commits durable Task facts only. Do not add execution-revocation rows, Stop the old lease, or wait for it. The old Turn still blocks Quiescence and may naturally finish file/external side effects, but cannot submit stale Task lifecycle/results.

Scope boundaries

Do not add graph revision, Writer lock, stale-reload/merge UI, or an AI conflict judge. Semantically duplicate but independently legal Tasks are retained. Owner lifecycle does not use LWW. The Coordinator is not a formal Task owner. Paused/Archived/Starting/Failed cannot activate, and Paused cannot auto-Resume.

Failure scenarios that must be rejected or remain no-ops

  • A model forges Writer authority, a link incorrectly grants Writer, or missing snapshot falls back to the template.
  • Empty call, session, or Turn context.
  • Same key/same request duplicates Task, generation, or outbox; same key with different request/Tool is accepted.
  • Two different call IDs in one Turn are incorrectly merged.
  • Receipt and business mutation only partially commit.
  • Two Writers updating different fields overwrite the whole row from stale snapshots; same-field last legal commit is not preserved; two individually valid patches create a cycle together and pass; LWW bypasses terminal/owner gates.
  • Two Idle Writers bump activation generation twice, or adding work while Working bumps it.
  • Cancellation/reassignment waits for or force-stops old execution, or a late old result is accepted.
  • A same-Member replacement bypasses FIFO, or the Team enters Idle while the old Turn remains active.

Acceptance and handoff

Verify fault injection at every transaction boundary; replay after response loss; same/different call_id matrix; Writer/link/model authority matrix; LWW same/different fields and metadata subkeys; cycle and owner cancel/complete races; concurrent Writer Idle activation; and explicit absence of execution-revocation rows and Stop calls. After merge, the formal control plane is usable behind the rollout gate. PR 8 may reuse only a stable enqueue_user_directed_work adapter and this actor/tool receipt; it must not copy Task Store or Writer resolution.

Suggested review commits — still one PR

A. Receipt schema/store and digest. B. Writer actor resolver and Tool assembly. C. Sparse LWW Task mutations. D. Idle activation/outbox/Wake plus fault/race tests. Every commit mutates through the PR 4 connection-scoped Store path and opens no second graph-writing path.

Plain-language contract

Dependency

PRs 1–6.

How it works

At execution time, resolve the Coordinator/additional Writer from the frozen snapshot. Graph administration uses sparse patching: different fields are preserved and the last legal commit wins for the same field, while every commit still checks cycle, terminal, and owner gates. Agent Org state-writing Tools reuse the existing CallContext.call_id; receipt and Task/history/outbox/activation commit in one transaction. Idle's first Tasks and Idle → Working commit only once, and Wake happens only after commit.

State after merge

Additional Writers can create, edit, cancel, and reassign formal Tasks to any Member. Retrying the same Tool Call does not duplicate side effects; two different call IDs remain two legal operations. Idle can reliably start another batch of formal work.

Boundaries

There is no graph lock, revision, stale-reload UI, or system judge for semantic conflicts between two AIs. Owner lifecycle does not use LWW. Cancellation/reassignment does not force-stop old execution; only the late formal result is rejected. The Coordinator remains a non-owner.

How to test

Test model/link Writer forgery, same/different call IDs, response loss, half-written receipts, concurrent Writers on same/different fields, cycles, owner completion versus cancellation, concurrent Idle activation, and explicit assertions that no revocation row or Stop call exists.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions