ACAgentic Craft

Intermediate~35 minHazelJS

Design an Agent Manifest

Capture HazelJS Agent DNA: exportAgentDna, bootstrapRuntimeFromDna, CLI hazel agent run, and a reviewable YAML/JSON manifest aligned with identity, skills, policy, and SLOs.

Authors
editorial-team
Published
Last reviewed

Before you start

  • A clear agent goal and @Tool / Skillgate inventory
  • Familiarity with budgets, approvals, and describeAgent basics

You will leave with

  • A versioned Agent DNA / manifest as a reviewable artifact
  • Use of exportAgentDna and bootstrapRuntimeFromDna / hazel agent run
  • Ownership, policy, and SLO fields you can operate against
On this page

Why manifests (Agent DNA)

Prompts scattered in code reviews do not scale. In HazelJS, Agent DNA is a portable snapshot (format: hazeljs.agent.dna) of what an agent is allowed to do: identity, system prompt, model preference, tool metadata, policies, and optional contracts/SLOs. Think “deployable contract,” not documentation cosplay.

DNA is configuration + contract, not a binary of your TypeScript handlers. Tool implementations stay in @Tool code (or Skillgate handlers). DNA tells the runtime which tools exist, which need approval, and which policies/prompts to apply.

Related: /glossary/agent-dna, /glossary/agent-os, /glossary/control-plane. Docs: Agent OS, Skillgate.

Export DNA from code

typescript
import {
  exportAgentDna,
  serializeDna,
  toMarketplacePackage,
  saveMarketplacePackage,
} from '@hazeljs/agent';
import fs from 'node:fs';

const dna = exportAgentDna({
  name: 'support-desk',
  description: 'Support desk agent',
  systemPrompt:
    'Use lookupOrder for facts. Use processRefund only after lookup and approval.',
  model: 'gpt-4o-mini',
  tools: [
    { name: 'lookupOrder', description: 'Look up order' },
    {
      name: 'processRefund',
      description: 'Process refund',
      requiresApproval: true,
    },
  ],
  policies: [
    {
      id: 'refund-hitl',
      tool: 'processRefund',
      effect: 'require_approval',
      priority: 20,
      reason: 'Refunds require human approval',
    },
  ],
  contracts: [
    {
      name: 'support-desk-slo',
      maxLatencyMs: 30_000,
      fallbackAgent: 'safe-desk',
    },
  ],
  version: '1.0.0',
});

fs.writeFileSync('./dna/support-desk.dna.json', serializeDna(dna));

const pkg = toMarketplacePackage(dna, {
  readme: 'Support desk agent',
  keywords: ['support', 'agent-os'],
});
saveMarketplacePackage(pkg, './dna/support-desk.marketplace.json');

Manifest outline (YAML aligned with DNA)

Use YAML or JSON—keep it reviewed in PRs. Fields below mirror DNA + operating metadata you should also track:

yaml
# Reviewable manifest — maps to hazeljs.agent.dna + ops metadata
id: support-desk
version: 1.4.0
format: hazeljs.agent.dna
status: active
owners:
  eng: platform-agents
  product: support
identity:
  name: support-desk
  description: Summarize orders and gate refunds
goal: >
  Answer order status from tools; never invent ids; refunds need HITL.
done:
  type: structured
  notes: Cite tool results; stop when answered
model: gpt-4o-mini
systemPrompt: |
  Use lookupOrder for facts. processRefund only after lookup and approval.
skills: # Skillgate-curated or @Tool names
  allow:
    - name: lookupOrder
      side_effect: read
    - name: processRefund
      side_effect: irreversible
      requiresApproval: true
  deny:
    - shell
    - sql_write
policy:
  - id: refund-hitl
    tool: processRefund
    effect: require_approval
    priority: 20
slos:
  - name: support-desk-slo
    maxLatencyMs: 30000
    fallbackAgent: safe-desk
budgets:
  maxSteps: 8
  loopMaxIterations: 4
  maxCostUsd: 0.25
memory:
  layers:
    working: ephemeral
    session: 7d
    long_term: disabled
evals:
  suite: describeAgent/support-desk
  gate: ci
observability:
  timeline: true
  inspector: true
kill_switch: feature_flag.support_desk

Bootstrap and CLI

hazel agent run uses bootstrapRuntimeFromDna—DNA + durable store + mock or OpenAI-compatible LLM:

bash
hazel agent doctor
hazel agent run ./dna/support-desk.dna.json "Status of ORD-1001?" --mock
hazel agent runs list --dir .hazel/runs
hazel agent logs --timeline .hazel/runs/timeline.jsonl

Note: CLI DNA runs may stub tool handlers. Use your app (npm run dev / registered @Tool instances) for real tool behavior. Hot-reload (hotReloadDna / installAgentPackage) updates prompt, model, metadata, and policies on an already registered agent; new TypeScript tool bodies still require a deploy.

Design rules

  1. Tools are the real permissions. If it is not in DNA tools[] / Skillgate allow-list, it does not exist for that agent.
  2. Budgets and SLOs are numbers (maxSteps, loop, contract.maxLatencyMs), not paragraphs in the system prompt.
  3. Policies are declarative (require_approval, deny, mask)—wire the same rules into PolicyEngine at runtime.
  4. Evals are part of the artifact. A DNA without a describeAgent suite is a sketch.
  5. Owners are mandatory. No owner, no production.
  6. Version bumps for tool allow-list changes, budget raises, policy changes, and model swaps.

Mapping to runtime

At deploy / sync time your app or store apply should:

  • Load DNA version
  • Configure tool registry / Skillgate from allowed skills
  • Enforce budgets, contracts, recovery, governance on execute
  • Attach eval suite id for CI and canaries
  • Honor kill switch

If the runtime can ignore DNA, you have comments—not control. See Agent OS and Skillgate.

Progressive disclosure

  • v1: reads only, tiny budgets, five describeAgent cases
  • v2: session memory with TTL
  • v3: gated write tool + require_approval + durableSuspend
  • v4: SQL durable runs + worker leases

Record each step next to the DNA version.

Review checklist

  • Goal and done condition clear
  • Side-effect / requiresApproval accurate
  • Deny list includes dangerous defaults (shell, unrestricted HTTP, raw SQL)
  • Policies and contracts match runtime wiring
  • Memory retention compatible with policy
  • Eval suite exists and gates merge
  • Kill switch tested
  • hazel agent run --mock smoke passes

Anti-patterns

  • Manifest that only stores the system prompt
  • “Allow all tools” for convenience
  • Secret values inline in DNA
  • Expecting DNA to create brand-new agent classes that were never registered
  • Copy-pasting DNA per environment without drift control / store lockfiles

Next

Sources

Continue learning