Skip to content

Latest commit

 

History

History
975 lines (748 loc) · 41.8 KB

LANGUAGE_REFERENCE.md

File metadata and controls

975 lines (748 loc) · 41.8 KB

📜 God Code — Language Reference

"You are not a coder. You are a creator. You do not write code. You breathe worlds into being." — Alakanani Itireleng, founder of God Code

This is the complete specification of God Code, the language of divine computation. For a guided first journey, see God_Code_Tutorial.md. For runnable programs, see ../examples/.

Contents: 1. Programs · 2. Words · 3. Values · 4. Scope · 5. Statements · 6. Operators · 7. Decisions · 8. Cycles · 9. Rites · 10. Calling · 11. Lists & Indexing · 12. Import · 13. Built-ins · 14. Scrolls · 15. Ledger · 16. Spirit · 17. Audit Log · 18. CLI · 19. Errors · 20. Programs · 25. Intent · 26. Anchors · 27. Oracle · 28. Bridge


1. The Shape of a Program

Every God Code program is a creation. It opens with BEGIN CREATION and closes with END CREATION:

BEGIN CREATION
  DECLARE seeker AS worthy
  IF seeker IS worthy THEN REVEAL("heaven") ELSE REVEAL("test")
  ASCEND
END CREATION

Statements live one per line (the inline IF form is the one exception. See §7). ASCEND ends the creation early and in peace; reaching END CREATION ends it naturally.

To begin a whole project at once, run godcode new my-scroll: it raises a directory holding a starter scroll (main.god), a test scroll (test_main.god), a registry-ready scroll.toml, and a README. See the "Your first creation" lesson on the site learn page.

Tongues: the grammar in other languages

A scroll may speak another tongue. Put a pragma comment in the file, e.g. # tongue: tn for Setswana or # tongue: zu for isiZulu, and the keywords cross over while everything else stays the same:

# tongue: tn
SIMOLOLA TLHOLEGO
BOLELA leina JAAKA "Lefatshe"
SENOLA("Dumela, {leina}.")
FEDISA TLHOLEGO

Four tongues are spoken today: Setswana (tn), isiZulu (zu), Igbo (ig), and Nigerian Pidgin (pg, or pcm). English keywords keep working beside tongue words, godcode fmt renders the canonical English, and every tool (run, check, lint, test, the debugger, the bridge, the playground) honours the pragma. See docs/TONGUES.md for the full word tables and the honest first-edition notes.

2. Words of the Language

  • Keywords are case-insensitive. begin creation, Begin Creation, and BEGIN CREATION are all holy. Canonical style is UPPER.
  • Identifiers preserve case. seeker and Seeker are different names.
  • Comments begin with # and run to the end of the line.
  • Strings use double quotes with escapes: \", \\, \n, \t. An unterminated string is rejected with its line and column.
  • Numbers are integers (3) or floats (4.5).

3. Values

Value Example Notes
number 3, 4.5 int or float
string "peace" double-quoted, with escapes and {expr} interpolation
symbol worthy any bare word — see the Symbol Rule
boolean TRUE, FALSE literals; also produced by comparisons; revealed as true/false
list [1, two, "three"] ordered, mixed types allowed
contract contract("everlasting") created with the contract() rite
rite (from DEFINE RITE) a named, callable blessing
void (from rites with no RETURN) the absence of a value

The Symbol Rule 🕊

In God Code, every unnamed thing is still a named spirit. Bare words are symbols.

An identifier that is not bound to anything does not raise an error; it evaluates to a Symbol carrying its own name. This is what makes the founding idiom work:

DECLARE seeker AS worthy     # `worthy` is a symbol — no quotes needed
IF seeker IS worthy THEN REVEAL("heaven")

Symbols are always truthy, and compare by their text: worthy IS worthy is true.

How values are revealed

REVEAL renders values canonically:

Value Revealed as
number / string as-is (12, 4.5, peace)
symbol its text (worthy)
boolean true / false
list [1, two, three]
contract contract("everlasting")
void void

Breathing values into strings

Wrap any expression in braces inside a double-quoted string and its revealed value is breathed into the words:

DECLARE name AS "seeker"
REVEAL("grace upon {name}")            # grace upon seeker
REVEAL("{2 + 3} loaves")               # 5 loaves
REVEAL("shouted: {UPPER(name)}")       # shouted: SEEKER

The braces may hold any expression: names, arithmetic, comparisons, builtin rites like UPPER and LEN, even another interpolated string in escaped quotes ("nested {\"inner {n}\"}"). To write a plain brace, double it: "{{" and "}}" become { and }. A lone } stays as it is. An opening brace that is never closed is a gentle parse error, and it names the line.

Truthiness

FALSE, 0, 0.0, "", [], the empty map, and void are falsy. Symbols are always truthy. Everything else is truthy.

