Sley Tutorial

Home | Docs | Tutorial | Who / Why / Better | llms.txt | ZJX


Before You Start

Sley is still a v0 prototype. This tutorial uses canonical Sley target vocabulary: task, bind, state, gate, forge, shard, graft, trace, and ZJX.

1. Hello Task

module app.hello

task main -> Text {
  bind message = "hello sley"
  return message
}

Useful commands:

sley parse examples/hello.sley
sley format examples/hello.sley
sley check examples/hello.sley
sley run examples/hello.sley
sley graph examples/hello.sley

2. Task Inputs

module app.compute

task classify -> Text {
  take score: Int

  return if score >= 90 { "excellent" } else { "steady" }
}

task main -> Text {
  bind score = 40 + 55
  return classify(score)
}

take makes inputs visible as binding nodes. bind is the ordinary immutable local value.

3. State, Lists, And Loops

module app.collections

task sum -> Int {
  take values: List<Int>
  state index: Int = 0
  tally total: Int = 0

  while index < len(values) {
    total.add(values[index])
    index = index + 1
  }
  return total
}

task main -> Int {
  bind values = [2, 3, 5]
  if len(values) == 3 {
    return sum(values)
  } else {
    return 0
  }
}

4. Records And Slots

module app.profile

type User = form {
  slot id: Text
  slot name: Text
  slot email: Text
}

task display_name -> Text {
  take user: User

  return user.name
}

slot gives record and agent fields stable structural identity.

5. Gates And Tainted Input

module app.profile_load

effect DatabaseRead

task get_user -> Result<User, Error> uses DatabaseRead {
  take taint id: Text
  take gate db: DbRead

  bind clean_id = cleanse.user_id(id)
  bind row = call db.query_one("select * from users where id = ?", clean_id)?
  return Ok(User { id: row.text("id"), name: row.text("name"), email: row.text("email") })
}

taint marks untrusted input. gate marks concrete runtime authority. Neither is hidden inside a generic variable.

6. Forge Arenas

task summarize_page -> Summary {
  take page: HtmlPage

  forge {
    bind text = html.extract_text(page)
    bind facts = call facts.extract(text)
    witness checked = verify.no_secret_leak(facts)
    return Summary { facts: facts, proof: checked }
  }
}

A forge block is a temporary arena. It gives the Loom a clear cleanup and authority boundary for short-lived work.

7. Swarm Work

module app.maps_for

agent Crawler {
  port inbox: Job
  knot seen: Set<Url> with policy EventuallyConsistent

  absorb inbox {
    take job: Job
    spawn fetch(job.url)
  }
}

agent, port, knot, absorb, and spawn are Swarm words. Shared state is rare and loud.

8. The AI-Facing Workflow

  1. Parse .sley source into the canonical typed graph.
  2. Let an agent request a bounded graph shard, usually over ZJX.
  3. Let the agent submit a graft bundle.
  4. Run the graft through the Loom gate.
  5. Reject stale, malformed, type-invalid, or unauthorized edits.
  6. Emit a trace receipt and stable source projection for review.
sley graph src/app.sley --slice task:get_user --wire=zjx
sley graft patch.zjx
sley trace src/app.sley --wire=zjx
sley seal src/app.sley --out seal.zjx

ZJX is the native envelope for this Sley workflow. Read ZJX Documentation for the graph-shard and graft-transport boundary.


Read the full docs page