{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"format":{"type":"string","const":"decomphub.progress/v1"},"repository":{"type":"string","maxLength":2048},"revision":{"type":"string","pattern":"^[a-f0-9]{40,64}$"},"reportedAt":{"type":"string"},"tracks":{"minItems":1,"maxItems":20,"type":"array","items":{"type":"object","properties":{"id":{"type":"string","pattern":"^[a-z0-9][a-z0-9._-]{0,63}$"},"label":{"type":"string","minLength":1,"maxLength":120},"scope":{"type":"string","minLength":1,"maxLength":300},"measurement":{"anyOf":[{"type":"object","properties":{"kind":{"type":"string","const":"percent"},"value":{"type":"number","minimum":0,"maximum":100},"valueMax":{"type":"number","minimum":0,"maximum":100},"approximate":{"type":"boolean"}},"required":["kind","value"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"ratio"},"completed":{"type":"integer","minimum":0,"maximum":9007199254740991},"total":{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991},"unit":{"type":"string","minLength":1,"maxLength":40},"approximate":{"type":"boolean"}},"required":["kind","completed","total","unit"],"additionalProperties":false},{"type":"null"}]},"measuredAt":{"type":"string"}},"required":["id","label","scope","measurement"],"additionalProperties":false}}},"required":["format","repository","tracks"],"additionalProperties":false,"$id":"https://decomphub.com/schemas/progress-v1.json","title":"DecompHub progress report v1","description":"Independent scoped tracks. Semantic validation additionally requires unique track IDs, completed <= total, ordered percent ranges, canonical repository identity, and dates no later than observation + 24 hours. Null measurements mean unknown. No overall percentage is inferred."}