Skip to content

The Master TODO is the central, workspace-scoped ledger of work items that the Hoody agent orchestrator schedules, tracks, and reflects on. Each entry has a lifecycle status, a priority, dependency edges, budgeted spend and rounds, an optional spec, and a phase_id that ties it to a phase. Use these endpoints to read the full state, append new entries, and mutate individual fields such as status, priority, rounds, and specs.

GET /api/v1/workspaces/{workspaceID}/orchestration/todo

Returns the fully materialized Master TODO, including all entries and phases for the workspace.

NameInTypeRequiredDescription
workspaceIDpathstringYesWorkspace identifier
{
"id": "todo_01HMZ7K8XQF8RN2C9WXPEYJSVA",
"version": 42,
"created_at": 1717691342000,
"project_context": "Build a TypeScript SDK for the Hoody public API with full test coverage.",
"entries": [
{
"id": "entry_01HMZ7K9BQPJ3Y5T6H2SNQR4XZ",
"seq": 1,
"type": "task",
"content": "Generate OpenAPI client scaffolding",
"spec": {
"requirements": "Produce a typed client covering auth, workspaces, and agent endpoints.",
"acceptance_criteria": [
"Client compiles with tsc --noEmit",
"Every endpoint exposed by the public spec is wrapped"
],
"files_to_create": ["src/client.ts", "src/types.ts"],
"files_to_modify": ["package.json"],
"patterns": "Use the existing fetch-based HttpClient wrapper.",
"api_contract": "All public types must match the OpenAPI schema byte-for-byte.",
"examples": "See /examples/auth.ts for a runnable smoke test.",
"integration_points": "Publishes through @hoody/sdk.",
"authored_by": "specs-agent",
"last_edited": 1717691300000,
"revision": 4
},
"spec_frozen": false,
"status": "in_progress",
"priority": "high",
"depends_on": [],
"children": [],
"parallelizable": true,
"parallel_group": "scaffold",
"budget_usd": 25,
"spent_usd": 4.2,
"budget_rounds": 5,
"rounds_completed": 1,
"created_by": "user",
"assigned_to": "session_01HMZ7K0YQB4ET7JVM9F2D8N3P",
"session_ids": ["session_01HMZ7K0YQB4ET7JVM9F2D8N3P"],
"verified": false,
"phase_id": "phase_01HMZ7KAB9C3R5V7T8DXQW2YN4"
}
],
"phases": [
{
"id": "phase_01HMZ7KAB9C3R5V7T8DXQW2YN4",
"seq": 1,
"name": "Scaffolding",
"description": "Generate the initial client and project files.",
"status": "active",
"entry_ids": ["entry_01HMZ7K9BQPJ3Y5T6H2SNQR4XZ"],
"fixer_entry_ids": [],
"session_ids": ["session_01HMZ7K0YQB4ET7JVM9F2D8N3P"],
"phase_rounds": 3,
"phase_rounds_completed": 1,
"created_at": 1717691000000,
"updated_at": 1717691400000,
"summary": "Scaffolding underway.",
"memory": [
{
"text": "Switched to fetch-based client wrapper after benchmarking.",
"created_at": 1717691250000
}
]
}
]
}
const todo = await client.agent.orchestration.todoRead({
workspaceID: "ws_01HMZ7J2H3D9R5C8PWTY6QNBVE",
});

GET /api/v1/workspaces/{workspaceID}/orchestration/todo/entries/{entryID}

Fetches a single entry by ID.

NameInTypeRequiredDescription
workspaceIDpathstringYesWorkspace identifier
entryIDpathstringYesMaster TODO entry identifier
{
"entry": {
"id": "entry_01HMZ7K9BQPJ3Y5T6H2SNQR4XZ",
"seq": 1,
"type": "task",
"content": "Generate OpenAPI client scaffolding",
"spec": {
"requirements": "Produce a typed client covering auth, workspaces, and agent endpoints.",
"acceptance_criteria": [
"Client compiles with tsc --noEmit"
],
"authored_by": "specs-agent",
"last_edited": 1717691300000,
"revision": 4
},
"spec_frozen": false,
"status": "in_progress",
"priority": "high",
"depends_on": [],
"parallelizable": true,
"spent_usd": 4.2,
"budget_rounds": 5,
"rounds_completed": 1,
"created_by": "user",
"session_ids": ["session_01HMZ7K0YQB4ET7JVM9F2D8N3P"]
}
}
const { entry } = await client.agent.orchestration.todoGetEntry({
workspaceID: "ws_01HMZ7J2H3D9R5C8PWTY6QNBVE",
entryID: "entry_01HMZ7K9BQPJ3Y5T6H2SNQR4XZ",
});