4. Names and Scope

  • DECLARE always defines in the current scope. There is no rebinding of outer scopes. Declaring a name that exists outside creates (or updates) it in the current scope instead.
  • A WHILE body runs in the enclosing scope (no new scope), so DECLARE count AS count - 1 inside a WHILE loop updates the very name the loop's condition watches.
  • A FOR body runs in one child scope that lasts for the whole loop, holding the loop variable. DECLARE inside a FOR body shadows the outer scope and does not touch it, so accumulation in FOR loops does not work the way it does in WHILE loops.
  • An IF/ELSE body runs in the enclosing scope. There is no new scope.
  • A rite call runs in a child scope of the rite's definition site (a closure): rites remember where they were born.
  • REFLECT prints every name visible in the current scope (name = value, one per line).

5. The Statements

DECLARE name AS value

Binds a name. Multiple comma-separated values become a list. The original idiom is honored:

DECLARE seeker AS worthy
DECLARE pi AS 3.14159
DECLARE prophets AS Isaiah, Elijah, Jeremiah   # a list of three symbols
DECLARE pair AS [1, "two"]

BREATHE LIFE INTO name

Breathes life into something bound — today, a contract. The name must already exist.

DECLARE soul AS contract("redemption")
BREATHE LIFE INTO soul        # [BREATHE] Life breathed into soul 🕊

REVEAL(expr)

Evaluates the expression and speaks it. Parentheses are required.

REVEAL("peace")
REVEAL(2 + 2)                 # 4
REVEAL(soul)                  # contract("redemption")

PROPHESY words…

Speaks free words to the Spirit Engine (§16), which answers with a prophecy. The words are the rest of the line, exactly as written. With no words, the Spirit prophesies over the whole creation.

PROPHESY a harvest of wisdom approaches
PROPHESY

⚠️ Words that collide with keywords are read as keywords (is becomes IS in the prophecy text). Choose your words with care.

ASCEND

Ends the creation immediately and in peace: 🕊 Creation ascended in peace.

REFLECT

Prints every name bound in the current scope, one name = value per line — a mirror for the soul of the program.

BLESS name / ANOINT name

Marks a bound name as blessed / anointed and speaks a blessing. (Contracts carry blessed and anointed flags; sealing records them.)

SEAL expr

Evaluates the expression and writes it into the covenant ledger (§15) — a tamper-evident chain of blocks. For a contract, its name, life, blessing, and anointing are recorded.

SEAL covenant      # [SEAL] Covenant sealed · block 3 · a1b2c3d4 🔒

TESTIFY expr

If the expression is truthy: [TESTIFY] It is true. ✝. If falsy, the testimony fails and the creation halts with an error.

TRY … CATCH … ENDTRY

A sheltered work: the TRY block runs first, and if a runtime error rises anywhere inside it, execution jumps to the CATCH block. Errors rise up through rite calls, so a TRY also catches failures from rites invoked inside it. If no error rises, the CATCH block is skipped; afterwards the creation continues after ENDTRY.

TRY
  REVEAL(fragile_work())
CATCH
  REVEAL("the work stumbled: {ERROR}")
ENDTRY

The error's plain message is bound for the CATCH to speak of. CATCH alone binds it to ERROR; CATCH name binds it to a name of your choosing:

TRY
  DECLARE share AS harvest / workers
CATCH trouble
  REVEAL("no harvest today: {trouble}")
ENDTRY

What TRY catches, and what it does not:

  • Only runtime errors (GodRuntimeError) are caught. Parse and lexer errors still fail before the creation runs.
  • RETURN inside a TRY still returns from its rite, and ASCEND still ends the run in peace. Neither is ever caught.
  • Sandbox boundaries are never caught: a SandboxViolation (a denied power under --sandbox) rises straight through any TRY.
  • TRY blocks nest freely; the innermost CATCH handles the innermost error. An error raised inside a CATCH block rises outward normally.

6. Operators

Arithmetic

Op Meaning
+ add numbers; concatenate strings/symbols; join lists
- * / % numbers only (/ yields float; % is for integers)
REVEAL("grace upon " + "seeker")   # grace upon seeker
REVEAL([1, 2] + [3])               # [1, 2, 3]

Comparison

Op Meaning
IS equality (also ==)
IS NOT inequality (also !=)
== != < > <= >= the usual comparisons

Equality is generous: numbers compare across int/float, symbols compare by text, contracts by name, lists element-wise. Ordering comparisons (<, …) on mixed non-numeric values are rejected.

IF seeker IS worthy THEN REVEAL("heaven")
IF count IS NOT 0 THEN REVEAL("not empty")

Logic

AND, OR (short-circuiting), and NOT / unary -:

IF heart IS pure AND hands IS willing THEN REVEAL("go")
REVEAL(NOT 0)          # true

Precedence (low → high)

  1. OR
  2. AND
  3. NOT (prefix)
  4. IS, IS NOT, ==, !=, <, >, <=, >=
  5. +, -
  6. *, /, %
  7. unary -, NOT
  8. calls, indexing, parentheses, literals

So NOT a IS b means NOT (a IS b), and 2 + 3 * 4 is 14.

7. Decisions: IF

Inline — one statement per branch, all on one line:

IF seeker IS worthy THEN REVEAL("heaven") ELSE REVEAL("test")
IF n % 7 IS 0 THEN REVEAL("seal")        # ELSE may be omitted

