Repository navigation
feat(memories): hold the broker's gate-refused writes for review (g2.5) - #1985
Merged
Merged
Conversation
Contributor
Claude Code Review ✅ No issues found. Reviewed by |
The broker's write gate (caura-daemon, g2.3 and g2.4) refuses an agent's write to a memory file, such as CLAUDE.md, when the fleet policy denies it or requires approval. The broker can now send the refused write here to be held for a person's review, and the review queue shows where it came from. - POST /memories/bulk accepts `status: "quarantined"` on an item from the broker's install credential, and from no one else: anyone else's is an item error, as any status outside the vocabulary is. - The item's `metadata.write_gate`, the gate's account of the write (`tool`, `paths`, `action`, `rule_ids`), is kept in `_system.hold` with the reason `write_gate`. GET /memories/held shows it as `system_metadata.hold`, beside the session's `rules_receipt` (g2.8). - `write_gate` is a platform-only key: anyone else's is stripped, so a write can't make up its own provenance. A malformed account loses its malformed parts, not the hold. - Where the organization's trust level holds the whole batch (g2.8), the gate's account names the hold of the write it refused. - create_memories_bulk's `trusted_receipts` becomes `from_broker`, as it now covers both. A cloud without this refuses the status, so a held write never lands live on one. Signed-off-by: eldad-caura <eldad@caura.ai> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
eldad-caura-ai
force-pushed
the
feat/gate-held-writes
branch
from
October 7, 2026 12:55
7d1e268 to
1bff1c1
Compare
Member
Author
|
@erni-a plear rprpove |
erni-a
previously approved these changes
Oct 7, 2026
Brings in #1984. The one textual conflict is the write_hold import in memory_service.py; both sides are kept. Signed-off-by: eldad-caura <eldad@caura.ai> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
#1984 decides a bulk batch again when storage refuses it because the settings changed, and it held every item with the batch's new answer. A broker batch can carry captures beside a write its gate refused (g2.5). When the trust level was raised by another process, the captures' insert was refused, the batch was decided again, and the refused write lost the gate's account: it came back held as below_trust. decide_again now applies the hold as the first decision does: the gate's hold for a write it refused, the batch's for the rest. Signed-off-by: eldad-caura <eldad@caura.ai> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Member
Author
|
Resolved the conflict with #1984 by merging main into the branch (6f30fde). There was no force-push, so the original commit is unchanged. There is also one fix, 3ec0ea4.
@claude please review the two new commits, the merge resolution and the |
Contributor
Claude Code Review ✅ No issues found. Reviewed by |
Member
Author
|
@erni-a plasr arprpove |
erni-a
approved these changes
Oct 7, 2026
Merged
eldad-caura-ai
pushed a commit
that referenced
this pull request
Oct 7, 2026
🤖 I have created a release *beep* *boop* --- <details><summary>backend: 3.27.0</summary> ## [3.27.0](backend-v3.26.4...backend-v3.27.0) (2026-10-07) ### Features * **memories:** hold the broker's gate-refused writes for review (g2.5) ([#1985](#1985)) ([2892bc9](2892bc9)) ### Bug Fixes * **ci:** check every service lock and build core-worker's image (M-01) ([#1983](#1983)) ([54040d8](54040d8)) * **memories:** decide a write again when the hold changed after it was decided ([#1984](#1984)) ([7ce0212](7ce0212)) </details> --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). Signed-off-by: release-please[bot] <release-please[bot]@users.noreply.github.com> Co-authored-by: caura-deploy-bot[bot] <265395343+caura-deploy-bot[bot]@users.noreply.github.com>
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.
Summary
This is the cloud side of governance row g2.5. caura-daemon's write gate refuses an agent's write to a memory file, such as CLAUDE.md, when the fleet policy denies it or requires approval (g2.3, g2.4). With this PR, the broker can send that refused write here to be held for a person's review (decisions G7 and G8).
GET /memories/heldthen shows each held write's provenance:What changed
POST /memories/bulkaccepts"status": "quarantined"on an item from the broker's install credential, and from no one else. From anyone else it's an item error, as any status outside the vocabulary is.metadata.write_gate:tool,paths,actionandrule_ids._system.hold, with the reasonwrite_gate, soGET /memories/heldshows it assystem_metadata.hold, beside the session'srules_receipt(g2.8).services/write_gate_hold.py. A malformed part is dropped with a warning; the hold isn't, because the status, not the account, is what holds the write.write_gateis a platform-only key. Anyone else's is stripped, so a write can't make up its own provenance.below_trust.create_memories_bulk'strusted_receiptsbecomesfrom_broker, since it now covers both.docs/api-reference.md(the bulk and held-list rows).Release, reject, rollback and the release replay (g2.7–g2.9) are unchanged: a gate-held write is stored exactly as a trust-held one, only with another reason.
Safety on an older cloud: a cloud without this refuses the status, so a held write is never stored live there.
Verification
tests/test_write_gate_holds.pyhas 19, through the routes and storage plus the account's shape:denyis held too.mainin this local setup, so they predate this change.write_gatenot a platform key;denynot held;Pairs with
The broker side is caura-ai/caura-daemon#267. Merge and deploy this first: until then, the broker's held writes are refused by the cloud, and never stored live.
🤖 Generated with Claude Code