GET /api/v1/workspaces/{workspaceID}/orchestration/todo/entries/{entryID}/spec

Returns the structured spec attached to an entry, or null if no spec has been authored.

NameInTypeRequiredDescription
workspaceIDpathstringYesWorkspace identifier
entryIDpathstringYesMaster TODO entry identifier
{
"spec": {
"requirements": "Produce a typed client covering auth, workspaces, and agent endpoints.",
"acceptance_criteria": [
"Client compiles with tsc --noEmit",
"Every endpoint exposed by the public spec is wrapped"
],
"files_to_create": ["src/client.ts", "src/types.ts"],
"files_to_modify": ["package.json"],
"patterns": "Use the existing fetch-based HttpClient wrapper.",
"api_contract": "All public types must match the OpenAPI schema byte-for-byte.",
"examples": "See /examples/auth.ts for a runnable smoke test.",
"integration_points": "Publishes through @hoody/sdk.",
"authored_by": "specs-agent",
"last_edited": 1717691300000,
"revision": 4
}
}
const { spec } = await client.agent.orchestration.todoReadSpec({
workspaceID: "ws_01HMZ7J2H3D9R5C8PWTY6QNBVE",
entryID: "entry_01HMZ7K9BQPJ3Y5T6H2SNQR4XZ",
});

GET /api/v1/workspaces/{workspaceID}/orchestration/todo/events

Returns a paginated append-only event log covering every mutation to the Master TODO (entries, statuses, specs, phases, and more).

NameInTypeRequiredDescription
workspaceIDpathstringYesWorkspace identifier
pagequeryintegerNoPage number. Default: 1
limitqueryintegerNoItems per page. Default: 50
{
"items": [
{
"id": "evt_01HMZ7KAC8T7X5Z9Q2V1BHPRM3",
"seq": 128,
"type": "status_changed",
"payload": {
"entryID": "entry_01HMZ7K9BQPJ3Y5T6H2SNQR4XZ",
"from": "pending",
"to": "in_progress"
},
"timestamp": 1717691380000,
"actor": "session_01HMZ7K0YQB4ET7JVM9F2D8N3P"
},
{
"id": "evt_01HMZ7K9B4YJ2K6L0N1XDPQ5S7",
"seq": 127,
"type": "entry_created",
"payload": {
"entryID": "entry_01HMZ7K9BQPJ3Y5T6H2SNQR4XZ",
"type": "task",
"priority": "high"
},
"timestamp": 1717691342000,
"actor": "user"
}
],
"meta": {
"page": 1,
"limit": 50,
"total": 128,
"pages": 3
}
}
const events = await client.agent.orchestration.todoGetEvents({
workspaceID: "ws_01HMZ7J2H3D9R5C8PWTY6QNBVE",
page: 1,
limit: 50,
});

POST /api/v1/workspaces/{workspaceID}/orchestration/todo/entries

Appends one or more new entries to the Master TODO. Each entry must declare a type, content, and priority. An optional spec may be supplied to seed the entry with requirements and acceptance criteria.

NameInTypeRequiredDescription
workspaceIDpathstringYesWorkspace identifier
FieldTypeRequiredDescription
entriesarrayYesEntries to append. Each item requires type, content, and priority.

