{"$id":"https://agentictrafficcontrol.com/schema/v1.json","$schema":"https://json-schema.org/draft/2019-09/schema","allOf":[{"if":{"properties":{"type":{"const":"session.started"}},"required":["type"]},"then":{"properties":{"payload":{"$ref":"#/definitions/SessionStarted"}}}},{"if":{"properties":{"type":{"const":"session.ended"}},"required":["type"]},"then":{"properties":{"payload":{"$ref":"#/definitions/SessionEnded"}}}},{"if":{"properties":{"type":{"const":"agent.heartbeat"}},"required":["type"]},"then":{"properties":{"payload":{"$ref":"#/definitions/AgentHeartbeat"}}}},{"if":{"properties":{"type":{"const":"ticket.started"}},"required":["type"]},"then":{"properties":{"payload":{"$ref":"#/definitions/TicketStarted"}}}},{"if":{"properties":{"type":{"const":"ticket.finished"}},"required":["type"]},"then":{"properties":{"payload":{"$ref":"#/definitions/TicketFinished"}}}},{"if":{"properties":{"type":{"const":"ticket.failed"}},"required":["type"]},"then":{"properties":{"payload":{"$ref":"#/definitions/TicketFailed"}}}},{"if":{"properties":{"type":{"const":"decision.made"}},"required":["type"]},"then":{"properties":{"payload":{"$ref":"#/definitions/DecisionMade"}}}},{"if":{"properties":{"type":{"const":"question.raised"}},"required":["type"]},"then":{"properties":{"payload":{"$ref":"#/definitions/QuestionRaised"}}}},{"if":{"properties":{"type":{"const":"question.answered"}},"required":["type"]},"then":{"properties":{"payload":{"$ref":"#/definitions/QuestionAnswered"}}}},{"if":{"properties":{"type":{"const":"blocker.hit"}},"required":["type"]},"then":{"properties":{"payload":{"$ref":"#/definitions/BlockerHit"}}}},{"if":{"properties":{"type":{"const":"blocker.cleared"}},"required":["type"]},"then":{"properties":{"payload":{"$ref":"#/definitions/BlockerCleared"}}}},{"if":{"properties":{"type":{"const":"course.changed"}},"required":["type"]},"then":{"properties":{"payload":{"$ref":"#/definitions/CourseChanged"}}}},{"if":{"properties":{"type":{"const":"ci.result"}},"required":["type"]},"then":{"properties":{"payload":{"$ref":"#/definitions/CiResult"}}}},{"if":{"properties":{"type":{"const":"merge.requested"}},"required":["type"]},"then":{"properties":{"payload":{"$ref":"#/definitions/MergeRequested"}}}},{"if":{"properties":{"type":{"const":"merge.completed"}},"required":["type"]},"then":{"properties":{"payload":{"$ref":"#/definitions/MergeCompleted"}}}},{"if":{"properties":{"type":{"const":"merge.rejected"}},"required":["type"]},"then":{"properties":{"payload":{"$ref":"#/definitions/MergeRejected"}}}},{"if":{"properties":{"type":{"const":"structure.alert"}},"required":["type"]},"then":{"properties":{"payload":{"$ref":"#/definitions/StructureAlert"}}}},{"if":{"properties":{"type":{"const":"claude.hook"}},"required":["type"]},"then":{"properties":{"payload":{"$ref":"#/definitions/ClaudeHook"}}}},{"if":{"properties":{"type":{"const":"human.action"}},"required":["type"]},"then":{"properties":{"payload":{"$ref":"#/definitions/HumanAction"}}}}],"definitions":{"Action":{"description":"What the owner did with an item in the app.","oneOf":[{"enum":["acknowledge","snooze","resolve"],"type":"string"},{"description":"Approve a merge at the pass.","enum":["approve"],"type":"string"},{"description":"Send a merge back with notes.","enum":["send_back"],"type":"string"},{"description":"Answer a question.","enum":["answer"],"type":"string"}]},"Agent":{"properties":{"id":{"description":"Stable id for this agent. For Claude Code, the session id.","type":"string"},"model":{"type":["string","null"]},"name":{"description":"A human-friendly name, such as `worker-3` or the branch.","type":["string","null"]},"parent_id":{"description":"The orchestrating agent's id, when this agent was spawned by another.","type":["string","null"]},"runtime":{"description":"What runs the agent: `claude-code`, `claude-code-cloud`, `ci`, `watcher`, ...","type":["string","null"]}},"required":["id"],"type":"object"},"AgentHeartbeat":{"$ref":"#/definitions/AgentHeartbeat"},"BlockerCause":{"description":"Why an agent is blocked. These are the clusters the Andon analytics count, so pick the closest; `other` is fine when none fits.","oneOf":[{"enum":["other"],"type":"string"},{"description":"Docs, a spec or project knowledge the agent needs is missing.","enum":["missing_context"],"type":"string"},{"description":"The ticket can be read more than one way.","enum":["ambiguous_ticket"],"type":"string"},{"description":"A test fails intermittently.","enum":["flaky_test"],"type":"string"},{"description":"A permission prompt, a missing credential, or an action the agent may not take.","enum":["permission"],"type":"string"},{"description":"The machine, toolchain or network is wrong.","enum":["environment"],"type":"string"},{"description":"A dependency is broken, missing or incompatible.","enum":["dependency"],"type":"string"},{"description":"The build fails for reasons not the agent's own change.","enum":["build_failure"],"type":"string"},{"description":"Waiting on another agent's work.","enum":["waiting_on_agent"],"type":"string"},{"description":"Waiting on a human decision.","enum":["waiting_on_human"],"type":"string"},{"description":"The agent seems to be repeating itself.","enum":["possible_loop"],"type":"string"}]},"BlockerCleared":{"$ref":"#/definitions/BlockerCleared"},"BlockerHit":{"$ref":"#/definitions/BlockerHit"},"CiResult":{"$ref":"#/definitions/CiResult"},"CiStatus":{"enum":["pass","fail","cancelled","running"],"type":"string"},"ClaudeHook":{"$ref":"#/definitions/ClaudeHook"},"CourseChanged":{"$ref":"#/definitions/CourseChanged"},"DecisionMade":{"$ref":"#/definitions/DecisionMade"},"HumanAction":{"$ref":"#/definitions/HumanAction"},"Link":{"properties":{"href":{"description":"An `https://` URL.","type":"string"},"rel":{"description":"What the link is: `pr`, `ci`, `session`, `ticket`, `doc`, or anything else.","type":"string"},"title":{"type":["string","null"]}},"required":["href","rel"],"type":"object"},"MergeCompleted":{"$ref":"#/definitions/MergeCompleted"},"MergeRejected":{"$ref":"#/definitions/MergeRejected"},"MergeRequested":{"$ref":"#/definitions/MergeRequested"},"QuestionAnswered":{"$ref":"#/definitions/QuestionAnswered"},"QuestionRaised":{"$ref":"#/definitions/QuestionRaised"},"Repo":{"properties":{"branch":{"type":["string","null"]},"commit":{"type":["string","null"]},"name":{"description":"`owner/name`.","type":["string","null"]},"pr":{"description":"Pull request number.","format":"uint64","minimum":0.0,"type":["integer","null"]}},"type":"object"},"Risk":{"enum":["low","medium","high"],"type":"string"},"SessionEnded":{"$ref":"#/definitions/SessionEnded"},"SessionStarted":{"$ref":"#/definitions/SessionStarted"},"StructureAlert":{"$ref":"#/definitions/StructureAlert"},"StructureSignal":{"oneOf":[{"description":"A crate or module is an outlier in size against its siblings.","enum":["size"],"type":"string"},{"description":"It is growing quickly.","enum":["growth"],"type":"string"},{"description":"Many crates depend on it.","enum":["fan_in"],"type":"string"},{"description":"It depends on many crates.","enum":["fan_out"],"type":"string"},{"description":"It dominates build time.","enum":["build_time"],"type":"string"},{"description":"Many agents keep touching it.","enum":["churn"],"type":"string"}]},"Ticket":{"properties":{"id":{"description":"The ticket's id as the tracker shows it: `412`, `ENG-88`. A leading `#` is dropped.","type":"string"},"title":{"type":["string","null"]},"url":{"type":["string","null"]}},"required":["id"],"type":"object"},"TicketFailed":{"$ref":"#/definitions/TicketFailed"},"TicketFinished":{"$ref":"#/definitions/TicketFinished"},"TicketStarted":{"$ref":"#/definitions/TicketStarted"},"Urgency":{"oneOf":[{"enum":["low","normal","high"],"type":"string"},{"description":"Work has stopped until someone answers.","enum":["critical"],"type":"string"}]}},"description":"One event, as agents send it.","properties":{"agent":{"anyOf":[{"$ref":"#/definitions/Agent"},{"type":"null"}],"description":"The agent that sent it. Required for everything except repository events (`ci.*`, `merge.*`, `structure.*`), which may come from CI or a webhook, and the owner's own actions (`human.*`)."},"id":{"description":"A client-chosen unique id (a ULID or UUID is ideal), up to 64 characters of `[A-Za-z0-9._:-]`. Sending the same id twice stores the event once, so a retry is safe. If left out, the server makes one and retries are not deduplicated.","type":["string","null"]},"links":{"description":"Links shown beside the event (the PR, the CI run, the agent's session).","items":{"$ref":"#/definitions/Link"},"type":"array"},"occurred_at":{"description":"When it happened (RFC 3339). Defaults to the time the server received it.","format":"date-time","type":"string"},"payload":{"default":{},"description":"The type-specific body. Always a JSON object."},"project":{"description":"The project slug. Optional: the ingest token already names the project, and a mismatch is rejected.","type":["string","null"]},"repo":{"anyOf":[{"$ref":"#/definitions/Repo"},{"type":"null"}],"description":"Where the work lives."},"schema":{"description":"Always `\"atc.event/v1\"`.","type":"string"},"ticket":{"anyOf":[{"$ref":"#/definitions/Ticket"},{"type":"null"}],"description":"The ticket the work is for."},"type":{"description":"The event type, such as `blocker.hit`. See the payload definitions for known types.","type":"string"}},"required":["schema","type"],"title":"atc.event/v1","type":"object","x-known-types":["session.started","session.ended","agent.heartbeat","ticket.started","ticket.finished","ticket.failed","decision.made","question.raised","question.answered","blocker.hit","blocker.cleared","course.changed","ci.result","merge.requested","merge.completed","merge.rejected","structure.alert","claude.hook","human.action"]}