ASD '26
All Chapters

CHAPTER 04

The Role Contract, Evidence Registers & Deterministic Fact-Checking

Handoffs are artifacts, never chat

Reading time

13 min

The Law of Artifacts: Handoffs Are Never Chat

The first mistake most teams make with multiple agents is social. They assume more conversation means more intelligence. In practice, it usually means more compression. The Researcher paraphrases an interview. The Mapper paraphrases the paraphrase. The Critic then reviews a derivative story rather than the thing that actually happened. After three hops, the original evidence is gone. ASD forbids that pattern at the contract level. A role may explain itself in a host interface, but the durable handoff is always a typed artifact written through the store.

This matters because ASD is not a chat choreography layer sitting above a hidden database. It is one canonical practice contract and one runtime registry projected into twelve targets. The CLI, MCP server, coding-agent packs, BUZZ Persona Pack, and DeepSeek Harness Studio all touch the same underlying ideas: 10 roles, 80 shipped skills from 81 sources, 30 sd_* tools, 228 resources, 10 role prompts, 38 registered artifact-kind contracts, 39 vocabulary rows, 7 authored templates, and 12 emitted targets. The human-friendly artifact vocabulary lives in Appendix A. The command and tool surfaces live in Appendix B. In this chapter I stay on the write path itself.

The role contract is deliberately boring. That is a feature. A role runs a registered method, writes the method's declared output kind, and only then can another role consume it. If a handoff needs a condition, ASD records one. If a handoff names an artifact kind, that pointer must resolve inside the same project. No invisible context. No magical side channel. No "trust me, the previous agent covered it."

platform/_shared/role-contract.md
## 1. Handoffs are artifacts, not chat

1. Role A completes a registered method and writes its declared typed artifact.
2. The Orchestrator presents the gate and records the human decision through asd phase-advance.
3. Role B consumes the artifact; it never reconstructs the work from conversation.
4. Everything shown to a model must be reconstructable from the store.
5. Parallel work is explicit; writes still serialize through the project store.

Once I adopt that rule, the rest of the platform gets sharper. The Researcher does not hand the Mapper a speech about what riders felt. The Researcher hands over an insight-set or a journey-map draft with evidence pointers that can be inspected, reviewed, vetoed, replayed, and exported. The Orchestrator does not quietly decide that the team is ready for the next phase. The Orchestrator prepares the gate record, then a human authorizes it with an approval receipt. Even the Critic does not shout into the void. It writes rows.

My take: The artifact rule feels heavy for about three days. Then a stakeholder asks why a recommendation exists, I open the store, and the answer is sitting there as evidence IDs, artifact JSON, review rows, and a gate receipt. That is when the weight starts to feel like relief.
Question Chat-native answer ASD answer
What does one role hand to the next? A summary in prose. A typed artifact plus resolvable evidence references.
How do I know what the model actually saw? I usually cannot prove it. The store, log, artifact, and evidence must tell the same story.
How does parallel work stay coherent? Thread memory and goodwill. Explicit orchestration plus a single serialized write path.
How is a gate crossed? Someone says we are done. A human records an approval receipt through asd phase-advance.

Evidence Registers and Content Addressing

The artifact rule only works because artifacts do not float free. They stand on a register, and the register is closed. ASD allows exactly three evidence kinds: quote, telemetry, and document. That small vocabulary does more work than a bloated ontology ever could. Quotes preserve verbatim human voice. Telemetry preserves measured operational facts. Documents preserve written institutional context: field notes, rosters, policies, notices, screenshots captured into prose, and the dull paperwork that usually kills overconfident ideas.

Each evidence row is content-addressed. The id is the SHA-256 of (source, kind, body). Same source, same kind, same body, same id. Different body, different id. Re-import a transcript twice and you do not get duplicate truth; you get the same row. That property is what lets me cite an evidence id in a journey node, in a Critic defect row, and later in a traceability report without inventing a second naming scheme.

terminal / asd evidence-add
asd evidence-add --projectId lighthouse-transit-f7e5f8a2   --source call-821004   --kind quote   --body "Told to wait 15 min for next bus; nobody held the tram."

asd evidence-add --projectId lighthouse-transit-f7e5f8a2   --source avl-extract-2025-11   --kind telemetry   --body "Route 41 weekday OTP 71 percent; peak-shoulder misses cluster 16:00-19:00."

asd evidence-add --projectId lighthouse-transit-f7e5f8a2   --source rosters-07   --kind document   --body "Eleven routes cannot hold a 3-minute connection under current roster rules."

