taskfleet-core 0.12.0

Core state, locking, and supervisor protocol library for Taskfleet.
Documentation
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://taskfleet.dev/schemas/plan.v3.schema.json",
  "title": "taskfleet plan.json (v3)",
  "description": "The interface contract the spec-node writes and the supervisor + orchestrator read. Immutable per revision, versioned, provenance-bearing. See issues/code-pipeline/plan-schema.md and design.md §4/§7/§13. v3 makes the baseline provenance fields (commit_oid, toolchain, enumerated_targets_hash) structurally REQUIRED — a plan missing them is rejected, not silently defaulted. This schema is the checked-in machine-readable artifact; the operative source of truth for readers/writers is the taskfleet_core::plan Rust validator, and a drift-guard test keeps the two in agreement.",
  "type": "object",
  "additionalProperties": false,
  "required": [
    "schema_version",
    "plan_rev",
    "intent_rev",
    "feature",
    "baseline",
    "acceptance",
    "chunks"
  ],
  "properties": {
    "schema_version": {
      "description": "Major schema version. Readers reject unsupported majors (do NOT silently ignore).",
      "type": "integer",
      "const": 3
    },
    "plan_rev": {
      "description": "Immutable revision of this plan. A fix or re-spec writes plan.v(N+1).json; each chunk attempt records the plan_rev it consumed.",
      "type": "integer",
      "minimum": 0
    },
    "intent_rev": {
      "description": "The orchestrator-owned intent.md revision this plan targets. Intent is referenced, not embedded.",
      "type": "integer",
      "minimum": 0
    },
    "feature": {
      "type": "object",
      "additionalProperties": false,
      "required": ["slug", "source_branch", "integration_branch"],
      "properties": {
        "slug": { "type": "string", "minLength": 1 },
        "source_branch": { "type": "string", "minLength": 1 },
        "integration_branch": { "type": "string", "minLength": 1 }
      }
    },
    "baseline": {
      "description": "Snapshot at feat/<slug> fork; verify + the deterministic floor diff against it. Supervisor-owned.",
      "type": "object",
      "additionalProperties": false,
      "required": ["ref", "commit_oid", "toolchain", "test_passlist_hash", "clippy_warnings_hash", "enumerated_targets_hash"],
      "properties": {
        "ref": { "type": "string", "minLength": 1 },
        "commit_oid": { "type": "string", "minLength": 1, "description": "Ref resolved to an immutable commit OID at capture time (floor provenance; required as of v3)." },
        "toolchain": { "type": "string", "minLength": 1, "description": "rustc -V fingerprint the snapshot was captured with (floor provenance; required as of v3)." },
        "test_passlist_hash": { "type": "string", "minLength": 1 },
        "clippy_warnings_hash": { "type": "string", "minLength": 1 },
        "enumerated_targets_hash": { "type": "string", "minLength": 1, "description": "Hash of the enumerated (package, target_kind, target) test-target set (floor F7 superset check; required as of v3)." }
      }
    },
    "acceptance": {
      "description": "Whole-feature intent gate. Each item is an executable check or an LLM-judged assertion; at least one must be a check.",
      "type": "array",
      "minItems": 1,
      "items": { "$ref": "#/$defs/acceptance_item" }
    },
    "chunks": {
      "description": "The DAG of implementation chunks. deps form an acyclic dependency graph.",
      "type": "array",
      "minItems": 1,
      "items": { "$ref": "#/$defs/chunk" }
    }
  },
  "$defs": {
    "acceptance_item": {
      "oneOf": [
        {
          "type": "object",
          "additionalProperties": false,
          "required": ["kind", "desc", "run"],
          "properties": {
            "kind": { "const": "check" },
            "desc": { "type": "string", "minLength": 1 },
            "run": { "type": "string", "minLength": 1 },
            "cwd": {
              "description": "Optional working directory to run `run` in; absent = worktree root. Must be a safe repo-relative path (no absolute paths, `~`, `..`, backslash, `:`, control chars, or a bare `.`) — enforced by the taskfleet_core::plan validator, as for files_touched.",
              "type": "string",
              "minLength": 1
            },
            "expect_exit": {
              "description": "Optional expected exit code; the check passes iff the command exits with it. Absent = 0. A shell exit status is 0..=255.",
              "type": "integer",
              "minimum": 0,
              "maximum": 255
            }
          }
        },
        {
          "type": "object",
          "additionalProperties": false,
          "required": ["kind", "desc"],
          "properties": {
            "kind": { "const": "assertion" },
            "desc": { "type": "string", "minLength": 1 }
          }
        }
      ]
    },
    "check": {
      "description": "An executable check: the general goal (desc) plus a flexible shell command (run), with optional cwd/expect_exit precision. Precision is available, not forced.",
      "type": "object",
      "additionalProperties": false,
      "required": ["desc", "run"],
      "properties": {
        "desc": {
          "description": "The general goal of the check — what it verifies. Always present.",
          "type": "string",
          "minLength": 1
        },
        "run": {
          "description": "A flexible shell command executed via `sh -c`.",
          "type": "string",
          "minLength": 1
        },
        "cwd": {
          "description": "Optional working directory to run `run` in; absent = worktree root. Must be a safe repo-relative path (no absolute paths, `~`, `..`, backslash, `:`, control chars, or a bare `.`) — enforced by the taskfleet_core::plan validator, as for files_touched.",
          "type": "string",
          "minLength": 1
        },
        "expect_exit": {
          "description": "Optional expected exit code; the check passes iff the command exits with it. Absent = 0. A shell exit status is 0..=255.",
          "type": "integer",
          "minimum": 0,
          "maximum": 255
        }
      }
    },
    "chunk": {
      "type": "object",
      "additionalProperties": false,
      "required": ["id", "title", "tier", "brief", "files_touched", "checks"],
      "properties": {
        "id": {
          "description": "Unique within the plan; referenced by other chunks' deps.",
          "type": "string",
          "pattern": "^[A-Za-z0-9][A-Za-z0-9_.-]*$"
        },
        "title": { "type": "string", "minLength": 1 },
        "deps": {
          "description": "Ids of chunks this one depends on. Every entry must reference an existing chunk; entries must be unique; the graph must be acyclic (acyclicity is enforced by the Rust validator, not expressible in JSON Schema).",
          "type": "array",
          "items": { "type": "string" },
          "uniqueItems": true,
          "default": []
        },
        "tier": {
          "description": "Starting model tier hint; the orchestrator owns promotion.",
          "type": "string",
          "enum": ["code", "mid", "high"]
        },
        "brief": {
          "description": "Turnkey, self-contained implementation brief.",
          "type": "string",
          "minLength": 1
        },
        "files_touched": {
          "description": "Merge-time constraint (not just a hint): repo-relative paths, no traversal.",
          "type": "array",
          "minItems": 1,
          "items": { "type": "string", "minLength": 1 }
        },
        "checks": {
          "description": "Executable per-chunk checks; at least one required.",
          "type": "array",
          "minItems": 1,
          "items": { "$ref": "#/$defs/check" }
        },
        "assertions": {
          "description": "LLM-judged criteria, additive above the deterministic floor. Each must be a non-empty string (the Rust validator additionally rejects whitespace-only strings).",
          "type": "array",
          "items": { "type": "string", "minLength": 1 },
          "default": []
        },
        "requires_tests": {
          "description": "If true, the supervisor blocks a merge that added/modified no tests.",
          "type": "boolean",
          "default": false
        }
      }
    }
  }
}