read_only. A personal contribution is how something learned in that Session reaches the team anyway. The Session asks to write exact documents, the person approves those bytes, and the approval becomes a Memory proposal in the team’s store under that person’s name. Nothing else from the Session goes with it.
This guide sets up the store and the Session, then shows the person’s approval and the team’s review.
Before starting, have:
- A Workspace-bound
CHECKFU_API_KEYthat can administer grants (root or admin). - The person’s Principal (
prin_…) inCHECKFU_PRINCIPAL_ID, withinvoke,steerandact_ason the Agent (see Build a personal assistant). - An Agent on an ACP (
acp-v1) harness image (see Bring a custom harness). Pi, the Container harnesses (claude-code,codex,deepseek) and connected runtimes don’t offer the contribution tool yet. - An Environment (
env_…) with no network access, as every personal Session requires.
1. Share a team store
Create a Workspace store that reviews changes, and grant it. The person needsread to mount it and write because the contribution lands under their own grant. The Agent needs read. A curator needs read and approve to promote proposals.
2. Mount it in the person’s private Session
Create apersonal Session acting as the person, with the team store mounted read-only:
read_write on the team store is refused, because the person’s Session is narrower than the team.
3. The Session asks to contribute
Apersonal or group Session is offered one Checkfu tool for this, checkfu_memory_contribute. Its input names a store the Session mounts read-only and up to 16 document operations on distinct paths, with at most one document’s size of content in all:
put may carry expected_sha256 (the document it replaces, or null to create it); a delete must.
The tool writes nothing. It records one ActionApproval of kind memory_contribution that binds the store and the exact operations, and answers approval_requested with its action_approval_id. The Run doesn’t wait: the Agent ends its turn and tells the person what’s waiting. The same bytes asked again in the same Run return the same approval. Changing the store or any byte, or asking in another Run, is a new approval. Once the person declines, the tool answers declined, and the Agent shouldn’t ask again unless the person asks it to.
A workspace Session, or one that names no audience, isn’t offered the tool, since it may write shared stores through ordinary grants.
4. The person approves the exact bytes
List the Session’s approvals and show the person what would land. While it’s pending,context_summary.operations holds the exact operations:
acted_as set to them:
403, and the approval stays pending. For a group Session created by a key acting as itself, the boundary approval rules decide who may answer: an active person in the audience who holds approve. A StandingApproval or always_allow never covers a contribution. The person can also answer in the Console.
On approval, Checkfu lands the operations once, as a MemoryProposal authored by the approving person under their current write grant. The approval then drops its copy of the bytes (context_summary.operations becomes null) and names the proposal in memory_proposal_id. Approving again, or replaying the request, answers the same proposal. If the person has lost write, or a document changed under an expected_sha256, nothing lands: the response is refused and the approval is spent with no proposal. A transient failure keeps the approval reserved, and approving again finishes it.
5. The team reviews it
The contribution is now an ordinary proposal, so the store’s own review applies. A curator promotes or rejects it, in the Console or with their own credential:What this leaves out
- A direct write. Every contribution becomes a proposal, even on a store with
canonical_writes: "direct". - A Console card that shows a contribution’s documents. The Console marks it as a boundary approval; read the operations from the API.
- Unanswered approvals. One that expires keeps its bytes in storage until the Session is deleted.