Metadata-Version: 2.4
Name: runglet
Version: 0.4.1
Summary: Intent-oriented industrial control language and Relay IR toolchain
Author: Runglet contributors
License-Expression: MPL-2.0
Project-URL: Homepage, https://github.com/vedit/Runglet
Project-URL: Repository, https://github.com/vedit/Runglet
Project-URL: Documentation, https://github.com/vedit/Runglet/tree/master/docs
Project-URL: Issues, https://github.com/vedit/Runglet/issues
Project-URL: Changelog, https://github.com/vedit/Runglet/blob/master/CHANGELOG.md
Keywords: compiler,industrial-control,language-server,ladder-logic,plc
Classifier: Development Status :: 3 - Alpha
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Manufacturing
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Software Development :: Compilers
Classifier: Typing :: Typed
Requires-Python: >=3.12
Description-Content-Type: text/markdown
License-File: LICENSE
License-File: LICENSING.md
License-File: NOTICE
Requires-Dist: lark==1.3.1
Requires-Dist: lsprotocol==2025.0.0
Requires-Dist: pygls==2.1.1
Provides-Extra: dev
Requires-Dist: coverage==7.10.1; extra == "dev"
Requires-Dist: hypothesis==6.136.7; extra == "dev"
Requires-Dist: mypy==1.17.0; extra == "dev"
Requires-Dist: pyinstaller==6.21.0; extra == "dev"
Requires-Dist: pytest==8.4.1; extra == "dev"
Requires-Dist: pytest-cov==6.2.1; extra == "dev"
Requires-Dist: pytest-xdist==3.8.0; extra == "dev"
Requires-Dist: ruff==0.12.3; extra == "dev"
Dynamic: license-file

# Runglet

Runglet is a block-based, intent-oriented language for industrial control. It lowers into a typed, canonical Relay IR that can be interpreted, tested, and compiled for PLC targets.

The initial backend targets FATEK FBs controllers through WinProLadder 3.32. The initial physical verification target is an isolated FBs-20MCR2-AC test panel; no pressure vessel, oxygen-enriched environment, final chamber actuators, or human occupancy is in scope.

Runglet is alpha software. Its offline compiler and authoring workflow are usable, but
target-specific delivery remains evidence-gated and is not production-ready.

The current language specification is frozen at 0.19.0. It includes declarative writable
`MEMORY`, deterministic `MACHINE`, nominal fixed records/arrays/flags, bounded
traversal, explicit integer overflow and numeric conversion policies, and nominal
flags algebra with width-bounded bit-position traversal and transactional parameter
sets with schema, replay, integrity, retention, and atomic activation contracts;
generic ordered validation; pure total functions; and statically instantiated
components with typed/configuration/generic ports and private state, pure generic
functions, total fixed-array indexing, integer scaling, and exact periodic instance
activation with a typed compile-time sample period and held atomic results. It also includes explicit path-independent
source `UNIT`s, named public imports, deterministic offline project graphs, exact locked
local/vendored packages, and initial reviewed events/numeric source libraries.
Unsupported target shapes continue to fail closed. See the mechanical
[language freeze](docs/language/language-freeze.md).

## Install

Runglet requires Python 3.12 or later. For the isolated command-line application:

```shell
pipx install runglet
```

To install it into an existing Python environment:

```shell
python -m pip install runglet
```

Runglet, including its compiler, language specification, and VS Code extension,
is licensed under the
[Mozilla Public License 2.0](https://github.com/vedit/Runglet/blob/master/LICENSE).
User-authored Runglet programs and compiler-generated artifacts are not relicensed
merely because Runglet processes them; see the
[licensing policy](https://github.com/vedit/Runglet/blob/master/LICENSING.md) for the
precise scope and exceptions.

For Windows authoring without a Python installation, CI also produces a portable
`runglet-authoring-*-windows-*.zip`. It contains native launchers for both
`runglet.exe` and `runglet-lsp.exe`, their shared private runtime, and the matching
VS Code extension. Extract the complete archive, add its `bin` directory to the user
`PATH`, and install `vscode\runglet-vscode.vsix`. The executables launch directly and
do not use PowerShell. See
[`packaging/windows/README.md`](https://github.com/vedit/Runglet/blob/master/packaging/windows/README.md).

Tagged builds are available from
[GitHub Releases](https://github.com/vedit/Runglet/releases). Each `vVERSION` release
provides the Python wheel and source archive, the standalone Windows authoring ZIP, the
matching versioned VSIX, and `SHA256SUMS`.

## Installed package quick start

Create a checked, offline, single-file authoring workspace without a repository
checkout:

```shell
runglet init my-controller --name my_controller
cd my-controller
runglet authoring-context --profile core --format markdown
runglet format src/main.rung --check
runglet check src/main.rung
runglet resources src/main.rung --json
runglet suite src/main.rung --scan-period-ms 10
```

Common interactive aliases are `new` for `init`, `fmt` for `format`, `ctx` for
`authoring-context`, and `test` for `suite`. Run `runglet help --all` for the complete
tool catalog or `runglet help COMMAND` for focused usage.

Specialist tools use one namespace level: `runglet hil COMMAND`,
`runglet winpro COMMAND`, and `runglet fatek COMMAND`. Run each namespace with
`--help` to list its actions. The earlier flat `hil-*`, `winpro-*`, and `fatek-*`
spellings remain accepted as compatibility aliases but are omitted from help.

The scaffold includes `AGENTS.md` and `CLAUDE.md` entrypoints, portable Codex and Claude
skills, a machine-readable installed-version capability declaration, a canonical starter
with passing scenarios, and a hash-bound scaffold manifest. Initialization refuses to
merge or overwrite existing files. Its capability declaration explicitly distinguishes
sampled scan logic from unavailable sub-scan capture, motion, and certified-safety
contracts. It never contacts WinProLadder, a PLC, or the network.

An explicit multi-file project lists every source namespace rather than including or
concatenating files:

```toml
[project]
name = "plant-control"
version = "0.1.0"
language = "0.19.0"
root_program = "plant.main.controller"
source_roots = ["src"]

[sources]
"plant.main" = "src/main.rung"
"plant.types" = "src/types.rung"
```

Each listed file begins with a matching `UNIT` header. Run `runglet check runglet.toml`
to validate the complete public/private import graph and emit its deterministic graph
identity. Imports have no runtime, storage, scan-order, target-binding, or network
effect. See the normative
[project and import semantics](docs/semantics/project-and-import-semantics.md).
The language server uses the same project resolver for cross-file diagnostics,
completion, hover, definitions, references, workspace symbols, and safe rename.

Physical addresses and acquisition do not belong in `.rung`. Versioned target binding
manifests declare acquisition groups, directions, addresses, publication, and typed
safe/default values; see
[acquisition and physical bindings](docs/deployment/acquisition-and-physical-bindings.md).

Packages retain semantic imports—there is no textual `include`. Declare an explicit
manifest-relative path and version constraint, then lock the complete offline graph:

```toml
[dependencies]
"runglet.std.events" = { path = "vendor/runglet.std.events", version = "^0.4.0" }
```

```shell
runglet vendor runglet.std.events .
runglet lock .
runglet lock . --check
runglet check .
```

`runglet.lock` binds every transitive package version, manifest, public API, source, and
content hash. Dependency-bearing builds fail when it is missing or stale and never use
the network. `runglet vendor` copies reviewed `runglet.std.events` or
`runglet.std.numeric` sources without merging or overwriting. See the checked
[standard-library project](examples/projects/standard-library/README.md) and normative
[package and lock semantics](docs/semantics/package-and-lock-semantics.md).

## Development

Prerequisites:

- Python 3.12
- `uv`

Install the locked development environment:

```shell
uv sync --extra dev --locked
```

Run all local checks:

```shell
uv run ruff format --check .
uv run ruff check .
uv run mypy
uv run pytest -n 8 --dist load --cov -m "not slow_integration"
uv run pytest -n 0 -m slow_integration
```

For rapid full-suite feedback between coverage gates, run
`uv run pytest -n auto --dist load`.

Run the CLI:

```shell
uv run runglet --version
```

Start a productive offline authoring loop with the minimal example:

```shell
uv run runglet check examples/starter/starter.rung
uv run runglet format examples/starter/starter.rung --check
uv run runglet build examples/starter/starter.rung --output build/starter
uv run runglet resources examples/starter/starter.rung --json
uv run runglet suite examples/starter/starter.rung --scan-period-ms 10
```

`check` runs the same syntax, resolution, type, ownership, and command validation as
the language server without invoking a backend. `format --write` applies canonical
source layout. `build` adds Relay IR lowering and creates canonical source, Relay IR,
and a deterministic hash-bound manifest in a new directory. `resources` reports
portable logical state and worst-case abstract work while keeping unavailable target
register, instruction, and network counts explicit. See the
[diagnostics guide](https://github.com/vedit/Runglet/blob/master/docs/language/diagnostics.md)
for codes and exit behavior. The compact
[authoring card](https://github.com/vedit/Runglet/blob/master/docs/language/authoring-card.md)
and checked
[`examples/patterns`](https://github.com/vedit/Runglet/tree/master/examples/patterns)
are the preferred starting context for both
human and LLM-authored Runglet.

The checked writable-state pattern is
[`examples/patterns/core/writable-memory.rung`](https://github.com/vedit/Runglet/blob/master/examples/patterns/core/writable-memory.rung).
Bare `MEMORY` remains a self-holding declaration for v0.2 compatibility; add an
`UPDATE` block only under `SNAPSHOT_ATOMIC`.

Failed signal scenarios include the surrounding scan samples in `suite --json`, with
the sampled refresh flag, public signal age, and effective quality. This makes staged
`SET SIGNAL` timing and exact stale boundaries inspectable without changing runtime
semantics.

Machine-facing authoring interfaces are deterministic and offline:

```shell
uv run runglet inspect examples/starter/starter.rung --json
uv run runglet authoring-context --profile core --format markdown
```

The repository also contains an internal
[PLC-industry agent-authoring benchmark](https://github.com/vedit/Runglet/blob/master/benchmarks/agent-authoring/README.md).
It seeds a fresh `runglet init` repository for each task and grades the result with
evaluator-owned compiler and exact-scan oracles. It is not a public CLI command and
does not authorize vendor software, HIL, PLC, or network contact.

The Python environment also installs `runglet-lsp`. The internal contributor VSIX under
[`editors/vscode`](https://github.com/vedit/Runglet/tree/master/editors/vscode)
prefers that workspace `.venv`, but also carries a
version-locked Python runtime for ordinary non-repository folders. It never uses
PowerShell or installs global packages. The server supplies diagnostics, safe fixes,
formatting, symbols, hover, completion, and same-file navigation. Its bounded command
palette directly exposes saved-source `check`, backend-neutral `build`, embedded
scenario `suite`, and one-scenario `trace` tasks. Checked declaration snippets, server
status, semantic occurrence highlights, and matching-block navigation complete the
small single-file authoring loop. The extension does not expose target, WinPro, FATEK
runtime, or PLC commands.

The repository workspace explicitly associates `*.rung` with the `runglet` language.
After installing the VSIX, reload VS Code once. To verify the entire editor surface,
run **Tasks: Run Test Task** → **Runglet: Verify Editor Integration**, or use:

```shell
cd editors/vscode
npm ci
npm run verify
```

Build and smoke the same standalone Windows preview locally with:

```powershell
uv sync --extra dev --locked
cd editors/vscode
npm ci
cd ../..
uv run python scripts/windows/build-authoring-preview.py
```

The result is written below `dist/windows/`. The smoke test invokes the frozen CLI and
stdio language server themselves, including project initialization, checking,
inspection, scenarios, build output, UTF-16 LSP initialization, and clean shutdown.

That check covers the language association and assets, direct server/compiler
discovery, the offline compiler task, diagnostics, formatting, completion, hover,
definition, references and highlights, matching-block navigation, status reporting,
missing-server recovery, and post-start server crash recovery without contacting
WinPro or a PLC.

Generate the reviewable paired-FUN30 initial-delivery plan (no PLC download or run).
ADR-0007 selects this explicit native integer contract first; the generated binary32
implementation remains a portable follow-on and comparison oracle:

```shell
uv run runglet check fixtures/control/split-range-fun30-v0.2/controller.rung
uv run runglet format fixtures/control/split-range-fun30-v0.2/controller.rung --check
uv run runglet winpro fun30-plan \
  fixtures/control/split-range-fun30-v0.2/controller.rung \
  --profile profiles/fatek/fbs-20mcr2-ac.json \
  --allocation-policy profiles/fatek/fbs-20mcr2-ac-allocation.json \
  --config fixtures/control/split-range-fun30-v0.2/fun30-plan.json \
  --output build/fun30-plan
```

After filling a copy of `vendor-trace-template.json` from a WinPro simulator capture,
verify its plan identity, field contract, scan ordering, and first arithmetic divergence:

```shell
uv run runglet winpro fun30-verify-trace \
  fixtures/control/split-range-fun30-v0.2/controller.rung \
  build/fun30-vendor-capture.json \
  --profile profiles/fatek/fbs-20mcr2-ac.json \
  --allocation-policy profiles/fatek/fbs-20mcr2-ac-allocation.json \
  --config fixtures/control/split-range-fun30-v0.2/fun30-plan.json
```

The native fixture is a complete, canonical single-file program. `check` applies
resolution, integer type, ownership, and command-completeness validation; the plan
command repeats those checks before invoking the explicit target-native lowering path.
Generic `build` remains the backend-neutral Relay IR path and does not lower native
FUN30 declarations.

The emitted `parameters.json` records the mandatory native language contract, requested
and realized tuning for both directions, exact quantization errors, documented native
parameter ranges, and the ordered FUN30 PR table layout. `wrapper-relay-ir.json` is the
integer-only, executable Relay IR for compiler-owned direction, dwell, override, and
routing behavior; the vendor FUN30 outputs and error flags remain explicit boundaries.
`wrapper-differential.json` records stable-ID alignment across the independent oracle,
source Relay IR, and FATEK Network IR without claiming vendor timer execution.
`direction-project.ldr` is the evidence-bounded 64-record PID direction, parameter-table,
and paired-core artifact; its provenance explicitly excludes the remaining control and
routing wrapper. `vendor-trace-template.json` binds both native cores and their parameter
tables to ten required simulator cases per direction, with raw observations for all seven
private working registers; it remains `not_captured` until checked WinPro evidence is
supplied. `wrapper-emission-coverage.json` accounts for all 32 planned ladder network
IDs: the accepted artifact covers 17 of 29 source networks plus signed-error
materialization, while 12 source networks and two derived core-enable snapshots remain
as 26 staged control/routing steps. `evidence-manifest.json` binds all four source inputs
and twelve generated
artifacts by SHA-256. It records the four completed offline gates and leaves WinPro
lifecycle, vendor arithmetic/timer, simulator, review, and bench gates explicitly `not_verified`;
therefore the emitted candidate is not promotion-ready.
Exact native tuning and target configuration are currently supplied by the checked
`fun30-plan.json` contract, with tuning realization recorded in `parameters.json`;
binding those values to the portable source parameter-set contract remains native
backend work.

Run the complete bench-only demonstration suite with human-readable semantic coverage:

```shell
uv run runglet suite fixtures/demo-chamber-v0.1/demo.rung --scan-period-ms 10
```

Use `--json` for a canonical machine-readable scenario and coverage report. Run the
checked mutation campaign with:

```shell
uv run runglet mutate fixtures/demo-chamber-v0.1/demo.rung \
  --manifest fixtures/demo-chamber-v0.1/mutations.json \
  --scan-period-ms 10
```

The demonstration is an exact-scan reference-runtime proof over normalized Boolean
test points and dummy commands. It is not a production chamber program, safety
function, physical deployment authorization, or compliance argument.

For the isolated-bench workflow, validate the design and generate the unexecuted manual
checkout first:

```shell
uv run runglet hil bench-check hil/bench-panel-v0.1.json
uv run runglet hil checkout-plan hil/bench-panel-v0.1.json \
  --output build/hil/manual-io-checkout.json
```

After qualified assembly/review and local authorization, `runglet hil observe` can append
read-only status and X0-X6/Y0-Y3 samples under manual stimulus control. It exposes no
physical write option and does not authorize energization. See
[`docs/hil/read-only-recorder-v0.1.md`](https://github.com/vedit/Runglet/blob/master/docs/hil/read-only-recorder-v0.1.md).

Project architecture and milestones are documented in `IMPLEMENTATION_PLAN.md`,
`DESIGN_DECISIONS.md`, and `TASK_BREAKDOWN.md`. The current usable workflow and
ordered delivery gaps are summarized in
[`docs/language/readiness.md`](https://github.com/vedit/Runglet/blob/master/docs/language/readiness.md).
The dependency-ordered post-initial language, file/import, component, FATEK, and
library plan is in
[`docs/language/roadmap.md`](https://github.com/vedit/Runglet/blob/master/docs/language/roadmap.md).
For a clean Codex and WinProLadder move to another Windows machine, follow the
[`bare-metal Windows handoff`](https://github.com/vedit/Runglet/blob/master/docs/bare-metal-windows-handoff.md).
