Skip to main content
A person’s private Session can read a team’s shared Memory store, but it can’t write to it: a store the Session doesn’t own mounts only 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_KEY that can administer grants (root or admin).
  • The person’s Principal (prin_…) in CHECKFU_PRINCIPAL_ID, with invoke, steer and act_as on 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.
Plain HTTP against the Checkfu API needs no private package. The Checkfu CLI and TypeScript SDK are optional private-alpha artifacts; the HTTP requests work without them. Part of this flow is behind a rollout fence; a deployment that has not enabled it refuses the request rather than running it. Confirm capability status before making availability part of your application’s contract.

1. Share a team store

Create a Workspace store that reviews changes, and grant it. The person needs read 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.
A store the Session owns is never a destination: the Session writes its own store through its mount.

2. Mount it in the person’s private Session

Create a personal Session acting as the person, with the team store mounted read-only:
Asking for read_write on the team store is refused, because the person’s Session is narrower than the team.

3. The Session asks to contribute

A personal 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:
Tell the Agent when to use it, for example in its system prompt: “When you learn something the whole support team should know, contribute it to the playbook store.” A 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:
Only the person the Session acts as can approve. Record their decision with acted_as set to them:
A Workspace administrator’s key acting as itself, another person, or a service is refused with 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:
Once promoted, the document is the team’s, under the team store’s permissions and retention. Nothing ties it to the Session: deleting the person’s Session later leaves the team’s copy, and the Session’s transcript, other Memory, Files and checkpoint never left it.

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.