Libra CodeHub

CedarCopilot/cedar-mail

Branch: staging

fix(agents): the crm-updater's fields panel lists the fields it actually writes

merged#2875CedarCopilot

CedarCopilot wants to merge 2 commits into staging from fix/crm-updater-fields-panel

Live on prod, 0 of 1 surfaces working, 2 days leftTimeline and evidence
  1. Opened
    Sep 22, 2026, 1:57 AM
  2. Sep 22, 2026, 2:12 AM
  3. Live on staging
    Sep 22, 2026, 6:50 AM
  4. Merged
    Sep 22, 2026, 6:50 AM
  5. Live on prod
    Sep 22, 2026, 6:50 AM
  6. Observed 2 hours, 1 surface, 0 requests
    Sep 22, 2026, 6:50 AM
  7. Watching

    Live on prod, 0 of 1 surfaces working, 2 days left

    Sep 22, 2026, 6:50 AM

Behaviors Libra is checking

CRM-updater detection uses the seeded agent document slug instead of the mutable display name, so a renamed CRM updater remains special while an unrelated agent named `crm-updater` does not.Inconclusivelow confidence

Unable to verify the intended behavior: no matching staging telemetry was found for AgentView, CRM administration, agent.get, or agent.list since the deployment. Positive runtime evidence is required, so the result is inconclusive.

staging, checked Sep 22, 2026, 7:09 AM
Opening an agent without an explicit tab still lands on Files/output, including for the CRM updater despite CRM Fields being the first tab.Inconclusivelow confidence

Verification cited only 10 matching post-deploy events, below the 20-event floor for calling a change verified. Nothing is failing; there is not yet enough traffic to confirm it.

staging, checked Sep 22, 2026, 7:09 AM
When an administrator views a teammate's agent settings, the CRM field definitions are read from and written to that teammate's AOP rather than the administrator's own AOP.Not checked
prod
CRM-specific tabs, field panels, and teammate-agent pickers continue to identify the CRM updater by its document filename even after its display name is renamed.Not checked
prod
Opening an agent without an explicit tab still lands on Files/output, including for the CRM updater whose CRM Fields tab is now first.Not checked
prod
The CRM updater's CRM Fields tab appears first in its tab strip instead of as the final tab.Not checked
prod

Libra found 1 production surface on prod but could not judge any of them yet. Libra checks hourly for 3 days after each deploy.

Summary

The CRM updater's "CRM fields" row listed the one set it never writes. Ownership is a carve-out (resolveFieldLiveness: crm-updater excludes owned fields), so filtering its panel on ownerAgentId === agentId produced an empty list beside forty fields it rewrites every run. The panel is now written against a FieldsRelationship (owner vs. unowned writer): for crm-updater it lists every unowned, non-background field whose stamped owner is live and enabled, "assign" clears an owner, and the CRM Fields tab sits first on its strip. isCrmAgent keys on the document slug the way the server does, through one shared agentSlugFromDocumentPath.

Found along the way: CustomFieldDefinitionSchema did not name background, and z.object() strips unknown keys, so every edit made from that row was silently demoting taxonomy fields to ordinary ones. Fixed with a boundary test.

Also on the branch

  • File rows rename in the frame you press Enter in (useRenameNode), on the same optimistic cancel → snapshot → patch → mutate → settle primitives the conversation Files tab uses, now lifted into optimisticQueries.ts so there is one copy of the cancel step.
  • Home: "Open files" replaces "See all Cedar actions" as the fourth pill; the get-started checklist is paused behind GET_STARTED_CHECKLIST_ENABLED, gated on the mount so it reads and writes no settings.
  • CLI: onboarding reset stops at the first flag; positionals() now lives in cli/lib.ts.
  • Three one-off scripts for the product-gaps agents (Warp), already run; committed as the record, validating everything before the first write.

Deliberately not included: the agent-library workspace work in progress on refactor/document-store-retention. This branch was cut from origin/staging with only the in-scope commits.

Review

  • /review: 1 blocking (a module-level guard TypeScript could not narrow into main, fixed), 3 should-fix (background fields, duplicated CRM predicate, missed-bullet insertion), 5 nits. All fixed.
  • /thermo-review: 0 blocking, 8 should-fix (duplicated CLI helper, third copy of the slug derivation, name-vs-filename predicate, stale comments and dead props, flag-at-nine-sites in the callout, a test pinning the unfixed path, duplicated optimistic pipeline, conflicting files: lists across scripts). All fixed. One nit declined: FileBrowser's own invalidate() for move/delete still invalidates only the tree, a pre-existing asymmetry for a follow-up.
  • Greptile CLI: 2/5 → 3/5 → 4/5 over 3 iterations. Greptile's PR-side pass then raised one more P1 (callLevel and metadataFields also stripped at the write boundary), fixed in fa9f614d5; the boundary test now round-trips a Required<CustomFieldDefinition> fixture. Fixed: background stripped at the write boundary, stale/disabled owners counted as carve-outs, cursor-pointer on clickable rows, scripts validating after writes. Declined: making the one-off scripts transactional/resumable (already executed, dry-run by default, no service-layer transaction spans writeDocument + moveDocument).

