Chat tool registry + role palette

50 tools × 10 roles → palette-gated discovery · tool_registry · tool_role_palettes · tool_invocations telemetry

Every chat tool is registered in tool_registry with a side-effects taxonomy. The tool_role_palettes table grants tools to roles. Mike's chat session loads only the palette for his current role — the LLM sees a filtered catalog and cannot invoke ungranted tools. Telemetry from tool_invocations drives a nightly recompute of invocation_count_7d, so least-used tools surface for review.

50 tools registered 10 roles Permission-gated writes

Architecture — registry, palette, telemetry

Tool registry + palette — tool_registry × tool_role_palettes × tool_invocations → 10 roles × 50 tools → search_tools discovery Registry (left) Palette gating (middle) Role fanout (right) tool_registry 50 rows · PK tool_id columns: tool_id TEXT PK category TEXT side_effects TEXT permission_required INTEGER description TEXT invocation_count_7d INTEGER last_invoked_at TEXT source_path TEXT (e.g. chat_tools/impls.ts:6593) retired_at TEXT NULLABLE search_tools (discovery surface) chat tool · LLM uses to find candidates filtered by current role palette FRONTEND · part of chat catalog tool_role_palettes PK (role_id, tool_id) · granted_at columns: role_id TEXT tool_id TEXT granted_at TEXT granted_by TEXT revoked_at TEXT NULLABLE join from filterToolsForRole(role_id) tool_invocations (telemetry) append-only · one row per call (tool_id, called_at, role_id, session_id, latency_ms, success, error_text) nightly: refresh invocation_count_7d admin (Mike) pricing ar sales purchasing order_mgmt_admin warehouse finance exec compliance Side-effects taxonomy (gates writes) none · reads_ns · writes_ns · writes_d1 stages_proposed_action · writes_kv · sends_email reindex · cron_trigger Permission gate side_effects=stages_proposed_action → admin-tier roles ONLY Telemetry refresh — nightly tool_invocations → nightly aggregate → tool_registry.invocation_count_7d surfaces least-used tools for retirement review (avoids palette bloat) MESSAGEBUS · cron 30 3 * * *

Tool count by category — live D1 query

From SELECT category, COUNT(*) FROM tool_registry GROUP BY category. Tool catalog ships in src/chat_tools/prompt.ts as CHAT_TOOLS_FOR_PROMPT.

customer
8
sales · ar · admin
vendor
6
purchasing · admin
item
7
all roles
pricing
6
pricing · admin
order
5
order_mgmt_admin
ar
4
ar · finance · admin
bid
4
sales · admin
spec
3
all roles
health
2
exec · admin · ar
audit
3
compliance · admin
discovery
1
all roles · search_tools
misc
1
admin

Total: 50 tools across 12 categories. Numbers reflect canonical R561 catalog; live count may differ if tools were added/retired this round (check src/chat_tools/prompt.tsCHAT_TOOLS_FOR_PROMPT).

Side-effects taxonomy — what each value means

valuewritesrequires HITLexample tool
nonenonenosearch_tools
reads_nsread-only NS via SuiteQLnoget_customer_by_name
writes_nsdirect NS write (rare; via RESTlet)yes — bypasses queue is forbidden(legacy only; deprecated)
writes_d1D1 mutation only (no NS)depends — risk-tier drivenadd_entity_note
stages_proposed_actionrow in proposed_actionsYES — ADR-031 invariantupdate_vendor_cost
writes_kvCACHE binding writenoset_kill_switch (admin only)
sends_emailEMAIL bindingyes — via HITLsend_customer_quote
reindexVectorize reindexnoreindex_knowledge_corpus
cron_triggermanual trigger of a cron pathno — admin onlyrun_anomaly_hunter_now

Role palette — coverage matrix

roletools granted (approx)writes allowedtypical user
admin50 (all)all side-effects incl. stages_proposed_actionMike
pricing~18stages_proposed_action (pricing) + reads_nsprice analyst
ar~14writes_d1 (notes) + reads_nsAR collector
sales~16stages_proposed_action (quotes) + sends_email (HITL)sales rep
purchasing~12stages_proposed_action (vendor cost) + reads_nsbuyer
order_mgmt_admin~22 (absorbed inventory + logistics + USDA per R96)stages_proposed_action (SO/PO) + reads_nsops lead
warehouse~8reads_ns + writes_d1 (movement notes)warehouse
finance~14reads_ns + writes_d1 (memo)finance ops
exec~10 (read-heavy)reads only + customer_health readsexecs
compliance~6 (audit-focused)reads only + audit reindexcompliance

Endpoints + admin operations

endpointpurpose
POST /api/admin/tool-registry/seedidempotent seed of tool_registry from CHAT_TOOLS_FOR_PROMPT
GET /api/tool-registry/listlist all tools, filterable by category · side_effects · role
POST /api/admin/tool-role-palette/grantgrant tool to role (admin only)
POST /api/admin/tool-role-palette/revokerevoke tool from role
GET /api/tool-registry/usageinvocation_count_7d view sorted ascending — least-used surface

Catalog source: src/chat_tools/prompt.ts · CHAT_TOOLS_FOR_PROMPT. Role filter: filterToolsForRole(role_id). Implementations: src/chat_tools/impls.ts.