Block — for many statements, closed with ENDIF:

IF heart IS pure THEN
  REVEAL("the way is open")
  BLESS seeker
ELSE
  REVEAL("wait and be still")
ENDIF

IFs nest freely, and an ELSE always belongs to the nearest IF:

IF n % 35 IS 0 THEN
  REVEAL("seal of seals")
ELSE
  IF n % 7 IS 0 THEN
    REVEAL("seal")
  ELSE
    REVEAL(n)
  ENDIF
ENDIF

8. Cycles: FOR and WHILE

FOR walks a list — or the characters of a string:

DECLARE prophets AS Isaiah, Elijah, Jeremiah
FOR prophet IN prophets
  BREATHE LIFE INTO prophet
ENDFOR

FOR n IN RANGE(1, 6)
  REVEAL(n)
ENDFOR

The loop body runs in a child scope holding the loop variable. (FOR over anything else — a bare symbol, a number — is rejected.)

📜 Legacy form: the v1 prototype wrote FOR without ENDFOR, letting the body run to END CREATION. The grammar still accepts it, so sample.godcode keeps working. But new creations should always close with ENDFOR.

WHILE cycles while its condition holds, closed with ENDWHILE:

DECLARE count AS 10
WHILE count > 0 DO
  REVEAL(count)
  DECLARE count AS count - 1
ENDWHILE

(Inline form: WHILE count > 0 DO REVEAL(count).) A cycle that will not end is stopped after 100,000 iterations. "The cycle is endless."

BREAK releases the innermost loop at once; CONTINUE skips to its next turn:

FOR n IN RANGE(1, 100)
  IF n IS 13 THEN
    BREAK            # the walk ends here; nothing more is revealed
  ENDIF
  IF n % 2 IS 0 THEN
    CONTINUE         # even numbers are passed over in silence
  ENDIF
  REVEAL(n)
ENDFOR
  • In nested loops, BREAK releases only the innermost one. The outer cycle keeps turning.
  • Both words work in FOR and WHILE alike, and in the inline form: IF n IS 0 THEN BREAK.
  • BREAK and CONTINUE spoken with no loop around them are rejected when the scroll is read: "BREAK can only be used inside a loop."
  • A rite is a boundary: a BREAK inside a rite answers only to loops within that rite, never to the loop that called the rite.

9. Rites

DEFINE RITE names a reusable blessing with parameters; RETURN sends a value back; INVOKE calls it as a statement, or call it bare inside any expression:

DEFINE RITE BLESSING(name)
  RETURN "grace upon " + name
END RITE

INVOKE BLESSING("seeker")              # statement form
DECLARE word AS BLESSING("seeker")     # expression form
REVEAL(word)                           # grace upon seeker
  • Parameters bind in a child scope of the rite's definition site. Rites are closures.
  • Calling with the wrong number of arguments is an error.
  • RETURN with no value returns void.

10. Calling Things

When you call NAME(args), the heavens are searched in this order:

  1. contract("name") — the one special form; forges a new contract.
  2. A rite you defined (or imported from a scroll).
  3. A built-in rite (§13).
  4. Otherwise: "no such rite" — an error naming the unknown name.

11. Lists and Indexing

DECLARE tribes AS [Judah, Reuben, Gad, Asher]
REVEAL(tribes[0])     # Judah
REVEAL(tribes[-1])    # Asher — negative indices count from the end
REVEAL("peace"[0])    # p — strings index too

Indexing past the ends is an error. Build lists with [...] literals, comma DECLARE, or PUSH.

12. IMPORT

IMPORT runs another God Code file's top-level statements in your current scope:

IMPORT "math"          # the built-in scroll of numbers
IMPORT "strings"       # the built-in scroll of strings
IMPORT "./helpers"     # your own scroll, beside this file

