{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "$id": "https://itlackey.github.io/akm/schemas/akm-task.json",
  "title": "AKM Task source v4",
  "description": "Task source v4: typed inputs:, a single bounded output: schema, and OPTIONAL scheduling — a document with no schedule: is valid, runnable manually, composable, and is skipped (not rejected) by `akm task sync`. The akm: options bag and the on: trigger block from task v3 are gone (their members are top-level); there is no github-action uses: target; with: is legal only alongside uses: akm/command (use inputs: everywhere else for typed parameters), and output: is legal only on a command target (uses: commands/<ref> or uses: akm/command) — the only kinds whose runtime enforces it. task-v2 and task-v3 sources are converted to this schema by `akm migrate apply` — this document publishes only the version: 4 shape a task source parses to today.",
  "x-akm-runtimeConstraints": {
    "authoritativeParser": "src/tasks/source/task-source-v4.ts",
    "maxSourceUtf8Bytes": 1048576,
    "maxStringUtf8Bytes": 262144,
    "maxJsonDepth": 64,
    "maxJsonNodes": 10000,
    "canonicalRefsRequireNfc": true,
    "workingDirectoryRequiresWorkspaceRoot": true
  },
  "type": "object",
  "required": ["version"],
  "additionalProperties": false,
  "properties": {
    "version": { "const": 4 },
    "name": { "type": "string", "maxLength": 262144 },
    "description": { "type": "string", "maxLength": 262144 },
    "when_to_use": { "type": "string", "maxLength": 262144 },
    "tags": {
      "type": "array",
      "maxItems": 1024,
      "items": { "type": "string", "minLength": 1, "maxLength": 262144 }
    },
    "inputs": {
      "type": "object",
      "propertyNames": { "$ref": "#/definitions/taskInputName" },
      "additionalProperties": { "$ref": "#/definitions/inputDeclaration" }
    },
    "output": { "$ref": "#/definitions/outputSchemaDefinition" },
    "uses": {
      "oneOf": [
        { "const": "akm/command" },
        { "$ref": "#/definitions/akmExecutableRef" }
      ]
    },
    "run": { "$ref": "#/definitions/nonemptyLiteral" },
    "with": { "$ref": "#/definitions/builtinCommandWith" },
    "env": {
      "type": "object",
      "maxProperties": 256,
      "propertyNames": { "pattern": "^[A-Za-z_][A-Za-z0-9_]*$" },
      "additionalProperties": {
        "oneOf": [
          { "type": "string", "maxLength": 262144 },
          { "type": "number" },
          { "type": "boolean" }
        ]
      }
    },
    "shell": { "enum": ["bash", "sh", "zsh", "pwsh", "powershell", "cmd"] },
    "working-directory": {
      "type": "string",
      "minLength": 1,
      "maxLength": 262144,
      "pattern": "^(?![\\\\/])(?![A-Za-z]:[\\\\/])(?!.*(?:^|[\\\\/])\\.\\.(?:[\\\\/]|$))(?!.*[\\\\/]{2})(?!.*[\\\\/]$)[^\\u0000]+$"
    },
    "schedule": {
      "oneOf": [
        { "$ref": "#/definitions/nonemptyLiteral" },
        {
          "type": "array",
          "minItems": 1,
          "maxItems": 64,
          "items": { "$ref": "#/definitions/taskSourceV4ScheduleEntry" }
        }
      ]
    },
    "agent": { "$ref": "#/definitions/nullableSelector" },
    "engine": { "$ref": "#/definitions/nullableSelector" },
    "model": { "$ref": "#/definitions/nullableSelector" },
    "inference": {
      "oneOf": [
        { "$ref": "#/definitions/jsonObject" },
        { "type": "null" }
      ]
    },
    "tools": {
      "oneOf": [
        { "type": "string", "maxLength": 262144 },
        {
          "type": "array",
          "maxItems": 1024,
          "items": { "type": "string", "maxLength": 262144 }
        },
        { "$ref": "#/definitions/jsonObject" },
        { "type": "null" }
      ]
    },
    "timeout": {
      "oneOf": [
        { "type": "integer", "minimum": 0, "maximum": 2147483647 },
        { "type": "string", "pattern": "^\\d+[mMhHdD]$" },
        { "type": "null" }
      ]
    },
    "redact": {
      "type": "array",
      "maxItems": 32,
      "uniqueItems": true,
      "items": { "type": "string", "pattern": "^[A-Za-z_][A-Za-z0-9_]*$" }
    },
    "maxSteps": { "type": "integer", "minimum": 1, "maximum": 9007199254740991 },
    "maxRetries": { "type": "integer", "minimum": 0 }
  },
  "oneOf": [
    {
      "description": "AKM's built-in anonymous/stored command action.",
      "required": ["uses", "with"],
      "properties": {
        "uses": { "const": "akm/command" },
        "with": { "$ref": "#/definitions/builtinCommandWith" }
      },
      "not": {
        "anyOf": [
          { "required": ["run"] },
          { "required": ["shell"] },
          { "required": ["working-directory"] }
        ]
      }
    },
    {
      "description": "A canonical AKM executable ref (commands/, scripts/, or workflows/). No with: here — declare typed parameters with inputs: instead. output: is legal only on the commands/ arm: a scripts/ or workflows/ execution consumes no output schema, so an authored one would be a silently unenforced contract (src/tasks/source/task-source-v4.ts's targetConsumesOutputSchema).",
      "required": ["uses"],
      "properties": {
        "uses": { "$ref": "#/definitions/akmExecutableRef" }
      },
      "not": {
        "anyOf": [
          { "required": ["run"] },
          { "required": ["with"] },
          { "required": ["shell"] },
          { "required": ["working-directory"] }
        ]
      },
      "if": {
        "required": ["uses"],
        "properties": { "uses": { "$ref": "#/definitions/akmCommandRef" } }
      },
      "else": { "not": { "required": ["output"] } }
    },
    {
      "description": "One exact host-shell string. No output: here — a run: execution decides status from its exit code alone and never enforces an output schema.",
      "required": ["run"],
      "not": {
        "anyOf": [
          { "required": ["uses"] },
          { "required": ["with"] },
          { "required": ["output"] }
        ]
      }
    }
  ],
  "definitions": {
    "nonemptyLiteral": {
      "type": "string",
      "minLength": 1,
      "maxLength": 262144,
      "pattern": "^(?![\\s\\S]*\\$\\{\\{)[\\s\\S]*\\S[\\s\\S]*$"
    },
    "nullableSelector": {
      "oneOf": [
        { "type": "string", "minLength": 1, "maxLength": 262144, "pattern": ".*\\S.*" },
        { "type": "null" }
      ]
    },
    "akmExecutableRef": {
      "type": "string",
      "maxLength": 262144,
      "pattern": "^(?:[^\\s:.#/]+//)?(?:commands|workflows|scripts)/(?!\\.{1,2}(?:/|$))[^\\s#\\\\/\\u0000]+(?:/(?!\\.{1,2}(?:/|$))[^\\s#\\\\/\\u0000]+)*$"
    },
    "akmCommandRef": {
      "description": "The commands/-only subset of akmExecutableRef — the executable-ref kind whose runtime actually consumes output: (the other consumer, uses: akm/command, is a const, not a ref). Same grammar, with the kind alternation narrowed to commands.",
      "type": "string",
      "maxLength": 262144,
      "pattern": "^(?:[^\\s:.#/]+//)?commands/(?!\\.{1,2}(?:/|$))[^\\s#\\\\/\\u0000]+(?:/(?!\\.{1,2}(?:/|$))[^\\s#\\\\/\\u0000]+)*$"
    },
    "taskSourceV4ScheduleEntry": {
      "description": "One schedule: list entry. Activation is host-local scheduler configuration, never task source; inputs are validated against inputs: at parse time and delivered to the scheduled run's own invocation.",
      "type": "object",
      "required": ["cron"],
      "additionalProperties": false,
      "properties": {
        "cron": { "$ref": "#/definitions/nonemptyLiteral" },
        "inputs": { "$ref": "#/definitions/taskSourceV4ScheduleInputs" }
      }
    },
    "taskSourceV4ScheduleInputs": {
      "description": "schedule[i].inputs literals: keys are closed to the input-name pattern (the same pattern inputs: declarations use), not the free-form jsonObject shape — the runtime parser additionally rejects any key not present in the document's own inputs: declarations, which static JSON Schema cannot cross-reference here.",
      "type": "object",
      "maxProperties": 128,
      "propertyNames": { "pattern": "^[A-Za-z_][A-Za-z0-9_]*$" },
      "additionalProperties": { "$ref": "#/definitions/jsonValue" }
    },
    "taskInputName": {
      "description": "One `inputs:` declaration key. Matches the identifier pattern AND excludes every name `akm task run` reserves for its own flags (src/tasks/task-run-reserved-flags.ts's TASK_RUN_RESERVED_FLAG_NAMES — the union of TASK_RUN_VALUE_FLAGS, TASK_RUN_BOOLEAN_FLAGS, and TASK_RUN_SELF_DIAGNOSED_FLAGS) — declaring an input under one of these names is rejected at parse time (TASK_SOURCE_INVALID, parseInputDeclarations) because the CLI would always treat the flag as its own, never as this input's. `no-quiet`/`no-verbose` are citty's negations of the `quiet`/`verbose` booleans and are listed for completeness even though the identifier pattern already excludes any hyphenated name.",
      "type": "string",
      "pattern": "^[A-Za-z_][A-Za-z0-9_]*$",
      "not": {
        "enum": [
          "bundle",
          "format",
          "detail",
          "shape",
          "output",
          "scheduled",
          "quiet",
          "verbose",
          "help",
          "no-quiet",
          "no-verbose",
          "target"
        ]
      }
    },
    "inputDeclaration": {
      "description": "One inputs: declaration: a bounded JSON Schema. At the declaration ROOT, required is task source v4's own boolean flag, not JSON Schema's required array; default must itself satisfy the remaining schema; default + required:true together is invalid (D2-N3). Nested schemas (properties/items/allOf/anyOf/oneOf/not) keep ordinary JSON-Schema meaning via outputSchemaDefinition. Closed to exactly this key set — an unlisted keyword (e.g. pattern) is rejected here even though the runtime subset accepts it inside output:, because a task input declaration is intentionally narrower.",
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "type": {
          "oneOf": [
            { "$ref": "#/definitions/outputSchemaTypeName" },
            {
              "type": "array",
              "minItems": 1,
              "maxItems": 1024,
              "items": { "$ref": "#/definitions/outputSchemaTypeName" }
            }
          ]
        },
        "enum": {
          "type": "array",
          "minItems": 1,
          "maxItems": 1024,
          "items": {
            "oneOf": [
              { "type": "string", "maxLength": 262144 },
              { "type": "number" },
              { "type": "boolean" },
              { "type": "null" }
            ]
          }
        },
        "properties": {
          "type": "object",
          "maxProperties": 256,
          "propertyNames": { "maxLength": 262144 },
          "additionalProperties": { "$ref": "#/definitions/outputSchemaDefinition" }
        },
        "required": {
          "description": "Declaration-ROOT required is task source v4's own boolean flag, not a JSON-Schema required array (D2-N3).",
          "type": "boolean"
        },
        "items": { "$ref": "#/definitions/outputSchemaDefinition" },
        "additionalProperties": { "type": "boolean" },
        "minItems": { "type": "integer", "minimum": 0 },
        "maxItems": { "type": "integer", "minimum": 0 },
        "minLength": { "type": "integer", "minimum": 0 },
        "maxLength": { "type": "integer", "minimum": 0 },
        "minimum": { "type": "number" },
        "maximum": { "type": "number" },
        "allOf": { "$ref": "#/definitions/outputSchemaArray" },
        "anyOf": { "$ref": "#/definitions/outputSchemaArray" },
        "oneOf": { "$ref": "#/definitions/outputSchemaArray" },
        "not": { "$ref": "#/definitions/outputSchemaDefinition" },
        "title": { "type": "string", "maxLength": 262144 },
        "description": { "type": "string", "maxLength": 262144 },
        "default": { "$ref": "#/definitions/jsonValue" }
      }
    },
    "outputSchemaDefinition": {
      "type": "object",
      "maxProperties": 256,
      "properties": {
        "type": {
          "oneOf": [
            { "$ref": "#/definitions/outputSchemaTypeName" },
            {
              "type": "array",
              "minItems": 1,
              "maxItems": 1024,
              "items": { "$ref": "#/definitions/outputSchemaTypeName" }
            }
          ]
        },
        "enum": {
          "type": "array",
          "minItems": 1,
          "maxItems": 1024,
          "items": {
            "oneOf": [
              { "type": "string", "maxLength": 262144 },
              { "type": "number" },
              { "type": "boolean" },
              { "type": "null" }
            ]
          }
        },
        "properties": {
          "type": "object",
          "maxProperties": 256,
          "propertyNames": { "maxLength": 262144 },
          "additionalProperties": { "$ref": "#/definitions/outputSchemaDefinition" }
        },
        "required": {
          "type": "array",
          "maxItems": 1024,
          "items": { "type": "string", "maxLength": 262144 }
        },
        "items": { "$ref": "#/definitions/outputSchemaDefinition" },
        "additionalProperties": { "type": "boolean" },
        "minItems": { "type": "integer", "minimum": 0 },
        "maxItems": { "type": "integer", "minimum": 0 },
        "minLength": { "type": "integer", "minimum": 0 },
        "maxLength": { "type": "integer", "minimum": 0 },
        "minimum": { "type": "number" },
        "maximum": { "type": "number" },
        "allOf": { "$ref": "#/definitions/outputSchemaArray" },
        "anyOf": { "$ref": "#/definitions/outputSchemaArray" },
        "oneOf": { "$ref": "#/definitions/outputSchemaArray" },
        "not": { "$ref": "#/definitions/outputSchemaDefinition" },
        "$ref": false,
        "$defs": false,
        "definitions": false,
        "$anchor": false,
        "$dynamicRef": false,
        "$dynamicAnchor": false,
        "if": false,
        "then": false,
        "else": false,
        "const": false,
        "pattern": false,
        "format": false,
        "patternProperties": false,
        "propertyNames": false,
        "additionalItems": false,
        "prefixItems": false,
        "contains": false,
        "minContains": false,
        "maxContains": false,
        "uniqueItems": false,
        "multipleOf": false,
        "exclusiveMinimum": false,
        "exclusiveMaximum": false,
        "minProperties": false,
        "maxProperties": false,
        "dependencies": false,
        "dependentRequired": false,
        "dependentSchemas": false,
        "unevaluatedItems": false,
        "unevaluatedProperties": false,
        "contentEncoding": false,
        "contentMediaType": false,
        "contentSchema": false
      },
      "additionalProperties": { "$ref": "#/definitions/jsonValue" }
    },
    "outputSchemaArray": {
      "type": "array",
      "minItems": 1,
      "maxItems": 1024,
      "items": { "$ref": "#/definitions/outputSchemaDefinition" }
    },
    "outputSchemaTypeName": {
      "enum": ["string", "number", "integer", "boolean", "object", "array", "null"]
    },
    "builtinCommandWith": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "ref": { "type": "string", "minLength": 1, "maxLength": 262144 },
        "content": { "type": "string", "maxLength": 262144 },
        "arguments": { "type": "string", "maxLength": 262144 }
      },
      "oneOf": [
        { "required": ["ref"], "not": { "required": ["content"] } },
        { "required": ["content"], "not": { "required": ["ref"] } }
      ]
    },
    "jsonValue": {
      "oneOf": [
        { "type": "string", "maxLength": 262144 },
        { "type": "number" },
        { "type": "boolean" },
        { "type": "null" },
        { "$ref": "#/definitions/jsonArray" },
        { "$ref": "#/definitions/jsonObject" }
      ]
    },
    "jsonArray": {
      "type": "array",
      "maxItems": 1024,
      "items": { "$ref": "#/definitions/jsonValue" }
    },
    "jsonObject": {
      "type": "object",
      "maxProperties": 256,
      "propertyNames": { "maxLength": 262144 },
      "additionalProperties": { "$ref": "#/definitions/jsonValue" }
    }
  }
}
