{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "title": "Upstream harvest candidate list",
  "description": "Structured output of detect-upstream-candidates: the patterns worth proposing into a template repo, scored by cross-client corroboration.",
  "type": "object",
  "additionalProperties": false,
  "required": ["candidates"],
  "properties": {
    "candidates": {
      "type": "array",
      "items": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "id",
          "intent",
          "target_files",
          "sources",
          "corroboration_count",
          "confidence",
          "rationale"
        ],
        "properties": {
          "id": {
            "type": "string",
            "description": "Stable kebab-case slug of the intent. Same intent -> same id across runs (drives dedup and the deterministic branch name harvest/<id>).",
            "pattern": "^[a-z0-9]+(-[a-z0-9]+)*$"
          },
          "intent": {
            "type": "string",
            "description": "One-line description of the directional change relative to the template baseline."
          },
          "target_files": {
            "type": "array",
            "description": "Paths in the template repo the change should apply to.",
            "items": { "type": "string" }
          },
          "sources": {
            "type": "array",
            "description": "Every client source that exhibits this pattern. More than one => corroboration.",
            "items": {
              "type": "object",
              "additionalProperties": false,
              "required": ["repo", "location"],
              "properties": {
                "repo": { "type": "string", "description": "org/repo" },
                "ref": { "type": "string", "description": "PR number (e.g. #41), branch, or commit SHA" },
                "location": { "type": "string", "description": "path[:line] within the source where the pattern lives" },
                "snippet": { "type": "string", "description": "the relevant (already eligible, non-secret) snippet" }
              }
            }
          },
          "corroboration_count": {
            "type": "integer",
            "minimum": 1,
            "description": "Number of distinct source repos converging on this intent."
          },
          "confidence": {
            "type": "string",
            "enum": ["single", "corroborated"],
            "description": "corroborated when corroboration_count >= 2."
          },
          "rationale": {
            "type": "string",
            "description": "Why this improves the template for all consumers."
          },
          "promoted_by_corroboration": {
            "type": "boolean",
            "description": "True when a borderline candidate was promoted to proposed solely because a second client corroborated it."
          }
        }
      }
    },
    "considered_but_skipped": {
      "type": "array",
      "description": "Deltas detection saw but did not propose, for transparency.",
      "items": {
        "type": "object",
        "additionalProperties": false,
        "required": ["id", "intent", "reason"],
        "properties": {
          "id": { "type": "string" },
          "intent": { "type": "string" },
          "reason": { "type": "string", "description": "e.g. client-specific, already in template, in ledger, denylisted" }
        }
      }
    }
  }
}
