{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "$schema": {
      "description": "Path to the shipped config.schema.json",
      "type": "string"
    },
    "version": {
      "type": "number",
      "description": "The config format version (1 or 2)"
    },
    "defaults": {
      "type": "object",
      "properties": {
        "maxConcurrentWorkers": {
          "type": "number",
          "minimum": 0,
          "description": "Parallel omp sessions (default 2)"
        },
        "maxConcurrentWorkersPerRepo": {
          "type": "number",
          "minimum": 0,
          "description": "Max live workers per repository (default 1)"
        },
        "dailySpendUsd": {
          "anyOf": [
            {
              "type": "number",
              "minimum": 0
            },
            {
              "type": "null"
            }
          ],
          "description": "Rolling-day spend ceiling; null means no spend gate (default 25)"
        },
        "maxRunSpendUsd": {
          "anyOf": [
            {
              "type": "number",
              "exclusiveMinimum": 0
            },
            {
              "type": "null"
            }
          ],
          "description": "Ceiling on one run, reserved from the daily budget before it launches; null derives it from dailySpendUsd. Must not exceed dailySpendUsd"
        },
        "planUsage": {
          "anyOf": [
            {
              "type": "object",
              "properties": {
                "windowId": {
                  "type": "string",
                  "minLength": 1,
                  "description": "The allowance window this threshold guards"
                },
                "maxUsedFraction": {
                  "type": "number",
                  "minimum": 0,
                  "maximum": 1,
                  "description": "Consumed share, 0–1, at which new claims stop"
                }
              },
              "required": [
                "windowId",
                "maxUsedFraction"
              ],
              "additionalProperties": false,
              "description": "An allowance-window spend guard, or null for unmetered"
            },
            {
              "type": "null"
            }
          ],
          "description": "Plan-allowance guard, or null for unmetered"
        },
        "workerMaxTurns": {
          "type": "number",
          "minimum": 0,
          "description": "Turn ceiling for one worker (default 120)"
        },
        "workerMaxTurnsCeiling": {
          "type": "number",
          "minimum": 0,
          "description": "Maximum turn budget assignable to one issue's next attempt"
        },
        "workerWallClockMs": {
          "type": "number",
          "minimum": 0,
          "description": "Wall-clock ceiling for one worker (default 5400000)"
        },
        "workerStallSilenceMs": {
          "anyOf": [
            {
              "type": "number",
              "minimum": 0
            },
            {
              "type": "null"
            }
          ],
          "description": "How long a live worker's transcript may stay unwritten before the daemon settles it as a progress stall; null derives a third of workerWallClockMs"
        },
        "maxAttemptsPerIssue": {
          "type": "number",
          "minimum": 0,
          "description": "Failed attempts allowed before escalation (default 2)"
        },
        "maxContinuationsPerIssue": {
          "type": "number",
          "minimum": 0,
          "description": "Operational continuations allowed before crash/resume escalation (default 2)"
        }
      },
      "additionalProperties": {},
      "description": "Per-fleet or per-project hard limits"
    },
    "dbBackupDir": {
      "description": "Absolute directory for restorable conductor.db snapshots; defaults to <stateDir>/backups/db",
      "type": "string",
      "minLength": 1
    },
    "host": {
      "description": "Host facts every worker brief renders; absent renders no section",
      "type": "object",
      "properties": {
        "description": {
          "type": "string",
          "minLength": 1,
          "description": "What this host is and what else it runs"
        },
        "path": {
          "type": "string",
          "minLength": 1,
          "description": "The non-interactive PATH a script or `ssh host \"<cmd>\"` invocation must export"
        },
        "conventions": {
          "type": "object",
          "propertyNames": {
            "type": "string",
            "minLength": 1
          },
          "additionalProperties": {
            "type": "string",
            "minLength": 1
          },
          "description": "Per-repo command conventions, keyed by the brief's `owner/repo` slug"
        }
      },
      "additionalProperties": false
    },
    "projects": {
      "minItems": 1,
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1
          },
          "tracker": {
            "type": "object",
            "properties": {
              "kind": {
                "type": "string",
                "const": "github"
              },
              "repo": {
                "type": "string",
                "pattern": "^[A-Za-z0-9._-]+\\/[A-Za-z0-9._-]+$"
              }
            },
            "required": [
              "repo"
            ],
            "additionalProperties": false
          },
          "queueLabel": {
            "type": "string",
            "minLength": 1
          },
          "groomBelow": {
            "anyOf": [
              {
                "type": "integer",
                "minimum": 1,
                "maximum": 9007199254740991
              },
              {
                "type": "string",
                "const": "always"
              }
            ]
          },
          "groomRole": {
            "type": "string",
            "pattern": "^[A-Za-z0-9][A-Za-z0-9._-]*$"
          },
          "stateLabels": {
            "type": "object",
            "properties": {
              "inProgress": {},
              "blocked": {},
              "failed": {},
              "backlog": {}
            },
            "additionalProperties": false
          },
          "routing": {
            "type": "object",
            "properties": {
              "labelPrefix": {},
              "repos": {
                "type": "object",
                "propertyNames": {
                  "type": "string"
                },
                "additionalProperties": {
                  "type": "object",
                  "properties": {
                    "name": {},
                    "cloneUrl": {
                      "type": "string",
                      "minLength": 1
                    },
                    "defaultBranch": {
                      "default": "main"
                    },
                    "gates": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "cmd": {
                            "type": "string"
                          },
                          "cwd": {
                            "default": "."
                          }
                        },
                        "additionalProperties": false
                      }
                    },
                    "graphProject": {
                      "type": "string"
                    },
                    "migrations": {
                      "type": "object",
                      "properties": {
                        "dir": {
                          "type": "string",
                          "minLength": 1
                        }
                      },
                      "required": [
                        "dir"
                      ],
                      "additionalProperties": false
                    },
                    "release": {
                      "type": "object",
                      "properties": {
                        "versionFile": {
                          "type": "string",
                          "minLength": 1
                        }
                      },
                      "required": [
                        "versionFile"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "required": [
                    "cloneUrl"
                  ],
                  "additionalProperties": false
                }
              }
            },
            "required": [
              "repos"
            ],
            "additionalProperties": false
          },
          "caps": {
            "type": "object",
            "properties": {
              "maxConcurrentWorkers": {
                "type": "number",
                "minimum": 0,
                "description": "Parallel omp sessions (default 2)"
              },
              "maxConcurrentWorkersPerRepo": {
                "type": "number",
                "minimum": 0,
                "description": "Max live workers per repository (default 1)"
              },
              "dailySpendUsd": {
                "anyOf": [
                  {
                    "type": "number",
                    "minimum": 0
                  },
                  {
                    "type": "null"
                  }
                ],
                "description": "Rolling-day spend ceiling; null means no spend gate (default 25)"
              },
              "maxRunSpendUsd": {
                "anyOf": [
                  {
                    "type": "number",
                    "exclusiveMinimum": 0
                  },
                  {
                    "type": "null"
                  }
                ],
                "description": "Ceiling on one run, reserved from the daily budget before it launches; null derives it from dailySpendUsd. Must not exceed dailySpendUsd"
              },
              "planUsage": {
                "anyOf": [
                  {
                    "type": "object",
                    "properties": {
                      "windowId": {
                        "type": "string",
                        "minLength": 1,
                        "description": "The allowance window this threshold guards"
                      },
                      "maxUsedFraction": {
                        "type": "number",
                        "minimum": 0,
                        "maximum": 1,
                        "description": "Consumed share, 0–1, at which new claims stop"
                      }
                    },
                    "required": [
                      "windowId",
                      "maxUsedFraction"
                    ],
                    "additionalProperties": false,
                    "description": "An allowance-window spend guard, or null for unmetered"
                  },
                  {
                    "type": "null"
                  }
                ],
                "description": "Plan-allowance guard, or null for unmetered"
              },
              "workerMaxTurns": {
                "type": "number",
                "minimum": 0,
                "description": "Turn ceiling for one worker (default 120)"
              },
              "workerMaxTurnsCeiling": {
                "type": "number",
                "minimum": 0,
                "description": "Maximum turn budget assignable to one issue's next attempt"
              },
              "workerWallClockMs": {
                "type": "number",
                "minimum": 0,
                "description": "Wall-clock ceiling for one worker (default 5400000)"
              },
              "workerStallSilenceMs": {
                "anyOf": [
                  {
                    "type": "number",
                    "minimum": 0
                  },
                  {
                    "type": "null"
                  }
                ],
                "description": "How long a live worker's transcript may stay unwritten before the daemon settles it as a progress stall; null derives a third of workerWallClockMs"
              },
              "maxAttemptsPerIssue": {
                "type": "number",
                "minimum": 0,
                "description": "Failed attempts allowed before escalation (default 2)"
              },
              "maxContinuationsPerIssue": {
                "type": "number",
                "minimum": 0,
                "description": "Operational continuations allowed before crash/resume escalation (default 2)"
              }
            },
            "additionalProperties": {},
            "description": "Per-fleet or per-project hard limits"
          },
          "workerModel": {},
          "modelFallbacks": {},
          "modelFallbackThreshold": {},
          "workerEscalationModel": {},
          "requireOauthProviders": {},
          "ompSettings": {},
          "workerAdvisor": {},
          "escalation": {
            "type": "object",
            "properties": {
              "telegramChatId": {},
              "telegramTopicId": {},
              "fallbackToIssueComment": {
                "default": true
              },
              "orchestrator": {
                "default": "embedded",
                "type": "string",
                "enum": [
                  "embedded",
                  "external"
                ]
              }
            },
            "additionalProperties": false
          },
          "arm": {
            "type": "object",
            "properties": {
              "proof": {
                "default": "challenge",
                "type": "string",
                "enum": [
                  "challenge",
                  "claim-only"
                ]
              }
            },
            "additionalProperties": false,
            "description": "How `arm` proves a human just approved arming"
          },
          "review": {
            "type": "object",
            "properties": {
              "strictness": {
                "default": "medium",
                "type": "string",
                "enum": [
                  "low",
                  "medium",
                  "high"
                ]
              },
              "maxRounds": {
                "default": 3,
                "type": "integer",
                "minimum": 1,
                "maximum": 6
              },
              "adjudicator": {
                "default": "task",
                "type": "string",
                "pattern": "^[A-Za-z0-9][A-Za-z0-9._-]*$"
              }
            },
            "additionalProperties": false,
            "description": "Review strictness, round ceiling and adjudicator role for green PRs"
          },
          "authority": {
            "type": "object",
            "properties": {
              "merge": {
                "default": "human",
                "type": "string",
                "enum": [
                  "human",
                  "orchestrator"
                ]
              },
              "release": {
                "default": "human",
                "type": "string",
                "enum": [
                  "human",
                  "orchestrator"
                ]
              },
              "promotion": {
                "default": "human",
                "type": "string",
                "enum": [
                  "human",
                  "orchestrator"
                ]
              }
            },
            "additionalProperties": false
          },
          "releasePolicy": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "none",
                  "operator-brief"
                ]
              },
              {
                "type": "object",
                "propertyNames": {
                  "type": "string"
                },
                "additionalProperties": {
                  "type": "string",
                  "enum": [
                    "human",
                    "orchestrator"
                  ]
                }
              }
            ]
          },
          "policy": {
            "type": "object",
            "properties": {
              "merge": {
                "type": "object",
                "properties": {
                  "requiredChecks": {
                    "default": [],
                    "type": "array",
                    "items": {
                      "type": "string",
                      "minLength": 1
                    }
                  },
                  "baseFreshness": {
                    "default": "up-to-date",
                    "type": "string",
                    "enum": [
                      "up-to-date",
                      "any"
                    ]
                  },
                  "drafts": {
                    "default": "block",
                    "type": "string",
                    "enum": [
                      "block",
                      "allow"
                    ]
                  },
                  "whenBehindBase": {
                    "default": "update-branch",
                    "type": "string",
                    "enum": [
                      "update-branch",
                      "hold",
                      "escalate"
                    ]
                  }
                },
                "additionalProperties": false
              },
              "release": {
                "type": "object",
                "properties": {
                  "requires": {
                    "default": [
                      "runs-settled"
                    ],
                    "type": "array",
                    "items": {
                      "type": "string",
                      "enum": [
                        "runs-settled",
                        "fleet-runs-settled",
                        "no-open-prs",
                        "queue-drained",
                        "base-branch-green",
                        "epic-children-closed"
                      ]
                    }
                  },
                  "requiredChecks": {
                    "default": [],
                    "type": "array",
                    "items": {
                      "type": "string",
                      "minLength": 1
                    }
                  },
                  "artefacts": {
                    "default": [],
                    "type": "array",
                    "items": {
                      "type": "string",
                      "minLength": 1
                    }
                  },
                  "environments": {
                    "default": [],
                    "type": "array",
                    "items": {
                      "type": "string",
                      "minLength": 1
                    }
                  }
                },
                "additionalProperties": false
              }
            },
            "additionalProperties": false
          },
          "recoveryMerges": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "prUrl": {
                  "type": "string",
                  "pattern": "^https:\\/\\/github\\.com\\/[A-Za-z0-9_.-]+\\/[A-Za-z0-9_.-]+\\/pull\\/\\d+$"
                },
                "headSha": {
                  "type": "string",
                  "pattern": "^[0-9a-fA-F]{40}$"
                },
                "reason": {
                  "type": "string",
                  "const": "operator-instructed"
                }
              },
              "required": [
                "prUrl",
                "headSha",
                "reason"
              ],
              "additionalProperties": false
            }
          },
          "reporting": {
            "type": "object",
            "properties": {
              "scope": {
                "description": "Legacy reporting preset; mutually exclusive with the explicit form",
                "type": "string",
                "enum": [
                  "escalations",
                  "decisions",
                  "material"
                ]
              },
              "scopePreset": {
                "description": "Back-annotation of the legacy preset this policy came from",
                "type": "string",
                "enum": [
                  "escalations",
                  "decisions",
                  "material"
                ]
              },
              "interruptOn": {
                "description": "Which categories interrupt the operator's phone",
                "type": "array",
                "items": {
                  "type": "string",
                  "enum": [
                    "tier2",
                    "decision-needed",
                    "fleet-stopped",
                    "confirmed-failure",
                    "material"
                  ]
                }
              },
              "digest": {
                "type": "object",
                "properties": {
                  "cadence": {
                    "type": "string",
                    "enum": [
                      "none",
                      "per-tick",
                      "daily"
                    ],
                    "description": "When the daily/report rollup is due"
                  },
                  "at": {
                    "description": "Daily rollup time",
                    "type": "string",
                    "pattern": "^([01]\\d|2[0-3]):[0-5]\\d$"
                  },
                  "timezone": {
                    "type": "string",
                    "description": "IANA timezone of the daily rollup"
                  }
                },
                "required": [
                  "cadence"
                ],
                "additionalProperties": false,
                "description": "The reporting digest/rollup schedule"
              },
              "availability": {
                "type": "object",
                "properties": {
                  "timezone": {
                    "type": "string",
                    "minLength": 1,
                    "description": "IANA timezone of the window"
                  },
                  "days": {
                    "minItems": 1,
                    "type": "array",
                    "items": {
                      "type": "string",
                      "enum": [
                        "mon",
                        "tue",
                        "wed",
                        "thu",
                        "fri",
                        "sat",
                        "sun"
                      ]
                    },
                    "description": "Days the window is open"
                  },
                  "start": {
                    "type": "string",
                    "pattern": "^([01]\\d|2[0-3]):[0-5]\\d$",
                    "description": "Window open time, operator-local"
                  },
                  "end": {
                    "type": "string",
                    "pattern": "^([01]\\d|2[0-3]):[0-5]\\d$",
                    "description": "Window close time, operator-local"
                  },
                  "bypass": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "enum": [
                        "tier2",
                        "decision-needed",
                        "fleet-stopped",
                        "confirmed-failure",
                        "material"
                      ]
                    },
                    "description": "Categories that may interrupt outside the window"
                  }
                },
                "required": [
                  "timezone",
                  "days",
                  "start",
                  "end"
                ],
                "additionalProperties": false
              }
            },
            "additionalProperties": false
          },
          "criticalBase": {},
          "workspaceRoot": {},
          "mirrorRoot": {}
        },
        "required": [
          "name",
          "tracker",
          "queueLabel"
        ],
        "additionalProperties": {},
        "description": "One product this conductor services"
      }
    }
  },
  "required": [
    "version",
    "projects"
  ],
  "additionalProperties": {},
  "description": "On-disk configuration for omp-conductor"
}
