Context
0050 put@stackra/ai on AI SDK core with Bedrock as the default. A first
draft of this ADR split agentic features across free Stackra, @stackra-pro/ai-agents and Figentra OS. The owner reopened it
and asked for one unified AI system and package, the simplest and most powerful one: tools, skills, agents and
agent-to-agent communication. The design takes its developer experience from Laravel’s AI package (an agent class with
prompt, stream and queue), and its protocols from open standards: Agent Skills (SKILL.md), MCP and A2A. The safety rules of
0021 and the action pipeline of 0098 must hold
for every agent call.
Decision
- One package,
@stackra/ai, atpackages/application/ai, free and MIT, on AI SDK v7. It holds agents, tools, skills, multi-agent coordination, MCP, A2A, conversations, approvals, evaluation runs and test fakes. - Agents are classes:
@Agent class X extends Promptable.Promptablegivesprompt,stream,queueandresume. Model choice is a failover profile in config. Bedrock is the default provider, reached through IAM roles, never keys. Approvals surface asDecisionobjects.LoadSkillloads a skill into a run,AgentToollets one agent call another, and fakes replace the model in tests. - Every tool call is an action dispatch through the one pipeline of 0098, with an
agentactor whoseonBehalfOfchain names the human, and the idempotency keyrunId:toolCallId. Plain@Toolclasses that are not actions are allowed only at L0–L1 (read-only, 0099), and gen checks it. - Agents are iam principals. An agent’s effective access is the intersection of the user’s permissions and the agent’s own grant. An agent never has access its user lacks.
- Approval. L2 actions called by an agent need approval by default; a tenant may switch that off per action through settings. L3 and L4 always need a named human approver. MCP-client and remote (A2A) tools default to L2 with approval, unless allow-listed.
@ClientTooldeclares a frontend tool (toggle theme, navigate, open a record) with a Zod schema and no serverexecute. It is L0, UI-only, and sent with each chat request.- Protocols, pinned exactly: Agent Skills
SKILL.mdfor skills; MCP SDK v2 as both server and client; A2A 1.0 to expose agents and call remote ones; AI SDK v7. Skillscripts/are never run; only a skill’s instructions and resources are loaded. - Builder-UI agents are allowed as data that only references code: an agent defined in a Pro builder names tools, skills and actions defined in code, and can add none. This amends the “runtime schema engine” row of 0011 the same way 0110 does.
- Prompt and response text is stored only in conversations: tenant-scoped, encrypted, with a 90-day default retention. Runs, evidence and audit store hashes, never text.
- Tables, each with
tenant_idand row-level security:ai_conversations,ai_messages,ai_runs,ai_steps,ai_tool_calls,ai_approvals,ai_embeddingsanda2a_tasks. - Three integration events only:
ai.approval.requested.v1,ai.approval.resolved.v1andai.run.completed.v1. - Evaluation.
@Evaluationsuites and recorded-run replay (on AI SDK’s mock language model) are free. The eval workspace UI is Pro. - Intent is metadata on the action, not a separate kind. Evidence is separate from audit: evidence records why an action ran (inputs, plan, approvals); audit records that it ran.
- Secrets never reach the model. Credentials are secret references resolved by the runtime; tenant credentials come from
the connections store (0107); outbound HTTP goes through an egress
driver,
directoragent-vault(0106). There is no agent vault. - Pro is UIs only: the agent builder UI, the registry UI and the eval workspace. AgentCore is deferred, not a driver. The registry is 0109.
Consequences
- One package and one mental model: an agent is a class, a tool is an action, a skill is a folder, and other agents are tools.
- Skills and multi-agent coordination are free, which reverses the first draft of this ADR and the “AI agents kit” Pro row of 0077.
- A tenant that switches off L2 approval accepts agent writes without a human in the loop; this changes 0021 decision 5, which required a human approver for every write tool call.
- Three protocols pinned exactly means upgrades come through dedicated changes, each with its conformance tests.
- AgentCore as a runtime would need the “separate-language agent runtime” row of 0011 changed first; it stays deferred.
Enforcement
Planned: the gen validation pass rejects a@Tool above L1, an @AsTool action without agent in actors, and an L3–L4
action whose approval can be disabled; a test that skill loading never executes scripts/; an RLS isolation test per AI
table; exact pins checked by catalogMode: strict in pnpm-workspace.yaml. Nothing checks this today.
Revival trigger
AgentCore (deferred): a product needs managed agent hosting that a service process cannot provide.Supersedes and sources
Supersedes: 0050 (decisions 1 to 4 restated; decision 5 replaced by decision 5 here). Amends 0021 decision 5 (L2 approval is tenant-configurable) and 0078 decision 3 (the envelope carries the actor chain of 0098). Sources: owner decisions in chat, 2026-10-19 (“AI redesign” and “AI full design v2”; AI1 to AI10 and AI12 locked in Round 11). Informational: Laravel AI; Vercel AI SDK;/Users/akouta/Downloads/2026/archive/ai-1.x.