Skip to content

v0.2.2

Latest

Choose a tag to compare

@github-actions github-actions released this 15 Jul 12:49
3307bd7

Added

  • Human-in-the-loop (HIL) elicitation for APL. A policy can pause an operation to ask a human — manager approval, a confirm, a step-up re-auth, an attestation — and resume once the human responds, without blocking the request path. Sugar verbs (require_approval / confirm / require_step_up / require_attestation / request_info / require_review) desugar to one Step::Elicit, resolved by name to an ElicitationHandler plugin exactly like delegate(...). While the human hasn't answered, the phase suspends (Decision stays Allow with a pending bundle) and the host emits JSON-RPC -32120 so the agent retries by echoing the elicitation id; expiry, channel error, denial, or a failed validation fail closed (default on_error: deny). The approval is bound to the live request args via an APL scope: expression (args.amount <= 25000) the runtime checks at resolution — never an LLM summary. Ships a working Keycloak CIBA channel plugin (kind: elicitation/ciba, in cpex-builtins default features). See [Elicitation]({{< relref "/docs/apl/elicitation" >}}). (#115)

Changed

  • read_headers granted to every synthetic policy handler. The entity-less HTTP catch-all, per-entity routes (tool/prompt/resource), and defaults are now all granted the read_headers capability at install time, so http.* request attributes (http.method / http.path / http.host / http.scheme / http.request_headers.*) are available to policy evaluation wherever the host attaches an HttpExtension. Previously only the global HTTP catch-all had it, so a per-entity rule could not read the HTTP request line. This lets one policy combine http.* with entity/args.* predicates in a single evaluation (e.g. an MCP tool route that also gates on http.method). It is a no-op for hosts that never populate the HTTP extension — there is nothing to read — and http.host continues to be sourced from a validated request authority, never a raw client Host header. (#120)
  • APL order comparisons now coerce numeric-looking strings. numeric_compare parses string operands as f64 for order operators (>, >=, <, <=), so args.amount > 10000 fires when the arg arrives as the string "25000" — as LLM tool arguments routinely do. This affects all order comparisons in the engine, not just elicitation scope: bindings: a comparison that previously returned false because one side was a numeric string may now evaluate numerically. Equality (==) is unchanged, and genuinely non-numeric strings still don't order-compare (they yield false, per spec §2.3). (#115)