Each entry item supports:

  • type — one of "task", "correction", "review", "snapshot", "note", "parent"
  • content — human-readable description
  • spec — optional object with requirements (required), acceptance_criteria (required, array of strings), and optional files_to_create, files_to_modify, patterns, api_contract, examples, integration_points
  • priority — one of "critical", "high", "medium", "low"
  • depends_on — array of entry IDs; defaults to []
  • parallelizable — boolean; defaults to true
  • parallel_group — string label grouping parallel-safe entries
  • budget_usd — optional per-entry spend cap
  • budget_rounds — integer; defaults to 3
  • phase_id — optional phase binding
  • container_id — optional container binding
{
"entries": [
{
"type": "task",
"content": "Implement POST /api/v1/auth/login",
"priority": "high",
"spec": {
"requirements": "Accept JSON { email, password } and return a signed session token.",
"acceptance_criteria": [
"Valid credentials return 200 with a token",
"Invalid credentials return 401 with an error code"
],
"files_to_create": ["src/routes/auth/login.ts"],
"files_to_modify": ["src/routes/auth/index.ts"]
},
"depends_on": [],
"parallelizable": true,
"budget_usd": 10,
"budget_rounds": 4
}
]
}
{
"added": [
"entry_01HMZ7K9BQPJ3Y5T6H2SNQR4XZ"
],
"count": 1
}
const result = await client.agent.orchestration.todoAppend({
workspaceID: "ws_01HMZ7J2H3D9R5C8PWTY6QNBVE",
data: {
entries: [
{
type: "task",
content: "Implement POST /api/v1/auth/login",
priority: "high",
spec: {
requirements: "Accept JSON { email, password } and return a signed session token.",
acceptance_criteria: [
"Valid credentials return 200 with a token",
"Invalid credentials return 401 with an error code"
],
files_to_create: ["src/routes/auth/login.ts"],
files_to_modify: ["src/routes/auth/index.ts"]
},
budget_rounds: 4
}
]
}
});

PUT /api/v1/workspaces/{workspaceID}/orchestration/todo/entries/{entryID}/spec

Replaces the spec attached to an entry and increments its revision. The entry must not be frozen.

NameInTypeRequiredDescription
workspaceIDpathstringYesWorkspace identifier
entryIDpathstringYesMaster TODO entry identifier
FieldTypeRequiredDescription
requirementsstringYesFree-form requirements text
acceptance_criteriaarrayYesArray of strings describing acceptance criteria
files_to_createarrayNoArray of file paths to create
files_to_modifyarrayNoArray of file paths to modify
patternsstringNoPatterns or conventions to follow
api_contractstringNoAPI contract details
examplesstringNoExample usage or references
integration_pointsstringNoNotes on how the entry integrates with surrounding work
{
"requirements": "Accept JSON { email, password } and return a signed session token; throttle by IP.",
"acceptance_criteria": [
"Valid credentials return 200 with a token",
"Invalid credentials return 401 with an error code",
"More than 10 attempts/minute from one IP returns 429"
],
"files_to_create": ["src/routes/auth/login.ts"],
"files_to_modify": ["src/routes/auth/index.ts", "src/middleware/rate-limit.ts"],
"patterns": "Use the existing HttpError helper for error responses."
}
{
"entryID": "entry_01HMZ7K9BQPJ3Y5T6H2SNQR4XZ",
"revision": 5
}
const result = await client.agent.orchestration.todoUpdateSpec({
workspaceID: "ws_01HMZ7J2H3D9R5C8PWTY6QNBVE",
entryID: "entry_01HMZ7K9BQPJ3Y5T6H2SNQR4XZ",
data: {
requirements: "Accept JSON { email, password } and return a signed session token; throttle by IP.",
acceptance_criteria: [
"Valid credentials return 200 with a token",
"Invalid credentials return 401 with an error code"
]
}
});

POST /api/v1/workspaces/{workspaceID}/orchestration/todo/entries/{entryID}/spec/freeze

Locks an entry’s spec so that subsequent update attempts are rejected with 409. Use this to commit a spec before the implementation sessions begin.

NameInTypeRequiredDescription
workspaceIDpathstringYesWorkspace identifier
entryIDpathstringYesMaster TODO entry identifier
{
"entryID": "entry_01HMZ7K9BQPJ3Y5T6H2SNQR4XZ",
"frozen": true
}
const result = await client.agent.orchestration.todoFreezeSpec({
workspaceID: "ws_01HMZ7J2H3D9R5C8PWTY6QNBVE",
entryID: "entry_01HMZ7K9BQPJ3Y5T6H2SNQR4XZ",
});

