Skip to main content

as-engine

The spec-driven engine behind the *-as command-line tools (jira-as, confluence-as).

It reads Atlassian's published OpenAPI documents as Base Documents, applies Enrichment Entries (an OpenAPI Overlay in a small target subset) where the documents are silent or wrong, compiles the Enriched Spec into a compact operation index at build time, and interprets that index at runtime: a Generic Surface that can call any operation by its published name, tag-driven transforms (rich text, paging, prerequisite resolution), a guard that enforces project scope, and progressive-disclosure help. Products stay thin: they hold their Base Documents, overlays, Wrapper Verbs and configuration.

Status: bootstrap (JAS-32). The design is the spec on JAS-31 in the grand-camel-platform tracker; the decisions live on the wayfinder map JAS-6.

Index API

Products build their vendored OpenAPI documents with as_engine.build.compile_product(spec_dir, out_dir). The source directory contains manifest.json; each document entry records its source filename, declared API version (info.version), SHA-256, tier, overlay filenames, and explicitly stripped top-level extensions. The build writes deterministic <id>.index.json files and catalog.json. The supported input format is OpenAPI 3; local component references are resolved without network access.

Overlay targets support dot keys, quoted bracket keys, and nonnegative bracket indexes (including chained brackets). Updates merge objects and append arrays; removals delete the selected element. Targets must exist; add properties by updating their parent object. Filters, wildcards, recursive descent, slices, and copy actions are refused explicitly. Metadata on actions is preserved without enforcement; enrichment validation belongs to the product.

compile_document(document, overlays, normalizers=...) also accepts defect normalization callables, applied after overlays. No vendor defects are patched implicitly. JSON uses sorted keys, fixed separators and one trailing newline. The returned catalog is authoritative; packaging should include its listed indexes and catalog.json, not arbitrary older files in the output directory.

At runtime, load_index(path) returns an OperationIndex whose operations map holds Operation records. ProductIndexes(directory) loads catalog entries marked primary at construction; get(document_id) loads lower tiers on demand.

Discovery imports stay lightweight: importing the surface, output and help modules does not load requests, assistant_skills_lib or jsonschema. Transform implementations load when the registry is first used, and the HTTP stack loads when an HTTP transport is constructed. Table output keeps the shared formatter's simple-table and fallback behavior locally so discovery can render tables without loading the shared package's HTTP dependencies.

Development

Development prerequisites: pip install -e '.[dev]' includes hatchling and build; check local wheel and source builds with python -m build --no-isolation. For Base Document refreshes, install oasdiff 1.31.0: on macOS run curl --fail --location --retry 3 --output oasdiff.tar.gz https://github.com/oasdiff/oasdiff/releases/download/1.31.0/oasdiff_1.31.0_darwin_all.tar.gz; on Linux run curl --fail --location --retry 3 --output oasdiff.tar.gz https://github.com/oasdiff/oasdiff/releases/download/1.31.0/oasdiff_1.31.0_linux_amd64.tar.gz. Then run tar -xzf oasdiff.tar.gz oasdiff and chmod +x oasdiff, and place the binary on PATH (required by the refresh acceptance test), or set OASDIFF=/path/to/oasdiff for the refresh script.

pip install -e ".[dev]"
pytest
ruff check .

Releases are tagged v<version>; a published GitHub release builds the wheel, runs the downstream suites of confluence-as and jira-as against it, and only then publishes to PyPI. This package is never promoted on its own: a product's pinned build carries the core version it was released with (ADR 0013 in grand-camel-platform).

Generic Surface

Surface(ProductIndexes(directory), transport_factory) provides call, search, describe and topics. The factory receives (document_id, OperationIndex) and returns a transport implementing call(operation: Operation, parameters: Mapping[str, Any], body: Any) -> Response. Response carries status, body and headers. HTTP domain exceptions reuse assistant-skills-lib; the product can pass its existing HTTP error mapper. The surface converts failures to SurfaceError, including the operation note. It closes transports that provide close() after each call. A direct Python consumer can keep an HTTPTransport context open for pooled sequential calls.

Parameters are checked before the factory is called: required values, primitive and array/object types, enums and retained bounds. kebab_case maps canonical operation/parameter names to flags. Body fields are JSON-typed when parseable; --field 'spaceId="5"' therefore supplies a string while --field spaceId=5 supplies an integer. Files and stdin must contain JSON. Conflicting dotted paths are refused rather than overwritten. parse_call_flags accepts repeated arrays, JSON arrays or comma-separated arrays, explicit true/false, and --name=value. If a spec parameter collides with body, field, format, validate-body or help, its flag is prefixed --parameter-. Duplicate scalar flags are refused.

Bodies are checked only with validate_body=True or after a 400. The small checker supports local references, required/properties, additionalProperties:false, nullable, enums, primitive types, bounds, arrays and allOf/oneOf/anyOf. Unsupported validation keywords yield explicit diagnostics; format annotations are not assertions. It neither imports jsonschema nor fetches references. Validation reflects the indexed schema, including upstream defects such as overlapping oneOf branches. Schema repair belongs in a product overlay.

