Skip to content

xenomorphtech/lux

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

45 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Lux

Minimalist compiler targeting Erlang/BEAM with content-addressed function modules.

License

MIT. See LICENSE.

Run Example

This compiles one .core and one .beam per function (module names are hashes), and writes metadata for introspection.

cd /home/sdancer/lux
cargo run -- examples/fib.lux

Generated artifacts live under target/lux/ by default:

cat target/lux/artifacts/fib.meta.json

Run the compiled entry function (replace module hash if different):

erl -noshell -pa /home/sdancer/lux/target/lux/artifacts -eval "io:format(\"~p~n\", ['e8a56de9f0f836e0':apply()]), halt()."

Expected output for examples/fib.lux:

55

Set LUX_HOME to use a different workspace:

LUX_HOME=/tmp/lux-dev cargo run -- examples/fib.lux

Local Service

Start the local HTTP service:

cargo run -- --serve

Health check:

curl -sS http://127.0.0.1:4002/health

Publish code into a namespace:

curl -sS -X POST http://127.0.0.1:4002/publish \
  -H 'content-type: application/json' \
  --data '{"namespace":"dev","source":"fn fib(n) { if n <= 1 { n } else { fib(n - 1) + fib(n - 2) } }\nfn main() { fib(10) }"}'

Dry-run compile without publishing:

curl -sS -X POST http://127.0.0.1:4002/compile \
  -H 'content-type: application/json' \
  --data '{"source":"fn main() { 42 }"}'

Compile against an existing snapshot without publishing:

curl -sS -X POST http://127.0.0.1:4002/compile \
  -H 'content-type: application/json' \
  --data '{"snapshot_id":1,"source":"fn main() { fib(10) }"}'

Publish only selected symbols from a package:

curl -sS -X POST http://127.0.0.1:4002/publish \
  -H 'content-type: application/json' \
  --data '{"namespace":"dev","source":"fn helper() { 41 } fn main() { helper() + 1 }","symbols":["main/0"]}'

Create a snapshot:

curl -sS -X POST http://127.0.0.1:4002/snapshot \
  -H 'content-type: application/json' \
  --data '{"namespace":"dev"}'

Run published code from a snapshot:

curl -sS -X POST http://127.0.0.1:4002/run \
  -H 'content-type: application/json' \
  --data '{"snapshot_id":1,"target":"main/0"}'

Deploy a long-running instance from a snapshot:

curl -sS -X POST http://127.0.0.1:4002/deploy \
  -H 'content-type: application/json' \
  --data '{"snapshot_id":1,"target":"main/0"}'

List and inspect instances:

curl -sS http://127.0.0.1:4002/instances
curl -sS http://127.0.0.1:4002/instances/<instance_id>

Stop an instance:

curl -sS -X POST http://127.0.0.1:4002/instances/<instance_id>/stop

Evaluate an ephemeral snippet against a snapshot:

curl -sS -X POST http://127.0.0.1:4002/eval \
  -H 'content-type: application/json' \
  --data '{"snapshot_id":1,"source":"fn main() { fib(10) }"}'

Execution limits can be set per request:

curl -sS -X POST http://127.0.0.1:4002/eval \
  -H 'content-type: application/json' \
  --data '{"snapshot_id":1,"source":"fn main() { main() }","limits":{"timeout_ms":50}}'
curl -sS -X POST http://127.0.0.1:4002/eval \
  -H 'content-type: application/json' \
  --data '{"snapshot_id":1,"source":"fn main() { \"...large value...\" }","limits":{"output_limit_bytes":1024}}'

Inspect recent execution summaries:

curl -sS http://127.0.0.1:4002/executions

Inspect namespaces and frozen snapshots:

curl -sS http://127.0.0.1:4002/namespaces
curl -sS http://127.0.0.1:4002/namespaces/dev
curl -sS http://127.0.0.1:4002/snapshots/1

Diff two namespace generations:

curl -sS 'http://127.0.0.1:4002/namespaces/dev/diff?from=1&to=2'

Filter and page execution summaries:

curl -sS 'http://127.0.0.1:4002/executions?request_kind=eval&status=success&limit=10'

Prune old execution summaries:

curl -sS -X POST http://127.0.0.1:4002/executions/prune \
  -H 'content-type: application/json' \
  --data '{"finished_before_ms":9999999999999}'

POC REPL

Start the service first:

cargo run -- --serve

Use a different port:

cargo run -- --serve --port 4010

Then start the REPL client:

cargo run --bin repl

Point the REPL at a specific port:

cargo run --bin repl -- --port 4010

Minimal session:

:namespace repl
:snapshot-create
:paste
fn fib(n) { if n <= 1 { n } else { fib(n - 1) + fib(n - 2) } }
:end
:publish fib/1
fib(10)

The REPL is a thin client over the HTTP service. Bare lines are evaluated as expressions by wrapping them in fn main() { ... }.

Security Model

The intended security boundary for Lux is the language and type/capability system, not OS sandboxing.

  • No syscall / network isolation is intended as the primary enforcement mechanism.
  • No per-job OS sandboxing is intended as the primary enforcement mechanism.
  • The goal is to make unsafe APIs unavailable at compile time by not admitting them into the typed execution environment.
  • In other words, code should be unable to name or typecheck against capabilities that are not explicitly present in the environment.

This is meant to be a stronger and more principled model than relying on ad hoc runtime blocking. It should ultimately stand on the correctness of the language, type system, and capability surface, rather than on post hoc process restrictions.

Current runtime limits such as timeouts and output caps are still useful operational controls, but they are not the long-term security story.

About

a friendly language

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages