Skip to main content

CLI and toolkit to generate /.llm/ layers conformant to ENACTABLE/1.0 from OpenAPI/Swagger

Project description

enactable — CLI for ENACTABLE/1.0

Generate, validate and serve /.llm/ layers conformant to ENACTABLE/1.0 from an existing OpenAPI/Swagger specification.

The principle: a Swagger file describes how to call an API. ENACTABLE describes why an endpoint exists, which human intention triggers it, what effects it has, and how much autonomy to give an agent. This CLI infers the first layer automatically and guides you in completing what an LLM cannot deduce.


Installation

pip install enactable
# optional, for LLM-assisted generation:
pip install "enactable[all]"   # anthropic + openai + pyyaml

Requires Python >= 3.9. The only core dependency is pydantic.


The four commands

generate — from OpenAPI to a /.llm/ draft

enactable generate ./swagger.json -o ./.llm --app-id com.acme.app

Reads the OpenAPI spec (2.0 or 3.x, JSON or YAML), infers manifest, actions, forms, permissions and a context skeleton, and writes the files to the output directory.

With ANTHROPIC_API_KEY or OPENAI_API_KEY set in the environment it uses an LLM for richer intents and hints. Without a key, it falls back to a deterministic heuristic generator that infers from patterns (HTTP method, field naming): it always works, even offline.

--llm flag: auto (default), anthropic, openai, heuristic.

validate — check conformance and consistency

enactable validate ./.llm

Two levels of checks: schema conformance and cross-document consistency. It enforces the safety rules of the draft, including:

  • an irreversible action must require confirmation
  • an irreversible action cannot be autonomous
  • permissions cannot reference non-existent actions
  • forms cannot reference non-existent actions
  • write operations should declare their side_effects

It exits with a non-zero code if it finds errors, so it can be used in CI.

review — complete the non-inferable fields

enactable review ./.llm

Interactive wizard for what no LLM can deduce from the API: which fields must never be inferred (cannot_infer), the domain business rules, and a review of the proposed autonomy for each action.

serve — expose the layer over HTTP

enactable serve ./.llm -p 3000

Standard-library server (zero dependencies) that mounts:

  • GET /.llm/ → machine-readable index of the documents
  • GET /.llm/<doc>.json → the individual documents, with an X-Enactable-Version header and CORS

Typical workflow

enactable generate ./openapi.json -o ./.llm   # 1. automatic draft
enactable review ./.llm                        # 2. complete domain and safety
enactable validate ./.llm                      # 3. check conformance
enactable serve ./.llm                         # 4. expose the layer

Architecture

enactable/
├── core/
│   ├── models.py       # ENACTABLE schema as Pydantic models
│   ├── validator.py    # conformance + cross-document consistency + safety rules
│   └── serializer.py   # EnactableSpec <-> /.llm/ files
├── generator/
│   ├── parser.py       # OpenAPI 2.0 / 3.x -> internal representation
│   ├── llm.py          # LLM provider + deterministic heuristic fallback
│   ├── generator.py    # orchestration parser -> LLM -> EnactableSpec
│   └── prompts/        # prompts for actions, forms, permissions
├── cli/
│   ├── main.py         # argparse entry point
│   ├── output.py       # colored output (ANSI)
│   └── commands/       # command implementations
└── server/
    └── server.py       # HTTP server for the /.llm/ layer

The key design point: the generator is not required for correctness. It produces a draft; the validator is the authority on conformance. A hand-written spec passes through the same validator. Generator and framework have distinct roles.


What is inferable and what is not

Inferable from the API (automatic) Requires human input (review)
intent, side_effects, reversible domain business_rules
requires_confirmation cannot_infer (sensitive fields)
capabilities, auth.type final safety autonomy
forms with basic hints disambiguation on edge cases

The CLI is honest about this boundary: it generates everything deducible, flags the gaps explicitly, and does not pretend that safety decisions can be automated.


Created by Antonio Stassi · 2026 · Draft 1.0

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

enactable-1.0.0.tar.gz (21.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

enactable-1.0.0-py3-none-any.whl (24.7 kB view details)

Uploaded Python 3

File details

Details for the file enactable-1.0.0.tar.gz.

File metadata

  • Download URL: enactable-1.0.0.tar.gz
  • Upload date:
  • Size: 21.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.9.6

File hashes

Hashes for enactable-1.0.0.tar.gz
Algorithm Hash digest
SHA256 544adc19e0d29d17e11fec72d0f15b19b755f5b3ba1ba888cc1533032410b07b
MD5 9c688450d4b5514aaf4db465f478a20a
BLAKE2b-256 cbe104216b1808f89198b9cd287dc15e608d65c886546277ac6abe55a76d7812

See more details on using hashes here.

File details

Details for the file enactable-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: enactable-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 24.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.9.6

File hashes

Hashes for enactable-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 bffe9f8bb97249145d88cab5e876bd58d039093ddbcd0570d9ed64b5d4705fbb
MD5 846c517aa707405b71d234bfdf6e4a35
BLAKE2b-256 7b5cf24f2cf4fd34b7949483fd19c411f6075d5cd0ddc95e20c5f8bb0a76a2a2

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page