Skip to content

refactor(ai): skills-only AI surface — real Actions instead of 10 fictional tools, retire the two agents - #512

Merged
os-zhuang merged 2 commits into
mainfrom
claude/agent-metadata-positioning-th5hhm
Jul 28, 2026
Merged

refactor(ai): skills-only AI surface — real Actions instead of 10 fictional tools, retire the two agents#512
os-zhuang merged 2 commits into
mainfrom
claude/agent-metadata-positioning-th5hhm

Conversation

@os-zhuang

Copy link
Copy Markdown
Contributor

HotCRM is the corpus that motivated objectstack-ai/objectstack#3820: 6 skills declaring 16 tool references, 10 of which named tools that exist nowhere. The copilot's instructions claimed abilities it did not have — the runtime silently drops an unresolved tool, so the model improvised or failed when asked to use one. Every instance passed objectstack validate and lint cleanly. This is the dogfood fix, and the first app to run on ADR-0109's authoring model.

The fix is mostly deletion

The fictional references were a category error: "analyze the pipeline", "generate email copy", "score this lead" are reasoning, not tools. What genuinely needed a tool was the handful of steps that change state — and those already exist as HotCRM Actions, reachable through the action_<name> tools the runtime materialises from them. That is ADR-0109's default path: no tool records to author.

Skill Was Now
case_triage triage_case priority rubric in instructions; action_escalate_case / action_close_case do the work
email_drafting generate_email_copy, optimize_subject_line, personalize_content, generate_email the model writes the copy; action_send_email sends it
lead_qualification analyze_lead, suggest_next_action BANT reasoning over get_record; action_convert_lead / action_schedule_followup act
revenue_forecasting analyze_pipeline, identify_at_risk, forecast_revenue aggregate_data / query_records / visualize_data + the forecasting method spelled out
live_data, customer_360 already resolved correctly untouched but for prose

Because every state change now goes through the same Action the UI button uses, permissions and audit are identical whether a human clicks or the assistant calls.

case_triage also handed off to response_drafting — a skill that never existed (the original audit's "hand-off to a nonexistent skill", §7 non-goal because it lives in free-form prompt text). Repointed at the real email_drafting while rewriting the instructions.

The two agents are deleted

sales_copilot and service_copilot were unreachable metadata: ADR-0063 §2 closed *.agent.ts to third parties, and objectstack-ai/cloud#904 made the runtime refuse non-platform agent records. Carrying them is exactly the ADR-0078 lie the whole issue is about. The capability lives in the skills, which attach to the platform assistant by surface affinity — so this removes a fiction without removing a feature.

Prose updated to match (src/docs/crm_admin.md "AI copilots" → "AI skills", plus two stale comments naming the copilots).

Verification

Refs objectstack-ai/objectstack#3820 · ADR-0109 · ADR-0063 · ADR-0078

🤖 Generated with Claude Code

https://claude.ai/code/session_01BHjroNkLkajskKbJaidko4


Generated by Claude Code

…tional tools, retire the two agents (objectstack#3820, ADR-0109)

HotCRM was the corpus that motivated objectstack#3820: 6 skills declaring
16 tool references, of which 10 named tools that exist nowhere. The
copilot's instructions therefore claimed abilities it did not have — the
runtime silently drops an unresolved tool, so the model improvised or
failed when asked to use one. Every instance passed `objectstack
validate` and `lint` cleanly.

The fix is mostly deletion, because the references were a category error:
"analyze the pipeline", "generate email copy", "score this lead" are
REASONING, not tools. What actually needed a tool was the handful of
steps that change state — and those already exist as HotCRM Actions,
reachable through the `action_<name>` tools the runtime materialises from
them (ADR-0109's default path: no tool records to author).

- case_triage: `triage_case` → the priority rubric moves into
  instructions; `action_escalate_case` / `action_close_case` do the work.
  Also repoints the hand-off that named `response_drafting`, a skill that
  never existed (the audit's "hand-off to a nonexistent skill"), at the
  real `email_drafting`.
- email_drafting: 4 fictional copy tools → the model writes the copy;
  `action_send_email` sends it, so recipient resolution, permissions and
  audit match the UI path.
- lead_qualification: `analyze_lead` / `suggest_next_action` → BANT
  reasoning in instructions over `get_record`; `action_convert_lead` /
  `action_schedule_followup` act, and conversion requires confirmation.
- revenue_forecasting: 3 fictional analytics tools → `aggregate_data` /
  `query_records` / `visualize_data` with the actual forecasting method
  spelled out in instructions.
- live_data, customer_360: already correct, untouched but for prose.

The two agents (`sales_copilot`, `service_copilot`) are DELETED. ADR-0063
§2 closed `*.agent.ts` to third parties and cloud#904 made the runtime
refuse non-platform agent records, so they were unreachable metadata —
carrying them is the ADR-0078 lie. The capability lives in the skills,
which attach to the platform assistant by surface affinity.

Verified with the merged reference-integrity rule
(objectstack#3885 `validate-ai-tool-references`): 22 tool references, 0
findings — was 16 references with 10 dead. typecheck, `objectstack
validate`, and the 67-test suite pass.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BHjroNkLkajskKbJaidko4
@vercel

vercel Bot commented Jul 28, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
hotcrm-docs Ready Ready Preview, Comment Jul 28, 2026 3:13pm

Request Review

…DR-0011)

Follow-up to the skills rewrite in this PR. The first pass routed state
changes through `action_escalate_case` / `action_close_case` /
`action_send_email` — but the runtime materialises `action_<name>` ONLY
for an Action that opts in (`ai.exposed` + `ai.description`) AND has a
headless path. All three are `type: 'modal'`: they collect a reason /
resolution / final copy from a person, so they are UI-only and no tool is
ever generated. Referencing them would have re-created the bug this PR
fixes, one layer down.

- `convert_lead` and `schedule_followup` are flow-typed with targets, so
  they only needed the opt-in: both now carry `ai.exposed` + an
  LLM-facing description. `convert_lead` keeps its `confirmText`, which
  the runtime reads as approval-required — an agent invocation lands in
  the HITL queue instead of converting a lead unattended, which is what
  we want for an irreversible outcome.
- `case_triage` and `email_drafting` no longer claim to act. They read,
  reason, and hand a ready-to-paste `reason` / `resolution` / draft to
  the user, pointing at the Escalate / Close / Send Email button. The
  instructions say plainly that the assistant cannot press it — a modal
  Action staying human-driven is the right shape for these, not a gap.

Re-verified with the corrected rule (objectstack#3894, which now models
AI exposure): 19 tool references, 0 findings. Both directions hold — the
two opted-in flow Actions resolve, the three modal ones would not.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BHjroNkLkajskKbJaidko4
@os-zhuang
os-zhuang marked this pull request as ready for review July 28, 2026 15:35
@os-zhuang
os-zhuang merged commit fa0370e into main Jul 28, 2026
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants