Skip to content

HACP — Human-Agent Collaboration Protocol

FieldValue
Version0.1.0-draft
StatusDraft, validated by the current reference implementation
LayerL2, top layer of the Loops Protocol Stack
Document typeFull protocol specification
Primary concernHuman-owned work delegated to autonomous agents

HACP defines how people and autonomous agents collaborate around a bounded unit of work called a Task. It covers assignment, checkpoints, ownership, artifact delivery, review, project state, and audit.

HACP is transport-agnostic. It specifies protocol semantics, not whether those semantics are carried over HTTP, WebSocket, gRPC, stdio, an event bus, or a host platform API.

Normative keywords follow RFC 2119: MUST, MUST NOT, SHOULD, SHOULD NOT, and MAY.

Scope

HACP governs:

  • Human principals assigning work to agents.
  • Agents raising decision checkpoints.
  • Human reviewers accepting, rejecting, or requesting changes on artifacts.
  • Ownership transfer across humans and agents.
  • Immutable artifact versions and append-only project ledger state.
  • Audit events for protocol replay and accountability.

HACP does not govern:

  • How an agent internally executes a run.
  • How agents delegate to other agents; that is AAP.
  • How agents invoke tools or skills; that is CAP.
  • How notifications are rendered in chat, web, mobile, or CLI channels.
  • The host platform's identity, RBAC, billing, or tenant model.

Roles

RoleDefinition
principalThe human ultimately responsible for the task. The principal MUST be human and MUST NOT change during task lifetime.
assigneeThe current executor. The assignee MAY be a human or an agent and may change through protocol operations.
reviewerA human who reviews an artifact. The reviewer MUST be human and MAY differ from the principal.

First-Class Objects

HACP defines seven first-class objects. A conforming implementation MUST support all seven.

ObjectPurposeLifecycle
TaskThe primary unit of accountable workCreated to completed
CheckpointA decision point raised by an agentRaised to resolved or expired
OwnershipTransferable responsibility for a taskExists with the task
ReviewHuman verdict and feedback on an artifactImmutable after submit
ArtifactA versioned deliverable with provenanceIndependent, immutable versions
LedgerAppend-only project or organization stateScope-scoped, append-only
AuditImmutable operation logAppend-only forever

Immutability

HACP is forward-only:

  • Task spec MUST NOT change after task.create.
  • Artifact versions MUST NOT change after artifact.commit.
  • Review records MUST NOT change after review.submit.
  • Ledger entries MUST NOT be deleted.
  • Audit events MUST NEVER be deleted or modified.

Corrections are represented as new tasks, new artifact versions, new reviews, or new ledger entries.

Identifiers

Object identifiers MUST use ULID-compatible entropy and sortable ordering with type prefixes.

ObjectPrefixExample
Tasktask_task_01J0K7M4N8Y7...
Checkpointckpt_ckpt_01J0K9C3G2T1...
Reviewrev_rev_01J0KAMJ6D8P...
Artifactart_art_01J0KBYF2Q3V...
Ledgerled_led_01J0KC8A7M5R...
AuditEventaud_aud_01J0KDK3N6A2...

Timestamps MUST use RFC 3339 UTC.

Task

Task is the subject of the protocol.

yaml
Task:
  id: task_
  type: string
  spec: TaskSpec
  ownership: Ownership
  state: TaskState
  parent_task: task_ | null
  created_at: timestamp
  deadline: timestamp | null
  checkpoints: [ckpt_]
  artifacts: [art_]
  audit_trail: aud_

TaskSpec:
  goal: string
  acceptance_criteria: [string]
  inputs: [InputRef]
  constraints: Constraints

InputRef:
  kind: "artifact" | "resource"
  id: string
  version: string
  uri: string

Constraints:
  max_duration: duration
  must_use_capabilities: [CapabilityRef]

Rules:

  • spec MUST be immutable after creation.
  • ownership.principal MUST be set at creation and MUST NEVER change.
  • state transitions MUST follow the Task state machine.

Task State Machine

Only the listed transitions are valid.

text
created
  -> assigned
  -> in_progress
       -> blocked -> in_progress
       -> review_ready -> under_review -> in_progress
                                      -> accepted -> completed
                                      -> rejected

created | assigned | in_progress | blocked -> completed by task.cancel
FromToTrigger
createdassignedtask.assign
assignedin_progressAgent starts work
in_progressblockedcheckpoint.raise
blockedin_progresscheckpoint.resolve with approve or provide
blockedcompletedcheckpoint.resolve with reject
in_progressreview_readyartifact.commit
review_readyunder_reviewreview.submit begins review
under_reviewin_progressreview.submit with changes requested
under_reviewacceptedreview.submit with approved
under_reviewrejectedreview.submit with rejected
acceptedcompletedAutomatic completion
created, assigned, in_progress, blockedcompletedtask.cancel

