All posts
SeriesD2D Agentic Architecture· Part 2

Inside a D2D Agent: The Manifest, System Prompt, and Tool Contract

agentic-aid2dai-architecturesecurity-engineering
July 13, 2026 · PlayCISO

In the D2D overview we covered the coordinator, worker, and killer node model. Now let's get concrete: what do the actual files look like inside one of these agents?

The Three-File Pattern

Every D2D agent — whether coordinator or worker — is fully described by three artifacts. This is what makes D2D composable: you can swap out an agent's model, budget, or tool set by editing these files, without touching the orchestration layer.

1. manifest.yaml

name: cve-enrichment-worker
domain: vuln-management
model: claude-haiku-4-5
token_budget: 8000
heartbeat_interval_s: 30
max_retries: 2
tools:
  - nvd_lookup
  - epss_score
  - exploitdb_search
  - jira_create_ticket
output_schema: ./schemas/cve-enrichment-result.json
escalation:
  on_timeout: killer
  on_schema_fail: killer
  on_retry_exhausted: human

Key fields to notice:

  • domain — scopes this worker; the coordinator uses this to route tasks
  • token_budget — the killer node monitors this; if exceeded, the agent is terminated
  • output_schema — every worker output is validated against this before it's accepted by the coordinator
  • escalation — explicit rules: what goes to the killer, what goes to a human

2. system.md (the agent's system prompt)

# CVE Enrichment Worker

You are a specialist agent for enriching CVE data. You operate within the vuln-management domain.

## Your job
Given a CVE ID and an optional affected asset, you must:
1. Look up the CVE in NVD and return the CVSS score, vector, and description
2. Retrieve the EPSS score (probability of exploitation in the wild)
3. Search ExploitDB for any public exploit code
4. Create a Jira ticket if CVSS >= 8.0 AND EPSS >= 0.3

## Constraints
- You may ONLY call tools listed in your manifest. Never attempt to call unlisted tools.
- If NVD returns no result, emit status: "not_found" and stop.
- Do not infer or guess CVE details. Only use data returned by tools.
- Your output must conform to the output schema exactly.

## Output format
Return a single JSON object matching the schema at schemas/cve-enrichment-result.json.
Do not include any prose outside the JSON object.

The system prompt is deliberately narrow. A worker that can "infer or guess" is a liability — it will hallucinate CVE details under time pressure. The constraint is a safety property, not a limitation.

3. Tool definitions (tools.json)

{
  "nvd_lookup": {
    "description": "Query the NVD API for a CVE by ID",
    "input": { "cve_id": "string" },
    "output": { "cvss_score": "number", "cvss_vector": "string", "description": "string" },
    "endpoint": "https://services.nvd.nist.gov/rest/json/cves/2.0"
  },
  "epss_score": {
    "description": "Retrieve EPSS exploitation probability for a CVE",
    "input": { "cve_id": "string" },
    "output": { "epss": "number", "percentile": "number" },
    "endpoint": "https://api.first.org/data/v1/epss"
  }
}

Tool definitions are the trust boundary. The agent runtime enforces that the agent can only call tools declared here, with input shapes that match the schema. There is no ambient tool access.

The Coordinator's Routing Table

The coordinator keeps a routing table that maps incoming task types to worker domains:

routes:
  - task_type: enrich_cve
    domain: vuln-management
    worker: cve-enrichment-worker
  - task_type: query_siem
    domain: detection
    worker: siem-query-worker
  - task_type: notify_slack
    domain: comms
    worker: slack-notify-worker
  - task_type: human_review
    domain: null
    escalate: pagerduty

The Killer Node's Watch Loop

The killer node runs a simple watch loop against all active workers:

every 10s:
  for each active worker:
    if now - last_heartbeat > heartbeat_interval * 2:
      emit KILL(worker_id, reason="timeout")
    if worker.tokens_used > worker.token_budget:
      emit KILL(worker_id, reason="budget_exceeded")
    if worker.output_schema_failures > 2:
      emit KILL(worker_id, reason="schema_fail")

When a KILL is emitted, the coordinator decides whether to retry (up to max_retries) or escalate to a human. The worker's last known state — including any intermediate tool outputs — is preserved in the task log for post-mortem.

Why This Pattern Is Auditable

Every message in the system is structured and logged: task assignment, heartbeat, tool call, tool result, output, KILL signal. An incident investigator can reconstruct exactly what every agent did, why it did it, and what the coordinator decided at each step. That's the audit trail a CISO can actually show to a board.

Next in this series: how the coordinator handles mission planning and re-planning under partial failure.

Ready to practise the decisions these articles describe?

Run a free War Room →