Skip to content

Batteries-Included, Closed-World by Design

The capabilities an AI generator most often reaches for — sending email, sending SMS, syncing a CRM, talking to a database, reading and writing object storage, scheduling work, emitting metrics, declaring data schemas — are first-class language features in Arcana, not arbitrary packages to wire up.

This isn’t a packaging convenience. It’s two simultaneous properties:

  • A productivity property: the AI writes intent, not integration glue. There is no SDK to download, configure, version-pin, mock for tests, and re-pin when it deprecates. The code expresses what it wants to do; the runtime expresses how.
  • A safety property: a closed world with no arbitrary package-pull is a structural reduction of the supply-chain surface available to AI-generated code within the safe code path (Arcana retains an opt-in Unsafe FFI escape hatch covered below; the closed-world property applies to the default code path, not as an absolute constraint on what’s possible). The 2025-era pattern of an AI generator confidently npm install-ing a typosquat or a maintainer-compromised package isn’t something the default Arcana surface can do, because the resolution surface that allows it doesn’t exist.

These properties reinforce each other: the productivity gain comes from the closed-world model. They aren’t two separate design moves that happen to coexist.

Below is a real verified fixture from the Arcana repo — get_posts from tests/rpc-fixtures/blog.arcana. The default tab shows the canonical S-expression form (verbatim from the fixture; what AI emits and the compiler parses). The “Human view” tab shows the same function rendered through the human-readable projection (taken from the fixture’s own ;; comment header). Both tabs describe the same AST. See Known Issues §9 for the council-ratified disclosure about the bidirectional projection’s current HEAD state.

;; pub fn get_posts() -> {Database} Int
(dc-fn :fn
(fn-decl
:body (block
:stmts ()
:expr (ex-call
:args ((arg-positional :expr (ex-lit :value (lit-string :value "SELECT id, title, body, published FROM posts WHERE published = 1"))))
:fn (ex-ident :name "db_query")))
:contracts ()
:effects (Database)
:name "get_posts"
:params ()
:ret (ty-named :path "Int")
:tparams ()
:vis pub))

The {Database} declared in the function’s effect row is the contract: the function may read or write the database; it may not send email, call the network, write to the filesystem, or do anything else. The runtime (a Wasmtime-based sandbox) enforces the same contract at execution. The same shape applies for {Email}, {SMS}, {CRM}, {Network}, {ObjectStore(read/write)}, {Monitor}, scheduled work, and other capabilities (see Effect Contracts & Capability Discipline for the admission-controlled vocabulary).

One declaration becomes types, SQL, and validation. Below is Evt, a real verified dc-schema fixture from tests/v175-c2/fixtures/dc-schema.arcana — the canonical AST node dc-schema is the source-of-truth form; the human view is the projection.

;; v1.7.5 C2 §7.1/§7.2/§7.4 fixture: dc-schema leaf lowering.
(arcana-ast :version 1 :module "dc_schema"
(dc-mod
:name "main"
:items (
(dc-schema
:fields (
(field-decl :name "id" :type (ty-named :path "Int") :vis pub)
(field-decl :name "name" :type (ty-named :path "String") :vis pub)
(field-decl :name "active" :type (ty-named :path "Bool") :vis pub))
:mode "server"
:name "Evt"
:tparams ()
:vis pub))))

A single dc-schema declaration produces:

  • The Arcana type (used in function signatures)
  • The SQL CREATE TABLE (and migrations) when :mode "server"
  • The input validation at every boundary (form submission, API ingestion)
  • The serialization shape

Because there’s no drift surface — one declaration, multiple derivatives — there’s no opportunity for a generator to get the Arcana type right while accidentally producing a SQL schema that allows null where the type forbids it. The fixture above uses simple Int/String/Bool types; the refinement-typed field forms (String(max: 100), Email(unique: true), default values like Role = .member, list types [Post]) are detailed under “Refinement types” on Compile-Time Safety. The mechanism appears in this pillar because the practical effect is “batteries included for data modeling,” not just a type-system convenience.

Arcana ships with a curated standard library and a blessed-library tier rather than an open package ecosystem. This is intentional:

  • Generators don’t choose packages. The capability is reached for by effect ({Email}), not by package name (sendgrid vs mailgun vs ses-sdk). The platform decides which implementation backs the effect at deploy time.
  • The supply-chain surface is bounded by construction. There is no arcana install <arbitrary>. An AI generator confidently calling for a fictional or compromised package returns nothing to call.
  • The package-resolution failure mode reverses. Where mainstream languages fail open (npm install left-pad → it just works → security risk), Arcana fails closed (capability not in the closed world → compile error → human decision).

This is the closed-world-assumption-for-AI-safety property: when a generator’s training data contains a malicious or hallucinated package, the language doesn’t have a surface that lets the package be summoned.

The “Generating Arcana” guide (an open intention)

Section titled “The “Generating Arcana” guide (an open intention)”

The companion to this pillar is a guide for AI agents on how to actually generate Arcana competently — idiomatic patterns, common anti-patterns, the contract between generator and reviewer. The guide is currently named in Open Intentions as a wanted-but-uncommitted artifact, not a shipped one.

  • The effect set shipped today covers the common-case capabilities (the canonical list is documented in the language specification, which publishes publicly alongside the v1.x complete release). Specific effects with limited current coverage — for example, scheduled work, certain {Monitor} instrumentation patterns, file-system traversal cases — are honestly documented in the spec rather than hidden.
  • Modules as first-class language constructs (Folio for blog/CMS, marketplace primitives) are a later-release deliverable. The current closed-world layer is the stdlib + blessed libs; the modules-as-marketplace tier follows.
  • Closed-world doesn’t mean closed-language. Arcana has an Unsafe escape hatch for FFI to native code when truly needed — but Unsafe is opt-in, explicit, and the compiler warns at every use site. The closed-world property holds for the safe surface, not as an absolute constraint on what’s possible.

See Honest Scope for the canonical per-mechanism status.

  • Compile-Time Safety has more to enforce because first-class effects are typed — there’s nothing for safety to “miss” by being routed through an untyped SDK.
  • Effect Contracts & Capability Discipline is what governs which batteries get included. The admission-controlled vocabulary is the discipline behind the closed world.
  • Governance & Honest Scope is what keeps the closed world honest — the marketing-claims ledger forbids overclaiming the scope of safety properties, so “no supply-chain surface” is named precisely (within the safe code path, not across Unsafe).