{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "$id": "https://cleo-dev.com/schemas/v1/config.schema.json",
  "schemaVersion": "2.11.0",
  "title": "CLEO Configuration Schema",
  "description": "Configuration for archive policies, validation rules, logging, and session behavior.",
  "type": "object",
  "required": [
    "version"
  ],
  "additionalProperties": false,
  "properties": {
    "$schema": {
      "type": "string",
      "description": "JSON Schema reference for validation."
    },
    "version": {
      "type": "string",
      "pattern": "^\\d+\\.\\d+\\.\\d+$",
      "description": "Legacy schema version field (deprecated, use _meta.schemaVersion)"
    },
    "_meta": {
      "type": "object",
      "description": "Configuration file metadata.",
      "required": [
        "schemaVersion"
      ],
      "additionalProperties": false,
      "properties": {
        "schemaVersion": {
          "type": "string",
          "pattern": "^\\d+\\.\\d+\\.\\d+$",
          "description": "Schema version for this file (semver). Canonical source for schema version (replaces root version field)."
        }
      }
    },
    "extends": {
      "oneOf": [
        {
          "type": "string",
          "description": "Single config to extend (file path or npm package)"
        },
        {
          "type": "array",
          "items": {
            "type": "string"
          },
          "minItems": 1,
          "description": "Multiple configs to extend (processed left-to-right, last wins)"
        }
      ],
      "description": "Configuration inheritance. Supports file paths (~/.cleo/config.json, ../shared/config.json) or npm packages (@cleo/config-ci). Resolution order: global config → extended configs (left-to-right) → project config → environment variables. Deep merge strategy: primitive values last-wins, arrays concatenate with deduplication, objects merge recursively. Circular extends chains MUST be detected and MUST fail with exit code 6 (E_VALIDATION_FAILED).",
      "examples": [
        "~/.cleo/config.json",
        [
          "~/.cleo/config.json",
          "@cleo/config-ci"
        ]
      ]
    },
    "directories": {
      "type": "object",
      "description": "Directory path configuration. Only agentOutputs is consumed; all other sub-fields were vaporware (T109).",
      "additionalProperties": false,
      "properties": {
        "agentOutputs": {
          "type": "string",
          "default": ".cleo/agent-outputs",
          "description": "DEPRECATED: Use agentOutputs.directory instead. Agent manifest outputs (legacy flat-file location). Retained as Priority 3 fallback in paths.ts. New writes go to pipeline_manifest per ADR-027.",
          "x-deprecated": true,
          "x-deprecated-by": "agentOutputs.directory"
        }
      }
    },
    "archive": {
      "type": "object",
      "description": "Archive automation settings.",
      "additionalProperties": false,
      "properties": {
        "enabled": {
          "type": "boolean",
          "default": true,
          "description": "Enable automatic archiving of completed tasks."
        },
        "daysUntilArchive": {
          "type": "integer",
          "minimum": 1,
          "maximum": 365,
          "default": 7,
          "description": "Days after completion before task is eligible for archive."
        },
        "maxCompletedTasks": {
          "type": "integer",
          "minimum": 1,
          "maximum": 100,
          "default": 15,
          "description": "Max completed tasks in todo.json before triggering archive."
        },
        "preserveRecentCount": {
          "type": "integer",
          "minimum": 0,
          "maximum": 20,
          "default": 3,
          "description": "Always keep this many recent completed tasks (for context)."
        },
        "archiveOnSessionEnd": {
          "type": "boolean",
          "default": true,
          "description": "Run archive check at session end."
        },
        "autoArchiveOnComplete": {
          "type": "boolean",
          "default": false,
          "description": "Automatically archive completed task if eligible (age >= daysUntilArchive)."
        },
        "exemptLabels": {
          "type": "array",
          "items": {
            "type": "string",
            "minLength": 1
          },
          "default": [
            "pinned",
            "keep"
          ],
          "description": "Labels that exempt tasks from automatic archiving. Add these labels to any task/epic you want to protect from auto-archive."
        },
        "labelPolicies": {
          "type": "object",
          "description": "Per-label retention policies overriding defaults.",
          "additionalProperties": {
            "type": "object",
            "additionalProperties": false,
            "properties": {
              "daysUntilArchive": {
                "type": "integer",
                "minimum": 1,
                "maximum": 365,
                "description": "Days after completion before task with this label is eligible for archive."
              },
              "neverArchive": {
                "type": "boolean",
                "description": "If true, tasks with this label are never automatically archived."
              }
            }
          },
          "default": {}
        },
        "relationshipSafety": {
          "type": "object",
          "description": "Safety settings for archiving tasks with relationships.",
          "additionalProperties": false,
          "properties": {
            "preventOrphanChildren": {
              "type": "boolean",
              "default": true,
              "description": "Don't archive parent tasks with active children."
            },
            "preventBrokenDependencies": {
              "type": "boolean",
              "default": true,
              "description": "Warn before archiving tasks that would break dependency chains."
            },
            "cascadeArchive": {
              "type": "boolean",
              "default": false,
              "description": "Allow cascade archiving of completed children when parent is archived."
            }
          }
        },
        "phaseTriggers": {
          "type": "object",
          "description": "Phase completion triggers for auto-archiving.",
          "additionalProperties": false,
          "properties": {
            "enabled": {
              "type": "boolean",
              "default": false,
              "description": "Enable phase-based archive triggers."
            },
            "phases": {
              "type": "array",
              "items": {
                "type": "string",
                "pattern": "^[a-z][a-z0-9-]*$"
              },
              "default": [],
              "description": "Phase slugs that trigger archiving when completed."
            },
            "archivePhaseOnly": {
              "type": "boolean",
              "default": true,
              "description": "Only archive tasks from the completed phase (vs all eligible tasks)."
            }
          }
        },
        "interactive": {
          "type": "object",
          "description": "Interactive prompts and warnings for archive operations.",
          "additionalProperties": false,
          "properties": {
            "confirmBeforeArchive": {
              "type": "boolean",
              "default": false,
              "description": "Prompt for confirmation before archiving tasks."
            },
            "showWarnings": {
              "type": "boolean",
              "default": true,
              "description": "Show warnings about relationships and dependencies before archiving."
            }
          }
        }
      }
    },
    "pinoLogging": {
      "type": "object",
      "description": "Application diagnostic logging (pino). Writes to .cleo/logs/cleo.log.",
      "additionalProperties": false,
      "properties": {
        "level": {
          "type": "string",
          "enum": ["trace", "debug", "info", "warn", "error", "fatal", "silent"],
          "default": "info",
          "description": "Minimum log level to record."
        },
        "filePath": {
          "type": "string",
          "default": "logs/cleo.log",
          "description": "Log file path relative to .cleo/ directory."
        },
        "maxFileSize": {
          "type": "integer",
          "minimum": 1048576,
          "maximum": 1073741824,
          "default": 10485760,
          "description": "Max log file size in bytes before rotation (default: 10MB)."
        },
        "maxFiles": {
          "type": "integer",
          "minimum": 1,
          "maximum": 100,
          "default": 5,
          "description": "Number of rotated log files to retain."
        }
      }
    },
    "validation": {
      "type": "object",
      "description": "Legacy validation settings. Most fields have been superseded by dedicated enforcement sections. Only deprecated fields retained for backward compatibility with existing config files.",
      "additionalProperties": false,
      "properties": {
        "validateDependencies": {
          "type": "boolean",
          "default": true,
          "x-deprecated": true,
          "description": "DEPRECATED: dependency validation always runs unconditionally. This flag is never read by the engine. Retained for backward compatibility only."
        },
        "detectCircularDeps": {
          "type": "boolean",
          "default": true,
          "x-deprecated": true,
          "description": "DEPRECATED: circular dependency detection always runs unconditionally. This flag is never read by the engine. Retained for backward compatibility only."
        },
        "releaseGates": {
          "type": "array",
          "description": "DEPRECATED: Use release.gates instead. Validation gates for release operations.",
          "x-deprecated": true,
          "x-deprecated-by": "release.gates",
          "items": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "name",
              "command"
            ],
            "properties": {
              "name": {
                "type": "string",
                "pattern": "^[a-z][a-z0-9_-]*$",
                "description": "Unique gate identifier."
              },
              "command": {
                "type": "string",
                "minLength": 1,
                "description": "Shell command to execute."
              },
              "required": {
                "type": "boolean",
                "default": true,
                "description": "If true, gate failure blocks release."
              },
              "description": {
                "type": "string",
                "description": "Human-readable description."
              }
            }
          },
          "default": []
        }
      }
    },
    "verification": {
      "type": "object",
      "description": "Verification gates configuration for task quality tracking.",
      "additionalProperties": false,
      "properties": {
        "enabled": {
          "type": "boolean",
          "default": true,
          "description": "Enable verification gates for task completion. When true, parent auto-complete requires verification.passed = true."
        },
        "requiredForTypes": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "default": ["epic", "task", "subtask"],
          "description": "Task types that require verification gates."
        },
        "autoInitialize": {
          "type": "boolean",
          "default": true,
          "description": "Automatically initialize verification metadata on task creation."
        },
        "maxRounds": {
          "type": "integer",
          "minimum": 1,
          "maximum": 10,
          "default": 5,
          "description": "Maximum implementation rounds before HITL escalation."
        },
        "requiredGates": {
          "type": "array",
          "items": {
            "type": "string",
            "enum": [
              "implemented",
              "testsPassed",
              "qaPassed",
              "cleanupDone",
              "securityPassed",
              "documented"
            ]
          },
          "default": [
            "implemented",
            "testsPassed",
            "qaPassed",
            "securityPassed",
            "documented"
          ],
          "description": "Gates required to pass for verification.passed = true. cleanupDone excluded by default."
        },
        "autoSetImplementedOnComplete": {
          "type": "boolean",
          "default": true,
          "description": "Automatically set gates.implemented = true when ct complete runs."
        },
        "requireForParentAutoComplete": {
          "type": "boolean",
          "default": true,
          "description": "Require verification.passed = true for parent auto-complete."
        },
        "allowManualOverride": {
          "type": "boolean",
          "default": true,
          "description": "Allow --skip-verification flag on ct complete."
        }
      }
    },
    "defaults": {
      "type": "object",
      "description": "Default values for new tasks. Only priority is consumed (T109).",
      "additionalProperties": false,
      "properties": {
        "priority": {
          "type": "string",
          "enum": [
            "critical",
            "high",
            "medium",
            "low"
          ],
          "default": "medium"
        }
      }
    },
    "session": {
      "type": "object",
      "description": "Session behavior settings. Only enforcement is consumed from config; other fields were vaporware (T109). Core session behavior uses enforcement.session.requiredForMutate.",
      "additionalProperties": false,
      "properties": {
        "enforcement": {
          "type": "string",
          "enum": [
            "strict",
            "warn",
            "advisory",
            "none",
            "off"
          ],
          "default": "strict",
          "description": "Session enforcement mode for write operations. strict=block without session, warn/advisory=warn but allow, none/off=no enforcement."
        },
        "autoStart": {
          "type": "boolean",
          "default": false,
          "x-deprecated": true,
          "description": "DEPRECATED: not enforced by the engine. Auto-start behavior is not supported. Retained for backward compatibility."
        },
        "multiSession": {
          "type": "boolean",
          "default": false,
          "x-deprecated": true,
          "description": "DEPRECATED: not enforced by the engine. Multi-session mode is not supported. Retained for backward compatibility."
        }
      }
    },
    "output": {
      "type": "object",
      "description": "Output formatting and display preferences. Fields are ENV-mapped (CLEO_FORMAT, CLEO_OUTPUT_*) but not consumed by the rendering layer at runtime — format is determined by CLI flags. Fields retained for ENV_MAP wiring only.",
      "additionalProperties": false,
      "properties": {
        "defaultFormat": {
          "type": "string",
          "enum": [
            "text",
            "json",
            "jsonl",
            "csv",
            "tsv",
            "markdown",
            "table"
          ],
          "default": "text",
          "description": "Default output format for list and export commands. Mapped from CLEO_FORMAT env var."
        },
        "showColor": {
          "type": "boolean",
          "default": true,
          "description": "Enable ANSI color output. Respects NO_COLOR env var. Mapped from CLEO_OUTPUT_SHOW_COLOR."
        },
        "showUnicode": {
          "type": "boolean",
          "default": true,
          "description": "Use Unicode symbols and box-drawing characters. Mapped from CLEO_OUTPUT_SHOW_UNICODE."
        },
        "showProgressBars": {
          "type": "boolean",
          "default": true,
          "description": "Show progress bars in dashboard and phase views. Mapped from CLEO_OUTPUT_SHOW_PROGRESS_BARS."
        },
        "dateFormat": {
          "type": "string",
          "enum": [
            "iso8601",
            "relative",
            "unix",
            "locale"
          ],
          "default": "iso8601",
          "description": "Date/time display format. Mapped from CLEO_OUTPUT_DATE_FORMAT. NOTE: enum differs from contracts/config.ts DateFormat type — reconcile in follow-up."
        }
      }
    },
    "backup": {
      "type": "object",
      "description": "Backup system configuration for snapshots, safety backups, incremental backups, and archive backups.",
      "additionalProperties": false,
      "properties": {
        "enabled": {
          "type": "boolean",
          "default": true,
          "description": "Enable backup system globally."
        },
        "directory": {
          "type": "string",
          "default": ".claude/backups",
          "description": "Directory for storing all backup types (snapshot, safety, incremental, archive, migration)."
        },
        "maxSnapshots": {
          "type": "integer",
          "minimum": 0,
          "maximum": 100,
          "default": 10,
          "description": "Maximum number of snapshot backups to retain (count-based retention)."
        },
        "maxSafetyBackups": {
          "type": "integer",
          "minimum": 0,
          "maximum": 50,
          "default": 5,
          "description": "Maximum number of safety backups to retain (count-based retention, works with safetyRetentionDays)."
        },
        "maxOperationalBackups": {
          "type": "integer",
          "minimum": 0,
          "maximum": 100,
          "default": 10,
          "description": "Maximum number of operational (session-triggered) backups to retain (count-based retention)."
        },
        "maxIncremental": {
          "type": "integer",
          "minimum": 0,
          "maximum": 100,
          "default": 10,
          "description": "Maximum number of incremental backups to retain (count-based retention)."
        },
        "maxArchiveBackups": {
          "type": "integer",
          "minimum": 0,
          "maximum": 20,
          "default": 3,
          "description": "Maximum number of archive backups to retain (count-based retention)."
        },
        "safetyRetentionDays": {
          "type": "integer",
          "minimum": 0,
          "maximum": 365,
          "default": 7,
          "description": "Days to retain safety backups (time-based retention, works with maxSafetyBackups)."
        },
        "scheduled": {
          "type": "object",
          "description": "Scheduled/automatic backup settings for session events and operations.",
          "additionalProperties": false,
          "properties": {
            "onSessionStart": {
              "type": "boolean",
              "default": false,
              "description": "Create snapshot backup when session starts."
            },
            "onSessionEnd": {
              "type": "boolean",
              "default": false,
              "description": "Create safety backup when session ends."
            },
            "onArchive": {
              "type": "boolean",
              "default": true,
              "description": "Create safety backup before archive operations."
            },
            "intervalMinutes": {
              "type": "integer",
              "minimum": 0,
              "maximum": 1440,
              "default": 0,
              "description": "Optional interval (minutes) for timed backups. 0 disables interval-based backups. When set, backups are created on CLI invocation if interval has elapsed since last backup."
            }
          }
        }
      }
    },
    "cancellation": {
      "type": "object",
      "description": "DEPRECATED: cancellation behavior is controlled by CLI flags (--children, --reason, --force). None of these fields are read by the engine. Retained for backward compatibility only.",
      "x-deprecated": true,
      "additionalProperties": false,
      "properties": {
        "cascadeConfirmThreshold": {
          "type": "integer",
          "minimum": 1,
          "maximum": 100,
          "default": 10,
          "x-deprecated": true,
          "description": "DEPRECATED: not enforced by the engine. Use --force CLI flag to bypass confirmation."
        },
        "requireReason": {
          "type": "boolean",
          "default": true,
          "x-deprecated": true,
          "description": "DEPRECATED: not enforced by the engine. Cancellation reason is optional and passed via --reason CLI flag."
        },
        "daysUntilArchive": {
          "type": "integer",
          "minimum": 0,
          "maximum": 365,
          "default": 3,
          "x-deprecated": true,
          "description": "DEPRECATED: not enforced by the engine. Cancelled task archiving is handled by the archive section."
        },
        "allowCascade": {
          "type": "boolean",
          "default": true,
          "x-deprecated": true,
          "description": "DEPRECATED: not enforced by the engine. Cascade behavior is controlled by the --children CLI flag."
        },
        "defaultChildStrategy": {
          "type": "string",
          "enum": [
            "block",
            "orphan",
            "cascade",
            "fail"
          ],
          "default": "block",
          "x-deprecated": true,
          "description": "DEPRECATED: not enforced by the engine. Default child strategy is always 'block'; override with --children CLI flag."
        }
      }
    },
    "hierarchy": {
      "type": "object",
      "description": "Hierarchy constraints for Epic → Task → Subtask structure. LLM-Agent-First design: limits are organizational, not cognitive.",
      "additionalProperties": false,
      "properties": {
        "maxSiblings": {
          "type": "integer",
          "minimum": 0,
          "maximum": 1000,
          "default": 0,
          "description": "Maximum children per parent (0 = unlimited, recommended for LLM agents). Done tasks excluded by default. See TASK-HIERARCHY-SPEC.md Part 3.2."
        },
        "maxDepth": {
          "type": "integer",
          "minimum": 1,
          "maximum": 10,
          "default": 3,
          "description": "Maximum hierarchy depth (epic=0, task=1, subtask=2). Rarely needs changing."
        },
        "countDoneInLimit": {
          "type": "boolean",
          "default": false,
          "description": "Whether done tasks count toward maxSiblings. Default false: done tasks are historical record, not active context."
        },
        "maxActiveSiblings": {
          "type": "integer",
          "minimum": 0,
          "maximum": 100,
          "default": 8,
          "description": "Maximum active (non-done) children per parent. Aligns with TodoWrite sync limit for context management."
        }
      }
    },
    "storage": {
      "type": "object",
      "description": "Storage engine configuration. SQLite is always used unconditionally — this field is declarative intent only and has no behavioral effect (T109).",
      "additionalProperties": false,
      "properties": {
        "engine": {
          "type": "string",
          "enum": [
            "json",
            "sqlite",
            "dual"
          ],
          "default": "sqlite",
          "description": "Storage engine declaration. NOTE: SQLite is always used; this field is not read at runtime to select the engine. Declarative only.",
          "x-deprecated": true
        }
      }
    },
    "analyze": {
      "type": "object",
      "description": "Configuration for the analyze command. Only lockAwareness.{enabled,warnOnly} are consumed (T109).",
      "additionalProperties": false,
      "properties": {
        "lockAwareness": {
          "type": "object",
          "description": "Lock file detection and concurrent operation awareness settings.",
          "additionalProperties": false,
          "properties": {
            "enabled": {
              "type": "boolean",
              "default": true,
              "description": "Enable lock detection in analyze output."
            },
            "warnOnly": {
              "type": "boolean",
              "default": true,
              "description": "Warn about locks but don't block operations. Set false to block on active locks."
            }
          }
        }
      }
    },
    "contextAlerts": {
      "type": "object",
      "description": "Context window alert configuration. Controls when and how users are alerted about context window usage approaching thresholds.",
      "additionalProperties": false,
      "properties": {
        "enabled": {
          "type": "boolean",
          "default": true,
          "description": "Enable context window threshold alerts. When false, no alerts are shown."
        },
        "triggerCommands": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "default": [
            "complete",
            "focus",
            "add",
            "session"
          ],
          "description": "Commands that trigger context alert checks. Empty array = all commands."
        },
        "suppressDuration": {
          "type": "integer",
          "minimum": 0,
          "maximum": 3600,
          "default": 0,
          "description": "Seconds to suppress repeat alerts at same threshold level. 0 = show on every threshold crossing."
        }
      }
    },
    "agentOutputs": {
      "type": "object",
      "description": "Cross-agent output configuration. Only directory and manifestFile are consumed (T109).",
      "additionalProperties": false,
      "properties": {
        "directory": {
          "type": "string",
          "default": ".cleo/agent-outputs",
          "description": "Directory for agent outputs relative to project root.",
          "x-deprecated-alias": "research.outputDir"
        },
        "manifestFile": {
          "type": "string",
          "default": "legacy-manifest.jsonl",
          "description": "DEPRECATED: Flat-file manifest retired per ADR-027. New entries go to pipeline_manifest (tasks.db) via cleo manifest CLI. This default kept for migration read-back only."
        }
      }
    },
    "research": {
      "type": "object",
      "description": "DEPRECATED: Use agentOutputs instead. Only outputDir and manifestFile are consumed (T109).",
      "x-deprecated": true,
      "x-deprecated-by": "agentOutputs",
      "additionalProperties": false,
      "properties": {
        "outputDir": {
          "type": "string",
          "default": ".cleo/agent-outputs",
          "description": "DEPRECATED: Use agentOutputs.directory instead. Directory for research outputs relative to project root.",
          "x-deprecated": true,
          "x-deprecated-by": "agentOutputs.directory"
        },
        "manifestFile": {
          "type": "string",
          "default": "legacy-manifest.jsonl",
          "description": "DEPRECATED: Use agentOutputs.manifestFile instead. Flat-file retired per ADR-027.",
          "x-deprecated": true,
          "x-deprecated-by": "agentOutputs.manifestFile"
        }
      }
    },
    "release": {
      "type": "object",
      "description": "Release system configuration including validation gates for pre-release checks.",
      "additionalProperties": false,
      "properties": {
        "gates": {
          "type": "array",
          "description": "Validation gates executed before release. Each gate is a command that must exit 0 to pass.",
          "items": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "name",
              "command"
            ],
            "properties": {
              "name": {
                "type": "string",
                "pattern": "^[a-z][a-z0-9_-]*$",
                "description": "Unique gate identifier (snake_case or kebab-case)."
              },
              "command": {
                "type": "string",
                "minLength": 1,
                "description": "Shell command to execute. Exit 0 = pass, non-zero = fail."
              },
              "required": {
                "type": "boolean",
                "default": true,
                "description": "If true, gate failure blocks release. If false, failure is logged as warning."
              },
              "description": {
                "type": "string",
                "description": "Human-readable description of what this gate validates."
              }
            }
          },
          "default": []
        },
        "guards": {
          "type": "object",
          "description": "Release guard configuration. Controls pre-release safety checks.",
          "additionalProperties": false,
          "properties": {
            "epicCompleteness": {
              "type": "string",
              "enum": ["warn", "block", "off"],
              "default": "warn",
              "description": "Epic completeness guard mode. 'warn' shows incomplete tasks as warning, 'block' prevents release (use --force to override), 'off' disables check."
            }
          }
        },
        "versionBump": {
          "type": "object",
          "description": "Portable version bump configuration. Defines which files to update when bumping the project version during release.",
          "additionalProperties": false,
          "properties": {
            "enabled": {
              "type": "boolean",
              "default": true,
              "description": "Enable version bump during release ship --bump-version."
            },
            "autoDiscover": {
              "type": "boolean",
              "default": true,
              "description": "When `files` is empty, auto-discover version-bearing files from the project's ecosystem (pnpm/yarn/npm workspaces, Cargo [workspace.package] / per-crate [package] versions). Set to false to skip auto-discovery and require explicit `files` entries."
            },
            "files": {
              "type": "array",
              "description": "Files to update with the new version. Each entry defines a file path, update strategy, and strategy-specific options. When empty AND autoDiscover is true (default), the engine falls back to workspace discovery.",
              "items": {
                "type": "object",
                "required": ["path", "strategy"],
                "additionalProperties": false,
                "properties": {
                  "path": {
                    "type": "string",
                    "minLength": 1,
                    "description": "File path relative to project root."
                  },
                  "strategy": {
                    "type": "string",
                    "enum": ["plain", "json", "toml", "sed"],
                    "description": "Update strategy. 'plain' overwrites file with version string. 'json' updates a JSON field via jq. 'toml' updates a TOML key. 'sed' applies a custom sed pattern."
                  },
                  "jsonPath": {
                    "type": "string",
                    "description": "jq path expression for 'json' strategy (e.g., '.version', '.package.version'). Required when strategy is 'json'."
                  },
                  "tomlKey": {
                    "type": "string",
                    "description": "TOML key to update for 'toml' strategy (e.g., 'version'). Defaults to 'version'."
                  },
                  "tomlSection": {
                    "type": "string",
                    "description": "TOML section to scope the key lookup to (e.g., 'package', 'workspace.package'). When omitted, the first top-level matching key is bumped. Use 'workspace.package' for Cargo workspace-inherited versions."
                  },
                  "sedPattern": {
                    "type": "string",
                    "description": "Custom sed substitution pattern for 'sed' strategy. Use {{VERSION}} as placeholder for the new version (e.g., 's|version-[0-9]+\\.[0-9]+\\.[0-9]+-|version-{{VERSION}}-|g'). Required when strategy is 'sed'."
                  },
                  "sedMatch": {
                    "type": "string",
                    "description": "Grep pattern to verify the sed target exists before applying. Used with 'sed' strategy to fail fast if the pattern is not found."
                  },
                  "optional": {
                    "type": "boolean",
                    "default": false,
                    "description": "If true, skip this file silently when it does not exist. If false (default), fail with an error."
                  },
                  "description": {
                    "type": "string",
                    "description": "Human-readable description of what this file contains (e.g., 'README version badge', 'NPM package version')."
                  }
                }
              },
              "default": []
            },
            "preValidate": {
              "type": "string",
              "description": "Shell command to run before version bump. Exit 0 = pass. Used to verify current version state is clean."
            },
            "postValidate": {
              "type": "string",
              "description": "Shell command to run after version bump. Exit 0 = pass. Used to verify all files were updated correctly."
            }
          }
        },
        "changelog": {
          "type": "object",
          "description": "Changelog generation and output configuration.",
          "additionalProperties": false,
          "properties": {
            "enabled": {
              "type": "boolean",
              "default": true,
              "description": "Enable changelog generation during release."
            },
            "autoGenerate": {
              "type": "boolean",
              "default": false,
              "description": "Automatically generate changelog from commits and task history."
            },
            "source": {
              "type": "string",
              "default": "CHANGELOG.md",
              "description": "Source file for changelog content."
            },
            "outputs": {
              "type": "array",
              "description": "Output targets for changelog generation. Supports multiple documentation platforms.",
              "items": {
                "type": "object",
                "required": [
                  "platform",
                  "path"
                ],
                "additionalProperties": false,
                "properties": {
                  "platform": {
                    "type": "string",
                    "enum": [
                      "mintlify",
                      "docusaurus",
                      "github",
                      "plain",
                      "custom"
                    ],
                    "description": "Documentation platform type. Determines format and transformations applied."
                  },
                  "enabled": {
                    "type": "boolean",
                    "default": true,
                    "description": "Enable this output target."
                  },
                  "path": {
                    "type": "string",
                    "description": "Output file path relative to project root."
                  }
                }
              },
              "default": []
            }
          }
        }
      }
    },
    "retention": {
      "type": "object",
      "description": "Retention policies for session lifecycle management. Only autoEndActiveAfterDays is consumed (T109).",
      "additionalProperties": false,
      "properties": {
        "autoEndActiveAfterDays": {
          "type": "integer",
          "minimum": 1,
          "maximum": 365,
          "default": 7,
          "description": "Automatically end active sessions with no activity for this many days. Prevents stale sessions from accumulating."
        }
      }
    },
    "orchestrator": {
      "type": "object",
      "description": "Orchestrator agent configuration. Only contextThresholds.{warning,critical} are consumed (T109).",
      "additionalProperties": false,
      "properties": {
        "contextThresholds": {
          "type": "object",
          "description": "Context window usage thresholds that trigger orchestrator actions. Values are percentages of context window capacity.",
          "additionalProperties": false,
          "properties": {
            "warning": {
              "type": "integer",
              "minimum": 50,
              "maximum": 95,
              "default": 70,
              "description": "Warning threshold (%). At this level, orchestrator should plan to wrap up current work and delegate remaining tasks to subagents."
            },
            "critical": {
              "type": "integer",
              "minimum": 60,
              "maximum": 100,
              "default": 80,
              "description": "Critical threshold (%). At this level, orchestrator must STOP immediately, pause session, and generate HITL summary for human handoff."
            }
          }
        }
      }
    },
    "enforcement": {
      "type": "object",
      "description": "Enforcement configuration for task metadata fields. Controls validation and warning behavior for size, acceptance criteria, and auto-extraction features.",
      "additionalProperties": false,
      "properties": {
        "size": {
          "type": "object",
          "description": "Size field enforcement settings.",
          "additionalProperties": false,
          "properties": {
            "requireOnCreate": {
              "type": "boolean",
              "default": false,
              "description": "Require size field on task creation. When true, tasks cannot be created without specifying size."
            },
            "warnMissing": {
              "type": "boolean",
              "default": true,
              "description": "Warn when size is not specified during task creation."
            },
            "defaultValue": {
              "type": [
                "string",
                "null"
              ],
              "enum": [
                "small",
                "medium",
                "large",
                null
              ],
              "default": null,
              "description": "Default size value when not specified. Null means no default (field remains unset)."
            }
          }
        },
        "acceptance": {
          "type": "object",
          "description": "Acceptance criteria enforcement settings.",
          "additionalProperties": false,
          "properties": {
            "mode": {
              "type": "string",
              "enum": [
                "off",
                "warn",
                "block"
              ],
              "default": "block",
              "description": "Enforcement mode: off=no enforcement, warn=warn when missing, block=require on creation."
            },
            "requiredForPriorities": {
              "type": "array",
              "items": {
                "type": "string",
                "enum": [
                  "critical",
                  "high",
                  "medium",
                  "low"
                ]
              },
              "default": [
                "critical",
                "high",
                "medium",
                "low"
              ],
              "description": "Priority levels that require acceptance criteria when mode is 'warn' or 'block'."
            },
            "minimumCriteria": {
              "type": "integer",
              "default": 3,
              "minimum": 1,
              "description": "Minimum number of acceptance criteria required."
            }
          }
        },
        "session": {
          "type": "object",
          "description": "Session enforcement settings for tasks.",
          "additionalProperties": false,
          "properties": {
            "requiredForMutate": {
              "type": "boolean",
              "default": true,
              "description": "Require an active session for task operations."
            }
          }
        },
        "pipeline": {
          "type": "object",
          "description": "Pipeline stage enforcement settings.",
          "additionalProperties": false,
          "properties": {
            "bindTasksToStage": {
              "type": "boolean",
              "default": true,
              "description": "Automatically bind tasks to RCASD-IVTR+C pipeline stages."
            }
          }
        },
        "verification": {
          "type": "object",
          "description": "Verification gate auto-set settings.",
          "additionalProperties": false,
          "properties": {
            "autoSetImplemented": {
              "type": "boolean",
              "default": true,
              "description": "Automatically set verification.gates.implemented = true when task is completed."
            }
          }
        }
      }
    },
    "lifecycle": {
      "type": "object",
      "description": "Lifecycle enforcement shorthand. Alias for lifecycleEnforcement — both keys are accepted for backward compatibility.",
      "additionalProperties": false,
      "properties": {
        "mode": {
          "type": "string",
          "enum": [
            "strict",
            "advisory",
            "off"
          ],
          "default": "strict",
          "description": "Enforcement mode: strict (blocks spawn if prerequisites not met), advisory (warns but allows spawn), off (disables gate checks)."
        }
      }
    },
    "gitCheckpoint": {
      "type": "object",
      "description": "Automatic git checkpointing of .cleo/ state files at semantic boundaries. Opt-in feature that commits state files (todo.json, sessions.json, etc.) to git history with debounce to prevent commit noise.",
      "additionalProperties": false,
      "properties": {
        "enabled": {
          "type": "boolean",
          "default": false,
          "description": "Enable automatic git checkpointing of state files. Opt-in (default: false)."
        },
        "debounceMinutes": {
          "type": "integer",
          "minimum": 0,
          "default": 5,
          "description": "Minimum minutes between auto-checkpoints. Set to 0 for every trigger. Does not apply to manual or session-end checkpoints."
        },
        "messagePrefix": {
          "type": "string",
          "default": "chore(cleo):",
          "description": "Prefix for checkpoint commit messages."
        },
        "noVerify": {
          "type": "boolean",
          "default": true,
          "description": "Skip pre-commit hooks on checkpoint commits (--no-verify). Recommended to avoid interference from project hooks."
        }
      },
      "default": {
        "enabled": false,
        "debounceMinutes": 5,
        "messagePrefix": "chore(cleo):",
        "noVerify": true
      }
    },
    "lifecycleEnforcement": {
      "type": "object",
      "description": "Lifecycle gate enforcement configuration. Controls how strictly the RCSD→IVTR pipeline progression is enforced.",
      "additionalProperties": false,
      "properties": {
        "mode": {
          "type": "string",
          "enum": [
            "strict",
            "advisory",
            "off"
          ],
          "default": "strict",
          "description": "Enforcement mode: strict (blocks spawn if prerequisites not met), advisory (warns but allows spawn), off (disables gate checks)."
        }
      },
      "default": {
        "mode": "strict"
      }
    },
    "contributor": {
      "type": "object",
      "description": "Contributor/dev-mode settings. Auto-populated when CLEO detects it is running inside its own source repository (ADR-016 §2.3, ADR-029).",
      "additionalProperties": false,
      "properties": {
        "isContributorProject": {
          "type": "boolean",
          "default": false,
          "description": "True when this project IS the CLEO source repository. Detected automatically by fingerprinting src/mcp/, src/dispatch/, src/core/ and package.json#name. When true, agents MUST use cleo-dev CLI and local MCP server instead of production @cleocode/cleo@latest."
        },
        "devCli": {
          "type": "string",
          "default": "cleo-dev",
          "description": "The CLI command for the local dev build (ADR-016 §2.3). Injected into agent context when isContributorProject is true."
        }
      }
    },
    "llm": {
      "type": "object",
      "description": "LLM configuration — default provider+model, per-provider API key overrides, and role-based routing. T-LLM-CRED-CENTRALIZATION Phase 4 (T9306).",
      "additionalProperties": false,
      "properties": {
        "daemon": {
          "type": "object",
          "description": "REMOVED — this field is no longer read by the resolver. Kept in schema so existing config files that still carry this key are not rejected by AJV. Migrate to `default` or `llm.roles.<role>`.",
          "x-deprecated": true,
          "additionalProperties": true
        },
        "providers": {
          "type": "object",
          "description": "Per-provider API key overrides keyed by provider name (anthropic | openai | gemini | moonshot).",
          "additionalProperties": {
            "type": "object",
            "additionalProperties": false,
            "properties": {
              "apiKey": {
                "type": "string",
                "description": "Override API key for this provider (stored in config, not env)."
              }
            }
          }
        },
        "default": {
          "type": "object",
          "description": "Canonical default LLM for unscoped calls. Replaces `daemon`. T-LLM-CRED-CENTRALIZATION Phase 2 (T9256).",
          "additionalProperties": false,
          "properties": {
            "provider": {
              "type": "string",
              "enum": ["anthropic", "openai", "gemini", "moonshot"],
              "description": "LLM provider transport for the default model."
            },
            "model": {
              "type": "string",
              "description": "Full model identifier for the selected provider."
            }
          },
          "required": ["provider", "model"]
        },
        "roles": {
          "type": "object",
          "description": "Per-role LLM overrides. Resolution: roles[role] -> default -> implicit fallback. T-LLM-CRED-CENTRALIZATION Phase 4 (T9306).",
          "additionalProperties": false,
          "properties": {
            "extraction": { "$ref": "#/properties/llm/$defs/roleEntry" },
            "consolidation": { "$ref": "#/properties/llm/$defs/roleEntry" },
            "derivation": { "$ref": "#/properties/llm/$defs/roleEntry" },
            "hygiene": { "$ref": "#/properties/llm/$defs/roleEntry" },
            "judgement": { "$ref": "#/properties/llm/$defs/roleEntry" }
          }
        }
      },
      "$defs": {
        "roleEntry": {
          "type": "object",
          "additionalProperties": false,
          "properties": {
            "provider": {
              "type": "string",
              "enum": ["anthropic", "openai", "gemini", "moonshot"],
              "description": "LLM provider transport for this role."
            },
            "model": {
              "type": "string",
              "description": "Full model identifier for the selected provider."
            },
            "credentialLabel": {
              "type": "string",
              "description": "Optional credential label to pin this role to a specific credential entry resolved by resolveCredentials()."
            }
          },
          "required": ["provider", "model"]
        }
      }
    }
  }
}
