Source profileQuality 94/100

objectstack-ai/objectstack/skills/objectstack-ai/SKILL.md

objectstack-ai

Design ObjectStack AI skills, tools, knowledge sources, conversations, model registry entries, and MCP integrations. Use when the user is adding `*.skill.ts` / `*.tool.ts`, configuring an LLM provider, wiring agent tools, or indexing ObjectStack data as a knowledge source for RAG. Agents themselves are platform-internal (`ask` / `build`) — third parties extend them via skills and tools, not by authoring `*.agent.ts`. Do not use for general LLM prompting questions unrelated to ObjectStack metadat

Source repository stars
39
Declared platforms
0
Static risk flags
1
Last source update
2026-08-25
Source checked
2026-08-25

Decision brief

What it does: where it fits

Expert instructions for designing AI skills, tools, and knowledge sources — and the platform agents they plug into — using the ObjectStack specification. This skill covers the Agent → Skill → Tool three-tier architecture aligned with Salesforce Agentforce, Microsoft Copilot Stud…

Best for

  • You need to define skills — bundles of related tools bound to the
  • You are configuring tools for data queries, actions, or integrations.
  • You want to index ObjectStack data as a knowledge source for RAG

Not for

  • Overly broad instructions. Agents with vague instructions hallucinate
  • Too many tools per skill. Keep skills focused (3–8 tools). If a skill

Compatibility matrix

Platform support, with evidence labels

PlatformStatusEvidenceWhat to check
CodexNot declaredNo explicit evidencePortability before use
Claude CodeNot declaredNo explicit evidencePortability before use
CursorNot declaredNo explicit evidencePortability before use
Gemini CLINot declaredNo explicit evidencePortability before use
Open the compatibility checker

Installation

Inspect first. Install second.

The source command is displayed only when detected. A safe inspection prompt is always available so your agent can explain every action before execution.

Source-detected install commandSource
npx skills add https://github.com/objectstack-ai/objectstack --skill "skills/objectstack-ai"
Safe inspection promptEditorial

Inspect the Agent Skill "objectstack-ai" from https://github.com/objectstack-ai/objectstack/blob/2cc71222459e91964e883419611a820c28302429/skills/objectstack-ai/SKILL.md at commit 2cc71222459e91964e883419611a820c28302429. List every install step, command, network request, credential, file read/write, external action, and rollback step. Explain whether it fits my task. Do not install or execute anything until I approve.

Workflow

What the source asks the agent to do

  1. 01

    When to Use This Skill

    You need to define skills — bundles of related tools bound to the

    You need to define skills — bundles of related tools bound to theYou are configuring tools for data queries, actions, or integrations.You want to index ObjectStack data as a knowledge source for RAG
  2. 02

    Three-Tier Architecture

    Best practice: Always model via Skills first. Direct tool assignment to agents is supported but considered legacy. Skills provide better discoverability, instruction scoping, and reuse.

    ask — the data product (≈ Claude Chat). Conversational read / query /build — the authoring product (≈ Claude Code). Agentic authoring ofBest practice: Always model via Skills first. Direct tool assignment to agents is supported but considered legacy. Skills provide better discoverability, instruction scoping, and reuse.
  3. 03

    Why Three Tiers?

    Best practice: Always model via Skills first. Direct tool assignment to agents is supported but considered legacy. Skills provide better discoverability, instruction scoping, and reuse.

    Best practice: Always model via Skills first. Direct tool assignment to agents is supported but considered legacy. Skills provide better discoverability, instruction scoping, and reuse.
  4. 04

    Built-in agents: ask & build (ADR-0063 / ADR-0064)

    The runtime ships exactly two platform agents, bound by surface — the user never picks from a roster; the surface they are in selects the agent:

    ask — the data product (≈ Claude Chat). Conversational read / query /build — the authoring product (≈ Claude Code). Agentic authoring ofThe runtime ships exactly two platform agents, bound by surface — the user never picks from a roster; the surface they are in selects the agent:
  5. 05

    Skill → agent affinity: the surface field (ADR-0063 §3)

    Every skill declares which surface it binds to via surface: 'ask' | 'build' | 'both' (defaults to 'ask'). A skill may bind only to an agent whose surface it matches; 'both' binds to either. The runtime enforces this in resolveActiveSkills at load time — an incompatible binding i…

    Every skill declares which surface it binds to via surface: 'ask' | 'build' | 'both' (defaults to 'ask'). A skill may bind only to an agent whose surface it matches; 'both' binds to either. The runtime enforces this in…The built-in skills and their affinities:To grant data exploration to your own (platform-internal) agent, add dataexplorer / schemareader to its skills[]; deactivating a skill (active: false) revokes that capability for every agent that references it.