If I try to smuggle in an observation kind, the CLI rejects it. Good. An observation is not a fourth primitive truth type in ASD. It becomes either a quote or a document, depending on what it actually is. That distinction sounds fussy until the first time somebody tries to promote a designer's interpretation into ground truth. The platform says no before the meeting gets confused.

CORE PRINCIPLE: Evidence is allowed to be incomplete. It is not allowed to be vague about what kind of thing it is.
Kind What it captures Typical service-design use
quote Verbatim human words. Interview lines, complaint excerpts, diary snippets, frontline speech.
telemetry Measured operational or behavioral data. Queue times, no-show rates, completion rates, usage extracts, ticket volumes.
document Written context and institutional constraints. Policies, rosters, field notes, consent forms, service standards, notices.

One more boundary matters here. Appendix A lists the platform's artifact vocabulary and its aliases; the register is not that catalog. Evidence rows are smaller and blunter than artifacts on purpose. I want the raw facts to stay primitive so the design layer above them can be checked mechanically.

Acceptance Rules, Failed Writes, and the Draft Lane

Most systems do something unhelpful at write time. They either accept too much and hope review catches it later, or they reject too hard and leave no record of what almost got in. ASD takes a better path. Every method manifest names an acceptance contract, and failed writes persist as draft with machine-readable failures attached. That means the platform tells the truth twice: it tells the truth that the artifact exists, and it tells the truth that the artifact is not yet good enough.

The acceptance vocabulary is intentionally tiny: min-nodes, min-evidence-per-node, and field-non-empty. Some methods add a narrow extra rule such as forbid-field-values, but the platform's core posture is still compact. A chapter like this one can explain the whole thing because there are not thirty hidden validators. For example, contextual-inquiry demands at least 3 nodes, at least 1 evidence row per node, and a non-empty theme field. transcript-mining tightens the evidence floor to 2 and the node floor to 4. behavioural-personas requires 2 evidence rows per persona, a non-empty goal, and rejects demographic description as a defining basis. The manifest is the contract. The write path enforces it.

artifact-write.failure.json
{
  "accepted": false,
  "status": "draft",
  "artifact": {
    "id": "2f537689386e439abd3ae43769ab710c",
    "kind": "journey-map",
    "methodId": "journey-from-transcripts",
    "status": "draft",
    "check": {
      "pass": false,
      "failures": [
        {
          "rule": "min-nodes",
          "message": "expected at least 3 nodes, found 1"
        },
        {
          "rule": "min-evidence-per-node",
          "nodeId": "transfer",
          "message": "node \"transfer\" cites 0 evidence refs, needs 1"
        },
        {
          "rule": "field-non-empty",
          "nodeId": "transfer",
          "message": "node \"transfer\" field \"touchpoint\" must be non-empty"
        }
      ]
    }
  },
  "failures": [
    "expected at least 3 nodes, found 1",
    "node \"transfer\" cites 0 evidence refs, needs 1",
    "node \"transfer\" field \"touchpoint\" must be non-empty"
  ]
}

The subtle point is the status line. Even a structurally accepted artifact remains draft until the review gate is cleared. So ASD really has three observable moments even though it exposes two statuses: a failed draft, an accepted draft, and a final artifact. That middle state matters. It means the method contract passed, but the Critic has not yet granted promotion.

CAUTION: Draft does not mean disposable. If you treat drafts like scratchpads, you lose the audit trail that explains why the eventual final looked the way it did.
Rule What it protects Typical failure
min-nodes Prevents tiny artifacts from pretending to cover a system. A journey with one stage, a research plan with one activity, a persona set with one persona.
min-evidence-per-node Prevents unsupported claims inside otherwise well-formed artifacts. A pain point with zero quotes, a persona defined by one anecdote, a gap row citing nothing.
field-non-empty Prevents placeholder semantics from slipping into delivery. touchpoint: "", theme: "tbd", lane: "n/a".

Because the failure report stays attached, remediation gets precise. I do not ask an agent to "improve the journey." I tell it to rewrite artifact 2f537689386e439abd3ae43769ab710c, add evidence to node transfer, fill touchpoint, and bring the node count above the floor. Specificity is the reward for preserving the failure instead of hiding it.

The Critic on the Write Path: Pass, Veto, and review-veto-log

Acceptance is necessary. It is not sufficient. A journey can meet its node floor and still propose a fantasy. A blueprint can cite real evidence and still violate an operational constraint hidden in a document row. That is why ASD makes review a data structure, not an opinion. If a method declares reviewGate: critic, the artifact is only final after asd review returns a valid verdict.

A pass is stricter than people expect. It still needs evidence-cited rows. You do not get to pass with an empty array because "everything looked fine." The minimum honest pass is an evidence-cited proposal row. A veto is stricter still. It needs at least one defect row, and every defect row needs a fix. That is what turns review from hand-waving into an executable remediation loop.

