MACP

Task Mode

Mode identifier: macp.mode.task.v1 Participant model: orchestrated Determinism: structural-only

Purpose

Bounded task delegation from a coordinator (initiator) to an assignee, with progress tracking through to completion or failure.

Session Lifecycle

SessionStart → TaskRequest → TaskAccept/TaskReject

                              TaskUpdate (0..n)

                          TaskComplete / TaskFail

                              Commitment

API

TaskSession

import { TaskSession } from 'macp-sdk-typescript';

const session = new TaskSession(client);
await session.start({ intent: '...', participants: ['worker'], ttlMs: 120_000 });

Methods

MethodMessage TypeDescription
request(input)TaskRequestDefine the task (coordinator only)
acceptTask(input)TaskAcceptAccept the assignment
rejectTask(input)TaskRejectDecline the assignment
update(input)TaskUpdateReport progress
complete(input)TaskCompleteMark task as done
fail(input)TaskFailMark task as failed
commit(input)CommitmentFinalize the session

Request a Task

await session.request({
  taskId: 't1',
  title: 'Implement login page',
  instructions: 'Build a login form with email/password, OAuth, and MFA',
  requestedAssignee: 'worker',
  deadlineUnixMs: Date.now() + 3600_000,  // optional, 1 hour
});

Accept / Reject

// Worker accepts
await session.acceptTask({
  taskId: 't1',
  assignee: 'worker',
  reason: 'starting now',
  sender: 'worker',
  auth: Auth.devAgent('worker'),
});

// Or worker rejects
await session.rejectTask({
  taskId: 't1',
  assignee: 'worker',
  reason: 'no capacity',
  sender: 'worker',
  auth: Auth.devAgent('worker'),
});

Progress Updates

await session.update({
  taskId: 't1',
  status: 'in_progress',
  progress: 0.5,       // 0.0 to 1.0
  message: 'form layout complete, starting validation',
  sender: 'worker',
  auth: Auth.devAgent('worker'),
});

Complete / Fail

// Success
await session.complete({
  taskId: 't1',
  assignee: 'worker',
  output: Buffer.from(JSON.stringify({ artifact: 'login-page-v1' })),
  summary: 'Login page with email/password and OAuth',
  sender: 'worker',
  auth: Auth.devAgent('worker'),
});

// Failure
await session.fail({
  taskId: 't1',
  assignee: 'worker',
  errorCode: 'DEPENDENCY_UNAVAILABLE',
  reason: 'OAuth provider API is down',
  retryable: true,
  sender: 'worker',
  auth: Auth.devAgent('worker'),
});

Important: TaskComplete and TaskFail do not resolve the session. Only Commitment does.

TaskProjection

State

PropertyTypeDescription
tasksMap<string, TaskRecord>Tasks with status and progress
updatesTaskUpdateRecord[]All progress updates
completionsTaskCompletionRecord[]Completion records
failuresTaskFailureRecord[]Failure records
phase'Requesting' | 'InProgress' | 'Completed' | 'Failed' | 'Committed'Current phase

TaskRecord Status

StatusMeaning
requestedTask created, awaiting acceptance
acceptedAssignee accepted
rejectedAssignee declined
in_progressWork underway (set on first TaskUpdate)
completedTaskComplete received
failedTaskFail received

Query Helpers

session.projection.getTask('t1');         // full TaskRecord
session.projection.progressOf('t1');      // 0.0 - 1.0
session.projection.isComplete('t1');      // true after TaskComplete
session.projection.isFailed('t1');        // true after TaskFail
session.projection.isRetryable('t1');     // true if failure was retryable
session.projection.activeTasks();         // tasks in requested/accepted/in_progress

RFC Validation Rules

  1. At most one TaskRequest per session (base v1)
  2. TaskAccept/TaskReject must come from the requested assignee
  3. Only one assignee may be active at a time
  4. TaskUpdate/TaskComplete/TaskFail must come from the active assignee
  5. Only the initiator can emit Commitment

Example

See examples/task-smoke.ts.