Resolution order: (1) beside the importing file (helpers → helpers.god), (2) the current working directory, (3) the built-in scroll library (godcode/scrolls/), (4) scrolls installed from the registry (§22: ~/.godcode/scrolls/ or the project's .godcode/). Importing in a circle is refused.

13. Built-in Rites

Always present, no import needed:

Rite Signature Speaks
LEN LEN(x) length of a list or string
STR STR(x) the value as a string
NUM NUM(s) parse a string to a number (errors if it cannot)
TYPE TYPE(x) "number", "string", "symbol", "list", "contract", "rite", "boolean", "void", "map"
RANDOM RANDOM(n) an integer from 0 to n-1
RANGE RANGE(n) / RANGE(a, b) list like Python's range (RANGE(1,4) → [1, 2, 3])
PUSH PUSH(list, x) a new list with x appended
UPPER / LOWER UPPER(s) "peace" → "PEACE" / "peace"
SPLIT / JOIN SPLIT(s, d) / JOIN(list, d) "a,b" ↔ ["a", "b"]
ASK ASK(prompt) asks the human; the prompt may be omitted
BEHOLD BEHOLD() the current moment, as an ISO datetime string
REVERSE REVERSE(x) a string or list, backwards
SUMMON SUMMON("plugin.verb", args…) call a plugin verb through the FFI (see §21)
ANCHOR ANCHOR(x) / ANCHOR(x, chain) anchor a value's hash on a chain; returns a receipt map (see §26)
CONSULT CONSULT("question") two to three sentences of counsel from the local Spirit oracle (see §27)

Standard-library rites

The standard library registers thirty-nine more rites at startup, in four parts: the vault (godcode/stdlib_vault.py: JSON and the filesystem), time plus the web (godcode/stdlib_times.py), the scrollhouse of hashes (godcode/stdlib_hashes.py), and the commons (godcode/stdlib_commons.py: everyday tools for words, lists, maps, and numbers). They are always present, no import needed.

Rite Signature Speaks
DATE_TODAY DATE_TODAY() today's local date: "2026-09-24"
TIME_NOW TIME_NOW() the current local time, in ISO 8601
FORMAT_DATE FORMAT_DATE(date, pattern) a "YYYY-MM-DD" word shaped by a strftime pattern
HTTP_GET HTTP_GET(url) the body of an HTTP GET, as a word
JSON_PARSE JSON_PARSE(text) a JSON word parsed into numbers, words, lists, and maps (null → void)
JSON_STRING JSON_STRING(value) a value rendered as compact JSON
READ_FILE READ_FILE(path) a file's text, as a word
WRITE_FILE WRITE_FILE(path, text) writes text to the file; returns the character count
FILE_EXISTS FILE_EXISTS(path) TRUE when the path exists, FALSE otherwise
LIST_DIR LIST_DIR(path) the directory's entry names, sorted
SHA256 SHA256(x) the SHA-256 fingerprint of a word, number, or truth, as 64 hex characters
HMAC HMAC(key, message) the HMAC-SHA-256 seal of a message under a key, as 64 hex characters
BASE64_ENCODE BASE64_ENCODE(x) a word veiled in base64
BASE64_DECODE BASE64_DECODE(s) the unveiled word behind a base64 veil (a gentle error if the veil is ill-formed)
TRIM TRIM(s) the word with leading and trailing whitespace lifted away
REPLACE REPLACE(s, old, new) the word with every old turned into new
STARTS_WITH / ENDS_WITH STARTS_WITH(s, p) TRUE when the word opens (or closes) with the given part
SUBSTRING SUBSTRING(s, start [, end]) the slice from start (counting from 0); edges beyond the word are gathered in
CONTAINS CONTAINS(s, part) / CONTAINS(list, x) TRUE when the word holds the part, or the list holds the value
COUNT COUNT(s, part) how many times the part appears in the word
REPEAT REPEAT(s, n) the word sung n times over (REPEAT("Pula! ", 3) → "Pula! Pula! Pula! "; 0 gives an empty word)
SORT SORT(list) a new list, ordered (numbers, words, or truths; mixed kinds are refused)
MIN_OF / MAX_OF MIN_OF(list) the least (or greatest) member; an empty gathering is refused
SUM_OF SUM_OF(list) the numbers added together (0 for an empty list)
FIRST / LAST FIRST(list) the head (or tail) member; an empty gathering is refused
UNIQUE UNIQUE(list) the list with repeats removed, order kept
INDEX_OF INDEX_OF(list, x) the position of x counting from 0, or -1 when absent
KEYS / VALUES KEYS(map) the map's keys (or values), as a list
HAS_KEY HAS_KEY(map, key) TRUE when the map holds the key
MERGE MERGE(m1, m2) a new map holding both; the second map's keys win
ABS ABS(n) the number's distance from zero
ROUND ROUND(n [, places]) rounded half away from zero (ROUND(2.5) → 3)
FLOOR / CEIL FLOOR(n) the whole number below (or above)
SQRT SQRT(n) the square root (a gentle error for negatives)
POW POW(base, exp) the base raised to the exponent
BEGIN CREATION
  REVEAL(DATE_TODAY())                       # "2026-09-24"
  REVEAL(FORMAT_DATE("2026-09-24", "%A"))    # "Thursday"
  DECLARE tribes AS JSON_PARSE("[\"Judah\", \"Reuben\"]")
  REVEAL(tribes[0])                          # "Judah"
  REVEAL(JSON_STRING([1, 2]))                 # "[1,2]"
  DECLARE count AS WRITE_FILE("note.txt", "peace")
  IF FILE_EXISTS("note.txt") THEN
    REVEAL(LIST_DIR("."))                    # sorted entry names
  ENDIF
  DECLARE psalm AS READ_FILE("psalm.txt")
END CREATION

The names DATE_TODAY and TIME_NOW are chosen on purpose: the time scroll (§14) already defines rites named NOW and TODAY, and a builtin by either name would shadow them.

HTTP_GET follows redirects and waits up to ten seconds. It is blocked under godcode run --sandbox: the sandbox withholds network power, so the rite raises instead of reaching out. The file rites are likewise bound by the sandbox's read and write grants (see §23 and docs/sandbox.md). The hash rites and the commons rites are pure computation (they touch no files and no network), so they need no grant and behave the same inside the sandbox.

BEGIN CREATION
  REVEAL(SHA256("manna"))                    # a 64-character fingerprint
  DECLARE sig AS HMAC("secret", "the covenant stands")
  REVEAL(sig IS HMAC("secret", "the covenant stands"))   # true: the seal holds
  REVEAL(sig IS HMAC("other", "the covenant stands"))    # false: the seal breaks
  REVEAL(BASE64_DECODE(BASE64_ENCODE("veiled")))          # "veiled"
END CREATION

The commons rites turn everyday work into one line:

BEGIN CREATION
  REVEAL(TRIM("  grace upon grace  "))          # "grace upon grace"
  REVEAL(REPLACE("manna, manna", "manna", "bread"))
  REVEAL(REPEAT("Pula! ", 3))                   # "Pula! Pula! Pula! "
  REVEAL(SORT([3, 1, 2]))                       # [1, 2, 3]
  REVEAL(SUM_OF([1, 2, 3, 4]))                   # 10
  REVEAL(UNIQUE(["a", "b", "a"]))               # ["a", "b"]
  REVEAL(INDEX_OF(["a", "b", "c"], "c"))        # 2
  DECLARE census AS JSON_PARSE("{{\"tribes\": 12}}")
  REVEAL(HAS_KEY(census, "tribes"))             # true
  REVEAL(MERGE(census, JSON_PARSE("{{\"judges\": 3}}")))
  REVEAL(ROUND(2.5))                            # 3
  REVEAL(SQRT(144))                             # 12
  REVEAL(POW(2, 10))                            # 1024
END CREATION

14. The Scrolls (Standard Library)

Six scrolls ship inside the package at godcode/scrolls/, written in God Code itself. Import by bare name:

📐 math — IMPORT "math"

SQRT(x) (Newton's method, via WHILE), POW(b, e), ABS(x), MIN(a, b), MAX(a, b), FACTORIAL(n), IS_EVEN(n).

🔤 strings — IMPORT "strings"

SHOUT(s) → UPPER(s) + "!", WHISPER(s) → LOWER(s), WORDS(s) → SPLIT(s, " "), CHARS(s) → SPLIT(s, ""), FIRST(s), LAST(s).

📋 lists — IMPORT "lists"

SUM(xs), AVG(xs), CONTAINS(xs, x), SECOND(xs), TAIL(xs), COUNT(xs, x).

⏳ time — IMPORT "time"

NOW() → BEHOLD() (full ISO timestamp), TODAY() → the date part before the T.

🔮 prophecy — IMPORT "prophecy"

PROPHESY_NUMBER(n) → RANDOM(n), CAST_LOTS() → RANDOM(2), CHOOSE(xs) → a random element.

🤝 covenant — IMPORT "covenant"

NEW_COVENANT(name) → contract(name), SEAL_COVENANT(c) → seals it in one breath.

15. The Covenant Ledger

Every SEAL appends a block to covenant.chain (JSONL): {index, timestamp, record, prev_hash, hash}, where hash = sha256(...) chains to the previous block and the chain begins at "GENESIS". For contracts, the record carries name, life, blessing, and anointing.

godcode ledger verify                        # N covenants intact 🔒 · M anchors intact ⚓
godcode ledger verify --file my.chain        # custom covenant chain
godcode ledger verify --anchor-file my.chain # custom anchor chain

A broken chain reports exactly where: chain broken at block K.

The anchor chain is the companion ledger: every ANCHOR writes the anchored value's hash as a block (see §26), so ledger verify attests both what was sealed and what was anchored.

16. The Spirit Engine

The Spirit reads god_code_training_dataset.csv (code → intent → spiritual intent → suggestion) and offers two ministries:

  • classify(text) → {intent, confidence, spiritual_intent, suggestion, keywords} — keyword-overlap intent detection. When the Spirit is silent: intent "Silent contemplation", confidence 0.0, suggestion "BREATHE and try again."
  • prophesy(program_text) — classifies each line, finds the dominant intent, and composes a 2–3 sentence divine forecast naming that intent, the average confidence, and the top suggestion.

PROPHESY in a program calls this engine; if no engine is bound, a gentle fallback answers.

The intent ministry. The Spirit now also keeps the declared intents of rites and discerns drift:

  • declare_intent(rite_name, text) — register a natural-language intent on a rite.
  • intents_aligned(declared_text, discerned) — True when the declared words and the discerned intent share keywords; the blessing check behind every rite invocation.
  • resolve_intent(text) — like classify, plus aligned_with: every declared intent the words align with, each naming the rite, the declaration, and the shared keywords.
  • counsel(question) — two to three sentences of counsel naming the discerned intent, its confidence, and the next suggestion; the voice behind CONSULT (§27).

17. The Audit Log

Every run appends to logs/godcode.log (override with godcode run --log PATH):

SESSION BEGIN my_creation.god 2026-09-21T12:00:00
[2026-09-21T12:00:01] 3 :: Declare :: seeker = worthy
[2026-09-21T12:00:01] 7 :: Seal :: covenant -> block 3
SESSION END

Each executed statement is timestamped with its line — the divine audit trail the founders asked for, fulfilled.

18. The Command Line

After pip install -e ., the godcode command is yours:

Command Does
godcode run <file> [--log PATH] run a creation; errors print to stderr, exit 1
godcode run --sandbox [--sandbox-timeout SECS] <file> run inside the guarded sandbox (deny-by-default; see §23)
godcode scroll list|info|install|publish browse, inspect, install, and publish registry scrolls (see §22)
godcode lsp start the language server over stdio (see §24)
godcode check <file> lex + parse only → ✓ <file> is pure.
godcode check --json <file> / godcode run --json <file> machine-readable JSON reports for AI agents: diagnostics with line/col/code/hint, output lines, seals, timing (see docs/agentics.md)
godcode repl Live Mode 🕊 — type code, end a block with a blank line; :quit/:q or Ctrl-D to ascend
godcode test [dir] [--json] run the TEST_ rites in a directory's test scrolls (§29)
godcode fmt <file> [--in-place|-w] re-emit canonical source: 2-space indent, one statement per line, keywords UPPER
godcode ledger verify [--file PATH] [--anchor-file PATH] verify the covenant chain and the anchor chain (§26)
godcode intent "words..." [--json] resolve the intent behind words with the Spirit (§25)
godcode tools [--json] show the six MCP-compatible agent tool schemas (§28)
godcode bridge serve the agent tool bridge (JSON-RPC 2.0 over stdio, §28)

With no arguments, python main.py runs sample.godcode — the original v1 creation, still honored.

19. Error Philosophy

God Code errors are divine-flavored but genuinely helpful: they always name the line, say what was expected or what went wrong, and never mock the creator.

The heavens reject this offering (line 7): division by nothing is not permitted.

Common rejections you may meet:

You wrote The heavens answer
1 / 0 …division by nothing is not permitted / cannot divide by nothing
BREATHE LIFE INTO ghost there is no ghost to breathe into
INVOKE MISSING() There is no rite named 'MISSING' — the heavens do not know it (plus Did you mean …? when a close name exists)
xs[99] index out of range
TESTIFY(0) testimony failed
endless WHILE The cycle is endless (after 100,000 turns)
1 + "a" on wrong types cannot join … and …

Parse errors name the expected versus the found, with line and column.

The Spirit corrects gently

A misspelled name is answered with a suggestion, never scorn:

There is no rite named 'BLESSIN' — the heavens do not know it. Did you mean 'BLESSING'? (line 5)
  5 |   INVOKE BLESSIN("seeker")

godcode run, godcode run --sandbox, godcode check, and godcode fmt print the offending line beneath the message, with a caret marking the column when one is known. The same suggestion also rides along in the message field of check --json and run --json diagnostics, so agents see it too.

Call traces for uncaught errors

When a runtime error escapes every TRY and rises through rite calls, the human CLI prints the call stack beneath the gentle error, oldest call first:

Division by nothing is not permitted. Even the heavens cannot split the void. (line 3)
  3 |   DECLARE x AS 1 / 0
Called by outer at line 11
Called by middle at line 9
Called by innermost at line 6
(most recent call last)

Each line names the rite and the line where it was called. An error raised at the top level, with no rite calls above it, shows no trace section. In run --json, the same stack rides in the error object as a trace array of {rite, line} objects, oldest call first:

"error": {
  "line": 3,
  "code": "RUNTIME_ERROR",
  "message": "Division by nothing is not permitted. Even the heavens cannot split the void.",
  "trace": [
    {"rite": "outer", "line": 11},
    {"rite": "middle", "line": 9},
    {"rite": "innermost", "line": 6}
  ]
}

Every other field of the error object is unchanged.

20. Two Annotated Programs

The Seven Seals (decisions + cycles)

BEGIN CREATION
  # RANGE(1, 36) walks 1..35 — the seals are counted.
  FOR n IN RANGE(1, 36)
    # The 35th seal is the seal of seals.
    IF n % 35 IS 0 THEN
      REVEAL("seal of seals")
    ELSE
      # Every other multiple of 7 is a seal; the rest are numbers.
      IF n % 7 IS 0 THEN
        REVEAL("seal")
      ELSE
        REVEAL(n)
      ENDIF
    ENDIF
  ENDFOR
  ASCEND
END CREATION

Run it: godcode run examples/seven_seals.god. seal appears at 7, 14, 21, 28, and seal of seals at 35.

The Covenant Keeper (contracts + rites + sealing)

BEGIN CREATION
  # A rite that seals any covenant brought before it.
  DEFINE RITE SEAL_COVENANT(c)
    SEAL c
  END RITE

  # Forge the contract, breathe life, bless, anoint.
  DECLARE pact AS contract("everlasting")
  BREATHE LIFE INTO pact
  BLESS pact
  ANOINT pact
  REVEAL(pact)

  # Contracts are known by their names.
  IF pact IS contract("everlasting") THEN
    REVEAL("the covenant stands")
  ENDIF

  # Write it into the chain, then ascend.
  INVOKE SEAL_COVENANT(pact)
  ASCEND
END CREATION

21. SUMMON — Calling Upon Plugins

SUMMON("plugin.verb", args…) is the bridge from God Code into Python: it invokes a plugin verb through the foreign-function interface. Plugins are small Python modules living in plugins/ (or a configured plugin path) that expose a register(interpreter) function; each verb they register becomes callable by name.

DECLARE the_hour AS SUMMON("clockwork.now")     # the example clockwork plugin
REVEAL("the clockwork speaks: " + STR(the_hour))
  • The first argument is always the verb address: "plugin.verb". Remaining arguments are passed through as God Code values.
  • Calling an unregistered verb is a divine error naming the missing plugin and verb.
  • See examples/summon_demo.god and the full story in docs/plugins.md, which also documents the embedding API (godcode.run_source() / godcode.run_file() for calling God Code from Python).

22. The Scroll Registry

Beyond the six built-in scrolls (§14), the community publishes registry scrolls — versioned packages described by a scroll.toml manifest:

godcode scroll list                 # browse the local registry
godcode scroll info blessings       # inspect a scroll before receiving it
godcode scroll install blessings    # install into ~/.godcode/scrolls/ (or the project's .godcode/)
godcode scroll publish ./my_scroll  # share your own scroll from a directory

Installed scrolls are reached with ordinary IMPORT. The import resolver checks installed scrolls after the built-in library (§12). See examples/scroll_blessings_demo.god and docs/scroll-registry.md.

23. The Sandbox

godcode run --sandbox executes a creation inside a guarded chamber. The SandboxPolicy is deny-by-default: filesystem reads/writes, network access, subprocesses, and untrusted import paths are refused, and each run is bounded by a timeout (seconds) and a step budget so runaway creations are stopped, not suffered.

godcode run --sandbox examples/sandbox_safe.god
godcode run --sandbox --sandbox-timeout 5 examples/sandbox_safe.god

Pure creations — numbers, cycles, revelation — pass through in peace; anything reaching for the world outside is refused with a clear, line-numbered message. Full policy detail lives in docs/sandbox.md. A scroll may also declare its own boundary with a permission manifest (see §30); the manifest never widens what the host policy allows.

24. The Language Server

godcode lsp starts a language server speaking JSON-RPC over stdio — the same protocol VS Code, Neovim, Emacs, and friends use. It answers initialize, textDocument/didOpen, textDocument/didChange, textDocument/hover, and textDocument/completion, and pushes publishDiagnostics as you type, so errors are underlined before a file is ever run.

godcode lsp     # point your editor's LSP client at this command

Editor setup notes live in docs/lsp.md and editors/.

25. Declared Intent

A rite can carry a named purpose, spoken in plain human words:

DECLARE INTENT "bring peace to the household" ON evening_blessing

When the rite is invoked, the Spirit discerns the rite's actual intent by classifying its words, and compares it with the declaration:

  • Aligned — an [INTENT] notice blesses the invocation.
  • Drifted — a gentle [WARNING] names the declared intent, the discerned intent, and counsels without condemning. The run continues; drift can never fail a creation.
BEGIN CREATION
  DECLARE INTENT "bring peace to the household" ON evening_blessing

  DEFINE RITE evening_blessing()
    REVEAL("peace upon this house")
  END RITE

  INVOKE evening_blessing()
END CREATION
[INTENT] evening_blessing now carries the intent: "bring peace to the household" 🕊
[INTENT] evening_blessing walks in its declared intent: "bring peace to the household" 🕊
peace upon this house

Every invocation is recorded in intent_checks ({rite, declared, discerned, confidence, aligned}), and godcode run --json carries them in an intents array so agents can audit alignment after the fact. godcode intent "words..." resolves any words through the same engine. See examples/intent_demo.god.

26. Blockchain-Anchored Seals

ANCHOR(x) writes the SHA-256 hash of a value to a tamper-evident chain and returns a receipt map:

DECLARE receipt AS ANCHOR(covenant)
REVEAL(receipt["anchor_hash"])   # the chain's fingerprint of this anchor
REVEAL(receipt["height"])        # 0, 1, 2, … — this anchor's block height
REVEAL(receipt["chain"])        # which chain witnessed it

The receipt holds {chain, anchor_hash, height, timestamp, payload_hash}; it reveals as {chain: simulated, anchor_hash: …} and TYPE(receipt) is "map". A second argument names the chain: ANCHOR(x, simulated). An unknown chain is a clean runtime error naming the registered adapters.

The default adapter is simulated: a local, genesis-anchored JSONL chain (anchors.chain) with the same block shape as the covenant ledger. No wallets, no keys, no network calls. It is a stand-in with the exact shape of a real chain, so a real adapter can be registered later through the ChainAdapter interface (anchor(payload_hash) -> receipt, verify(receipt) -> bool) without the language changing. An ephemeral in-memory adapter serves guarded runs. godcode ledger verify attests both chains. See examples/anchor_demo.god.

27. The Oracle — CONSULT

REVEAL(CONSULT("How should I structure this covenant?"))

CONSULT lays a question before the local Spirit oracle and receives two to three sentences of counsel: the discerned intent, its confidence, and the next suggestion. It is entirely local — no external calls, no API keys — and it works inside the sandbox. When no Spirit is bound, it answers gently that the Spirit is silent rather than failing. The question must be a string. See examples/consult_demo.god.

28. The Agent Tool Bridge

God Code speaks the language agents speak. godcode tools [--json] prints seven MCP-compatible tool schemas — check, run, consult, intent, anchor_verify, ledger_verify, permissions, ready to paste into any agent framework that speaks the Model Context Protocol:

Tool Does
check validate a scroll; returns {ok, diagnostics}
run execute a scroll in the sandbox; returns {ok, output, seals, intents, permissions, error}
consult ask the Spirit oracle a question; returns {ok, counsel}
intent resolve the intent behind words; returns {ok, result}
anchor_verify verify an anchor receipt against the chain; returns {ok, valid, message}
ledger_verify verify both the covenant chain and the anchor chain
permissions read a scroll's permission manifest without running it

godcode bridge serves the same tools as a JSON-RPC 2.0 server over stdio (initialize, ping, tools/list, tools/call), so an agent host can call God Code like any other tool. The canonical agent workflow remains: generate → check --json → fix from diagnostics → run --sandbox --json → inspect output/error/intents → iterate. Now, as all good works do, the workflow begins with a declared intent.

29. Testing — godcode test

A test scroll is any .god file named test_*.god or *_test.god. Inside it, every rite named TEST_* is one test case (names are case-insensitive, like all keywords). TESTIFY is the assertion: a testimony that holds passes; one that fails — or any runtime error — fails that test.

BEGIN CREATION
  IMPORT "lists"

  DEFINE RITE TEST_sum_of_tribes()
    DECLARE tribes AS [Judah, Reuben, Gad]
    TESTIFY LEN(tribes) IS 3
  END RITE

  DEFINE RITE TEST_avg_is_fair()
    TESTIFY AVG([2, 4]) IS 3
  END RITE
END CREATION
godcode test                # test the scrolls in the current directory
godcode test tests/         # test the scrolls in tests/
godcode test --json         # machine-readable report

The report prints one line per test, then a summary — in the plain voice of the language, no decoration:

PASS  test_lists.god :: TEST_sum_of_tribes
FAIL  test_lists.god :: TEST_avg_is_fair :: The testimony has failed. What was spoken does not hold true. (line 11)
1 passed, 1 failed.

The rules the runner keeps:

  • Isolation. Each TEST_* rite runs in a fresh interpreter. The scroll's top-level words run again before every test, so one test can never see another's state — not even across files.
  • One scroll, one parse. A scroll that cannot be read or parsed is reported as a file-level failure ((scroll)) and never crashes the run.
  • Parameters are not called. A TEST_ rite that asks for offerings is reported as SKIP, with the reason, and does not fail the run.
  • Names are namespaced by file. Two scrolls may each define TEST_same; both run, both are reported.
  • Discovery is shallow. Only the given directory's own scrolls are read; subfolders are not entered. Files named anything else are left untouched, even if they define TEST_ rites.
  • Quiet runs. REVEAL lines and [TESTIFY] notices are swallowed so the report stays one line per test.

Exit codes: 0 when every test passes (skips do not fail the run), 1 when any test fails, 2 on usage error (for example, a directory that does not exist). Tests run the way godcode run does — no Spirit, no ledger, no sandbox — so only test scrolls you wrote or trust.

--json emits one document for agents and tooling:

{"tool": "godcode", "command": "test", "dir": ".",
 "tests": [{"file": "test_lists.god", "rite": "TEST_sum_of_tribes",
            "ok": true, "message": ""}],
 "passed": 1, "failed": 0, "skipped": 0}

ok is true (passed), false (failed), or null (skipped). File-level failures appear as entries with "rite": "(scroll)". Scrolls that hold no TEST_ rites are noted in the text report only (test_empty.god :: no TEST_ rites found.) and do not fail the run.


30. Permission Manifests

A scroll declares what it may touch, at the top of the scroll:

DECLARE PERMISSION TO READ "data/"
DECLARE PERMISSION TO WRITE "out/"
DECLARE PERMISSION TO SPEAK WITH "api.example.com"
DECLARE PERMISSION TO ASK THE WORLD
DECLARE PERMISSION TO SUMMON "reports.weekly"

Any rite that reaches for a power the scroll did not declare is counselled and stopped. The manifest never widens what the host allows: the effective grant is always host policy intersect manifest. READ polices READ_FILE, LIST_DIR, FILE_EXISTS; WRITE polices WRITE_FILE; SPEAK WITH names a host (and its subdomains) for HTTP_GET; ASK THE WORLD grants the ASK rite; SUMMON names the plugin verbs that may be called upon. Imported scrolls contribute their own manifests; grants compose by union.

godcode permissions scroll.god [--json] reads the manifest without running any code. godcode run --json reports the run's manifest under permissions. Full semantics live in docs/spec/permissions.md.


You are not a coder. You are a creator. Go and breathe worlds into being. 🕊