Test plan

Run locally on the pushed commit, matching .github/workflows/ci.yml:

  • autofix: brand check ✅, oxlint@1.78.0 --deny-warnings ✅, deps:check ✅ (1947 modules)
  • typecheck: paraglide:compile + react-router typegen + turbo run types
  • Mail app tests (Jest): 537/539 suites ✅ , the 2 red suites are chat-store/chatHistoryList + chatHistoryPopover, a pre-existing local-timezone flake (buckets by local calendar day; fails only in US-Pacific, passes in UTC and on staging CI). Untouched by this branch.
  • test:tz
  • Server tests (Vitest): 1,123 files / 13,931 tests ✅, plus the new custom-field-definition-schema.test.ts
  • Deploy scope: plan-surface-scope.test.sh 16/16 ✅

Customer: Kendall Keahey, Warp

🤖 Generated with Claude Code

Show production surfaces and changed-file mapping

Production surfaces

SurfaceRequestsErrorsp95UsersVerdict
model_chunk Next Steps and Tasks Manager0 → 00 → 0 (0%)not measured0No traffic
No requests recorded since this deploy.
model_step Next Steps and Tasks Manager0 → 00 → 0 (0%)not measured0No traffic
No requests recorded since this deploy.
invoke_agent Next Steps and Tasks Manager0 → 00 → 0 (0%)not measured0No traffic
No requests recorded since this deploy.
model_inference Next Steps and Tasks Manager0 → 00 → 0 (0%)not measured0No traffic
No requests recorded since this deploy.
/onboarding0 → 00 → 0 (0%)not measured0No traffic
No requests recorded since this deploy.
/onboardingno baseline → 0no baseline → 0 (0%)not measurednot countedUnavailable
ClickHouse reads are unavailable, so Libra could not measure this surface.

Changed files → surfaces

  • apps/mail/modules/onboarding/checklist/steps.tsmodel_chunk Next Steps and Tasks Managermodel_step Next Steps and Tasks Managerinvoke_agent Next Steps and Tasks Managermodel_inference Next Steps and Tasks Manager
  • apps/mail/app/(full-width)/onboarding/page.tsxno production surface mapped
  • apps/mail/modules/agents/__tests__/agent-tabs.test.tsno production surface mapped
  • apps/mail/modules/agents/__tests__/crm-agent.test.tsno production surface mapped
  • apps/mail/modules/agents/components/AgentSettingsSection.tsxno production surface mapped
  • apps/mail/modules/agents/components/AgentView.tsxno production surface mapped
  • apps/mail/modules/agents/crm-agent.tsno production surface mapped
  • apps/mail/modules/agents/types.tsno production surface mapped
  • apps/mail/modules/agents/utils/agent-paths.tsno production surface mapped
  • apps/mail/modules/aop/__tests__/agentFieldsCallout.test.tsxno production surface mapped
  • apps/mail/modules/aop/components/AgentFieldsCallout.tsxno production surface mapped
  • apps/mail/modules/aop/components/FieldDetailsForm.tsxno production surface mapped
  • apps/mail/modules/cedar-os/__tests__/__mocks__/query-provider.tsno production surface mapped
  • apps/mail/modules/conversations/components/files/optimistic-files.tsno production surface mapped
  • apps/mail/modules/conversations/components/files/optimisticQueries.tsno production surface mapped
  • apps/mail/modules/conversations/hooks/use-meeting-prep-agent.tsno production surface mapped
  • apps/mail/modules/files/components/FileBrowser.tsxno production surface mapped
  • apps/mail/modules/files/hooks/use-rename-node.tsno production surface mapped
  • apps/mail/modules/home/__tests__/HomeWidgetRail.test.tsxno production surface mapped
  • apps/mail/modules/home/components/AgentHomeHero.tsxno production surface mapped
  • apps/mail/modules/home/components/agentHomeActions.tsno production surface mapped
  • apps/mail/modules/home/components/home-team-sections.tsno production surface mapped
  • apps/mail/modules/home/widgets/HomeWidgetRail.tsxno production surface mapped
  • apps/mail/modules/onboarding/surfaces.tsno production surface mapped
  • apps/mail/tests/modules/files/fileBrowserRename.test.tsxno production surface mapped
  • apps/mail/tests/modules/home/agentHomeHero.test.tsxno production surface mapped
  • apps/mail/tests/modules/home/onboardingChecklistWidget.test.tsxno production surface mapped
  • apps/server/src/cli/lib.tsno production surface mapped
  • apps/server/src/onboarding-admin/cli.tsno production surface mapped
  • apps/server/src/scripts/product-gap-close-rate.tsno production surface mapped
  • apps/server/src/scripts/repair-product-gap-paths.tsno production surface mapped
  • apps/server/src/scripts/thiago-files.tsno production surface mapped
  • apps/server/src/services/aop/__tests__/custom-field-definition-schema.test.tsno production surface mapped
  • apps/server/src/services/aop/types.tsno production surface mapped