This engine was developed in a private repository and is published here as a
single tree. The development record is in
engine/docs/findings/, dated and sequential.
Commit hashes cited in findings refer to that private development repository.
This repository is a reference implementation of consequence-tiered API governance: each operation is assigned a consequence class at design time, and a gateway enforces that class before the call reaches the backend. It ships generators for Kong, Apache APISIX, and Apigee, plus a conformance kit you can point at a running URL.
Specification: open-gw/ctier ·
doi.org/10.5281/zenodo.22020288.
The release this engine implements is named in
engine/docs/SPEC.md.
Kong and APISIX are clean against conformance-kit/1.1 at both Level 2 and
Level 3: zero failed rows, skips carry stated reasons, matrices in
engine/docs/kit/matrices.md.
- Apigee cases in this repository are would-run predictions. There is no organisation result file. Generated artefacts exist; they have not been executed against an Apigee org here.
- C12 is inconclusive on a bare unrouted
404. Without provisioning a path that is routed at the enforcement point and absent from the composition, the kit cannot tell an unrouted miss from a C12 miss. - Five criteria are not observable at a running URL (C4, C8, C13, C14,
C15). Witnesses can falsify; they do not verify. See
engine/docs/kit/observability.md.
A clean matrix is a claim about the cases in the kit. It is not a claim about the specification.
cd engine && pip install -e ".[dev,serve]" && cd ..
make demo # needs Docker; warns, then resets volumes, then ten beats on Kong and APISIXThat is one command. It prints a warning naming the ledger, pending reviews, and revocations it is about to destroy, then resets both compose projects (including volumes) so a second run matches the first, then walks ten beats on Kong and the same ten on APISIX. You do not need to know pytest.
python -m pytest -q (from engine/) is the offline suite — socket-blocked,
no Docker. CI runs it on every push. pytest --live -q needs a local Kong or
APISIX rig and is not run in CI.
Levels 0–4 are in the specification this engine implements
(engine/docs/SPEC.md). What this engine deploys:
| Level | This engine |
|---|---|
| 0 · Classify | Coverage report and review queue; nothing compiled into a gateway |
| 1 · Observe | Proxy config that classifies and emits a decision record; coverage warns |
| 2 · Enforce 1/2/4 | Proxy config and AS flags; no custody; coverage fails the build |
| 3 · Withhold | Custody; persist, approve, execute |
| 4 · Accumulate | Scope floor on Kong and APISIX |
Level 4 on the two live gateways is the same property with two encodings:
Kong's plugin module starts the poller; APISIX starts it lazily from
generated Lua. Both read ngx.shared.ctier_floors on the request path.
Apigee has no live runtime here. The dict size is Configured (1m);
memory-pressure behaviour of lua_shared_dict has never been Observed.
In the 16d exclusion form: a reader who finishes impressed and then discovers one of these has been misled by omission.
- Apigee is unverified. The bundle in
targets/apigee/package/generated/is generated from the same compile as the live targets. It has not been executed against an organisation in this repository.print()in that JavaScript is Trace, not a log sink. Precedence against a PreProxy FlowHook is untestable from the artefact. - Observed figures are samples on one machine; bounds are Derived. Beat 6
states the visibility bound as threshold-crossing plus one poll interval
(1000 ms, Derived). It does not treat the 216 ms Observed sample as the bound.
See
engine/docs/measurements.md. - Fragment mode (C11). Bundle mode owns the path and strips inbound
x-ctier-*first. Fragment mode does not guarantee that order against arbitrary existing configuration. Seeengine/docs/portability.md. - Level 2 (C7). This engine strips inbound idempotency keys and emits none. Derived keys are emitted when custody persists context (Level 3).
- What this engine does not make unavoidable. The live rig isolates
echo on an internal network. Custody calls the backend directly.
Fragment emit does not pin strip-before-read against arbitrary existing
configuration. The C10 sink is NOTICE on the error log;
error_log ... warndrops every record. Seeengine/docs/portability.md.
ctier also does not guarantee durability of [ctier-decision] gateway-log
lines (requirement 4). An operator without a collector has not recorded them.
Those lines are the claimed C10 sink. They land in the gateway error log
at NOTICE. An error_log of warn or above discards them. nginx
access.log is not that sink. Other error-log lines (ledger-POST
failures, the floor poller) are diagnostics; see
engine/docs/portability.md.
This engine implements the standard profile. It does not implement
constrained.
| Specification this engine implements | engine/docs/SPEC.md |
| Requirements | engine/docs/PRD.md |
| Solution design | engine/docs/SOLUTION-DESIGN.md |
| Decisions | engine/docs/adr/ |
| Still open | engine/docs/DECISIONS.md |
| Kit matrices | engine/docs/kit/matrices.md |
See CONTRIBUTING.md. Security reports go through SECURITY.md. A code of conduct is optional.
If you use ctier-engine or the model, please cite the archived specification:
@software{dhanaraj2026ctier,
author = {Dhanaraj, Rinu},
title = {{ctier}: Consequence-Tiered {API} Governance for Autonomous {AI} Agents},
year = {2026},
publisher = {Zenodo},
doi = {10.5281/zenodo.22020288},
url = {https://doi.org/10.5281/zenodo.22020288}
}See CITATION.cff. The preferred citation is the specification, not this
repository.
Engine source is licensed under the Apache License, Version 2.0. See
LICENSE, NOTICE, and LICENSING.md. Package metadata in
engine/pyproject.toml and SPDX headers on engine/ctier/ sources state the
same licence.
The published specification (including the copy under engine/ctier/spec/) is
CC BY 4.0 and grants no patent
licence. Subject matter described in both repositories is the subject of US
provisional patent application 64/137,066.