2.0.15 Release notes: Autonomous Application Runtime

New @hazeljs/autonomous — observe → decide → approve → execute for ordinary services. Default deny, Gatekeeper, HITL digests, dry-run replay. Not a second unrestricted agent loop.
Production backends already have ordinary @Injectable() services that react to domain events — failed carriers, stuck orders, remediations. Turning those into “autonomous” paths usually means bolting on a second agent loop, a DIY workflow engine, and hoping AuthZ still holds.
This release ships @hazeljs/autonomous — the Autonomous Application Runtime (AAR) — so services can observe → decide → approve → execute under the same Agent OS boundaries you already trust: default deny, Gatekeeper, HITL with argument digests, and dry-run replay.
Observation ≠ Decision ≠ Policy ≠ Authorization ≠ Execution
Why this release
Teams shipping Agent OS agents still had a gap for non-agent services:
- Wrap every ops path in
@Agent/@Tool(wrong abstraction), or - Assemble bus + rules + AuthZ + HITL + durability by hand (Nest-style DIY).
AAR is a control plane, not a second runtime. It reuses Gatekeeper, optional Decision Plane, durable run projection, and CLI timeline/replay — so “autonomous” never means unrestricted.
Merged as PR #40 on main.
What’s new
@hazeljs/autonomous (new package)
| Capability | API |
|---|---|
| Module bootstrap | AutonomousModule.forRoot() |
| Runtime | emit · resume · inspect · timeline · replay · diff · recover · listRuns |
| Modes | disabled → observe-only → suggest → approval-required → governed-auto |
| Decisions | Built-in rules engine; optional Decision Plane / custom engine |
| Authorization | Syncs capability grants into Gatekeeper policies (aar.capability.*) |
| Durability | MemoryAutonomousRunStore (local) · createAgentBackedRunStore (Agent DurableRunStore) |
| Safety | Loop protection, payload redaction, simulate() live-effect barrier, dry-run replay only |
| CLI | hazel add autonomous · hazel agent runs timeline | replay | diff |
Docs: Autonomous package · AAR guide · concept.
Core metadata (@hazeljs/core)
Decorators are metadata-only (no AI deps on core):
@Autonomous({ id, mode, capabilities, … })@Observe('event.type')/@Observe({ event, recordOnly })@Capability({ id, effect, approval, idempotencyKey, reconcile })
Irreversible capabilities without idempotencyKey or reconcile fail validation (HAZEL_AUTONOMOUS_RETRY_UNSAFE).
CLI (@hazeljs/cli)
hazel add autonomous [--setup]- Run helpers: timeline, dry-run replay, diff (alongside existing agent runs commands)
Minimal example
import { Injectable, Autonomous, Observe, Capability, HazelModule } from '@hazeljs/core';
import { AutonomousModule, AutonomousRuntime } from '@hazeljs/autonomous';
@Injectable()
@Autonomous({
id: 'order-operations',
mode: 'approval-required',
capabilities: ['shipping.switch'],
objective: 'Recover when primary carrier fails',
})
export class OrderOperationsService {
@Observe('carrier.failed')
onFailure(event: { orderId: string }) {
return event;
}
@Capability({
id: 'shipping.switch',
effect: 'idempotent',
approval: 'auto',
idempotencyKey: true,
})
switchCarrier(input: { orderId: string; candidate: string }) {
return this.shipping.switch(input);
}
}
@HazelModule({
imports: [AutonomousModule.forRoot()],
providers: [OrderOperationsService],
})
export class AppModule {}
// later
const [runId] = await runtime.emit('carrier.failed', { orderId: 'ORD-1' }, { tenantId: 't1' });
await runtime.resume(runId!, { approved: true, actor: 'ops' });
Install:
npm install @hazeljs/autonomous @hazeljs/core @hazeljs/agent-gatekeeper
# or
hazel add autonomous --setup
Reference example in-package: packages/autonomous/examples/autonomous-order-operations. Meridian Ops teaching API: POST /api/autonomous/carrier-failed (flagship app update).
Security model (non-negotiable)
A capability executes only when all hold server-side:
- Capability registered
- Service grants include the id (default deny)
- Gatekeeper allows (or approval consumed)
- Tenant from trusted resolver — never model/event payload alone
- Loop / budget barriers permit
- Simulation / dry-run barriers permit
Approvals bind capability id + argument digest. Tampered arguments invalidate the pending approval. Observation payloads are redacted before timeline persistence.
There is no permission-bypassing mode. Marketing “fully autonomous” means governed-auto inside grants + Gatekeeper.
What we are not claiming
- AAR is not a replacement for
@Agent/@ToolLLM loops - Not exactly-once for arbitrary external side effects
- Not roadmap
@AutonomousOptimization(HTTP self-tuning — separate, unimplemented) - Memory store is for tests/demos — use Agent DurableRunStore bridge in production
Upgrade path
- Install
@hazeljs/autonomous+ Gatekeeper peer; enableexperimentalDecorators. - Annotate an existing service with
@Autonomous/@Observe/@Capabilityand explicit grants. - Start in
observe-onlyorapproval-required; graduate togoverned-autoonly with Gatekeeper enforce. - Wire
resolveTenantIdfrom request/auth context. - Use
simulate()/ dry-run replay in CI; never live-replay side effects.
Existing Agent Runtime, Decision Runtime, Skillgate, and Gatekeeper paths are unchanged if you never import AAR.
Package versions
| Package | Notes |
|---|---|
@hazeljs/autonomous | New — Autonomous Application Runtime |
@hazeljs/core | @Autonomous / @Observe / @Capability metadata |
@hazeljs/cli | hazel add autonomous + runs helpers |
Align installs to the 2.0.15 line when publishing this tag (see GitHub release v2.0.15).
Links
- Autonomous package
- Autonomous Runtime guide
- Agent OS concept — AAR
- Agent Gatekeeper
- Decision Runtime
- Agent OS guide
- What is an Agent OS?
- 2.0.14 — AI call contract + governance
Agents propose. Services may act — only when grants and Gatekeeper say so.