State ownership:

StateAssigneeMeaning
createdprincipalCreated but not assigned
assignedagentDelegated but not started
in_progressagentAgent is executing
blockedprincipalHuman decision required
review_readyprincipalArtifact delivered for review
under_reviewprincipalReview in progress
acceptedprincipalAccepted, ready to complete
completedprincipalTerminal successful or canceled state

Checkpoint

Checkpoint is the upward control surface from agent to human.

yaml
Checkpoint:
  id: ckpt_
  task_id: task_
  kind: "approval" | "choice" | "input" | "escalation"
  prompt: string
  options: [CheckpointOption]
  context: [Evidence]
  state: "pending" | "resolved" | "expired"
  raised_at: timestamp
  expires_at: timestamp | null
  resolution: CheckpointResolution | null

CheckpointOption:
  id: string
  label: string
  risk: "low" | "medium" | "high"

CheckpointResolution:
  by: user_
  action: "approve" | "reject" | "choose" | "provide" | "reassign"
  choice: string
  input: string
  reassign_to: agent_
  comment: string
  at: timestamp

Rules:

  • resolution.by MUST be a principal or authorized reviewer.
  • checkpoint.raise MUST move the task to blocked.
  • checkpoint.resolve MUST resolve the checkpoint before resuming work.
  • Expiration policy is implementation-defined in this draft, but expiration MUST emit an audit event.

Ownership

Ownership records responsibility and assignment.

yaml
Ownership:
  task_id: task_
  principal: user_
  assignee: user_ | agent_
  delegable: boolean
  chain: [OwnershipTransfer]

OwnershipTransfer:
  from: user_ | agent_
  to: user_ | agent_
  at: timestamp
  via: "assign" | "checkpoint" | "approve" | "reject" | "handoff"

Rules:

  • Every assignee change MUST append to chain.
  • Every transfer MUST correspond to a valid protocol event.
  • If delegable=false, an agent MUST NOT call ownership.delegate.

Review

Review captures human feedback on an artifact.

yaml
Review:
  id: rev_
  task_id: task_
  artifact_id: art_
  reviewer: user_
  verdict: "approved" | "changes_requested" | "rejected"
  comments: [ReviewComment]
  requested_changes: [string]
  at: timestamp

ReviewComment:
  anchor: string
  severity: "blocker" | "major" | "minor" | "nit"
  body: string

Rules:

  • Reviews MUST be immutable after submission.
  • reviewer MUST be human.
  • requested_changes MUST be present when verdict is changes_requested.

Artifact

Artifact is a deliverable produced by a task.

yaml
Artifact:
  id: art_
  type: string
  provenance: ArtifactProvenance
  version: string
  parent_version: string | null
  payload: ArtifactPayload
  references: [ArtifactRef]

ArtifactProvenance:
  produced_by: task_
  produced_at: timestamp

ArtifactPayload:
  kind: "diff" | "blob" | "ref" | "inline"
  uri: string
  checksum: string
  size: integer

ArtifactRef:
  task_id: task_
  as: "input" | "output"

Rules:

  • (id, version) MUST be globally unique.
  • Artifact references MUST lock both id and version.
  • checksum MUST verify payload integrity.
  • Updating an artifact MUST create a new version with parent_version.

Ledger

Ledger is append-only project or organization state.

yaml
Ledger:
  id: led_
  scope: string

LedgerEntry:
  key: string
  value: any
  written_at: timestamp
  by: task_

Rules:

  • Ledger entries MUST NEVER be deleted.
  • Rewriting a logical key MUST append a new entry.
  • Every write MUST emit an audit event.
  • Conflict handling is implementation-defined in this draft; implementations SHOULD document their policy.

Audit

Audit is the immutable observation plane.

yaml
AuditEvent:
  id: aud_
  seq: integer
  at: timestamp
  actor: user_ | agent_
  action: string
  subject:
    kind: string
    id: string
  task_id: task_ | null
  before: object | null
  after: object | null

Rules:

  • Every state-changing protocol operation MUST produce an audit event.
  • Audit events MUST NEVER be deleted or modified.
  • seq MUST be monotonically increasing within its audit scope.

Operations

HACP operation names follow <object>.<verb>. A conforming implementation MUST support all 21 operations.

