Libra CodeHub

CedarCopilot/cedar-mail

Branch: staging

fix(playbook): forward metadata on guarded resource patch/append writes

merged#2464CedarCopilot

CedarCopilot wants to merge 0 commits into staging from fix/guarded-write-patch-metadata

Live on prod, no production signal yetTimeline and evidence
  1. Opened
    Aug 12, 2026, 8:13 PM
  2. Merged
    Aug 13, 2026, 11:07 AM
  3. Live on prod
    Aug 13, 2026, 11:07 AM
  4. Observed 1 hour
    Aug 13, 2026, 11:07 AM
  5. Pipelines steady after this deploy
    Aug 13, 2026, 11:07 AM
  6. Unobserved

    Live on prod, no production signal yet

    Aug 13, 2026, 12:08 PM

Behaviors Libra is checking

Guarded patch writes forward caller-supplied metadata while preserving unrelated metadata already stored on the document, allowing injected subagent agent IDs to survive verification.Inconclusivelow confidence

OTEL fallback found no prod spans matching writeResourceGuarded(mode=patch) since deploy.

prod, checked Aug 13, 2026, 12:08 PM
Guarded append writes forward caller-supplied metadata while preserving unrelated metadata already stored on the document.Not checked
prod, checked Aug 13, 2026, 12:06 PM

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.

Problem

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.

Fix

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.

Tests

  • Added two regression tests to guarded-write.test.ts: assert writeDocument is called with the forwarded metadata on both patch and append.
  • Full guarded-write.test.ts suite passes (26/26); @zero/server typecheck clean for the changed files.

Follow-ups (out of scope for this PR)

  • Deploy the executable cedar-cli subagent run --trigger cron --name <agent> --execute path to staging/prod so on-demand subagent runs don't require a local server.
  • Consider a --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

Greptile Summary

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.

  • Adds params.metadata to guarded patch and append calls.
  • Adds tests asserting metadata reaches writeDocument in both modes.

Confidence Score: 4/5

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

Important Files Changed

FilenameOverview
apps/server/src/services/playbook/guarded-write.tsCorrectly 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.tsCovers argument forwarding for patch and append, but does not exercise preservation of pre-existing metadata when the supplied object is partial.
Prompt To Fix All With AI
### 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
Show production surfaces and changed-file mapping

Production surfaces

Libra has not measured any production surfaces for this change yet.

Changed files → surfaces

  • apps/server/src/services/playbook/__tests__/guarded-write.test.tsno production surface mapped
  • apps/server/src/services/playbook/guarded-write.tsno production surface mapped