Permission review

Static risk signals and limitations

Network access

medium · line 40

The documentation includes network, browsing, or remote request actions.

│ │ └─ Atomic operation (query, action, flow, API call)

Evidence record

Why each signal appears

EvidenceSourceComputedTestedEditorial
SignalValueEvidence typeMeaning
Quality score94/100ComputedDocumentation, specificity, maintenance, and trust rules
Repository stars39SourceRepository attention, not individual Skill quality
Compatibility0 platformsSourceDeclared in the catalog source record
Usage guideautomated source guideEditorialGenerated or reviewed according to the visible evidence level

Pinned source

Provenance and original SKILL.md

Repository
objectstack-ai/objectstack
Skill path
skills/objectstack-ai/SKILL.md
Commit
2cc71222459e91964e883419611a820c28302429
License
Apache-2.0
Collected
2026-08-25
Default branch
main
View the original SKILL.md

AI Agent Design — ObjectStack AI Protocol

Expert instructions for designing AI skills, tools, and knowledge sources — and the platform agents they plug into — using the ObjectStack specification. This skill covers the Agent → Skill → Tool three-tier architecture aligned with Salesforce Agentforce, Microsoft Copilot Studio, and ServiceNow Now Assist patterns.

Edition boundary (service-ai → cloud; open = MCP-only). The in-UI AI runtime — the ask / build agents, in-product chat, and the /api/v1/ai/* routes (@objectstack/service-ai) — ships in the cloud / Enterprise distribution, not the open framework. The agent / skill / tool schemas in @objectstack/spec/ai stay open, so you author *.skill.ts / *.tool.ts as source either way (*.agent.ts is platform-internal) — but they only execute in a cloud / EE host. On the open edition there is no in-product agent: expose the app to your own AI via @objectstack/mcp (BYO-AI) for data query, and author metadata in source mode with an AI coding agent (Claude Code, Cursor).


When to Use This Skill

  • You need to define skills — bundles of related tools bound to the ask / build surfaces.
  • You are configuring tools for data queries, actions, or integrations.
  • You want to index ObjectStack data as a knowledge source for RAG retrieval.
  • You are choosing and configuring LLM models (model registry).
  • You need to read or review agent configuration — platform-internal; third parties extend agents via skills, not by authoring them.

Three-Tier Architecture

Agent  →  Skill  →  Tool
  │         │         │
  │         │         └─ Atomic operation (query, action, flow, API call)
  │         └─ Capability bundle with instructions & trigger phrases
  └─ Autonomous actor with role, instructions, and guardrails

Why Three Tiers?

TierAnalogyReuse Level
AgentJob role (e.g., "Help Desk Agent")Per use-case
SkillCompetency (e.g., "Case Management")Across agents
ToolSpecific operation (e.g., "create_record")Across skills

Best practice: Always model via Skills first. Direct tool assignment to agents is supported but considered legacy. Skills provide better discoverability, instruction scoping, and reuse.

Built-in agents: ask & build (ADR-0063 / ADR-0064)

The runtime ships exactly two platform agents, bound by surface — the user never picks from a roster; the surface they are in selects the agent:

  • ask — the data product (≈ Claude Chat). Conversational read / query / explore over records, plus running the business actions the app already exposes. End-user audience, RLS-bounded. Canonical id ask (ASK_AGENT_NAME). Cloud / Enterprise — the ask runtime ships in the closed cloud AI runtime (@objectstack/service-ai); it is the implicit copilot for any cloud / EE app that does not pin app.defaultAgent. (Open editions have no in-product ask; use MCP.)
  • build — the authoring product (≈ Claude Code). Agentic authoring of metadata (objects, fields, views, flows) through plan → draft → verify → publish. Builder audience, governance-gated. Canonical id build. Cloud-only · paid — ships in the cloud AI Studio plugin; Studio pins it via app.defaultAgent.

There is no per-turn intent classifier: a build-shaped request arriving at ask is declined and redirected to the Builder, never silently re-routed into authoring (ADR-0063 §1/§5).

Legacy names are aliases only. data_chatask and metadata_assistantbuild resolve through the alias table for old bookmarks and persisted agent_ids; they are not vocabulary — always write ask / build. *.agent.ts is closed to third parties (agent type is allowRuntimeCreate:false, allowOrgOverride:false): you extend the platform with skills, never by authoring an agent (ADR-0063 §2).

Skill → agent affinity: the surface field (ADR-0063 §3)

Every skill declares which surface it binds to via surface: 'ask' | 'build' | 'both' (defaults to 'ask'). A skill may bind only to an agent whose surface it matches; 'both' binds to either. The runtime enforces this in resolveActiveSkills at load time — an incompatible binding is a fast load error, not a silent mis-scope. An agent's tool set is the union of its surface-compatible skills' tools — there is no global fall-through (ADR-0064), so ask cannot author by construction.

The built-in skills and their affinities:

SkillsurfaceOwnsEdition
schema_readerbothlist_objects, describe_object, query_dataOSS
data_exploreraskquery_records, get_record, aggregate_data, visualize_dataOSS
actions_executoraskaction_* (the business actions an object exposes)OSS
metadata_authoring + solution_designbuildmetadata draft / verify / publish + blueprint propose / applycloud only

To grant data exploration to your own (platform-internal) agent, add data_explorer / schema_reader to its skills[]; deactivating a skill (active: false) revokes that capability for every agent that references it.

surface:'build' skills are inert on OSS — by design, not a bug. The open single-env framework ships only the ask agent; metadata_authoring / solution_design (and any third-party surface:'build' skill) are supplied by the cloud AI Studio plugin and simply do not resolve in OSS. A build-intent turn on OSS degrades gracefully ("authoring lives in the cloud Build assistant") instead of dead-ending — this is intentional tiering. Do not assume authoring tools resolve in the open framework.

visualize_data: the only built-in tool that draws a chart — it aggregates an object and emits an inline data-chart part. Auto-registered only when an analytics service (IAnalyticsService) is wired; query_data / aggregate_data return numbers, not charts.

Ops: set AI_DAILY_USER_MESSAGES=<N> to cap user turns per user per day (backed by the ai_usage_daily object; no-op if unset). Adapter health is observable at GET /api/v1/ai/status; invalid ai settings are rejected at save time.


Agent Configuration

Reference only — third parties do not author agents. The agent type is closed (allowRuntimeCreate:false; ADR-0063 §2): the platform ships exactly ask and build, maintained by platform / cloud plugin authors. You extend the platform with skills + tools (and knowledge sources) — never by adding an agent. This section documents AgentSchema for reading existing agents and for platform-internal work.

Required Properties

PropertyTypeDescription
namesnake_caseUnique agent identifier
labelstringHuman-readable name
rolestringAgent's persona/role description
instructionsstringSystem prompt — detailed behavioural guidance

Important Optional Properties

PropertyPurpose
skillsArray of skill names — primary capability model
toolsDirect tool references — legacy fallback
surface'ask' | 'build' — the product surface this agent is (default 'ask')
modelLLM model configuration — provider, model, temperature, maxTokens, topP
knowledgeREMOVED in protocol 17 — declaring sources/indexes on an agent never scoped retrieval (search_knowledge takes sourceIds from the LLM's tool-call arguments). Restrict at the knowledge-service/source level; describe intended grounding in instructions
guardrailsmaxTokensPerInvocation, maxExecutionTimeSec, blockedTopics
structuredOutputOutput format (JSON schema, regex, etc.)
planningAutonomous reasoning — maxIterations (default 10)
memorylongTerm persistence + reflectionInterval
permissionsPermission-set capabilities required to use the agent
activeEnable/disable the agent

There is no top-level temperature / maxTokens on an agent — sampling parameters live under model (AIModelConfigSchema).

Agent Example

import { defineAgent } from '@objectstack/spec';

export default defineAgent({
  name: 'support_tier_1',
  label: 'First Line Support',
  role: 'Help Desk Assistant for customer support cases',
  instructions: `
    You are a friendly and professional help desk assistant.
    
    RULES:
    - Always greet the customer by name if available.
    - Search the knowledge base before creating a new case.
    - Escalate to a human agent if the issue is critical or security-related.
    - Never share internal system details with customers.
    - Respond in the customer's preferred language.
  `,
  skills: ['case_management', 'knowledge_search'],
  model: {
    provider: 'openai',
    model: 'gpt-4o',
    temperature: 0.3,
  },
  guardrails: {
    blockedTopics: ['internal_pricing', 'employee_data'],   // forbidden topics / action names
    maxTokensPerInvocation: 8000,                            // token budget per invocation
    maxExecutionTimeSec: 60,                                 // wall-clock cap per invocation
  },
});

Skill Configuration

A Skill is a named bundle of tools with dedicated instructions and trigger conditions.

Required Properties

PropertyTypeDescription
namesnake_caseUnique skill identifier (/^[a-z_][a-z0-9_]*$/)
labelstringHuman-readable name
toolsstring[]Tool names this skill grants access to (trailing wildcard allowed, e.g. action_*)

Important Optional Properties

PropertyPurpose
surface'ask' | 'build' | 'both' — agent surface affinity (default 'ask'; see above)
descriptionWhat the skill does — helps the agent decide when to use it
instructionsLLM prompt guidance specific to this skill's context
triggerPhrasesNatural language phrases that activate the skill
triggerConditionsProgrammatic activation rules
activeIs the skill enabled (default: true)

A skill has no permissions key — it was removed in 16.x. Skill invocation was never gated by it (the registry reads only active / triggerConditions / tools), and a security-shaped field that enforces nothing is worse than no field at all. Gate access at the agent instead — access / permissions on defineAgent are enforced at the chat route — or on the underlying actions the skill's tools call (permission sets, ADR-0066).

Skill Example

import { defineSkill } from '@objectstack/spec';

export default defineSkill({
  name: 'case_management',
  label: 'Case Management',
  description: 'Create, update, query, and escalate support cases.',
  instructions: `
    When managing cases:
    - Always check for duplicate cases before creating a new one.
    - Set priority based on customer tier: Enterprise → High, Pro → Medium, Free → Low.
    - Escalated cases must include a summary of actions already taken.
  `,
  tools: [
    'query_support_case',
    'create_support_case',
    'update_support_case',
    'escalate_case',
  ],
  triggerConditions: [
    { field: 'objectName', operator: 'eq', value: 'support_case' },
  ],
  active: true,
});

Trigger Conditions

OperatorMeaning
eqEquals
neqNot equals
inValue is in array
not_inValue is not in array
containsString contains substring

Tool Configuration

Tools are the atomic operations that skills expose to agents.

First-Class Tool Metadata (defineTool)

A tool authored as metadata (type: 'tool', *.tool.ts) is validated by ToolSchema: required name / label / description, a JSON Schema parameters object, plus optional objectName and outputSchema. ToolSchema is strict — an unknown key (a typo, or a retired key) is a parse error, not a silent strip. Retired in protocol 17: category, permissions, active and builtIn (all were authorable and inert; permissions gated nothing and active: false withdrew nothing — the rejection message carries each key's replacement), joining requiresConfirmation.

import { defineTool } from '@objectstack/spec';

export default defineTool({
  name: 'create_case',
  label: 'Create Support Case',
  description: 'Creates a new support case record',
  parameters: {
    type: 'object',
    properties: {
      subject: { type: 'string', description: 'Case subject' },
      priority: { type: 'string', enum: ['low', 'medium', 'high'] },
    },
    required: ['subject'],
  },
  objectName: 'support_case',
});

To gate what a tool can do, gate the underlying action (action.requiredPermissions, ADR-0066) or the objects it touches; to withdraw a tool, remove it from the skills/agents that reference it. Categorization, if you need it, belongs on the action side (action.ai.category — a live, enforced surface).

Tool metadata is a read-only projection — not an execution entry point. ToolSchema has no handler / implementation field, and no framework executor loads a metadata-authored tool. The runtime executes a separately-registered AIToolDefinition (cloud @objectstack/service-ai); tool metadata is a one-way projection for Studio / discovery. Do not expect a hand-authored tool to run in the open edition.

Inline Agent tools[] (legacy)

Entries in an agent's inline tools[] array are a different, legacy shape (AIToolSchema): { type: 'action' | 'flow' | 'query' | 'vector_search', name, description? } — references to existing actions / flows / queries, not tool definitions. Prefer skills + first-class tool names.

Auto-Exposed Actions

Cloud / EE runtime. registerActionsAsTools(), AIServicePlugin, and the HITL approval queue below ship in @objectstack/service-ai — the closed cloud / Enterprise runtime, not an open package. On the open edition, expose actions to your own AI via @objectstack/mcp instead.

You usually don't author tool definitions by hand for action invocation. Every Action you attach to an object via defineObject({ actions: [...] }) is auto-exposed as a tool named action_<actionName> by registerActionsAsTools() (invoked from AIServicePlugin).

Three action types dispatch headlessly:

action.typeDispatchWiring
scriptIDataEngine.executeAction(object, target, ctx) — same as Studio's row toolbarnone
apiHTTP call to action.target (fetch-based by default)AIServicePlugin({ apiActionBaseUrl, apiActionHeaders }) or custom apiClient
flowIAutomationService.execute(target, { triggerData })automation service registered with the kernel

Skipped automatically:

  • UI-only types (url, modal, form).
  • Dangerous variants (confirmText set, mode: 'delete', variant: 'danger') — unless the plugin is started with enableActionApproval: true, in which case they route through the HITL approval queue (see below).
  • Owner opt-outs (aiExposed: false).

type:'api' body assembly (last wins): user params → recordIdParam (using recordIdField, default 'id') → bodyExtra. bodyShape: { wrap: 'data' } nests user params under data while keeping recordIdParam flat.

Use actionSkipReason(action, ctx) (exported from @objectstack/service-ai — cloud-only, not importable on the open edition) when authoring an action and you want to know why it isn't surfacing in chat. Studio's "AI exposure" diagnostics use the same predicate. Pair with actionRequiresApproval(action) to know whether a registered action will be routed through HITL.

Human-In-The-Loop approval

Cloud / EE runtime. The HITL approval queue is part of @objectstack/service-ai and is not available in the open framework.

kernel.use(new AIServicePlugin({
  enableActionApproval: true,   // opt in; default is false
  apiActionBaseUrl: process.env.OS_AI_ACTION_API_BASE_URL,
}));

Flow:

  1. LLM picks action_delete_task → runtime persists an ai_pending_actions row and returns { status: 'pending_approval', pendingActionId }.
  2. Operator triages via Studio's AI Pending Actions inbox (or the REST endpoints: GET/POST /api/v1/ai/pending-actions/...).
  3. Approve → service re-runs the action via the pre-registered bypass-approval dispatcher; row transitions to executed / failed.
  4. Reject → row transitions to rejected with an optional reason.

Programmatic API on IAIService: proposePendingAction, approvePendingAction, rejectPendingAction, listPendingActions. All are optional (returns clear error when no IDataEngine is wired).


Knowledge Sources (RAG)

The platform's RAG primitive is the KnowledgeSource (KnowledgeSourceSchema in @objectstack/spec/ai): declarative metadata pairing what to index with the id of an IKnowledgeAdapter that does the work. Sources are registered at runtime via IKnowledgeService.registerSource() (there is no defineStack collection for them), and the search_knowledge tool exposes registered sources to agents.

KnowledgeSource Structure

PropertyPurpose
idSnake_case source id
label / descriptionDisplay metadata
adapterAdapter id (e.g. 'ragflow', 'memory'), resolved via IKnowledgeService.registerAdapter
adapterConfigAdapter-specific configuration (opaque to the service)
sourceWhat gets indexed — discriminated on kind: 'object' | 'file' | 'http'
embeddingOptional EmbeddingModelSchema ref (provider, model, dimensions) — adapters that manage embeddings internally (RAGFlow, Dify, Vectara) may ignore it
vectorStoreOptional VectorStoreSchema ref (provider, collection) — same caveat
refreshonRecordChange (default true for object sources) + optional cron (surfaced for an external scheduler, not self-scheduled)
aiExposedWhether search_knowledge may expose this source to agents (default true)

Source kinds:

source.kindFields
objectobject, contentFields[] (min 1; * = every readable text field), metadataFields?, where? (ObjectQL where syntax)
fileprefix (storage prefix, e.g. kb/handbooks/), mimeTypes?
httpurls[], userAgent?

Knowledge Source Example

import { KnowledgeSourceSchema, type KnowledgeSource } from '@objectstack/spec/ai';

export const supportKb: KnowledgeSource = KnowledgeSourceSchema.parse({
  id: 'support_kb',
  label: 'Support Knowledge Base',
  adapter: 'ragflow',                       // or 'memory' for dev/test
  source: {
    kind: 'object',
    object: 'kb_article',
    contentFields: ['title', 'body'],       // concatenated into document content
    metadataFields: ['category', 'owner_id'], // projected for search-time filtering
    where: { published: true },             // index published articles only
  },
  refresh: { onRecordChange: true },        // re-index on record.* events
});

Chunking, top-K, score thresholds, and rerankers are NOT platform metadata. The spec deliberately scopes them out (embedding.zod.ts): chunking strategies, retrieval pipelines, and RAG orchestration belong to the adapter (adapterConfig) or application code. The platform only carries the embed + vector primitives so any RAG strategy can be built on top.

Knowledge Source Best Practices

  1. Filter with where. Index only published/active records (where: { published: true }) so draft or archived content never enters the index.
  2. Index only meaningful text via contentFields. Do not include system fields or IDs; use * (all readable text fields) sparingly.
  3. Project filter fields into metadataFields (e.g. status, owner_id, tags) so searches can be narrowed at query time.
  4. Hide with aiExposed: false when a source should be indexed but not agent-searchable.
  5. Tune relevance in the adapter, not the metadata. Top-K, thresholds, and reranking are configured in your RAG backend (via adapterConfig), not in ObjectStack metadata.

Model Configuration

Supported Providers

ProviderModelsUse Case
openaiGPT-4o, GPT-4o-mini, o1, o3-miniGeneral purpose, reasoning
anthropicClaude Sonnet 4, Claude HaikuLong context, safety
azure_openaiSame as OpenAI, enterprise managedCompliance, data residency
localOllama, vLLM, llama.cppOn-premise, air-gapped

The inline agent model.provider enum is the narrow set above (openai / azure_openai / anthropic / local). Model-registry entries (ModelProviderSchema) accept a wider set: also google, cohere, huggingface, custom.

Model Selection Guidelines

ScenarioRecommended
Complex reasoning, multi-step planningGPT-4o / Claude Sonnet 4
High-volume, low-latencyGPT-4o-mini / Claude Haiku
Sensitive data, on-premiseLocal models via Ollama
Structured data extractionAny model + structuredOutput config

Temperature Guidelines

ValueUse Case
0.0–0.3Factual Q&A, data extraction, code generation
0.3–0.7Conversational agents, customer support
0.7–1.0Creative writing, brainstorming
> 1.0Experimental / highly creative (use with caution)

Structured Output

Force the agent to respond in a specific format:

structuredOutput: {
  format: 'json_schema',
  schema: {
    type: 'object',
    properties: {
      summary: { type: 'string' },
      priority: { type: 'string', enum: ['low', 'medium', 'high'] },
      action_items: { type: 'array', items: { type: 'string' } },
    },
    required: ['summary', 'priority'],
  },
  strict: true,     // enforce exact schema compliance (default: false)
  maxRetries: 3,    // max retries on validation failure (default: 3)
}

On validation failure the runtime retries by default (retryOnValidationFailure: true). Optional extras: fallbackFormat and a transformPipeline of post-processing steps (trim, parse_json, validate, coerce_types). There is no retry object — the knobs are retryOnValidationFailure + maxRetries.


Common Pitfalls

  1. Overly broad instructions. Agents with vague instructions hallucinate more. Be specific about what the agent should and should not do.
  2. Too many tools per skill. Keep skills focused (3–8 tools). If a skill has 15+ tools, split it.
  3. Missing guardrails and approval gates. Define blockedTopics (plus the token / time budgets) in agent guardrails; for destructive operations put a human in the loop with a gate that is actually enforcedenableActionApproval: true (HITL queue, cloud) for auto-exposed actions, ai.requiresConfirmation on the action, or approval: 'always' on an MCP tool binding. AI metadata edits are already gated: they land as drafts a human must publish (ADR-0033). ⚠️ requiresConfirmation on the tool was REMOVED (ADR-0033 §2) — it was read by no execution path, so it produced no pause. ToolSchema is strict, so authoring it now fails the parse with the migration attached. There is no requireApprovalFor field.
  4. Ignoring tool descriptions. The LLM uses tool description to decide when to call it. Poor descriptions = wrong tool selection.
  5. Not testing trigger phrases. Ambiguous trigger phrases cause skill conflicts. Test with edge-case inputs.
  6. Indexing everything. A knowledge source without a where filter and curated contentFields fills the index with drafts and boilerplate that pollute retrieval. Source hygiene is the metadata's job; relevance tuning (top-K, thresholds, reranking) belongs to the adapter.

App AI Blueprint (Skills + Tools + Knowledge)

Reference layout for a scaffolded app:

LayerFilePattern
Reusable skillsrc/skills/lead-qualification.skill.tsdefineSkill — trigger phrases + trigger conditions + bounded toolset; pick a surface
Tool metadatasrc/tools/query-leads.tool.tsdefineTool — JSON-Schema parameters; a discovery projection, not an executor (see caveat above)
Knowledge sourcesrc/knowledge/sales-kb.tsKnowledgeSourceSchema metadata, registered at runtime via IKnowledgeService.registerSource()
Central registrationdefineStack({ skills: [...], tools: [...] })agents / tools / skills are the only AI stack collections — knowledge sources have none; agents are platform-supplied

Default for metadata apps: push business capability logic into skills, keep tools atomic, and wire domain knowledge through knowledge sources.


Verify your work

After authoring a *.skill.ts / *.tool.ts (or platform-internal *.agent.ts) or a model-registry entry, run the author-time gate before reporting done:

os validate     # Zod schema + CEL predicate validation + bindings (no artifact)
# or: os build  # the same gates, plus emits dist/

It confirms the agent/tool/model metadata conforms to the protocol and that any CEL predicate (e.g. a tool's availability condition) parses and resolves. In a scaffolded project the gate is npm run validate. See objectstack-platform → Verify your work.


References

See references/_index.md for the full list of Zod schemas (with one-line descriptions) — pointers into node_modules/@objectstack/spec/src/. Always Read the source for exact field shapes; do not rely on memory of property names.

Frequently asked questions

What to verify before installation and use

What does the objectstack-ai source document cover?

Expert instructions for designing AI skills, tools, and knowledge sources — and the platform agents they plug into — using the ObjectStack specification. This skill covers the Agent → Skill → Tool three-tier architecture aligned with Salesforce Agentforce, Microsoft Copilot Stud…

How do I install objectstack-ai?

The source record exposes this install command: npx skills add https://github.com/objectstack-ai/objectstack --skill "skills/objectstack-ai". Inspect the command and pinned source before running it.

Which permission-related actions were detected?

Static rules flagged network in the source; the page lists the matching lines and excerpts.

Alternatives

Compare before choosing

Computed 10045,511

coreyhaines31/marketingskills

ab-testing

When the user wants to plan, design, or implement an A/B test or experiment, or build a growth experimentation program. Also use when the user mentions "A/B test," "split test," "experiment," "test this change," "variant copy," "multivariate test," "hypothesis," "should I test this," "which version is better," "test two versions," "statistical significance," "how long should I run this test," "growth experiments," "experiment velocity," "experiment backlog," "ICE score," "experimentation program

Computed 10045,511

coreyhaines31/marketingskills

churn-prevention

When the user wants to reduce churn, build cancellation flows, set up save offers, recover failed payments, or implement retention strategies. Also use when the user mentions 'churn,' 'cancel flow,' 'offboarding,' 'save offer,' 'dunning,' 'failed payment recovery,' 'win-back,' 'retention,' 'exit survey,' 'pause subscription,' 'involuntary churn,' 'people keep canceling,' 'churn rate is too high,' 'how do I keep users,' or 'customers are leaving.' Use this whenever someone is losing subscribers o

Computed 10014,671

prowler-cloud/prowler

postgresql-indexing

PostgreSQL indexing best practices for Prowler: index design, partial indexes, partitioned table indexing, EXPLAIN ANALYZE validation, concurrent operations, monitoring, and maintenance. Trigger: When creating or modifying PostgreSQL indexes, analyzing query performance with EXPLAIN, debugging slow queries, reviewing index usage statistics, reindexing, dropping indexes, or working with partitioned table indexes. Also trigger when discussing index strategies, partial indexes, or index maintenance

Computed 100147

oaustegard/claude-skills

featuring

Generate hierarchical _FEATURES.md files that describe what a codebase DOES from a user/consumer perspective, anchored to source symbols via tree-sitting. Supports large complex codebases through feature-driven decomposition into sub-feature files. Uses a multi-pass synthesis: orientation → detail → overview rewrite. Use when someone says "what does this do", "document features", "feature inventory", "_FEATURES.md", or needs to understand a codebase's purpose before modifying it. Complements tre