ADR-0017: AI/LLM integration principles
- Status: Accepted (drafted 2026-04-23 from Wave 3b audit; accepted 2026-04-26 by maintainer — policy precedes first AI feature per the Wave 3 §"Decisions needing maintainer input" recommendation; zero AI features in production today, so accepting now lets every future AI ADR cite this ADR as the standing constraint)
- Date: 2026-04-23 drafted; 2026-04-26 accepted
- Deciders: Vitor Rodovalho (maintainer)
- Related: ADR-0006 (plugin-sdk),
.claude/agents/ai-architect.md,docs/runbooks/dev-environment-ai-tooling.md
Context
On 2026-04-20, OX Security disclosed CVE-2025-49596 et al. — a design-level RCE affecting Anthropic's MCP (Model Context Protocol) SDK and 7,000+ publicly accessible MCP servers / 150M+ downloads. The core flaw: MCP's STDIO transport allows configuration-to-command execution with no sandboxing boundary. Anthropic declined to patch the reference implementation, calling the behaviour "expected."
Reference: The Hacker News — Anthropic MCP Design Vulnerability.
Panorama has no AI features in production today (correctly — .claude/agents/ai-architect.md is in standby until the first AI feature ADR lands, targeted 0.3+). This ADR establishes guardrails before any AI feature lands or ADR-0006 (plugin-sdk) exits Draft, so the team doesn't accidentally replicate MCP's architectural mistakes.
This ADR was drafted from Wave 3b audit findings (MCP-04). It is a skeleton — individual principles may be revised as the first AI feature is scoped. What is non-negotiable is that the ADR exists and is Accepted before AI code ships.
Decision
The following six principles govern any AI/LLM integration in Panorama — whether via a core feature, a plugin, a dev-environment tool, or a cloud-side inference path.
Principle 1 — Separation of configuration from execution
No configuration file (JSON, YAML, env var, manifest) shall trigger code execution by its mere presence or modification. Plugin manifests declare metadata; a separate audited loader with cryptographic verification decides whether to execute. This principle is the direct lesson from the MCP CVE family.
Principle 2 — Real isolation boundary for untrusted code
vm.runInContext, vm.createContext, and "Node VM" in general are not security boundaries (per Node.js documentation). Any code from a third party (plugin, AI tool, marketplace download, LLM-generated tool invocation) runs in one of:
- Worker thread with
--experimental-permission(Node 20+) and deny-by-default filesystem/network permissions - Container or sidecar with no host filesystem access beyond an explicit bind mount
- Deno isolate with explicit
--allow-*flags
Principle 3 — Explicit allowlist, deny by default
No MCP server, plugin, AI tool, or external inference endpoint runs in Panorama's process space unless:
- Explicitly allowlisted in a signed configuration file (cryptographic signature by a maintainer)
- Allowlist entries cite the purpose, the signing reviewer, and the review date
- Marketplace-sourced code requires human approval + signature verification before execution
Principle 4 — Prompt-injection threat modeling is mandatory
Any feature where an LLM reads user-supplied content (asset names, inspection notes, reservation comments, imported Snipe-IT data) and then calls tools based on that content MUST include a prompt-injection threat model section in its feature ADR. The threat model must cover:
- What tools can the LLM invoke?
- What is the worst-case outcome of a tool call triggered by injection?
- What is the rollback/audit path?
- How does the system distinguish human-initiated from LLM-initiated mutations?
Principle 5 — Tool-use audit parity
LLM-invoked tools that mutate tenant state emit the same panorama.* audit events as human-invoked code paths, with an additional actorSource: 'llm_agent' marker plus the LLM run ID, prompt hash, and tool-call ID. No AI mutation is silent. No exceptions.
Principle 6 — AI dependency supply-chain review
Before adding any AI/LLM dependency — @modelcontextprotocol/*, @anthropic-ai/*, openai, langchain, llamaindex, or equivalent — the security-reviewer must triage:
- Its CVE history (30 days minimum; check NVD + GHSA)
- Its transport model (STDIO vs HTTP vs WebSocket) and the trust boundary of each
- Its sandboxing guarantees
- Whether its authors have indicated a history of responding (or not) to security reports
Known-vulnerable transports (MCP STDIO without sidecar isolation) are vetoed pending upstream fix.
Alternatives considered
- No governance ADR; rely on the ai-architect subagent. Rejected — the subagent needs a policy document to enforce. Without it, guidance is implicit, inconsistent, and brittle to subagent-config drift.
- Ban all AI features until 1.0. Rejected — overly conservative. The guardrails above allow safe adoption at 0.3+.
- Defer the ADR until the first AI feature is scoped. Rejected — this is exactly how MCP's architecture mistake propagated (implementation first, governance later). The ADR is the gate, not the consequence.
Consequences
Positive
- First AI feature ships with security-reviewed architecture, not retrofitted controls.
- ADR-0006 (plugin-sdk) inherits the isolation requirements before it exits Draft — closes the analogy risk flagged as Wave 3b MCP-02.
- Dev-environment AI tooling guidance (see
docs/runbooks/dev-environment-ai-tooling.md) has a policy anchor. - The
ai-architectsubagent gets a written policy to enforce.
Negative
- Adds review overhead to AI feature proposals. This is deliberate.
- May slow initial AI feature development by requiring isolation infrastructure that doesn't exist yet.
Neutral
- This ADR is intentionally strict. It can be relaxed per-principle with a follow-up ADR if a specific use case justifies it — but the default is strict.
- The six principles will be re-evaluated whenever a new high-severity AI-supply-chain CVE class is disclosed (the MCP CVE family being the precipitating event for this ADR).