Synsema docsENES

Capabilities & intent

Synsema is deny-by-default. Nothing touches the network, filesystem, database, secrets, or shell unless you declare the capability with require. Forget it and the operation cannot run — the interpreter refuses, even if the code asks.

This is what makes running untrusted code (an LLM's output, a doc playground) safe by construction.

capabilities.syn
-- Doc example: deny-by-default capabilities + faithful scope.
-- Uses `secret` because it proves the model with no network/disk side effects.
intent: "doc example: capabilities and intent"
require secret("APP_*")          -- name-prefix scope: covers APP_KEY, APP_DB, ... only

task read_app_key()
    -- APP_KEY is under the declared APP_* scope → allowed (still redacted, as always)
    give text(secret("APP_KEY", "demo")) == "secret(APP_KEY)"

task read_unscoped()
    -- DB_PASSWORD is NOT under APP_* → denied at the capability check (before any use)
    give secret("DB_PASSWORD")

print("APP_KEY is in scope → " + text(read_app_key()))

test "a capability you declared (in scope) is allowed"
    assert(read_app_key())

test "anything outside the declared scope is denied (deny-by-default)"
    assert_error(read_unscoped)

Declare what you need

require net("api.example.com")    -- one host
require file.read("/data/*")      -- read-only, under /data
require db("./store.db")          -- this database
require secret("STRIPE_KEY")      -- this secret

A fetch to any host you didn't declare is blocked. A read_file outside the scope is blocked — the path scope is faithful: a .. escape normalizes and is denied.

Auto-granted vs. must-declare

Under run/test, only stdout / time / llm are auto-granted. Everything else — net, file, db, secret, exec, serve, reveal, and random — is deny-by-default (yes, random too: it's for tokens/nonces). Under serve, even those are required.

Scopes

Per-task capabilities

A task can declare its own narrower require — it can only reach what it declares, even if the program is broader:

task fetch_orders()
    require net("api.shop.com")
    give fetch("https://api.shop.com/orders")    -- can ONLY reach api.shop.com

sandbox

A sandbox block strips all capabilities for the untrusted body inside it — a require within is a no-op.

Host ceiling — --sandbox / --cap-set (running code you don't trust)

require, per-task scoping and sandbox all assume you wrote the code. When you didn't — running an LLM-generated program, a user's plugin, or a public playground — the host (whoever runs synsema) imposes a ceiling the code cannot exceed, no matter what it declares:

synsema run  --sandbox program.syn                       # ceiling = stdout + time only
synsema run  --cap-set "stdout,db=:memory:" program.syn  # a tailored ceiling
synsema test --cap-set "stdout,time,random,secret" tests.syn

Three layers — who restricts, and when:

LayerWho restrictsUse when
require cap("scope")the code declares what it needsyou trust the code
sandbox blockthe code isolates part of itselfyou trust the code
--sandbox / --cap-setthe host imposes a ceiling from outsideyou don't trust the code

--sandbox vs --cap-set:

The rule: caps_effective ⊆ require ∩ ceiling. A require net("") under --cap-set "net=api.mock" gets nothing — the code can never rise above the ceiling. It only ever removes*; auto-grants (stdout/time/llm) are filtered too, and it propagates to spawned agents and parallel_map workers.

Scope your file/db or you give too much: a bare --cap-set "…,file" lets the code read any absolute path — use file=scratch_* (a prefix) or db=:memory: so it only touches what you mean.

This site's playground uses exactly this: every Run/Test runs with a ceiling that allows compute, secret, in-memory SQL and scratch files, but denies exec and real net — try a snippet with require exec(...) and press Run. For a public deploy, combine it with an OS container (defense in depth).

intent

intent: "Read customer data and generate reports"

intent is descriptive (any language) and frozen at startup — a prompt injection cannot widen it. Security comes from capabilities, never from the prose. See Secrets for credentials.