ObjectOperationCallerSemantics
Tasktask.createprincipalCreate task in created state
Tasktask.assignprincipalAssign to agent and transfer ownership
Tasktask.cancelprincipalEnd an active task
Tasktask.getany authorized actorFetch one task
Tasktask.listany authorized actorQuery tasks
Checkpointcheckpoint.raiseagentDeclare a human decision point
Checkpointcheckpoint.resolvehumanResolve a pending checkpoint
Checkpointcheckpoint.expiresystemMark checkpoint expired
Ownershipownership.transfersystemTransfer assignee
Ownershipownership.delegateagentDelegate downward when allowed
Reviewreview.submitreviewerSubmit verdict and feedback
Reviewreview.commentreviewerAppend review comment
Artifactartifact.commitagentCommit deliverable or version
Artifactartifact.getany authorized actorFetch by id and version
Artifactartifact.referencetaskReference artifact as input
Ledgerledger.readany authorized actorRead key state
Ledgerledger.writetaskAppend key state
Ledgerledger.historyany authorized actorRead key history
Auditaudit.queryany authorized actorQuery audit events
Auditaudit.replayany authorized actorReplay task history

Operation Preconditions

Violations MUST return PRECONDITION_FAILED.

OperationRequired precondition
task.assignTask state is created
task.cancelTask state is created, assigned, in_progress, or blocked
checkpoint.raiseTask state is in_progress
checkpoint.resolveCheckpoint is pending and caller is authorized
ownership.delegateownership.delegable == true
artifact.commitTask state is in_progress or review rework state
review.submitTask state is review_ready or under_review

Audit Actions

State-changing operations MUST map to audit actions.

OperationAudit action
task.createtask.created
task.assigntask.assigned
task.canceltask.cancelled
checkpoint.raisetask.checkpoint.raised
checkpoint.resolvetask.checkpoint.resolved
checkpoint.expiretask.checkpoint.expired
ownership.transferownership.transferred
ownership.delegateownership.delegated
review.submitreview.submitted
artifact.commitartifact.committed
ledger.writeledger.written

Inter-layer Contracts

HACP is L2. It communicates downward through explicit contracts:

HACP eventAAP actionContract
task.assignagent.delegateTaskID MUST become Run.correlation_id
checkpoint.raiseagent.blockThe corresponding run MUST enter blocked
checkpoint.resolveagent.resumeResolution MUST be passed to the run
ownership.delegateagent.delegateParent run SHOULD remain traceable
ownership.transferagent.handoffCorrelation MUST be preserved

HACP MUST NOT directly invoke CAP capabilities. It references capabilities only through CapabilityRef.

Errors

CodeMeaning
INVALID_SPECTask spec is invalid
PRECONDITION_FAILEDOperation precondition failed
UNAUTHORIZEDCaller is not authorized
NOT_FOUNDObject does not exist
CONFLICTConcurrent mutation conflict
IMMUTABLE_VIOLATIONAttempt to mutate immutable object
DEADLINE_EXCEEDEDTask deadline exceeded
CHECKPOINT_EXPIREDCheckpoint can no longer be resolved

State transition, ownership update, and audit append SHOULD be atomic from the caller's perspective.

Conformance

An implementation claiming HACP 0.1.0-draft compatibility MUST:

  1. Support all seven first-class objects.
  2. Implement all 21 operations.
  3. Enforce the Task state machine.
  4. Enforce the immutability rules.
  5. Emit audit events for every state-changing protocol operation.
  6. Validate operation preconditions.
  7. Satisfy the inter-layer contracts when used in a full Loops stack.

Open Issues

The following topics remain intentionally draft-scoped:

IssueDraft stance
Transport bindingNot specified; implementations may choose HTTP, gRPC, WebSocket, stdio, or host APIs.
Checkpoint expiration defaultImplementation-defined; pure suspension plus configuration is recommended.
Delegation depthAllowed through delegable, but limits are host policy.
Ledger conflict handlingLast-write-wins plus audit is acceptable in this draft.
Multi-reviewer verdictsNot standardized; single reviewer is the baseline.
Cross-project artifact referencesRequire explicit authorization; mechanism is host-defined.
Version compatibilityExpected to follow semantic versioning after implementation feedback.

Reference Flow

text
Human Alice                 HACP                         Agent Devin
  | task.create              |                             |
  | task.assign              | -> AAP delegate(TaskID)     |
  |                           | <- checkpoint.raise         |
  | <- checkpoint notice      | -> AAP block                |
  | checkpoint.resolve        | -> AAP resume               |
  |                           | <- artifact.commit(v1)      |
  | review.submit(changes)    | -> in_progress              |
  |                           | <- artifact.commit(v2)      |
  | review.submit(approved)   | -> accepted -> completed    |
  |                           | -> ledger.write             |
  | audit.replay              | reconstructs the flow       |

This flow exercises task assignment, checkpoint gating, artifact delivery, human review, rework, completion, ledger persistence, and audit replay.

Loops Protocol Stack · loop0 owns execution · loop1 owns interaction · loop2 owns coordination