CedarCopilot wants to merge 0 commits into staging from fix/guarded-write-patch-metadata
Live on prod, no production signal yet
OTEL fallback found no prod spans matching writeResourceGuarded(mode=patch) since deploy.
Libra has verdicts on 0 of 2 tracked behaviors on prod; 2 are still being checked. Libra checks hourly for 3 days after each deploy.
writeResourceGuarded (the guard every resource/subagent-doc write routes through) only forwarded metadata on its create/upsert branch. The patch and append branches silently dropped it.
Because editing an existing resource or subagent doc always takes the patch path, this had a concrete failure mode: prepareSubagentWrite injects a subagent agent_id into both the frontmatter (content) and documents.metadata, but on an edit only the content change persisted , the metadata agent_id was dropped. The saved doc then failed verifySubagentDoc (agent_id_in_metadata: documents.metadata.agent_id is missing , the subagent cannot be resolved by ref), so authorSubagentDoc reverted the entire write. The subagent was left unresolvable-by-<ref> and the author/edit path could never repair it.
This was hit in practice healing a customer's pipeline-review subagent that had no agent_id: subagent author --execute wrote the frontmatter id but reverted on the missing metadata id, every time.
Forward params.metadata in the patch and append branches too, mirroring the create/upsert branch. writeDocument treats metadata: undefined as "keep existing", so plain edits that pass no metadata are unaffected , only callers that actually pass metadata (the author / subagent-move flows) now have it applied.
guarded-write.test.ts: assert writeDocument is called with the forwarded metadata on both patch and append.guarded-write.test.ts suite passes (26/26); @zero/server typecheck clean for the changed files.cedar-cli subagent run --trigger cron --name <agent> --execute path to staging/prod so on-demand subagent runs don't require a local server.--skip-reconcile option for the pipeline-review preview so a dry-run returns in seconds instead of walking the full pipeline against live Salesforce.š¤ Generated with Claude Code
This PR forwards metadata through guarded resource patch and append writes and adds regression coverage for both branches. The forwarding repairs subagent metadata persistence, but partial metadata supplied through the general document tool can now replace unrelated existing metadata.
params.metadata to guarded patch and append calls.writeDocument in both modes.The PR should not merge until guarded patch and append writes preserve existing metadata when callers provide only selected fields.
The new forwarding reaches a storage API that replaces metadata wholesale, allowing ordinary tool-driven resource edits with partial metadata to silently erase unrelated persisted fields.
Files Needing Attention: apps/server/src/services/playbook/guarded-write.ts
| Filename | Overview |
|---|---|
| apps/server/src/services/playbook/guarded-write.ts | Correctly forwards metadata for the reported repair path, but forwards partial objects into replacement-based storage semantics without preserving unrelated existing fields. |
| apps/server/src/services/playbook/tests/guarded-write.test.ts | Covers argument forwarding for patch and append, but does not exercise preservation of pre-existing metadata when the supplied object is partial. |
### Issue 1
apps/server/src/services/playbook/guarded-write.ts:494
**Partial metadata replaces existing fields**
When the document-writing tool patches or appends a resource with only selected metadata fields, forwarding that object to `writeDocument` replaces the complete stored metadata instead of merging it, silently removing unrelated fields such as subagent configuration.
---
For each issue above
Libra has not measured any production surfaces for this change yet.