terminal / asd review
asd review --projectId lighthouse-transit-f7e5f8a2   --artifactId 2f537689386e439abd3ae43769ab710c   --verdict veto   --rows '[
    {
      "rowKind": "defect",
      "severity": "high",
      "rule": "evidence-sufficiency",
      "message": "The missed-connection node needs the roster-constraint document cited alongside the rider quotes; without it the 3-minute connection fix looks feasible and is not.",
      "fix": "Cite rosters-07 on the transfer node.",
      "evidenceId": "ebc691cacc31cf5fb2db2f3c8347e5e085690a0971b0d3ca4d104a6e150fdc6a"
    }
  ]'
review-veto-log.json
{
  "id": "a3c09c90fdb24c49be6efd1c1a58ce43",
  "kind": "review-veto-log",
  "title": "Review: Current-state journey",
  "status": "final",
  "reviewOf": "2f537689386e439abd3ae43769ab710c",
  "nodes": [
    {
      "id": "r1",
      "label": "The missed-connection node needs the roster-constraint document cited first.",
      "evidence": [
        {
          "evidenceId": "ebc691cacc31cf5fb2db2f3c8347e5e085690a0971b0d3ca4d104a6e150fdc6a"
        }
      ],
      "fields": {
        "rowKind": "defect",
        "severity": "high",
        "rule": "evidence-sufficiency",
        "message": "The missed-connection node needs the roster-constraint document cited alongside the rider quotes; without it the 3-minute connection fix looks feasible and is not.",
        "fix": "Cite rosters-07 on the transfer node."
      }
    }
  ]
}

This artifact is administrative, and that is an important distinction. A review-veto-log is part of the runtime registry, but it is not one of the flagship fillable templates. It exists because governance itself needs evidence. The Critic's row is not a Slack comment. It is a final artifact linked by reviewOf to the artifact it judged. On a later pass, ASD reuses that same log artifact and appends the new rows so the story stays continuous.

Promotion therefore becomes exact. Failed acceptance yields draft. Accepted write still yields draft. Critic veto yields draft plus a final review-veto-log. Critic pass may promote the artifact to final. Nothing else does.

My take: The Critic becomes politically useful the moment its veto stops sounding like preference. If the row says which evidence id blocks the claim and which fix would satisfy the gate, the conversation changes from argument to workmanship.

The Fact-Check Triad and Why CI Trusts Exit Codes

The platform's final mechanical witness is asd factcheck. It replays the project as it exists now, not as it was when a role first wrote an artifact. That distinction matters. A manifest may tighten later. A bad ref may have slipped into an older file. A human may have copied something around the edges. factcheck does not care about excuses. It re-runs three tests for every artifact: integrity, acceptance, and review.

Integrity asks whether every cited evidence id resolves. Acceptance re-runs the method's rules against the live registry. Review checks that any artifact claiming final under a gated method actually carries a pass verdict. Drafts can remain drafts honestly. Failed finals cannot sneak through.

terminal / asd factcheck
asd factcheck --projectId lighthouse-transit-f7e5f8a2
factcheck-report.json
{
  "pass": false,
  "rows": [
    {
      "artifactId": "2f537689386e439abd3ae43769ab710c",
      "kind": "journey-map",
      "status": "draft",
      "integrity": {
        "pass": true,
        "dangling": []
      },
      "acceptance": {
        "pass": false,
        "failures": [
          "node \"transfer\" cites 0 evidence refs, needs 1"
        ]
      },
      "review": {
        "pass": true,
        "gate": "critic",
        "verdict": null
      },
      "methodId": "journey-from-transcripts",
      "methodResolution": "recorded"
    }
  ]
}

The row tells me exactly why the build is red, but CI does not even need to read the JSON. It reads the exit code. When pass is false, asd factcheck exits 1. That single design choice turns service-design rigor into an enforceable delivery gate. A project cannot talk its way into green. It must satisfy the replay.

CORE PRINCIPLE: A green-looking report is theater if the command still exits 1. CI reads the exit code, not the meeting energy.

This is also where the platform's honesty shows. A draft is allowed to exist. A veto log is allowed to exist. Open work is allowed to exist. What is not allowed is pretending that open work is ready for export, phase movement, or executive reporting. The six report kinds render deterministically, but only from what the store can defend.

Human Phase Gates, Approval Receipts, and the Boundary of Authority

After all that machinery, the most important rule is still human. ASD does not infer approval from a passing artifact. It does not promote a project because the Critic was satisfied. It does not let ACP pretend to authorize work. Only a human phase gate moves the project from discover to define, define to develop, or develop to deliver, and that move must carry an approval receipt.

