diff --git a/README.md b/README.md index 78920e7..195f927 100644 --- a/README.md +++ b/README.md @@ -344,7 +344,7 @@ exhaustively at the top of [`lua_interop.lua`](lua_interop.lua). The flagship is **[`examples/openresty/`](examples/openresty/)** — a complete guestbook web app whose validation rules are written once in Shen and run on *both* ends: as a typechecked core on the server (shen-lua inside OpenResty) and -as a [Ratatoskr](https://github.com/pyrex41/ratatoskr)-shaken, +as a [Yggdrasil](https://github.com/pyrex41/yggdrasil)-shaken, [ShenScript](https://github.com/pyrex41/ShenScript)-compiled module in the browser. One `rules.shen`, two runtimes, no client/server drift. See its [README](examples/openresty/README.md) for the walkthrough. @@ -358,7 +358,7 @@ browser. One `rules.shen`, two runtimes, no client/server drift. See its | [`examples/policy/`](examples/policy/) | a typed **authorization** gateway: one rule set enforced at the OpenResty edge and previewed in the browser, plus authz-as-type-inhabitation — a permission *is* a proof ([README](examples/policy/README.md)) | | [`examples/crdt/`](examples/crdt/) | a **CRDT** sync hub: replicas converge via a typed join-semilattice merge whose laws are checked by execution *and* by machine-checked sequent-calculus proof ([README](examples/crdt/README.md)) | | [`examples/pcr/`](examples/pcr/) | **proof-carrying requests over live facts**: the client carries a proof term, the OpenResty gate *checks* it — never searches — against a versioned fact store consulted at proof time, so revoking one fact makes the same proof bytes fail on the next request while delegation chains stay composable and every allow logs its justification ([README](examples/pcr/README.md)) | -| [`examples/openresty/`](examples/openresty/) | a **complete web app in Shen on OpenResty** (nginx + LuaJIT): typed request validators + a Shen router behind a JSON API, with a front end that runs the **same** typed rules in the browser — Ratatoskr-shaken and ShenScript-compiled to a ~140 KB module. One `rules.shen`, validated client- and server-side. Runs standalone (`luajit examples/openresty/selftest.lua`) or under `openresty` ([README](examples/openresty/README.md)) | +| [`examples/openresty/`](examples/openresty/) | a **complete web app in Shen on OpenResty** (nginx + LuaJIT): typed request validators + a Shen router behind a JSON API, with a front end that runs the **same** typed rules in the browser — Yggdrasil-shaken and ShenScript-compiled to a ~140 KB module. One `rules.shen`, validated client- and server-side. Runs standalone (`luajit examples/openresty/selftest.lua`) or under `openresty` ([README](examples/openresty/README.md)) | | [`examples/openresty-authz/`](examples/openresty-authz/) | durable multi-tenant **authorization**: the policy as a Prolog proof chain (`token → user → tenant → resource`), a typed `decision` witness that gates every response, and an event-sourced store (file + `lua-resty-lmdb`) whose append-only log makes decisions durable and auditable ([README](examples/openresty-authz/README.md)) | | [`examples/envoy/`](examples/envoy/) | **Shen at the edge**: Envoy fronting both apps above — `ext_authz` runs every request through the authz proof chain (edge decisions durably audited), and an Envoy **Lua filter** runs the same typed `rules.shen` inside the proxy, so malformed requests get their typed 400 before costing an upstream hop ([README](examples/envoy/README.md)) | diff --git a/bin/ratatoskr-build.lua b/bin/yggdrasil-build.lua similarity index 94% rename from bin/ratatoskr-build.lua rename to bin/yggdrasil-build.lua index eb72132..70e1704 100644 --- a/bin/ratatoskr-build.lua +++ b/bin/yggdrasil-build.lua @@ -1,10 +1,10 @@ --- bin/ratatoskr-build.lua : Ratatoskr stage-2 builder for shen-lua. +-- bin/yggdrasil-build.lua : Yggdrasil stage-2 builder for shen-lua. -- --- luajit bin/ratatoskr-build.lua [--linked] +-- luajit bin/yggdrasil-build.lua [--linked] -- --- is a Ratatoskr stage-1 output directory: a tree-shaken +-- is a Yggdrasil stage-1 output directory: a tree-shaken -- kernel (kernel.kl, ShenOSKernel-41.2 defuns in load order), the user --- program as KL (one or more user= files), and ratatoskr.manifest.txt. +-- program as KL (one or more user= files), and yggdrasil.manifest.txt. -- The builder compiles every KL form ahead of time with the port's own -- compiler (compiler.lua C.compile_top) and emits ONE runnable Lua -- program : @@ -57,7 +57,7 @@ -- generated program needs no KDATA serialization/rebuild step. -- ---- locate the repo root from this script's own path --------------------- -local self = arg and arg[0] or "bin/ratatoskr-build.lua" +local self = arg and arg[0] or "bin/yggdrasil-build.lua" local root = self:match("^(.*)[/\\]bin[/\\][^/\\]+$") or "." if not root:match("^[/\\]") and not root:match("^%a:[/\\]") then -- absolutize so --linked outputs bake a path that works from any cwd @@ -71,7 +71,7 @@ if not root:match("^[/\\]") and not root:match("^%a:[/\\]") then end package.path = root .. "/?.lua;" .. package.path -local USAGE = "usage: luajit bin/ratatoskr-build.lua [--linked]\n" +local USAGE = "usage: luajit bin/yggdrasil-build.lua [--linked]\n" local shaken_dir, outpath, linked for i = 1, #arg do @@ -80,7 +80,7 @@ for i = 1, #arg do elseif a == "-h" or a == "--help" then io.write(USAGE); os.exit(0) elseif not shaken_dir then shaken_dir = a elseif not outpath then outpath = a - else io.stderr:write("ratatoskr-build: unexpected argument " .. a .. "\n" .. USAGE); os.exit(2) end + else io.stderr:write("yggdrasil-build: unexpected argument " .. a .. "\n" .. USAGE); os.exit(2) end end if not (shaken_dir and outpath) then io.stderr:write(USAGE); os.exit(2) @@ -95,7 +95,7 @@ local function read_file(path) end -- ---- 1. parse the manifest ------------------------------------------------- -local MANIFEST = shaken_dir .. "/ratatoskr.manifest.txt" +local MANIFEST = shaken_dir .. "/yggdrasil.manifest.txt" local man = { user = {}, primitive = {} } for line in read_file(MANIFEST):gmatch("[^\r\n]+") do local k, v = line:match("^([%w%-]+)=(.*)$") @@ -109,7 +109,7 @@ assert(man.kernel, MANIFEST .. ": missing kernel=") assert(man.init, MANIFEST .. ": missing init=") assert(#man.user > 0, MANIFEST .. ": no user= entries") if man["kernel-version"] ~= "41.2" then - io.stderr:write(("ratatoskr-build: warning: manifest kernel-version=%s, this port is certified against 41.2\n") + io.stderr:write(("yggdrasil-build: warning: manifest kernel-version=%s, this port is certified against 41.2\n") :format(tostring(man["kernel-version"]))) end @@ -137,7 +137,7 @@ local BOOT_GLOBALS = { local GUARDED_DEAD = { ["shen.write-string"]=true, ["shen.read-unit-string"]=true } for _, name in ipairs(man.primitive) do if not (P.F[name] or SPECIAL[name] or BOOT_GLOBALS[name] or GUARDED_DEAD[name]) then - io.stderr:write("ratatoskr-build: warning: manifest primitive not provided by this port: " + io.stderr:write("yggdrasil-build: warning: manifest primitive not provided by this port: " .. name .. "\n") end end @@ -161,7 +161,7 @@ end -- in the shaken output. Any such name found in the port's vendored certified -- 41.2 kernel (klambda/*.kl) is BACKFILLED into the kernel chunk — with a -- loud warning, because each backfill is a stage-1 shaker bug that should be --- fixed in ratatoskr.shen. Names found nowhere are warn-only (they may be +-- fixed in yggdrasil.shen. Names found nowhere are warn-only (they may be -- guarded-dead, like shen.write-string behind shen.char-stoutput?). -- Limitation (same one stage 1 has): only head-position references are -- traced; a function passed by bare name in argument position is invisible. @@ -239,7 +239,7 @@ do if not (defined[n] or P.F[n] or SPECIAL[n]) then local form = certified[n] if form then - io.stderr:write("[ratatoskr] STAGE-1 UNDER-SHAKE: " .. n + io.stderr:write("[yggdrasil] STAGE-1 UNDER-SHAKE: " .. n .. " is called but missing from " .. man.kernel .. "; backfilling from certified kernel\n") kernel_forms[#kernel_forms+1] = form @@ -258,7 +258,7 @@ do end end for _, n in ipairs(unresolved) do - io.stderr:write("ratatoskr-build: warning: " .. n + io.stderr:write("yggdrasil-build: warning: " .. n .. " is referenced but provided nowhere (may be guarded-dead)\n") end end @@ -304,11 +304,11 @@ local function compile_chunks(forms, label) return chunks end -io.stderr:write(("[ratatoskr] compiling %s: %d kernel forms\n"):format(man.kernel, #kernel_forms)) +io.stderr:write(("[yggdrasil] compiling %s: %d kernel forms\n"):format(man.kernel, #kernel_forms)) local kernel_chunks = compile_chunks(kernel_forms, man.kernel) local user_chunks = {} for _, uf in ipairs(user_files) do - io.stderr:write(("[ratatoskr] compiling %s: %d user forms\n"):format(uf.name, #uf.forms)) + io.stderr:write(("[yggdrasil] compiling %s: %d user forms\n"):format(uf.name, #uf.forms)) for _, ch in ipairs(compile_chunks(uf.forms, uf.name)) do user_chunks[#user_chunks+1] = ch end @@ -328,7 +328,7 @@ local out = {} local function emit(s) out[#out+1] = s end local jitv = rawget(_G, "jit") -emit(("-- %s : shaken Shen program (generated by bin/ratatoskr-build.lua)\n"):format( +emit(("-- %s : shaken Shen program (generated by bin/yggdrasil-build.lua)\n"):format( outpath:match("[^/\\]+$") or outpath)) emit(("-- source: %s (kernel-version=%s, %d kernel defuns/forms, user: %s)\n"):format( shaken_dir, tostring(man["kernel-version"]), #kernel_forms, table.concat(man.user, ", "))) @@ -349,7 +349,7 @@ local loadstr = loadstring or load for name, src in pairs(sources) do if package.loaded[name] == nil then package.preload[name] = function(...) - return assert(loadstr(src, "@ratatoskr/" .. name .. ".lua"))(...) + return assert(loadstr(src, "@yggdrasil/" .. name .. ".lua"))(...) end end end @@ -453,5 +453,5 @@ local fh = assert(io.open(outpath, "wb")) local blob = table.concat(out) fh:write(blob) fh:close() -io.stderr:write(("[ratatoskr] wrote %s (%d bytes, %d kernel + %d user chunks%s)\n") +io.stderr:write(("[yggdrasil] wrote %s (%d bytes, %d kernel + %d user chunks%s)\n") :format(outpath, #blob, #kernel_chunks, #user_chunks, linked and ", linked" or ", self-contained")) diff --git a/examples/README.md b/examples/README.md index 0629d20..c330775 100644 --- a/examples/README.md +++ b/examples/README.md @@ -13,7 +13,7 @@ has a `selftest.lua` that runs off-nginx): | [`policy/`](policy/) | a typed **authorization** gateway: one rule set enforced at the OpenResty edge and previewed in the browser, plus authz-as-type-inhabitation (a permission *is* a proof). `luajit examples/policy/selftest.lua` | | [`crdt/`](crdt/) | a **CRDT** sync hub: replicas converge via a typed join-semilattice merge whose laws are checked by execution *and* by machine-checked sequent-calculus proof. `luajit examples/crdt/selftest.lua` | | [`pcr/`](pcr/) | **proof-carrying requests over live facts**: the client attaches a proof term, the OpenResty gate *checks* it — never searches — against a versioned fact store consulted at proof time, so revoking one fact makes the same proof bytes fail on the next request while delegation chains stay composable and every allow logs its full justification. `luajit examples/pcr/selftest.lua` | -| [`openresty/`](openresty/) | a complete web app — typed Shen validators + a Shen router on OpenResty (nginx + LuaJIT), with a front end that runs the **same** rules in the browser (Ratatoskr-shaken, ShenScript-compiled). Runs standalone via `luajit examples/openresty/selftest.lua`; see [its README](openresty/README.md) to serve it. | +| [`openresty/`](openresty/) | a complete web app — typed Shen validators + a Shen router on OpenResty (nginx + LuaJIT), with a front end that runs the **same** rules in the browser (Yggdrasil-shaken, ShenScript-compiled). Runs standalone via `luajit examples/openresty/selftest.lua`; see [its README](openresty/README.md) to serve it. | | [`openresty-authz/`](openresty-authz/) | durable multi-tenant **authorization**: the policy as a Prolog proof chain (`token → user → tenant → resource`), a typed `decision` witness that gates every response, and an event-sourced store (file + `lua-resty-lmdb`) whose append-only log makes decisions durable and auditable. Runs standalone via `luajit examples/openresty-authz/selftest.lua`; see [its README](openresty-authz/README.md). | | [`envoy/`](envoy/) | **Shen at the edge**: Envoy in front of both apps above — its `ext_authz` filter sends every request through the authz app's proof chain (edge decisions land in the same durable audit log), and an Envoy **Lua filter** runs the guestbook's typed `rules.shen` *inside the proxy* (LuaJIT), rejecting malformed bodies at the edge with the origin's exact error strings. One typed rule file, four hosts. Runs standalone via `luajit examples/envoy/selftest.lua`; see [its README](envoy/README.md). | diff --git a/examples/envoy/README.md b/examples/envoy/README.md index 1f47645..c7c803f 100644 --- a/examples/envoy/README.md +++ b/examples/envoy/README.md @@ -19,7 +19,7 @@ integration seams for exactly what it is good at: costs an upstream hop. Which makes it one `rules.shen`, enforced on **four hosts** from one typed -source: the browser (ShenScript, Ratatoskr-shaken), the Envoy edge (shen-lua on +source: the browser (ShenScript, Yggdrasil-shaken), the Envoy edge (shen-lua on Envoy's LuaJIT), the origin (shen-lua on OpenResty), and plain `luajit` in the selftests. Proved sound by the sequent-calculus typechecker wherever shen-lua loads it. diff --git a/examples/openresty/README.md b/examples/openresty/README.md index 427fcbe..ce011fb 100644 --- a/examples/openresty/README.md +++ b/examples/openresty/README.md @@ -10,7 +10,7 @@ host, so the backend can literally be Shen with a thin Lua glue layer. The front end runs Shen too: the browser validates with a build of the **same** `rules.shen`, compiled to JavaScript by [ShenScript](https://github.com/pyrex41/ShenScript) and tree-shaken by -[Ratatoskr](https://github.com/pyrex41/ratatoskr), so the field rules are +[Yggdrasil](https://github.com/pyrex41/yggdrasil), so the field rules are checked client-side AND server-side from one source of truth. ``` @@ -152,7 +152,7 @@ network); only a client-valid entry is POSTed, where the server re-runs That client module is not the whole ShenScript kernel — it is a **tree-shaken build of `rules.shen`**: -1. [Ratatoskr](https://github.com/pyrex41/ratatoskr), a Shen tree-shaker, walks +1. [Yggdrasil](https://github.com/pyrex41/yggdrasil), a Shen tree-shaker, walks the kernel call graph and emits only the ~100 kernel functions these rules can reach. Because the rules never touch `eval`/`read`/`tc`, the reader, the macro expander, the typechecker and `eval` itself all fall away @@ -183,10 +183,10 @@ The committed `shen-rules.client.js` is generated; rerun the build whenever examples/openresty/scripts/build-client.sh ``` -It needs sibling checkouts of [Ratatoskr](https://github.com/pyrex41/ratatoskr) -(the `ratatoskr` binary) and [ShenScript](https://github.com/pyrex41/ShenScript), +It needs sibling checkouts of [Yggdrasil](https://github.com/pyrex41/yggdrasil) +(the `yggdrasil` binary) and [ShenScript](https://github.com/pyrex41/ShenScript), plus `luajit` (the shake host) and Node 20+. Override locations with -`$RATATOSKR` and `$SHENSCRIPT_DIR`. The script concatenates `rules.shen` + +`$YGGDRASIL` and `$SHENSCRIPT_DIR`. The script concatenates `rules.shen` + `scripts/client.glue.shen`, shakes the slice, and compiles it to the module. The running page is self-documenting too: a "What this demonstrates" panel with diff --git a/examples/openresty/public/index.html b/examples/openresty/public/index.html index c5d8a22..46758ee 100644 --- a/examples/openresty/public/index.html +++ b/examples/openresty/public/index.html @@ -3,11 +3,11 @@ examples/openresty/public/index.html — the guestbook front end. This page runs Shen IN THE BROWSER. It imports vendor/shen-rules.client.js — a - Ratatoskr-shaken, ShenScript-compiled build of the SAME rules.shen the server + Yggdrasil-shaken, ShenScript-compiled build of the SAME rules.shen the server loads — and runs validate-message client-side for instant feedback. The server then re-runs the identical rules as the authoritative check. - "Shaken" = tree-shaken: Ratatoskr (https://github.com/pyrex41/ratatoskr) walks + "Shaken" = tree-shaken: Yggdrasil (https://github.com/pyrex41/yggdrasil) walks the Shen kernel call graph and emits only the ~100 functions rules.shen can reach, so the client module is ~140 KB and inits in ~20 ms — versus the full ~660 KB ShenScript kernel bundle booting in ~2.3 s. The artifact is generated @@ -53,7 +53,7 @@

Guestbook — validated by Shen, on both ends

The field rules live in one file, rules.shen, and run - twice: in your browser (a Ratatoskr-shaken, + twice: in your browser (a Yggdrasil-shaken, ShenScript-compiled build of those rules) for instant feedback, and on the server (shen-lua under OpenResty) as the authoritative check. Sign the guestbook below — then see @@ -85,7 +85,7 @@

What this demonstrates

sequent-calculus typechecker proves every rule sound before the first request — a type error aborts boot.
  • Tree-shaken for fast loading. - Ratatoskr walks the + Yggdrasil walks the Shen kernel call graph and emits only the ~100 functions these rules can reach (eval, the reader and the typechecker fall away). The client module is ~140 KB and inits in tens of ms, versus the full ~660 KB @@ -101,7 +101,7 @@

    What this demonstrates

    Lua interop.
  • -BROWSER  — ShenScript (Shen → JS), tree-shaken by Ratatoskr
    +BROWSER  — ShenScript (Shen → JS), tree-shaken by Yggdrasil
        you fill the form
             │
             ▼
    @@ -161,7 +161,7 @@ 

    What this demonstrates

    const t0 = performance.now(); checkFields = await createValidator(); const ms = Math.round(performance.now() - t0); - setStatus(`Shen ready in the browser (${ms} ms) — a Ratatoskr-shaken ` + setStatus(`Shen ready in the browser (${ms} ms) — a Yggdrasil-shaken ` + `build of rules.shen, the same rules the server runs.`); $$("submit").disabled = false; } catch (e) { diff --git a/examples/openresty/public/vendor/shen-rules.client.js b/examples/openresty/public/vendor/shen-rules.client.js index 131d14c..21fb856 100644 --- a/examples/openresty/public/vendor/shen-rules.client.js +++ b/examples/openresty/public/vendor/shen-rules.client.js @@ -1,11 +1,11 @@ // GENERATED — do not edit. Built by examples/openresty/scripts/build-client.{sh,mjs} -// from rules.shen (+ client.glue.shen) via Ratatoskr (Shen tree-shaker) and +// from rules.shen (+ client.glue.shen) via Yggdrasil (Shen tree-shaker) and // ShenScript's compiler. Regenerate with: examples/openresty/scripts/build-client.sh // kernel defuns: 99; user: client-prog.kl; needs-eval: false // Self-contained: runtime.js + overrides.js are embedded; no imports, no checkout needed at runtime. // The KLambda runtime: everything compiled kernel/user code references on $, // with no compiler. This module deliberately has ZERO imports and a single -// default export so build tools (bin/ratatoskr-build.js) can embed its source +// default export so build tools (bin/yggdrasil-build.js) can embed its source // verbatim by replacing "export default" with a const declaration. // eval-kl raises unless a compiler layer (lib/backend.js) is attached. diff --git a/examples/openresty/scripts/build-client.mjs b/examples/openresty/scripts/build-client.mjs index 972abd3..8b38993 100644 --- a/examples/openresty/scripts/build-client.mjs +++ b/examples/openresty/scripts/build-client.mjs @@ -1,8 +1,8 @@ -// build-client.mjs — Ratatoskr stage-2 builder for the BROWSER. +// build-client.mjs — Yggdrasil stage-2 builder for the BROWSER. // // node build-client.mjs // -// Like ShenScript's own bin/ratatoskr-build.js, but instead of emitting a +// Like ShenScript's own bin/yggdrasil-build.js, but instead of emitting a // Node "run once and exit" program, it emits a browser ES module that // compiles the shaken kernel+user slice ahead of time and EXPORTS an async // `createValidator()` returning a plain (name, message) -> string[] function @@ -10,7 +10,7 @@ // so the output is self-contained and runs in any modern browser with no // ShenScript checkout and no npm install. // -// Normally invoked via build-client.sh, which runs the Ratatoskr shake first. +// Normally invoked via build-client.sh, which runs the Yggdrasil shake first. // Needs a ShenScript checkout (env SHENSCRIPT_DIR, default ../ShenScript next // to this repo) for the ahead-of-time compile step only. @@ -39,7 +39,7 @@ const { Arrow, Block, Call, Const, Id, Let, Program, Return, Statement, generate // ---- manifest ------------------------------------------------------------- const manifest = { user: [] }; -for (const line of fs.readFileSync(path.join(shakenDir, 'ratatoskr.manifest.txt'), 'utf-8').split('\n')) { +for (const line of fs.readFileSync(path.join(shakenDir, 'yggdrasil.manifest.txt'), 'utf-8').split('\n')) { const t = line.trim(); if (!t) continue; const eq = t.indexOf('='); if (eq < 0) continue; const k = t.slice(0, eq), v = t.slice(eq + 1); @@ -50,7 +50,7 @@ if (manifest['needs-eval'] === 'true') { process.exit(1); } -// ---- compile the slice ahead of time (same pipeline as bin/ratatoskr-build.js) +// ---- compile the slice ahead of time (same pipeline as bin/yggdrasil-build.js) const $ = backend(); const { assemble, construct, isArray, s } = $; const parseKl = file => parseFile(fs.readFileSync(path.join(shakenDir, file), 'utf-8')); @@ -79,7 +79,7 @@ const embed = (file, rename) => .replace(/^export (class|const)/gm, '$1'); const artifact = `// GENERATED — do not edit. Built by examples/openresty/scripts/build-client.{sh,mjs} -// from rules.shen (+ client.glue.shen) via Ratatoskr (Shen tree-shaker) and +// from rules.shen (+ client.glue.shen) via Yggdrasil (Shen tree-shaker) and // ShenScript's compiler. Regenerate with: examples/openresty/scripts/build-client.sh // kernel defuns: ${kernelForms.length}; user: ${manifest.user.join(', ')}; needs-eval: ${manifest['needs-eval']} // Self-contained: runtime.js + overrides.js are embedded; no imports, no checkout needed at runtime. diff --git a/examples/openresty/scripts/build-client.sh b/examples/openresty/scripts/build-client.sh index 9131cd7..177b735 100755 --- a/examples/openresty/scripts/build-client.sh +++ b/examples/openresty/scripts/build-client.sh @@ -3,7 +3,7 @@ # # Pipeline: # 1. concatenate rules.shen + client.glue.shen into one program -# 2. Ratatoskr (Shen tree-shaker) shakes it to a minimal KLambda slice +# 2. Yggdrasil (Shen tree-shaker) shakes it to a minimal KLambda slice # (~100 kernel defuns instead of the full ~2500), eval-stripped # 3. build-client.mjs compiles that slice with ShenScript's compiler and # emits public/vendor/shen-rules.client.js — a self-contained ES module @@ -13,7 +13,7 @@ # whenever rules.shen changes so the client and server can't drift. # # Requires (siblings of this repo, override via env): -# RATATOSKR the ratatoskr binary (default ../../ratatoskr/ratatoskr) +# YGGDRASIL the yggdrasil binary (default ../../yggdrasil/yggdrasil) # SHENSCRIPT_DIR a ShenScript checkout (default ../../ShenScript) # plus luajit (for the shen-lua shake host) and node 20+. set -euo pipefail @@ -22,11 +22,11 @@ here="$(cd "$(dirname "$0")" && pwd)" example="$(cd "$here/.." && pwd)" repo="$(cd "$example/../.." && pwd)" -RATATOSKR="${RATATOSKR:-$repo/../ratatoskr/ratatoskr}" +YGGDRASIL="${YGGDRASIL:-$repo/../yggdrasil/yggdrasil}" SHENSCRIPT_DIR="${SHENSCRIPT_DIR:-$repo/../ShenScript}" out="$example/public/vendor/shen-rules.client.js" -[ -x "$RATATOSKR" ] || { echo "ratatoskr not found/executable at $RATATOSKR (set RATATOSKR)"; exit 1; } +[ -x "$YGGDRASIL" ] || { echo "yggdrasil not found/executable at $YGGDRASIL (set YGGDRASIL)"; exit 1; } [ -d "$SHENSCRIPT_DIR" ] || { echo "ShenScript not found at $SHENSCRIPT_DIR (set SHENSCRIPT_DIR)"; exit 1; } tmp="$(mktemp -d)" @@ -36,7 +36,7 @@ trap 'rm -rf "$tmp"' EXIT cat "$example/rules.shen" "$here/client.glue.shen" > "$tmp/client-prog.shen" # 2. shake (host = shen-lua's launcher; shake output is host-independent) -"$RATATOSKR" shake "$tmp/client-prog.shen" "$tmp/slice" \ +"$YGGDRASIL" shake "$tmp/client-prog.shen" "$tmp/slice" \ --host "$repo/bin/shen" --eval-style positional # 3. compile the slice to a self-contained browser ES module