Subtypev0.1
New The compiler runs today: check, explain, manifest, build, run →

Less than you asked for, on purpose.

A language for scripts that agents write and people run. Every program starts with a needs list of what it may touch, and the compiler and a WebAssembly sandbox hold it to that list.

Get started
fix.sub
// Test, report, push, announce.
needs [
  read  [./src],
  write [./src],
  run   ["npm test"],
]

let last = read(./src/report.txt) or ""
let t = run("npm test")
if (t.failed) {
  write(./src/report.txt, t.output)
  run("git push")
  fetch("https://api.github.com/status")
}

Edit the needs block on the left, the real compiler answers

2 errors: beyond its needs
error[E0201]: `run("git push")` is not allowed by `needs`
  --> fix.sub:12:3
   |
12 |   run("git push")
   |   ^^^^^^^^^^^^^^^ this command is not in the run list
   = help: add `run ["git push"]` to the `needs` block at the top of the file, or remove the call

error[E0201]: `fetch("https://api.github.com/status")` is not allowed by `needs`
  --> fix.sub:13:3
   |
13 |   fetch("https://api.github.com/status")
   |   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ api.github.com:443 is not covered by `needs`
   = help: add `net ["api.github.com:443"]` to the `needs` block at the top of the file, or remove the call

warning[W0603]: the failure of this call is ignored (IoError): if it fails, nothing says so
  --> fix.sub:11:3
   |
11 |   write(./src/report.txt, t.output)
   |   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   = help: add `?` to stop here when it fails, or `or { ... }` to say what to do

warning[W0603]: the failure of this call is ignored (NetworkError): if it fails, nothing says so
  --> fix.sub:13:3
   |
13 |   fetch("https://api.github.com/status")
   |   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   = help: add `?` to stop here when it fails, or `or { ... }` to say what to do

error: 2 errors found and 2 warnings

Output of sub check and sub explain, computed for all 16 combinations when this page was built.

Everything a script may do, on one screen.

The pieces below are the compiler's real output for examples/fix_tests.sub, not mock-ups.

A plain list of permissions

Missing means none. Reviewable in five seconds.

needs [
  read  [./src],
  write [./src],
  run   ["npm test", "git commit -m *"],
]

The error says the fix

Go past the list and the compiler stops, with the line and the change to make.

error[E0201]: `run("git push")` is not allowed by `needs`
  --> fix.sub:12:3
   |
12 |   run("git push")
   |   ^^^^^^^^^^^^^^^ this command is not in the run list
   = help: add `run ["git push"]` to the `needs` block at the top of the file, or remove the call

What it can and cannot do

sub explain in plain words, for the person who approves.

It can:
├─ can read files
│     ./src   and everything below it
├─ can write files
│     ./src   and everything below it
├─ can run programs
│     git add ./src     and any arguments after it
│     git commit -m *   exactly these arguments (a * is any one word)
│     npm test          and any arguments after it
└─ cannot
      use the network, read environment variables, read the clock, or use random numbers

One question, asked once

The run prompt shows the list. "Always" saves its hash, so an edited script asks again.

fix_tests.sub wants to
  • read and write ./src
  • run npm test, git add, git commit
Allow onceAlwaysDeny

A manifest tools can read

sub manifest: JSON with a hash. Centcom can approve it without parsing code.

{
  "format": "subtype-manifest/1",
  "needs": {
    "read": [
      "./src"
    ],
    "write": [
      "./src"
    ],
    "run": [
      "git add ./src",
      "git commit -m *",
      "npm test"
    ],
    "net": [],
    "env": [],
    "clock": false,
    "random": false
  },
  "hash": "sha256:a0e428abda7f95f…"
}

Less is a subtype

A function may ask for less than its caller holds. Never more.

write [.]⊃ write [./src]⊃ write [./src/lib]run ["git"]⊃ run ["git status"]

Two walls, one list.

The same needs block is checked by two different programs, so a mistake in one does not become a hole.

fix.subneeds [ ... ]+ the scriptWALL 1 · compilerevery call is checkedagainst needssub check · sub manifesterrors say how to fix itfix.wasmcarries its ownneeds and manifestWALL 2 · sandboxWasmtime, deny bydefaultrun and net are checkedagain, per call

Start with one script.

$ git clone <the repository> && cd subtype
$ cargo build
$ target/debug/sub explain examples/fix_tests.sub
$ target/debug/sub run examples/todo_report.sub