CedarCopilot wants to merge 2 commits into staging from feat/system-subagents-registry
Live on prod, no production signal yet
Libra has verdicts on 0 of 4 tracked behaviors on prod; 4 are still being checked. Libra checks hourly for 3 days after each deploy.
Phase 1 of the metadata-field-conventions unification (apps/server/docs/design/subagent-metadata-field-conventions.md , "The system fix, finalized").
Cedar ships nine system agents, but "is this a system agent" was decided in two places that could disagree:
SYSTEM_SUBAGENT_FILENAMES named only five (crm-updater, strategist, next-steps, meeting-prep, daily-agenda).agent-read.ts compensated by OR-ing it with a document's own system: true frontmatter claim to catch the other four (drafter, pipeline-review, coach-meeting, coach-weekly).aop-agents.ts's own SubagentDocAgent.isSystemDefault used only the first signal , no compensation , so it under-reported those four.This PR replaces the Set with one SYSTEM_SUBAGENTS registry naming all nine, each tagged with its dispatch kind (custom / scheduled / generic). Being in the registry is now what "system agent" means, not a document's claim about itself.
pipeline-review/coach-meeting/coach-weekly , the registry's generic kind reserves a toolAllowlist field, left undefined on purpose. Curating real allowlists needs production tool-call data (the same diligence STRATEGIST_TOOLS got), which is its own follow-up (Phase 3).runSubagentTool.ts's existing fallback (readSubagentFull + runAgent) already serves every non-custom agent today, registered or not, and is unchanged here. Nothing about dispatch behavior changes in this PR.runSubagentTool.ts's synthetic AgentDescriptor.isSystemDefault (a separate computation, hardcoded false in the generic-fallback branch) , this one feeds markExecutionAsFailedTool's failure-alert suppression, not UI classification. Conflating it with the registry would silently suppress production monitoring alerts for pipeline-review/coach-meeting/coach-weekly. Verified and deliberately left untouched.system-subagents-registry.test.ts , asserts the full nine-agent shape and dispatch classification (all passing).agent-read.ts's isSystemDefault change verified as behavior-preserving: its only consumers (AgentActionMenu.tsx's delete warning, agent-groups.ts's System section) already saw all nine agents correctly via the old OR , this just removes the second, disagreeable signal.aop-agents.ts's isSystemDefault change verified as safe: its only consumers (aop.ts/aop-agents.ts tRPC routes, Files-tab agent listing, backfill scripts) are UI-read-only, no execution-critical path.pnpm --filter @zero/server run types , clean.pnpm deps:check , no violations (1770 modules, 9251 dependencies cruised).oxlint --deny-warnings on all touched files , clean.agent-workspace suite (330 tests) + the three router tests + strategist-seed/reference-resolver , all green.🤖 Generated with Claude Code
https://claude.ai/code/session_01E3AhwqADAFeqe9wEhz6Mk7
The PR centralizes system-subagent identity and dispatch metadata in SYSTEM_SUBAGENTS, then updates both agent-listing paths and scheduled-trigger inference to use it.
The PR appears safe to merge after addressing two non-blocking correctness and test-maintainability concerns.
The registry matches the current canonical agents and dispatch paths, but prototype-chain membership can misclassify a specially named user agent, and the new registr
Libra has not measured any production surfaces for this change yet.