# Annotation catalog — AI module (ClientVerse Modules 0.4.0)
# Structural facts are authoritative in ../catalog.json. See ../README.md, ../../_conventions.md.
module: ai
package: modules
applies_to: [modules]
status: shipped-early-access
summary: >
  AI ships in Modules 0.4.0 and is a real, usable capability — this supersedes the 0.1–0.3
  guidance that described it as a placeholder to be documented as "coming". Two things ship: the
  CV AI Chat interface (a `CV_AI_Chat` tab and FlexiPage where a user asks a question in natural
  language and an LLM answers by calling ClientVerse named queries as tools), and the AI Actions
  framework (reusable, admin-defined AI operations invocable from flows and components).
  Both are OFF until a permission set is assigned, and engineering still tracks the chat as
  maturing — document AI as "available, early access, off by default", never as unavailable.
security_notes: >
  Two facts must accompany any customer-facing description of the chat. (1) Record access is
  enforced: tool queries run through the Core named-query framework in USER_MODE, so every row
  the model sees is scoped to the running user's CRUD, FLS and record sharing — the assistant
  cannot reach a record the user could not already open. (2) Firm data leaves the org: queries
  and their results are sent to Anthropic or OpenAI via the CV_Anthropic / CV_OpenAI named
  credentials, and prompt-injection hardening is explicitly incomplete at this stage. For a law
  firm the second point is a general-counsel decision, not a configuration step.
permission_sets:
  - {api_name: CV_AI_Schema_Access, purpose: "Visibility of the AI session objects, no component access."}
  - {api_name: CV_AI_User, purpose: "Everyday AI capability."}
  - {api_name: CV_AI_Chat_User, purpose: "The switch for CV AI Chat — nobody sees the interface without it."}
  - {api_name: CV_AI_Admin, purpose: "AI configuration: action templates, adapter limits, system prompts."}
  - {api_name: CV_AI_Actions_Permission, purpose: "Invoking AI Actions from flows and components."}
annotation_status: drafted

objects:
  - api_name: CV_AI_Session__c
    label: CV AI Session
    kind: custom_object
    data_source: Created by the chat interface at runtime
    audience: [admins, bd, attorneys]
    description: >
      One conversation between a user and the assistant. Owned by the running user, so a session
      is private to whoever held it. Records which provider and model answered, the record the
      conversation was opened against, and the token spend — which is what makes usage and cost
      reportable per user rather than only in the provider's own console.
    key_fields:
      - {api_name: CV_User__c, purpose: "The user whose session this is; conversations are owned by the running user."}
      - {api_name: CV_Provider__c, purpose: "Which LLM provider answered (Anthropic or OpenAI), selectable at runtime."}
      - {api_name: CV_Model__c, purpose: "The specific model used."}
      - {api_name: CV_Context_Record_Id__c, purpose: "The record the conversation was opened against, if any."}
      - {api_name: CV_Status__c, purpose: "Session state."}
      - {api_name: CV_Total_Tokens__c, purpose: "Total token spend for the session — the basis for usage reporting."}
      - {api_name: CV_Template_API_Name__c, purpose: "The AI Action template driving the session, where one applies."}

  - api_name: CV_AI_Session_Item__c
    label: CV AI Session Item
    kind: custom_object
    data_source: Created by the chat interface at runtime
    audience: [admins]
    description: >
      One turn within a session — a user message, a model response, or a tool call and its result.
      The sequence of items is the auditable record of what was asked, which named queries ran, and
      what came back. This is where an administrator looks to answer "what did the assistant
      actually do?", and it is the reason the chat is reviewable rather than opaque.
    key_fields:
      - {api_name: CV_Session__c, purpose: "Parent session."}
      - {api_name: CV_Sequence__c, purpose: "Order within the conversation."}
      - {api_name: CV_Role__c, purpose: "Who produced this turn — user, assistant, or tool."}
      - {api_name: CV_Item_Type__c, purpose: "Message vs tool call."}
      - {api_name: CV_Tool_Name__c, purpose: "The named query invoked, when the turn is a tool call."}
      - {api_name: CV_Tool_Call_Json__c, purpose: "The tool invocation payload — what the model asked the query for."}
      - {api_name: CV_Payload_Truncated__c, purpose: "Whether the stored payload was truncated for size."}

  - api_name: CV_AI_Action_Template__mdt
    label: CV AI Action Template
    kind: custom_metadata
    data_source: Configuration (custom metadata)
    audience: [admins]
    description: >
      A reusable AI action an admin defines once and flows or components then invoke: its
      instructions, default provider and model, the named queries it may call, the objects it
      targets, and its governance limits. Templates are the mechanism for offering AI capability
      without giving anyone an open-ended prompt box.
    key_fields:
      - {api_name: CV_Instructions__c, purpose: "The prompt/instructions for the action."}
      - {api_name: CV_Named_Query_Names__c, purpose: "Which named queries this action may call — the tool allowlist."}
      - {api_name: CV_Target_Objects__c, purpose: "Objects the action applies to."}
      - {api_name: CV_Require_Permission__c, purpose: "A permission gate on invoking the action."}
      - {api_name: CV_Max_Tokens__c, purpose: "Per-invocation token ceiling."}
      - {api_name: CV_Temperature__c, purpose: "Sampling temperature — lower is more deterministic."}
      - {api_name: CV_Output_Contract__c, purpose: "The expected response shape, so output can be validated rather than trusted."}
      - {api_name: CV_Is_Active__c, purpose: "Whether the template is available for invocation."}

  - api_name: System_Prompt_Config__mdt
    label: System Prompt Config
    kind: custom_metadata
    data_source: Configuration (custom metadata)
    audience: [admins]
    description: >
      The standing instructions the assistant operates under, applied across sessions. This is
      where the firm sets the assistant's ground rules — including the instruction to treat data
      returned from tools as untrusted, which is the current mitigation for prompt injection.
    key_fields:
      - {api_name: Instructions__c, purpose: "The system prompt text."}

  - api_name: AI_Adapter_Limit__mdt
    label: AI Adapter Limit
    kind: custom_metadata
    data_source: Configuration (custom metadata)
    audience: [admins]
    description: >
      A per-provider usage cap. Set these before widening access rather than after — they are the
      control on how much an unbounded rollout can cost against the provider account.
    key_fields:
      - {api_name: AI_Adapter__c, purpose: "The provider adapter the limit applies to."}
      - {api_name: API_Limit__c, purpose: "The cap for that adapter."}
