Observed since 20 Oct, 18:15 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
A compact AI Command Language engine for safe LLM tool workflows
ACL Engine is a lightweight Python execution engine for AI-generated action scripts.
It parses a compact ACL syntax, validates each command, applies safety checks, executes allowed actions in order, and returns structured JSON output.
The repository also includes syntax.md, SPEC.md, and runnable ACL samples in examples/.
pip install acl-engine
PyPI installs include the Python package and the acl CLI.
If you are working from a repository checkout or source distribution, you also get:
syntax.md for a focused language guideSPEC.md for the formal execution contractexamples/For local development:
pip install -e ".[dev]"
ACL Engine supports:
@reason="debug"-> nameresult.stdout and items[0]ACL intentionally does not support loops, conditionals, or nested control flow.
@reason="basic variable workflow"
util.echo(value="Hello from ACL Engine") -> greeting
memory.store(key="message", value=greeting)
memory.get(key="message") -> result
Structured values and selectors are supported:
util.echo(value={message="hello", items=["a", "b"]}) -> payload
util.echo(value=payload.message) -> msg
util.echo(value=payload.items[1]) -> second
Integration-oriented workflows are supported without dropping into Python:
net.request(method="GET", url="https://example.com/api/user") -> response
data.select(value=response.json, path="user.id") -> user_id
data.template(template="user-{id}", values={id=user_id}) -> label
Structured JSON files are also first-class, so ACL can move data between APIs and files without manual serialization steps:
data.pick(value=response.json, keys=["user", "meta"]) -> payload
file.write_json(path="cache/user.json", value=payload)
file.read_json(path="cache/user.json") -> stored
from acl_engine import execute_acl
result = execute_acl(
'''
util.echo(value="hello") -> msg
util.echo(value=msg) -> copy
'''
)
print(result)
You can also create a reusable engine instance:
from acl_engine import ACLEngine
engine = ACLEngine(workspace="./workspace", timeout=30)
result = engine.execute('file.read(path="main.py") -> code')
.acl FilesRun an .acl file from the CLI:
acl --workspace ./workspace run path/to/workflow.acl
If you want to invoke the CLI through Python directly:
python -m cli.main --workspace ./workspace run path/to/workflow.acl
Run an .acl file from Python code:
from pathlib import Path
from acl_engine import ACLEngine
engine = ACLEngine(workspace="./workspace", timeout=30)
acl_text = Path("path/to/workflow.acl").read_text(encoding="utf-8")
result = engine.execute(acl_text)
print(result)
For quick experiments without a file, you can still run inline ACL:
acl --workspace ./workspace exec 'util.echo(value="hello") -> msg'
from acl_engine import ACLEngine
engine = ACLEngine()
def db_query(sql: str):
return {"sql": sql, "rows": []}
engine.register_action(
"db.query",
db_query,
{"sql": {"type": str, "min_length": 1}},
capabilities={"data"},
description="Run a SQL query",
returns="object",
)
result = engine.execute('db.query(sql="SELECT 1") -> output')
If you are using a repository checkout or source distribution, there are runnable ACL samples in examples/ for common tool-oriented workflows.
If you installed only the wheel from PyPI, use the inline CLI examples below or copy the ACL snippets from the repository documentation.
Run an ACL file:
acl --workspace ./workspace run examples/basic.acl
acl --workspace ./workspace run examples/file_roundtrip.acl
acl --workspace ./workspace run examples/json_pipeline.acl
Run with a stricter policy:
acl --workspace ./workspace --policy strict run examples/basic.acl
Run inline ACL:
acl --workspace ./workspace exec 'util.echo(value="hello") -> msg'
Validate ACL without executing it:
acl validate --inline 'util.echo(value="hello") -> msg'
Inspect the execution plan:
acl dry-run --inline 'util.echo(value={message="hello"}) -> payload'
List available actions and their schemas:
acl actions
Filter available actions for integration discovery:
acl actions --namespace data
acl actions --capability filesystem
Load custom actions from one or more plugin files:
acl --plugin ./plugins/example.py actions
Continue after an error instead of stopping on the first failed step:
acl --continue-on-error exec 'util.echo(value="ok") -> a
system.run(command="python", args=["-c", "print(1)"])
util.echo(value="still-runs") -> b'
Restrict execution to specific capability groups:
acl --allow-capability utility --allow-capability memory exec 'util.echo(value="hello") -> msg'
Allow only specific network domains:
acl --allow-domain example.com exec 'net.request(method="GET", url="https://example.com") -> response'
Use the dev policy only for trusted local workflows that need interpreter-backed process execution:
acl --workspace ./workspace run examples/system_ls.acl
acl --workspace ./workspace --policy dev run examples/dev_python_probe.acl
CLI output is JSON:
{
"acl_version": "1.0",
"output_version": "1.2",
"trace_id": "...",
"status": "success",
"data": {
"msg": "hello"
},
"logs": [
{
"step": 1,
"line": 1,
"action": "util.echo",
"raw_params": {
"value": "hello"
},
"resolved_params": {
"value": "hello"
},
"status": "success",
"duration_ms": 0,
"meta": {},
"result": "hello"
}
],
"summary": {
"policy": "standard",
"steps_total": 1,
"steps_completed": 1,
"steps_failed": 0,
"duration_ms": 0
},
"error": null
}
ACL Engine applies a small, strict safety model:
standard only allows ls in system.rundev allows python, node, and ls for local iterationrm, sudo, &&, and ; are blockedshell=Falsestandard is the recommended profile for AI-facing or hosted usage.
dev and custom plugins should be treated as trusted local-development features, not as a security sandbox for untrusted scripts.
Execution policy profiles are available:
standard — safer default profile for deployed or AI-facing usestrict — disables network access and file deletion, and reduces allowed system commandsdev — relaxed local profile that enables interpreter-driven toolingSafety checks run after variable resolution so indirection cannot bypass restrictions.
file.read(path)file.read_json(path)file.write(path, content)file.write_json(path, value, indent=2, sort_keys=false)file.append(path, content)file.list(path)file.delete(path)file.exists(path)file.stat(path)file.mkdir(path)file.copy(source, destination, overwrite=false)file.move(source, destination, overwrite=false)file.glob(path=".", pattern="*")system.run(command, args=[], cwd=None)net.request(method, url, headers=None, query=None, body=None, json_body=None)memory.store(key, value)memory.get(key)memory.delete(key)memory.list()memory.clear()data.from_json(value)data.to_json(value, indent=2, sort_keys=false)data.merge(left, right, deep=false)data.template(template, values)data.select(value, path)data.pick(value, keys)data.omit(value, keys)util.echo(value)util.sleep(seconds)util.now()util.uuid()util.hash(value, algorithm="sha256")util.base64_encode(value)util.base64_decode(value)acl_engine/
__init__.py
engine.py
parser.py
validator.py
executor.py
context.py
resolver.py
actions/
data.py
file.py
system.py
net.py
memory.py
util.py
registry.py
cli/
main.py
examples/
basic.acl
tests/
pytest
The project is intentionally small and focused. The current goal is a reliable Python package and CLI, not a general-purpose workflow language.
Download counts and popularity will appear here as the collector receives them.
| Version | Published | Direct dependencies | Open version |
|---|---|---|---|
| 0.1.0 | 11 Apr 2026 | 2 |
This describes our collected data; it is not a security assessment.
Observed since 20 Oct, 18:15 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
package:64cca58b875575fe7111d47d33493ea38a83135111c9ca04bd691d703c509f57