The receipt is the antidote to fuzzy governance. Somebody approved. Somebody stated a rationale. Somebody put a timestamp on it. The command is idempotent because gates are too serious to duplicate casually.

approval-receipt.json
{
  "receiptId": "gate-discover-1",
  "decision": "approve",
  "rationale": "Discover evidence and synthesis are complete; the open risks are documented for Define.",
  "approvedBy": "service-lead",
  "approvedAt": "2026-08-22T12:00:00Z"
}
terminal / asd phase-advance
asd phase-advance --projectId lighthouse-transit-f7e5f8a2   --toPhase define   --idempotencyKey gate-discover-1   --approvalReceipt '{
    "receiptId": "gate-discover-1",
    "decision": "approve",
    "rationale": "Discover evidence and synthesis are complete; the open risks are documented for Define.",
    "approvedBy": "service-lead",
    "approvedAt": "2026-08-22T12:00:00Z"
  }'

In practice the tool also protects the shape of the gate. The transition must be legal. The receipt must be non-empty and well formed. The project must have at least one design artifact, passing factcheck, and no unresolved Critic veto standing in the way. That is why phase change belongs to the Orchestrator plus a human authority, not to whichever role happens to be loudest. The system can prepare the case; it cannot sign its own release.

This is also the point where ACP's boundary matters. asd-acp/1 is record-only. It can log a human gate, a handoff, an unsupported dispatch, or a Critic veto. It cannot promote a phase by narrative implication. BUZZ messages are not ACP transport. DSH UI events are not ACP transport. A host may present the gate beautifully, but the durable project truth is still the gate record.

My take: I do not want a platform that sounds decisive. I want one that knows exactly where its authority ends. ASD earns trust because it is willing to stop at the human gate and wait for a named person to own the call.

Put all of this together and the chapter's thesis becomes simple. Agents can discover, cluster, map, critique, and render. They cannot improvise the evidence, waive the acceptance floor, erase a veto, fake a fact-check, or authorize the next phase. That is why ASD stays useful under pressure. The platform is opinionated about what must be true before design becomes durable, and it keeps those truths inspectable all the way down to the row.

Next Chapter

Research Ops at Scale: Mining Transcripts & Field Inquiries

Two hundred interviews, one agent team

Continue Reading
ASD '26

The Agentic Service Designer

How AI Agent Teams, Service Blueprints-as-Code, and Autonomous Tooling Are Transforming Service Design from Insight to Operations. By Sam Mozaffari.

Front Matter

Front Matter

Front Matter

Copyright & License

Chapter 01

The AI-First Service Design Operating System

Chapter 02

The ASD Platform Architecture

Chapter 03

Service-Dominant Logic & Value Co-Creation in the Age of AI

Chapter 04

The Role Contract, Evidence Registers & Deterministic Fact-Checking

Chapter 05

Research Ops at Scale: Mining Transcripts & Field Inquiries

Chapter 06

Mixed Methods & Evidence-Backed Segmentation

Chapter 07

Mental Models, Alignment & Opportunity Mapping

Chapter 08

Ecosystem Value Mapping & Stakeholder Topologies

Chapter 09

Living Journey Maps: From Transcripts to Sentiment Curves

Chapter 10

The Master Blueprint: Five-Lane Architecture & Line of Visibility

Chapter 11

Agentic Service Blueprinting: The Sixth Lane & Autonomous Workflows

Chapter 12

Cross-Channel Orchestration & Story Mapping

Chapter 13

Structured Ideation & How Might We at Machine Speed

Chapter 14

Prototyping Services: Desktop Walkthroughs to Wizard-of-Oz

Chapter 15

Transformative Services, Behavior Change & Recovery Engineering

Chapter 16

Service Quality Management & CX Maturity Governance

Chapter 17

The ASD MCP Server

Chapter 18

Plugins & Host Packs: Claude Code and Beyond

Chapter 19

BUZZ: Multi-Agent Service Design on the Open Agent Network

Chapter 20

DeepSeek Harness Studio: The Integrated Workbench

Chapter 21

SOPs-as-Code: The AI Execution Playbook

Chapter 22

Frontline Enablement & Employee Experience

Chapter 23

The 15 Principles of Good Public Services

Chapter 24

Mastercase: Meridian Bay Ferries

Chapter 25

The Future of Service Design: The Agentic Practice

Appendix A

The ASD Method & Artifact Catalog

Appendix B

CLI & MCP Tool Specification

Appendix C

The 20-Book Canonical Cross-Reference

©2026 Sam Mozaffari. Free for personal/noncommercial use (CC BY-NC-ND 4.0); commercial license required for business use.