YAML Frontmatter + Markdown Body -- Agent-Consumable Task Definitions
ArkTower uses a hybrid task format combining YAML frontmatter for structured metadata with a Markdown body for human-readable descriptions. Every task is a single file that both humans and agents can read, edit, and process natively.
The canonical format is .task.md -- optimized for human authoring, version control diffs, and IDE editing. A parallel .task.json format exists for machine consumption. The two are losslessly convertible in both directions.
YAML frontmatter between --- delimiters for metadata. Markdown body below for description, acceptance criteria, and context. Git-friendly, IDE-native.
HUMAN_AUTHOREDFlat JSON object with all fields at top level. description field contains the Markdown body as a string. API responses, MCP tools, and WebSocket events all use this format.
MACHINE_CONSUMABLEComplete field reference for the ArkTower task format. All fields available in both .task.md frontmatter and .task.json.
| Field | Type | Required | Description |
|---|---|---|---|
id | string (UUID) | auto | Unique task identifier, auto-generated if omitted |
title | string | yes | Human-readable task title |
description | string | no | Markdown body -- acceptance criteria, context, references |
status | enum | auto | Current lifecycle state (10 values, default: submitted) |
priority | enum | no | priority: critical | high | medium | low (default: medium) |
tags | array[string] | no | Categorical labels for filtering and grouping |
labels | map[string, string] | no | Key-value labels for arbitrary metadata |
capabilities | array[string] | no | Required agent capabilities (e.g., python, api) |
required_tools | array[string] | no | MCP tools the agent needs (e.g., create_task) |
estimated_complexity | enum | no | trivial | low | medium | high | extreme |
parent_id | string | no | ID of parent task (for subtask hierarchy) |
context_id | string | no | Workflow or context grouping ID |
owner_id | string | no | Creator / owner identity (default: system) |
assigned_to | string | no | Agent or user currently assigned |
assigned_type | string | no | Assignee type (e.g., agent, human) |
parameters | map[string, any] | no | Arbitrary key-value parameters for task execution |
output | string | no | Completion output / result summary |
error | string | no | Error message (on failure) |
template_id | string | no | Template this task was created from |
max_steps | integer | no | Maximum execution steps allowed |
version | integer | auto | Optimistic concurrency version (default: 1) |
created_at | datetime | auto | ISO 8601 creation timestamp |
updated_at | datetime | auto | ISO 8601 last-update timestamp |
started_at | datetime | auto | When task entered in_progress |
completed_at | datetime | auto | When task reached a terminal state |
| Task Typing & Classification | |||
task_type | string | no | feature | bugfix | refactor | research | review | test | design | benchmark |
kind | string | no | Hierarchy kind: task | subtask | workflow (default: task) |
| Execution Constraints | |||
timeout_seconds | integer | no | Hard timeout for agent execution (seconds) |
max_retries | integer | no | Retries allowed on failure (default: 0) |
deadline | datetime | no | Absolute deadline (ISO 8601) |
budget_tokens | integer | no | Token budget cap for agent execution |
| Input/Output Contracts | |||
input_schema | object | no | JSON Schema defining expected inputs (default: {}) |
output_schema | object | no | JSON Schema defining expected output (default: {}) |
acceptance_criteria | array[string] | no | Testable done-when conditions |
constraints | array[string] | no | Non-negotiable boundaries for task execution |
| Context References | |||
context_refs | array[object] | no | References: each {"type": "file|url|task|snippet", "path"/"url"/"id": "...", "description": "..."} |
subtask_ids | array[string] | no | Child task IDs for hierarchical decomposition |
| Quality & Metrics | |||
quality_thresholds | object | no | Quality gates, e.g. {"coverage_pct": 80, "quality_score": 85} |
estimated_effort_minutes | integer | no | Estimated effort in minutes |
| Agent Interaction | |||
agent_instructions | string | no | Specific instructions for the claiming agent |
preferred_agent_type | string | no | Preferred agent type (e.g. code, research, review) |
retry_count | integer | auto | Current retry counter (default: 0) |
10 states, 15 named triggers. Every transition is validated and audited as a TaskEvent.
Initial state on creation
Ready for agent claim
Actively being worked on
Awaiting approval
Waiting for external input
Dependency or external block
Terminal -- success
Terminal -- error
Terminal -- manual cancel
Terminal -- timeout
| Trigger | From State | To State |
|---|---|---|
submit | (none) | submitted |
enqueue | submitted | queued |
claim | queued | in_progress |
request_input | in_progress | input_required |
resume | input_required | in_progress |
block | in_progress | blocked |
unblock | blocked | in_progress |
send_review | in_progress | review |
approve | review | completed |
reject | review | in_progress |
complete | in_progress | completed |
fail | in_progress | failed |
cancel | submitted, queued, in_progress, review, input_required, blocked | canceled |
timeout | in_progress, blocked, input_required | timed_out |
reopen | completed, failed, canceled, timed_out | queued |
Three complete task examples in both .task.md and .task.json, demonstrating the format for different task types.
1--- 2id: a1b2c3d4-e5f6-7890-abcd-ef1234567890 3title: Implement JWT Authentication for API Gateway 4status: queued 5priority: high 6task_type: feature 7kind: task 8tags: 9 - python 10 - api 11 - auth 12 - security 13capabilities: 14 - python 15 - fastapi 16 - jwt 17required_tools: 18 - create_task 19 - complete_task 20estimated_complexity: high 21owner_id: team-backend 22max_steps: 50 23timeout_seconds: 7200 24estimated_effort_minutes: 120 25preferred_agent_type: code 26parameters: 27 algorithm: RS256 28 token_expiry: 3600 29acceptance_criteria: 30 - POST /auth/login returns signed JWT 31 - Protected endpoints return 401 without valid token 32 - Token refresh endpoint implemented 33 - Unit tests for auth middleware with >80% coverage 34constraints: 35 - Must use RS256 signing (no symmetric keys) 36 - Backward compatible with existing session auth 37input_schema: 38 type: object 39 properties: 40 algorithm: {type: string} 41 token_expiry: {type: integer} 42output_schema: 43 type: object 44 properties: 45 endpoints_added: {type: array, items: {type: string}} 46 test_coverage: {type: number} 47context_refs: 48 - type: file 49 path: arktower/api/rest_routes.py 50 description: Existing API routes to protect 51 - type: url 52 url: https://pyjwt.readthedocs.io/en/stable/ 53 description: PyJWT library documentation 54 - type: file 55 path: doc_auto/architecture.md 56 description: System architecture reference 57quality_thresholds: 58 coverage_pct: 80 59 quality_score: 85 60 max_blocker_findings: 0 61--- 62 63## Description 64Add JWT-based authentication to the FastAPI gateway. Tokens 65should use RS256 signing with 1-hour expiry.
1{ 2 "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", 3 "title": "Implement JWT Authentication for API Gateway", 4 "status": "queued", 5 "priority": "high", 6 "task_type": "feature", 7 "kind": "task", 8 "tags": ["python", "api", "auth", "security"], 9 "capabilities": ["python", "fastapi", "jwt"], 10 "required_tools": ["create_task", "complete_task"], 11 "estimated_complexity": "high", 12 "owner_id": "team-backend", 13 "max_steps": 50, 14 "timeout_seconds": 7200, 15 "estimated_effort_minutes": 120, 16 "preferred_agent_type": "code", 17 "parameters": {"algorithm": "RS256", "token_expiry": 3600}, 18 "acceptance_criteria": [ 19 "POST /auth/login returns signed JWT", 20 "Protected endpoints return 401 without valid token", 21 "Token refresh endpoint implemented", 22 "Unit tests for auth middleware with >80% coverage" 23 ], 24 "constraints": [ 25 "Must use RS256 signing (no symmetric keys)", 26 "Backward compatible with existing session auth" 27 ], 28 "input_schema": { 29 "type": "object", 30 "properties": { 31 "algorithm": {"type": "string"}, 32 "token_expiry": {"type": "integer"} 33 } 34 }, 35 "output_schema": { 36 "type": "object", 37 "properties": { 38 "endpoints_added": {"type": "array", "items": {"type": "string"}}, 39 "test_coverage": {"type": "number"} 40 } 41 }, 42 "context_refs": [ 43 {"type": "file", "path": "arktower/api/rest_routes.py", "description": "Existing API routes"}, 44 {"type": "url", "url": "https://pyjwt.readthedocs.io/en/stable/", "description": "PyJWT docs"}, 45 {"type": "file", "path": "doc_auto/architecture.md", "description": "Architecture ref"} 46 ], 47 "quality_thresholds": { 48 "coverage_pct": 80, 49 "quality_score": 85, 50 "max_blocker_findings": 0 51 }, 52 "description": "## Description\nAdd JWT-based authentication to the FastAPI gateway. Tokens\nshould use RS256 signing with 1-hour expiry." 53}
1--- 2title: Fix NullReference in task claim under concurrent load 3priority: critical 4tags: 5 - bugfix 6 - production 7 - concurrency 8estimated_complexity: medium 9labels: 10 severity: P0 11 environment: production 12--- 13 14## Error Context 15``` 16TypeError: 'NoneType' object has no attribute 'status' 17 at arktower/core/task_service.py:218 18``` 19 20## Steps to Reproduce 211. Submit 10 tasks concurrently 222. Claim all from 5 parallel agents 233. Race condition on atomic_claim
1{ 2 "title": "Fix NullReference in task claim under concurrent load", 3 "priority": "critical", 4 "tags": [ 5 "bugfix", 6 "production", 7 "concurrency" 8 ], 9 "estimated_complexity": "medium", 10 "labels": { 11 "severity": "P0", 12 "environment": "production" 13 }, 14 "description": "## Error Context\n```\nTypeError: 'NoneType' object has no attribute 'status'\n at arktower/core/task_service.py:218\n```\n\n## Steps to Reproduce\n1. Submit 10 tasks concurrently\n2. Claim all from 5 parallel agents\n3. Race condition on atomic_claim" 15}
1--- 2title: Survey distributed task scheduling strategies 3priority: medium 4tags: 5 - research 6 - architecture 7 - scheduling 8capabilities: 9 - research 10 - distributed-systems 11estimated_complexity: high 12parameters: 13 scope: multi-agent task dispatch 14 context_refs: 15 - doc_auto/architecture.md 16 - arktower/core/task_service.py 17--- 18 19## Objective 20Evaluate scheduling strategies for multi-agent task pools: 21priority queues, capability-weighted dispatch, work-stealing, 22and fair-share scheduling. 23 24## Deliverables 25- [ ] Comparison matrix of 4+ strategies 26- [ ] Recommendation with trade-off analysis 27- [ ] Prototype implementation sketch
1{ 2 "title": "Survey distributed task scheduling strategies", 3 "priority": "medium", 4 "tags": [ 5 "research", 6 "architecture", 7 "scheduling" 8 ], 9 "capabilities": [ 10 "research", 11 "distributed-systems" 12 ], 13 "estimated_complexity": "high", 14 "parameters": { 15 "scope": "multi-agent task dispatch", 16 "context_refs": [ 17 "doc_auto/architecture.md", 18 "arktower/core/task_service.py" 19 ] 20 }, 21 "description": "## Objective\nEvaluate scheduling strategies for multi-agent task pools:\npriority queues, capability-weighted dispatch, work-stealing,\nand fair-share scheduling.\n\n## Deliverables\n- [ ] Comparison matrix of 4+ strategies\n- [ ] Recommendation with trade-off analysis\n- [ ] Prototype implementation sketch" 22}
JSON Schema for validating .task.json files. Used by the pre-analysis engine and API input validation.
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "ArkTower Task",
"type": "object",
"required": ["title"],
"properties": {
"id": {
"type": "string",
"format": "uuid"
},
"title": {
"type": "string",
"minLength": 1
},
"description": {
"type": "string"
},
"status": {
"type": "string",
"enum": [
"submitted",
"queued",
"in_progress",
"review",
"input_required",
"blocked",
"completed",
"failed",
"canceled",
"timed_out"
]
},
"priority": {
"type": "string",
"enum": ["critical", "high", "medium", "low"],
"default": "medium"
},
"tags": {
"type": "array",
"items": { "type": "string" }
},
"labels": {
"type": "object",
"additionalProperties": { "type": "string" }
},
"capabilities": {
"type": "array",
"items": { "type": "string" }
},
"required_tools": {
"type": "array",
"items": { "type": "string" }
},
"estimated_complexity": {
"type": "string",
"enum": ["trivial", "low", "medium", "high", "extreme"]
},
"parent_id": {
"type": ["string", "null"]
},
"context_id": {
"type": ["string", "null"]
},
"owner_id": {
"type": "string",
"default": "system"
},
"assigned_to": {
"type": ["string", "null"]
},
"assigned_type": {
"type": ["string", "null"]
},
"parameters": {
"type": "object"
},
"output": {
"type": ["string", "null"]
},
"error": {
"type": ["string", "null"]
},
"template_id": {
"type": ["string", "null"]
},
"max_steps": {
"type": ["integer", "null"],
"minimum": 1
},
"version": {
"type": "integer",
"minimum": 1
},
"created_at": {
"type": "string",
"format": "date-time"
},
"updated_at": {
"type": "string",
"format": "date-time"
},
"started_at": {
"type": ["string", "null"],
"format": "date-time"
},
"completed_at": {
"type": ["string", "null"],
"format": "date-time"
},
"task_type": {
"type": ["string", "null"],
"enum": ["feature", "bugfix", "refactor", "research", "review", "test", "design", "benchmark", null]
},
"kind": {
"type": "string",
"enum": ["task", "subtask", "workflow"],
"default": "task"
},
"timeout_seconds": {
"type": ["integer", "null"],
"minimum": 1
},
"max_retries": {
"type": "integer",
"minimum": 0,
"default": 0
},
"deadline": {
"type": ["string", "null"],
"format": "date-time"
},
"budget_tokens": {
"type": ["integer", "null"],
"minimum": 1
},
"input_schema": {
"type": "object"
},
"output_schema": {
"type": "object"
},
"acceptance_criteria": {
"type": "array",
"items": { "type": "string" }
},
"constraints": {
"type": "array",
"items": { "type": "string" }
},
"context_refs": {
"type": "array",
"items": {
"type": "object",
"properties": {
"type": { "type": "string", "enum": ["file", "url", "task", "snippet"] },
"path": { "type": "string" },
"url": { "type": "string" },
"id": { "type": "string" },
"description": { "type": "string" }
},
"required": ["type"]
}
},
"subtask_ids": {
"type": "array",
"items": { "type": "string" }
},
"quality_thresholds": {
"type": "object"
},
"estimated_effort_minutes": {
"type": ["integer", "null"],
"minimum": 1
},
"agent_instructions": {
"type": ["string", "null"]
},
"preferred_agent_type": {
"type": ["string", "null"]
},
"retry_count": {
"type": "integer",
"minimum": 0,
"default": 0
}
},
"additionalProperties": false
}
Bidirectional, lossless conversion between .task.md and .task.json formats.
1. Parse YAML frontmatter between --- delimiters
2. Extract all key-value pairs as top-level JSON fields
3. Everything below the closing --- becomes the description field
4. Arrays remain arrays, maps remain objects
5. Dates are ISO 8601 strings
1. All fields except description become YAML frontmatter
2. description field becomes the Markdown body below ---
3. Null fields are omitted from frontmatter
4. Arrays use YAML list syntax
5. Maps use nested YAML key-value syntax
Complex fields introduced in the enriched schema follow these rules:
acceptance_criteria, constraints, subtask_ids — JSON arrays in .task.json; YAML lists in .task.md frontmatter
context_refs — JSON array of objects in .task.json; YAML list of maps in .task.md
input_schema, output_schema, quality_thresholds — JSON objects in .task.json; nested YAML maps in .task.md
deadline — ISO 8601 datetime string in both formats
Empty collections ([], {}) and zero-value defaults (max_retries: 0) MAY be omitted from .task.md frontmatter