Libra CodeHub

CedarCopilot/cedar-mail

Branch: staging

fix(playbook): stop MISSING_SYSTEM_SUBAGENTS from freezing valid playbooks

merged#2574CedarCopilot

CedarCopilot wants to merge 2 commits into staging from fix/playbook-system-subagent-org-refs

Live on prod, no production signal yetTimeline and evidence
  1. Opened
    Aug 24, 2026, 8:46 PM
  2. Aug 24, 2026, 10:15 PM
  3. Merged
    Aug 25, 2026, 7:25 AM
  4. Live on prod
    Aug 25, 2026, 7:25 AM
  5. Observed 37 hours
    Aug 25, 2026, 7:25 AM
  6. Pipelines steady after this deploy
    Aug 25, 2026, 7:25 AM
  7. Unobserved

    Live on prod, no production signal yet

    Aug 26, 2026, 8:00 PM

Behaviors Libra is checking

User playbooks may satisfy the required crm-updater and next-steps references with shared organisation-scoped subagent documents, so valid playbook edits are no longer reverted as missing system subagents.Inconclusivehigh confidence

Since 2026-08-25T14:25:41Z, production CloudWatch returned 0 lines for concrete playbook.compile, compilePlaybookForDoc, successful compilation, aborted save, writeCompiledPlaybook, or MISSING_SYSTEM_SUBAGENTS tokens. OTEL likewise returned 0 spans whose attributes/status.

prod, checked Aug 26, 2026, 7:55 PM
Playbooks with seeded system subagents but no global any-trigger produce a non-blocking MISSING_SYSTEM_SUBAGENTS warning instead of an error, allowing edits to secondary playbooks to persist.Inconclusivehigh confidence

Since 2026-08-25T14:25:41Z, there is no positive runtime evidence that compilePlaybookForDoc/checkSystemSubagents processed a playbook with global.anyBlock=null. OTEL returned 0 playbook/MISSING_SYSTEM_SUBAGENTS-tied spans; CloudWatch returned 0 exact MISSING_SYSTEM_SUBAGENTS.

prod, checked Aug 26, 2026, 8:00 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.

The bug

checkSystemSubagents required the global <trigger type="any"> to reference the user-scoped crm-updater and next-steps doc ids specifically. Because writeDocumentGuarded reverts on any compile error, a playbook that fails this check is frozen: every subsequent write, to any unrelated part of it, compiles, hits this error, and gets rolled back.

Two legitimate configurations fail it today:

1. An org-linked user playbook referencing the shared org copy of a system subagent. userSubagentPaths is built from user/playbooks/{aopId}/subagents/%.md only (persist-playbook.ts:100), so a ref to organisation/playbooks/…/subagents/crm-updater.md looks like a ref to nothing. The markdown-era checker at verify-playbook.ts:305 never had this problem, because it matches on the referenced doc's path. The XML checker now does the same, with org subagent paths threaded through as orgSubagentPaths.

2. A secondary AOP with no any-block at all. Fundraising, Recruiting, and Non-deal AOPs commonly have crm-updater and next-steps docs seeded but never wired to a trigger. Editing such a playbook does not make that worse, so blocking every write to it is the wrong response. That case is now a warning that names the real condition (seeded but never run) instead of an error.

The hard error is unchanged where it matters: an any-block that exists but has dropped one of the two agents still fails.

Also

Removes the copy of this check inlined in compile-playbook.ts. It duplicated the extracted checkSystemSubagents that runCompiledChecks already runs from the same function , which is why the failure surfaced with its message printed twice:

playbook verification failed ... (reverted): Global <trigger type="any"> must reference both
crm-updater and next-steps subagents; Global <trigger type="any"> must reference both
crm-updater and next-steps subagents

Verified against production data

Compiled all 10 user playbooks across the 5 affected accounts with the new checker, reading real documents:

beforeafter
· DealsFAIL (org ref)pass
· DealsFAIL (org ref)pass
· Fundraising, Non-deal, RecruitingFAIL (no any-block)pass
· Event PartnershipsFAIL (no any-block)pass
· FundraisingFAIL (no any-block)pass
the 4 remaining Deals playbookspasspass

No data edits to any account. This matters for Karim in particular: the "obvious" data fix (repoint his any-block at his own user copy) would have been harmful , his user copy is missing the "Read-only pilot , HubSpot writes are OFF" section that the org copy carries, so the swap would have let his crm-updater start writing to HubSpot on a read-only pilot.

  • pnpm --filter @zero/server exec vitest run src/services/playbook , 625 passed / 29 files, including 3 new cases: org ref accepted, neither-ref still errors, no-any-block warns.
  • pnpm --filter @zero/server run types , clean.
  • pnpm deps:check , no violations.

🤖 Generated with Claude Code

Greptile Summary

The PR changes compiled playbook validation so org-scoped system-subagent references are recognized, playbooks without a global any-trigger receive a warning rather than an error, and the duplicate inline validation is removed.

  • Threads organization subagent paths through persistence and verification compile contexts.
  • Matches required system subagents by referenced document path.
  • Adds coverage for organization references, missing references, and absent any-trigger behavior.

Confidence Score: 4/5

The PR needs the organization subagent map scoped to the linked org AOP before merging, otherwise a reference to a different AOP's same-named agent can satisfy the required-agent guard.

The new path-based validation receives subagents from every org AOP and compares only filename suffixes, so i

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__/playbook-compiled-checks.test.tsno production surface mapped
  • apps/server/src/services/playbook/compile-playbook.tsno production surface mapped
  • apps/server/src/services/playbook/persist-playbook.tsno production surface mapped
  • apps/server/src/services/playbook/playbook-compiled-checks.tsno production surface mapped
  • apps/server/src/services/playbook/verify-playbook.tsno production surface mapped