PATCH /api/v1/workspaces/{workspaceID}/orchestration/todo/entries/{entryID}/priority

Re-orders an entry by changing its priority tier. The response includes the previous value so callers can audit the change.

NameInTypeRequiredDescription
workspaceIDpathstringYesWorkspace identifier
entryIDpathstringYesMaster TODO entry identifier
FieldTypeRequiredDescription
prioritystringYesOne of "critical", "high", "medium", "low"
{
"priority": "critical"
}
{
"entryID": "entry_01HMZ7K9BQPJ3Y5T6H2SNQR4XZ",
"priority": "critical",
"previous": "high"
}
const result = await client.agent.orchestration.todoSetPriority({
workspaceID: "ws_01HMZ7J2H3D9R5C8PWTY6QNBVE",
entryID: "entry_01HMZ7K9BQPJ3Y5T6H2SNQR4XZ",
data: { priority: "critical" },
});

PATCH /api/v1/workspaces/{workspaceID}/orchestration/todo/entries/{entryID}/rounds

Sets budget_rounds for an entry — the maximum number of execution rounds the orchestrator will attempt before giving up. The value must be between 1 and 50 inclusive.

NameInTypeRequiredDescription
workspaceIDpathstringYesWorkspace identifier
entryIDpathstringYesMaster TODO entry identifier
FieldTypeRequiredDescription
budget_roundsintegerYesMaximum number of execution rounds. Range: 1 to 50.
{
"budget_rounds": 8
}
{
"entryID": "entry_01HMZ7K9BQPJ3Y5T6H2SNQR4XZ",
"budget_rounds": 8
}
const result = await client.agent.orchestration.todoSetRounds({
workspaceID: "ws_01HMZ7J2H3D9R5C8PWTY6QNBVE",
entryID: "entry_01HMZ7K9BQPJ3Y5T6H2SNQR4XZ",
data: { budget_rounds: 8 },
});

PATCH /api/v1/workspaces/{workspaceID}/orchestration/todo/entries/{entryID}/status

Transitions an entry to a new status and optionally attaches a handoff note and a list of mistakes learned for future sessions. context_for_next is capped at 2000 characters.

NameInTypeRequiredDescription
workspaceIDpathstringYesWorkspace identifier
entryIDpathstringYesMaster TODO entry identifier
FieldTypeRequiredDescription
statusstringYesOne of "pending", "blocked", "in_progress", "done", "failed", "skipped", "superseded"
context_for_nextstringNoHandoff note for the next session. Maximum 2000 characters.
mistakes_learnedarrayNoArray of strings describing mistakes the next session should avoid.
{
"status": "done",
"context_for_next": "Login route implemented; rate limiter wired in via src/middleware/rate-limit.ts.",
"mistakes_learned": [
"Don't sha256 the password in the route handler — use the auth service."
]
}
{
"entryID": "entry_01HMZ7K9BQPJ3Y5T6H2SNQR4XZ",
"status": "done",
"previous": "in_progress"
}
const result = await client.agent.orchestration.todoSetStatus({
workspaceID: "ws_01HMZ7J2H3D9R5C8PWTY6QNBVE",
entryID: "entry_01HMZ7K9BQPJ3Y5T6H2SNQR4XZ",
data: {
status: "done",
context_for_next: "Login route implemented; rate limiter wired in via src/middleware/rate-limit.ts.",
mistakes_learned: [
"Don't sha256 the password in the route handler — use the auth service."
]
},
});

DELETE /api/v1/workspaces/{workspaceID}/orchestration/todo/entries/{entryID}

Removes an entry from the Master TODO. Returns 409 if the entry cannot be safely deleted in its current state (for example, when it is referenced as a dependency by other in-flight entries).

NameInTypeRequiredDescription
workspaceIDpathstringYesWorkspace identifier
entryIDpathstringYesMaster TODO entry identifier
{
"deleted": true,
"entryID": "entry_01HMZ7K9BQPJ3Y5T6H2SNQR4XZ"
}
const result = await client.agent.orchestration.todoDeleteEntry({
workspaceID: "ws_01HMZ7J2H3D9R5C8PWTY6QNBVE",
entryID: "entry_01HMZ7K9BQPJ3Y5T6H2SNQR4XZ",
});