Skip to content

v0.24.0

Choose a tag to compare

@github-actions github-actions released this 24 Jul 06:49
v0.24.0
c8b75cd

nr_llm 0.24.0 — Agent Runtime hardening

A focused hardening release for the Agent Runtime: identity and authorization, queue delivery idempotency, fail-closed tool enforcement, and encryption of queued/suspended state at rest — the invariants a consumer extension needs before running agents asynchronously in production.

⚠️ Breaking release. Several public interfaces changed signature. Out-of-tree consumers of the agent runtime, tools, guardrails, the conversation service or the specialized services must adapt — see Breaking changes below and the linked ADRs.

Security hardening

  • Agent-run identity & authorization (ADR-083 / 091 / 110) — every stateful agent entry point now carries an explicit AiActorContext instead of reading the ambient $GLOBALS['BE_USER'], and authorizes it fail-closed; a run/session UUID alone never suffices. Tools authorize against an explicit ToolExecutionContext resolved to the acting backend user, so a run authorizes identically synchronously and in a queue worker. Service accounts are limited to declared scopes and fail closed with none.
  • Queue delivery idempotency (ADR-111 / 112) — tools declare a ToolEffect (read-only / idempotent-write / non-idempotent-write). A writing tool's audit step is fail-closed, and a run reaped or failed mid non-idempotent-write is dead-lettered rather than retried — so an at-least-once retry never repeats a write that already ran.
  • Tool data-class enforcement, fail-closed & on by default (ADR-113 / 115) — the trust-zone tool gate observes only on an explicit observe; a missing, malformed or unreadable setting now enforces. New installs enforce by default; existing installs are pinned to observe by an upgrade wizard so the change does not silently strip tools from a working setup.
  • Agent run state encrypted at rest (ADR-114) — the queued request and suspended transcript in tx_nrllm_agentrun are encrypted via nr-vault's managed-key envelope encryption (rotatable master key, per-column AAD). Rows written before this landed still rehydrate (no data migration).

Breaking changes

  • Actor-context runtime surface (ADR-083) — AgentRuntimeInterface::approve(), submitInput(), cancel(), status(), events() take a required AiActorContext first parameter; ToolInterface::execute() takes a required ToolExecutionContext; AgentRunPersister::recordStep() now returns bool.
  • Conversation service (ADR-091) — ConversationServiceInterface::startSession() and send() take a leading AiActorContext; a session UUID alone no longer continues another user's conversation.
  • Per-configuration guardrail policies (ADR-106) — GuardrailInterface / InputGuardrailInterface gained getIdentifier() and isMandatory() via a shared GuardrailIdentity parent; an out-of-tree guardrail must implement both.
  • Specialized services through the shared pipeline (ADR-096 / 097 / 098) — AbstractSpecializedService gained required MiddlewarePipeline and InputGuardrailScreener constructor parameters; MiddlewarePipeline::run() / ProviderMiddlewareInterface::handle() drop the separate LlmConfiguration argument (it now travels on ProviderCallContext).
  • Rate-limit exception (ADR-095) — specialized services throw ServiceQuotaExceededException on HTTP 429 (a catch on the SpecializedServiceException base is unaffected).
  • Per-configuration tool gate in ToolLoopService (ADR-093) — every consumer of ToolLoopServiceInterface is now subject to the skills' allow-list ∩ allowed_tool_groups, not only the playground.
  • Runtime lifecycle service (ADR-101) — ToolPlaygroundController's constructor takes the runtime; AgentRunPersister::resumeHandle() returns ?AgentRunHandle; AgentRunRepositoryInterface gained maxEventSequence() and suspendRun() returns bool.
  • Schematx_nrllm_ai_session_message gains a UNIQUE key on (session, sequence) and tx_nrllm_ai_session a UNIQUE key on uuid; an installation with pre-existing colliding rows must dedupe before the database analyzer can apply the index.

Full changelog

This release also lands the queued agent-runtime work (ADR-092 … ADR-116) and the earlier retention/guardrail/specialized-pipeline changes. See the complete Added / Changed / Fixed breakdown in CHANGELOG.md → 0.24.0.

Merged PRs in this release: #492#518.

Merged pull requests

All pull requests in this release (#492#518)
  • chore(deps): update dependency sentence-transformers to v5.6.1 (#509)
  • fix(deps): update dependency netresearch/nr-vault to ^0.10.1 || ^0.11.0 || ^0.12.0 (#511)
  • docs(adr): central tooling authority — nr_llm owns builtin + MCP tools (#497)
  • chore(release): 0.24.0 (#518)
  • refactor(agent): encrypt agent state via nr-vault EncryptionService (P0 #4 follow-up) (#517)
  • feat(tool)!: enforce tool data-class gate by default for new installs (P0 #3, slice 3b) (#516)
  • feat(agent): encrypt queued and suspended agent-run state at rest (P0 #4) (#515)
  • fix(tool)!: fail-closed tool data-class enforcement switch (P0 #3, slice 3a) (#514)
  • feat(agent): queue delivery idempotency — tool effects + in-flight write fence (P0 #2) (#513)
  • feat(agent)!: gate service accounts by declared scopes, fail-closed (P0 #1, slice 1d) (#512)
  • refactor(agent)!: require an actor for run approve/submitInput/cancel/status/events (P0 #1, slice 1c) (#510)
  • refactor(tool)!: authorise tools from an explicit actor, not ambient BE_USER (P0 #1, slice 1b) (#508)
  • refactor(agent)!: carry the full AiActorContext through a queued run (P0 #1, slice 1a) (#507)
  • fix(agent): ownership-guard the terminal settle so a reclaimed run is never clobbered (#506)
  • fix(agent): heartbeat lease loss on MySQL no-op UPDATE + unbounded purge SELECT (#505)
  • docs(administration): add Agent Runs admin guide (#504)
  • build(phpstan): gate argument.type & varTag.nativeType on production code (#503)
  • fix(agent): fail-closed on a stale-run wake-up dispatch failure + release-readiness hardening (#502)
  • test(e2e): seed waiting runs to axe the Agent Runs approve/input forms (ADR-109) (#501)
  • test(e2e): axe accessibility coverage for the Agent Runs module (ADR-109) (#500)
  • feat(backend): Agent Runs approvals inbox (ADR-109) (#499)
  • feat(agent): typed ToolResult with run-only artifacts (ADR-108) (#498)
  • feat(agent): context-window management for the tool loop (ADR-107) (#496)
  • ci(pages): make the landing-page workflow a pure reusable caller (#495)
  • feat(guardrail): per-configuration guardrail policies (ADR-106) (#494)
  • feat(agent): typed user-input suspension — WAITING_FOR_INPUT (ADR-105) (#493)
  • ci(pages): delegate Pages deploy to shared reusable (#492)

Installation

composer require netresearch/nr-llm

Publication status

Security

All release artifacts are signed with Sigstore keyless signing.

Verify signatures

cosign verify-blob \
  --bundle nr-llm-0.24.0.zip.sigstore.json \
  --certificate-identity-regexp "https://github.com/netresearch/.*" \
  --certificate-oidc-issuer "https://token.actions.githubusercontent.com" \
  nr-llm-0.24.0.zip

Verify checksums

sha256sum -c checksums.txt

Software Bill of Materials (SBOM)

SBOMs are provided in both SPDX and CycloneDX formats for supply chain transparency.