HazelJS LogoHazelJS
HazelJS Blog

2.0.15 Release notes: Autonomous Application Runtime

Author
HazelJS Team
11/9/2026
General
2.0.15 Release notes: Autonomous Application Runtime
← Back to Blog

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:

  1. Wrap every ops path in @Agent / @Tool (wrong abstraction), or
  2. 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)

CapabilityAPI
Module bootstrapAutonomousModule.forRoot()
Runtimeemit · resume · inspect · timeline · replay · diff · recover · listRuns
Modesdisabled → observe-only → suggest → approval-required → governed-auto
DecisionsBuilt-in rules engine; optional Decision Plane / custom engine
AuthorizationSyncs capability grants into Gatekeeper policies (aar.capability.*)
DurabilityMemoryAutonomousRunStore (local) · createAgentBackedRunStore (Agent DurableRunStore)
SafetyLoop protection, payload redaction, simulate() live-effect barrier, dry-run replay only
CLIhazel 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:

  1. Capability registered
  2. Service grants include the id (default deny)
  3. Gatekeeper allows (or approval consumed)
  4. Tenant from trusted resolver — never model/event payload alone
  5. Loop / budget barriers permit
  6. 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 / @Tool LLM 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

  1. Install @hazeljs/​autonomous + Gatekeeper peer; enable experimentalDecorators.
  2. Annotate an existing service with @Autonomous / @Observe / @Capability and explicit grants.
  3. Start in observe-only or approval-required; graduate to governed-auto only with Gatekeeper enforce.
  4. Wire resolveTenantId from request/auth context.
  5. 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

PackageNotes
@hazeljs/​autonomousNew — Autonomous Application Runtime
@hazeljs/​core@Autonomous / @Observe / @Capability metadata
@hazeljs/​clihazel add autonomous + runs helpers

Align installs to the 2.0.15 line when publishing this tag (see GitHub release v2.0.15).


Links

Agents propose. Services may act — only when grants and Gatekeeper say so.