# ACL Syntax Guide

This document explains the ACL language itself: how commands are written, how values are shaped, and how variables move data between steps.

## Overview

ACL is a small sequential language for tool execution.

- One command per step
- Commands run in order
- Results can be assigned with `-> name`
- Later steps can reference earlier results
- No loops, branching, or nested control flow

Basic example:

```acl
util.echo(value="hello") -> msg
util.echo(value=msg) -> copy
```

## Command Shape

Every command uses this form:

```acl
namespace.action(param=value, other=value) -> result_name
```

Parts:

- `namespace.action` is the action name
- `(param=value, ...)` is the parameter block
- `-> result_name` is optional assignment

Action names must:

- be lowercase
- contain exactly one dot
- match `namespace.action`

Valid:

```acl
file.read(path="notes.txt")
data.select(value=payload, path="user.id")
```

Invalid:

```acl
File.read(path="notes.txt")
file.read.extra(path="notes.txt")
```

## Metadata

Metadata lines start with `@` and apply to the next command only.

```acl
@reason="inspect config"
@priority="high"
file.read(path="config.json") -> config
```

Rules:

- metadata must be on its own line
- metadata values are strings
- metadata must be followed by a command

## Values

ACL supports these value types.

### Strings

```acl
util.echo(value="hello")
```

Escape sequences inside strings:

- `\n` newline
- `\t` tab
- `\"` double quote
- `\\` backslash

### Triple-Quoted Strings

Use triple quotes when you want multiline content.

```acl
file.write(
    path="notes.txt",
    content="""line one
line two
line three"""
)
```

### Numbers

```acl
util.sleep(seconds=1)
util.sleep(seconds=0.5)
```

### Booleans and Null

```acl
util.echo(value=true)
util.echo(value=false)
util.echo(value=null)
util.echo(value=None)
```

### Lists

```acl
util.echo(value=["a", "b", 1, false]) -> items
```

### Objects

Objects accept either `=` or `:` between key and value.

```acl
util.echo(value={message="hello", count=1}) -> payload
util.echo(value={"message": "hello", "count": 1}) -> payload
```

## Variables

Assign a command result with `-> name`.

```acl
file.read(path="main.py") -> code
util.echo(value=code) -> copy
```

Bare identifiers in value positions are treated as variable references.

If a variable is missing, execution fails.

## Selectors

Variable references support field and index access.

### Field Selection

```acl
util.echo(value=payload.message)
util.echo(value=result.stdout)
```

### Index Selection

```acl
util.echo(value=items[0])
util.echo(value=payload.roles[1])
```

### Mixed Selectors

```acl
util.echo(value=response.json.user.name) -> name
util.echo(value=response.json.items[0].id) -> first_id
```

Bracket selectors can use:

- integer indexes like `[0]`
- string keys like `["user"]`
- identifier keys like `[user]`

## Multiline Parameters

Parameter blocks can span multiple lines.

```acl
file.write(
    path="report.txt",
    content="hello"
)
```

Whitespace inside the parentheses is ignored.

## Comments

Use `#` for comments.

```acl
# This is ignored
util.echo(value="hello") -> msg
```

Trailing comments after a command are also allowed.

```acl
util.echo(value="hello") -> msg # comment
```

## End-to-End Examples

### File Workflow

```acl
util.echo(value="hello world") -> content
file.write(path="output.txt", content=content)
file.read(path="output.txt") -> read_back
```

### JSON-Oriented Workflow

```acl
net.request(method="GET", url="https://example.com/user") -> response
data.pick(value=response.json, keys=["user", "meta"]) -> payload
file.write_json(path="user.json", value=payload)
file.read_json(path="user.json") -> stored
```

### Object and Selector Workflow

```acl
util.echo(value={message="hello", items=["a", "b"]}) -> payload
util.echo(value=payload.message) -> message
util.echo(value=payload.items[1]) -> second
```

## Validation Rules

Before execution, ACL Engine checks:

- the action exists
- required parameters are present
- unexpected parameters are rejected
- parameter types are valid
- referenced variables exist during validation and execution
- resolved values pass policy and safety checks

## Safety Notes

- File paths must stay inside the configured workspace.
- `standard` is the safer default profile.
- `dev` is the relaxed profile for local iteration.
- `strict` disables network access and file deletion and narrows process execution further.

For the full behavioral contract, see `SPEC.md`.