HTTPTransport serializes path/query/header/cookie parameters, pools requests, applies timeouts, and retries explicit 429 and all 5xx responses with exponential backoff and numeric/date Retry-After. It never retries a 409 or connection exception. Retries on mutation responses follow the existing product policy. JSON bodies retain their encoding; non-JSON multipart/form-data operations accept object fields with @path file parts. Binary-tagged operations stream to atomic files, return metadata, and allow one same-origin redirect; all cross-origin redirects are refused. Python consumers select destinations with Surface.call(..., output=path). Responder, cassette and simulation modes cover both encodings offline; see the binary and multipart contract. Surface.call(..., all_pages=True, limit=120) follows x-as-paging, returns its merged items array, and reports count=120 through the warning callback; one page is the default and the operation's parameters["limit"] remains page size. Prerequisite aliases resolve exact keys through the declared lookup; version tags inject current+1 or the draft override unless a version is supplied. Conflicting aliases/ids fail before lookup; 409 exits with conflict code 7 and never refreshes or retries. Responder.seed(operation_id, responses) queues copied bodies or Response objects and requests records calls; exhausted seeded queues fail. See transform hooks for the ordered, per-Surface registry and extension contract.

Responder(index, status=200, body=...) implements the identical call interface. An explicit body wins, including null; otherwise forced error statuses produce a message, and successes use a media/schema example or bounded deterministic schema generation. It does not persist state or infer a root from reachable schemas. Without an indexed 200 schema/example it returns null. Generated values are representative, not a guarantee that every arbitrary schema constraint is met.

SimulationStore and Simulation provide an opt-in, stateful transport double for product wrapper tests. It keeps a detached JSON snapshot, a shared copied call log, and only the explicitly documented Confluence operation semantics; unknown operations fail instead of reaching a responder or HTTP. See docs/simulation.md for its seed and CQL subset.

Search and topics visit primary indexes only. Search is case-insensitive over ID, summary, path, tags and x-as-note, with every supplied word required to match. Deprecated operations require include_deprecated=True. Naming a lower-tier operation loads that tier on demand. Describe returns a JSON-ready document (method/path, description, parameters, body outline, response schema and extensions) that describe_markdown renders. All x-as tags and vendor scope tags remain visible. x-as-deprecation/x-as-deprecated replacement metadata overrides the standard OpenAPI deprecated flag; x-as-topic accepts a topic string or list.

Additive index metadata

Old records load unchanged. New projections add fields only when source metadata exists: response_schema for an inline 200 schema (the original response_200 remains the named reference or null), response_example for a media example, deprecated, request_body_required, and request_media_types. Parameters retain explicit style/explode. The original requestBody representation is unchanged. These runtime additions require regenerating the product's packaged indexes through its build hook; there is no runtime Base Document fallback.

See exit codes for the machine-readable failure contract.

Progressive help is provided by as_engine.help: pure document builders for a product template, group/topic pages, operation details and existing enrichment examples, rendered consistently as Markdown or JSON. Descriptions support full=True; topic membership uses only x-as-topic, and x-as-risk is exposed for the product CLI's confirmation policy. See docs/help.md for the tag shapes, character-based token caps and golden regeneration command.

Rich-text tags now connect the shared converters to the Surface: tagged Markdown fields become storage or ADF, and tagged responses render as Markdown with lossless placeholders while retaining metadata. representation= chooses a declared write representation and raw=True returns stored response data; neither option changes vendor query parameters. build_body(..., operation=operation) preserves tagged Markdown fields and reads UTF-8 @file values. Date/duration tags use the scalar parser registry. See rich text for encoding, lookup isolation, CLI integration and the optional final-body validation contract.

Jira consumers can use exact OpenAPI parameter flags alongside kebab aliases. Paging also handles POST body continuation fields, optional token last-page signals, and decimal offsets whose published parameter schema is a string; the responder also decodes serialized JSON examples when the response schema declares a matching object or array. These additions preserve the existing Confluence call and paging contracts.

Release files for as-engine 0.1.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for as-engine 0.1.2
File Size Uploaded
as_engine-0.1.2.tar.gz 251.5 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for as-engine 0.1.2
File Interpreter ABI Platform
as_engine-0.1.2-py3-none-any.whl Python 3 none any Details

Total release size: 394.7 kB

Release files / as_engine-0.1.2.tar.gz

Download URL as_engine-0.1.2.tar.gz
Size 251.5 kB
Tags Source
SHA-256 checksum
How to use checksums
8788d8318cd5371dbbcdc54effef22650759acc7c6091054fca0021869fe5f92
BLAKE2b-256 checksum
How to use checksums
9928dd13835f88b42205d8ad9b16ffcd425c6b25a85bfead04177771ded33d1a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 25, 2026.

Transparency log

Release files / as_engine-0.1.2-py3-none-any.whl

Download URL as_engine-0.1.2-py3-none-any.whl
Size 143.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
ac4cb0b07effbecff812652a33aea54b036971e883d3fe349428c6d723d90d83
BLAKE2b-256 checksum
How to use checksums
9ced544ab9a6038e66dfea45cd6db097d05afc82f879fbdf28835e8de310e238
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 25, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.2 This release

2 release files

0.1.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page