How Graffiticode Keeps Agents Safe
The hard problem with AI agents is not whether they can call an API. It is whether you can let them. An agent that holds a Learnosity key can publish items. An agent that holds a Stripe key can charge cards. An agent that holds a Figma token can overwrite a design system. The risk is not the model — it is the credential.
Graffiticode is designed so that agents never receive credentials. They receive capabilities. This note describes the model.
FOUR LAYERS, ONE INVARIANT
Graffiticode separates four things that are normally tangled together:
- What can be expressed — the dialects and languages.
- What effects are possible — the capabilities each language exposes.
- What effects are allowed — the policies attached to a user, tenant, or agent.
- What effects may occur right now — the execution grant computed for a specific task.
Every external action a smart tool performs must satisfy a single invariant:
requiredEffects(task)
⊆ declaredEffects(capabilities)
⊆ allowedEffects(policy/grant)
If the inclusion fails at any layer, the effect does not happen.
CONTENT LANGUAGES AND SERVICE LANGUAGES
Smart tools come in two kinds.
Content languages describe artifacts — spreadsheets, diagrams, charts, documents. They are mostly pure. They transform data, validate structure, and render representations. They do not publish, send, charge, or delete. Their capabilities are descriptive: useful for planning, composition, and training the specialized AI, but not the security boundary.
Service languages integrate with external systems — Learnosity, Figma, Salesforce, Stripe. They perform real-world effects. Their capabilities are authoritative and enforced. Every effect a service language can produce is declared up front, in machine-readable metadata, and gated by policy at runtime.
A typical composition looks like this:
0166 (spreadsheet)
→ SpreadsheetAssessment artifact
→ 0158 (Learnosity)
→ Learnosity API
The content compiler produces typed artifacts. The service compiler consumes artifacts and performs effects. Composition happens through type compatibility and capability contracts — not by passing credentials from one language to another.
CAPABILITIES AS THE SAFE HANDLE
Every service language declares its capabilities in language-info.json:
{
"id": "0158",
"kind": "service",
"accepts": ["AssessmentContent", "SpreadsheetAssessment"],
"effects": {
"external": [
"write:learnosity:draft",
"publish:learnosity:item"
]
},
"requiresPolicy": true
}
The companion usage-guide.md describes the same capabilities in a form the
specialized AI and human reviewers can read.
Capabilities are the safe handle to an API key. The key itself never leaves the trusted authority layer. Agents see only the operations the language has declared, and only those operations the current policy and grant allow.
POLICIES AND EXECUTION GRANTS
Policies live in the console, MCP server, and policy service — never inside a compiler, task, or agent. A policy looks like this:
{
"allow": ["write:learnosity:draft"],
"requireApproval": ["publish:learnosity:item"],
"deny": ["delete:*:*"]
}
For each task, the policy and grant service computes a short-lived execution grant:
{
"allowedEffects": ["write:learnosity:draft"],
"deniedEffects": ["publish:learnosity:item"],
"connectionRefs": ["learnosity_prod"]
}
The compiler receives the execution grant. It does not receive raw policies or backend credentials.
THE COMPILER: PROOF, THEN EXECUTION
Each Graffiticode compiler runs in two phases.
The checker is the proof engine. It performs type checking, semantic validation, capability analysis, and grant proof checking. It proves that the effects the task requires are a subset of the effects the capabilities declare, which are in turn a subset of the effects the execution grant allows. Its output is an effect certificate:
{
"decision": "approval_required",
"requiredEffects": [
"write:learnosity:draft",
"publish:learnosity:item"
],
"obligations": [
{ "kind": "approval", "effect": "publish:learnosity:item" }
]
}
Possible outcomes are allow, deny, approval_required,
needs_scope_resolution, and partial_allowed.
The transformer is the executor of effects. It only runs effects the checker has already certified, and it re-validates each one against the execution grant as it executes — defense in depth against compiler bugs, malformed tasks, and malicious inputs. The transformer is also where the audit trail is written, so every API call an agent triggered through a smart tool is attributable end-to-end.
THE RUNTIME IS THE VIEWER
The runtime in Graffiticode is the embeddable front-end viewer that renders a compiled program — a spreadsheet, a diagram, an assessment, a chart. It is the presentation layer.
This note is about authoring-time effects: what an agent is allowed to do while it operates a smart tool to produce an artifact. The capability declarations, policies, grants, checker proofs, and transformer execution all govern that path — from agent intent to authored artifact, behind the trusted authority layer.
What the artifact does once it is delivered depends on the target platform. A published Learnosity item, for example, runs inside Learnosity's Item API and exchanges state with it; a Figma plugin runs inside Figma. Those runtime semantics belong to the downstream platform and its security model, not to Graffiticode. The Graffiticode security model governs the path from agent intent to authored artifact. The downstream platform governs the artifact in use.
THE SYSTEM AT A GLANCE
Console / MCP Server
├── user identity
├── backend credentials
├── policies
└── audit logs
Policy / Grant Service
└── computes execution grants
API Service
├── task storage
└── compiler routing
Language Servers / Compilers
├── declared capabilities
├── checker pass (proves effects are allowed)
└── transformer pass (executes the certified effects)
Embeddable Runtime / Viewer
└── renders the compiled program
The API service stays intentionally thin — it stores tasks, routes compiles, and orchestrates services. Anything credential-bearing for authoring-time effects lives behind the trusted authority layer.
MENTAL MODEL
Dialect = what can be expressed
Capabilities = what effects are possible
Policy = what effects are allowed
Grant = what effects are allowed right now
Checker = proof engine
Transformer = effect executor
Runtime = embeddable viewer
Languages declare capabilities. Policies restrict those capabilities. Execution grants narrow permissions for individual tasks. The checker proves each task stays inside its grant. The transformer runs the certified effects, re-validates them as it goes, and writes the audit trail. The runtime renders the result.
This is what we mean when we say a smart tool lets an agent use an API safely and reliably. The agent never holds the key. It holds a language — and the language holds the proof that whatever it just asked for was allowed.
