Skip to content
Registry

sentinel

v0.1.1

Error monitor for the iii engine: groups failures from trace and log telemetry by deterministic fingerprint, freezes the evidence before the in-memory store discards it, and opens assisted harness investigations that record a structured diagnosis.

license: Apache-2.0diagnosticserrorsincidentsmonitoringobservability

Install

bash
iii trigger compose::add worker=sentinel

Run in your project with the iii engine running. Exact versions are immutable and digest-pinned.

Agent-ready brief for v0.1.1
Install, config, dependencies, readme, skills and API reference, all in one place. Fetch as agent-context.md for an LLM to consume.
The same content rendered as discrete blocks below is exposed as a single markdown document at /registry/workers/sentinel.md. Paste it into an LLM prompt or pipe it through curl from a worker.

Install

iii trigger compose::add worker=sentinel@0.1.1

Configuration

iii-config.yaml
- archive:
    bucket:
  attribute_allowlist:

  database: primary
  enabled: true
  evidence:
    max_bytes: 1048576
    message_max_bytes: 65536
    settle_delay_ms: 5000
  fingerprint:
    identity_numbers:
      - HTTP
      - status
      - code
      - errno
      - exit
      - signal
      - port
  ignore_services:

  ingest:
    breaker_cooldown_ms: 30000
    breaker_failures: 5
  investigation:
    model:
  projects:

  redaction:
    patterns:

  retention:
    buckets_days: 30
    cron: 0 0 3 * * *
    evidence_per_group: 5
    occurrences_per_group: 1000
    resolved_ttl_days: 90
  service_aliases:

  sources:
    log:
      enabled: true
      join_window_ms: 2000
    trace:
      enabled: true
  triage:
    delay_ms: 300000
    enabled: true
    model:
  workers_ttl_ms: 60000

Dependencies

Readme

README.md

sentinel

Error monitoring for an iii engine. The engine already exports every worker's spans and logs; sentinel subscribes to the failures among them, groups them by a deterministic fingerprint so a thousand occurrences read as one problem, and — this is the part a dashboard cannot do — freezes the evidence at the moment of capture, because the engine's span store is a ring of 10 000 spans and the trace you want to look at is usually gone by the time you click. From a group you open an assisted harness investigation beside the page: you watch it read the code, you steer it, and it records a structured diagnosis against the group. Resolving and ignoring stay human decisions; regressions are detected on their own.

Install

iii trigger compose::add worker=sentinel worker=database worker=queue

sentinel keeps its groups in database (SQLite by default, zero-config) and its ingest in a durable queue, so both belong in the same call: without them the worker starts, reports itself disabled, and waits.

Quickstart

sentinel::status is the one call worth knowing first. It answers whether the monitor is actually working — not just running:

use iii_sdk::{register_worker, InitOptions};
use iii_sdk::protocol::TriggerRequest;
use serde_json::json;

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    let iii = register_worker("ws://localhost:49134", InitOptions::default());

    let status = iii
        .trigger(TriggerRequest {
            function_id: "sentinel::status".into(),
            payload: json!({}),
            action: None,
            timeout_ms: Some(5_000),
        })
        .await?;

    println!("{status:#?}");
    Ok(())
}
{
  "enabled": true,
  "engine": { "trace_store": "memory", "logs": true },
  "sources": { "trace": true, "log": true },
  "ingest": { "processed_total": 0, "redactions": 0, "lost_before_capture": 0, "…": 0 },
  "groups": { "open": 0, "regressed": 0, "ignored": 0, "resolved": 0 },
  "repositories": [{ "id": "workers", "path": "/home/me/workspaces/workers", "exists": true, "workers": ["harness"] }]
}

Three fields carry most of the diagnostic weight:

  • enabled is false while the store or the queue has not registered yet — the worker is up, ingest is closed, and nothing is being dropped silently.
  • lost_before_capture counts traces that left the engine's ring before the job ran. A number that climbs is the signal to raise the engine's memory_max_spans, not a bug in a group.
  • repositories[].exists says whether a mapped checkout is really on this machine. False disables code access for its workers; grouping, evidence and regression keep working.

The page

The console page appears under errors while the worker is up: the open groups ordered with regressions first, and behind each one the frozen evidence — the span that failed, the exception it carried, the tree around it and the logs of that trace.

Investigate opens a harness session beside the page. You watch the agent read the checkout mapped to the failing worker, and you can write to it at any time; a message lands in the turn that is already running. When it has a cause it records one by calling sentinel::diagnosis::record, which is the only write to this worker its policy allows. Besides reads of the code and the evidence, it can reach GitHub and the web, writes included (a PR merge, a POST); the engine's raw telemetry is not on the list at all. Each recording is a version; the most recent one stands and the earlier ones stay, so the same failure diagnosed twice can be compared.

Open in chat does the same thing without running anything: the session is created with the evidence already in the transcript and waits for you to speak.

Each group is also triaged once, five minutes after it is first seen, into defect, caller_error, transient, environment or test_traffic, and the label rides on sentinel::groups::list and ::get as triage. A "function not found" whose function is registered by then is decided without a model — a restart when it was brief, the environment when it was not; everything else goes to judge in batches. The judge sees the group as it was stored, so already redacted. Without judge deployed the groups simply stay untriaged, and a failing judge is left alone for five minutes. A label is a hint for ordering and filtering, never a state change. Switch it off, change the wait, or pick the judge and its model under Triage in the page's settings (triage.provider, triage.model); left empty, the judge worker's own default answers. A new choice labels the groups still waiting, never relabels the old ones.

The list opens on Relevant: defects, regressions, groups not triaged yet, and caller errors or environment problems that repeat (20 or more occurrences across an hour or more), since a program repeating a failing call needs a fix even when its message is a polite refusal. Noise holds the rest, ordered by kind, and each side shows its count, so nothing is more than a click away. sentinel::groups::list takes the same choice as relevance.

Resolving and ignoring are yours. An ignore can last forever, for a number of further occurrences, or until the worker version changes — and the counters keep running either way, so an ignored group still tells you how often it happened.

Investigating from outside the console

iii trigger sentinel::investigate group_id=grp_... mode=assisted
iii trigger sentinel::investigations::get investigation_id=inv_...

The session id it answers with is a real console conversation: opening it in the console puts you in the middle of the investigation, with the same controls as any other chat.

Configuration

Registered with the configuration worker under the id sentinel and hot-reloaded in place — every key except database takes effect without a restart. Each field ships with a default, so configure only what you mean to change:

enabled: true
sources:
  trace: { enabled: true }              # spans with status error
  log:   { enabled: true, join_window_ms: 2000 }   # an ERROR log waits this long for the span of its own trace
redaction:
  patterns: []                          # extra value shapes to redact on capture; the built-in set always runs
evidence:
  max_bytes: 1048576                    # ceiling for one frozen bundle
  settle_delay_ms: 5000                 # re-read the trace once, to catch ancestors still open at capture
retention:
  evidence_per_group: 5                 # bundles kept per group, plus the first and one per worker version
  occurrences_per_group: 1000
  resolved_ttl_days: 90
investigation:
  model: ""                             # catalog id an investigation opens with; each run may pick another
triage:
  enabled: true
  delay_ms: 300000                      # wait this long after first seen; a restart registers what it was missing
  model: ""                             # as the judge names it; empty keeps the judge's default
  # provider: openai                    # the judge-<provider> to ask; unset keeps the judge worker's default
projects:                               # where a worker's source lives on this machine (formerly `repositories`, still read)
  - id: workers
    path: /home/me/workspaces/workers
    workers: [harness, ade, queue]
service_aliases: {}                     # span service.name → registered worker name, when an SDK reports a binary name
database: primary                       # a `database` worker connection, SQLite or Postgres

There are deliberately no turn, token or cost ceilings: an investigation runs beside the group's page where you can watch it and stop it, and a ceiling that fires mid-investigation throws away the context that was about to pay off.

Secrets never reach a model or the store: every captured value — messages, stack traces, log bodies, attributes — passes a redactor before the first insert, and the agent reaches live telemetry only through proxies that apply the same redactor. status.ingest.redactions shows it working.

Every field and its default lives in src/config.rs.

A store shared by the team

database names a connection of the database worker, and the store runs on SQLite or Postgres. Point every teammate's sentinel at the same Postgres and everyone works from the same groups, evidence, triage and diagnoses:

# configuration id `database`
databases:
  primary:
    url: sqlite:./data/iii.db
  sentinel:
    url: ${SENTINEL_DATABASE_URL}       # postgres://user:password@host:5432/sentinel
    tls: { mode: verify-full }          # managed providers: see the database README
# configuration id `sentinel`
database: sentinel

The tables create themselves on the first boot against an empty database; database is the one key that needs a restart. What stays per machine is worth knowing before you share:

  • Groups merge by fingerprint, and the fingerprint includes the namespace: teammates on different namespaces see each other's groups side by side, not merged into one.
  • An investigation's session lives on the machine that opened it. Its diagnosis is in the store for everyone; the session opens only there.
  • Resolve until the version changes compares versions from every machine reporting, so a teammate still on the old build reopens the group as a regression.
  • projects, ignore_services and the rest of the configuration stay per machine; only what the store holds is shared.
  • Every sentinel triages: a new group may cost two judge calls when two instances reach it in the same sweep.

MySQL is refused at boot: the store relies on RETURNING.

The whole suite runs against Postgres too:

docker run -d --rm -p 127.0.0.1:5439:5432 -e POSTGRES_PASSWORD=pg postgres:17-alpine
SENTINEL_TEST_POSTGRES_URL=postgres://postgres:pg@127.0.0.1:5439/postgres cargo test

API reference (JSON)

agent-api-reference.json
{
  "functions": [
    {
      "description": "List every diagnosis recorded against a group, newest first. Each recording is a version and none are overwritten, so the same failure diagnosed twice can be compared.",
      "metadata": {},
      "name": "sentinel::diagnoses::list",
      "request_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "additionalProperties": false,
        "description": "Every diagnosis recorded against one group, across investigations.\n\nSeparate from `groups::get`, which carries only the one in force: the history is what the Diagnosis tab opens, and most readers never ask for it.",
        "properties": {
          "group_id": {
            "type": "string"
          },
          "limit": {
            "default": null,
            "format": "uint32",
            "minimum": 0,
            "type": [
              "integer",
              "null"
            ]
          },
          "offset": {
            "default": null,
            "format": "uint32",
            "minimum": 0,
            "type": [
              "integer",
              "null"
            ]
          }
        },
        "required": [
          "group_id"
        ],
        "title": "DiagnosesListRequestV1",
        "type": "object"
      },
      "response_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "additionalProperties": false,
        "definitions": {
          "ConfidenceV1": {
            "enum": [
              "high",
              "medium",
              "low"
            ],
            "type": "string"
          },
          "DiagnosisCategoryV1": {
            "oneOf": [
              {
                "enum": [
                  "bug",
                  "configuration",
                  "dependency",
                  "unknown"
                ],
                "type": "string"
              },
              {
                "description": "Real, but it went away on its own: a timeout, a restart, a race.",
                "enum": [
                  "transient"
                ],
                "type": "string"
              },
              {
                "description": "The failure is the designed behaviour of the code.",
                "enum": [
                  "expected"
                ],
                "type": "string"
              }
            ]
          },
          "DiagnosisEvidenceV1": {
            "additionalProperties": false,
            "description": "One thing the agent is pointing at, and why it matters.",
            "properties": {
              "excerpt": {
                "description": "At most 400 characters of the thing itself.",
                "type": "string"
              },
              "kind": {
                "$ref": "#/definitions/EvidenceKindV1"
              },
              "line": {
                "format": "uint32",
                "minimum": 0,
                "type": [
                  "integer",
                  "null"
                ]
              },
              "path": {
                "description": "Relative to the repository root, for `code`.",
                "type": [
                  "string",
                  "null"
                ]
              },
              "span_id": {
                "description": "The span this points at, for `trace`.",
                "type": [
                  "string",
                  "null"
                ]
              },
              "why": {
                "type": "string"
              }
            },
            "required": [
              "excerpt",
              "kind",
              "why"
            ],
            "type": "object"
          },
          "DiagnosisRecordV1": {
            "additionalProperties": false,
            "description": "A recorded diagnosis with its provenance.",
            "properties": {
              "created_ms": {
                "format": "int64",
                "type": "integer"
              },
              "diagnosis": {
                "anyOf": [
                  {
                    "$ref": "#/definitions/DiagnosisV1"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "group_id": {
                "type": "string"
              },
              "id": {
                "type": "string"
              },
              "investigation_id": {
                "type": "string"
              },
              "model": {
                "type": "string"
              },
              "raw_result": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "session_id": {
                "type": "string"
              },
              "source": {
                "$ref": "#/definitions/DiagnosisSourceV1"
              },
              "turn_id": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "valid": {
                "description": "False when the stored payload no longer parses as a `DiagnosisV1` — the raw text is kept so nothing is lost silently.",
                "type": "boolean"
              }
            },
            "required": [
              "created_ms",
              "group_id",
              "id",
              "investigation_id",
              "model",
              "session_id",
              "source",
              "valid"
            ],
            "type": "object"
          },
          "DiagnosisSourceV1": {
            "oneOf": [
              {
                "description": "Recorded while the automatic first pass was running.",
                "enum": [
                  "first_pass"
                ],
                "type": "string"
              },
              {
                "description": "Recorded later, in the conversation.",
                "enum": [
                  "conversation"
                ],
                "type": "string"
              }
            ]
          },
          "DiagnosisV1": {
            "additionalProperties": false,
            "description": "What an investigation concluded. Written by the agent, never by this worker, and kept verbatim: a later version supersedes it without erasing it, so the same failure diagnosed twice can be compared.",
            "properties": {
              "category": {
                "$ref": "#/definitions/DiagnosisCategoryV1"
              },
              "confidence": {
                "$ref": "#/definitions/ConfidenceV1"
              },
              "missing_evidence": {
                "description": "What would have raised the confidence. An honest `low` with this filled in is a better answer than a guess.",
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              "proposed_fix": {
                "anyOf": [
                  {
                    "$ref": "#/definitions/ProposedFixV1"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "related_groups": {
                "description": "Groups the agent believes share this cause. A suggestion the console shows; nothing is merged on the strength of it.",
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              "reproduction": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "root_cause": {
                "$ref": "#/definitions/RootCauseV1"
              },
              "summary": {
                "description": "One to three sentences, written for a person.",
                "type": "string"
              },
              "version_note": {
                "description": "Drift between the checkout that was read and the version that failed.",
                "type": [
                  "string",
                  "null"
                ]
              }
            },
            "required": [
              "category",
              "confidence",
              "root_cause",
              "summary"
            ],
            "type": "object"
          },
          "EvidenceKindV1": {
            "oneOf": [
              {
                "enum": [
                  "trace",
                  "log"
                ],
                "type": "string"
              },
              {
                "description": "A place in the repository, as a path relative to its root.",
                "enum": [
                  "code"
                ],
                "type": "string"
              }
            ]
          },
          "ProposedFixV1": {
            "additionalProperties": false,
            "properties": {
              "description": {
                "type": "string"
              },
              "files": {
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              "risk": {
                "$ref": "#/definitions/RiskV1"
              },
              "steps": {
                "items": {
                  "type": "string"
                },
                "type": "array"
              }
            },
            "required": [
              "description",
              "files",
              "risk",
              "steps"
            ],
            "type": "object"
          },
          "RiskV1": {
            "enum": [
              "low",
              "medium",
              "high"
            ],
            "type": "string"
          },
          "RootCauseV1": {
            "additionalProperties": false,
            "properties": {
              "description": {
                "type": "string"
              },
              "evidence": {
                "items": {
                  "$ref": "#/definitions/DiagnosisEvidenceV1"
                },
                "type": "array"
              }
            },
            "required": [
              "description",
              "evidence"
            ],
            "type": "object"
          }
        },
        "properties": {
          "diagnoses": {
            "description": "Newest first: the head is the one in force.",
            "items": {
              "$ref": "#/definitions/DiagnosisRecordV1"
            },
            "type": "array"
          },
          "total": {
            "format": "uint64",
            "minimum": 0,
            "type": "integer"
          }
        },
        "required": [
          "diagnoses",
          "total"
        ],
        "title": "DiagnosesListResponseV1",
        "type": "object"
      }
    },
    {
      "description": "Record what an investigation concluded about a group. Called by the agent from inside its own investigation session; the session's identity comes from the invocation, never from the payload. Each call is a new version and the most recent one stands.",
      "metadata": {},
      "name": "sentinel::diagnosis::record",
      "request_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "additionalProperties": false,
        "definitions": {
          "ConfidenceV1": {
            "enum": [
              "high",
              "medium",
              "low"
            ],
            "type": "string"
          },
          "DiagnosisCategoryV1": {
            "oneOf": [
              {
                "enum": [
                  "bug",
                  "configuration",
                  "dependency",
                  "unknown"
                ],
                "type": "string"
              },
              {
                "description": "Real, but it went away on its own: a timeout, a restart, a race.",
                "enum": [
                  "transient"
                ],
                "type": "string"
              },
              {
                "description": "The failure is the designed behaviour of the code.",
                "enum": [
                  "expected"
                ],
                "type": "string"
              }
            ]
          },
          "DiagnosisEvidenceV1": {
            "additionalProperties": false,
            "description": "One thing the agent is pointing at, and why it matters.",
            "properties": {
              "excerpt": {
                "description": "At most 400 characters of the thing itself.",
                "type": "string"
              },
              "kind": {
                "$ref": "#/definitions/EvidenceKindV1"
              },
              "line": {
                "format": "uint32",
                "minimum": 0,
                "type": [
                  "integer",
                  "null"
                ]
              },
              "path": {
                "description": "Relative to the repository root, for `code`.",
                "type": [
                  "string",
                  "null"
                ]
              },
              "span_id": {
                "description": "The span this points at, for `trace`.",
                "type": [
                  "string",
                  "null"
                ]
              },
              "why": {
                "type": "string"
              }
            },
            "required": [
              "excerpt",
              "kind",
              "why"
            ],
            "type": "object"
          },
          "DiagnosisV1": {
            "additionalProperties": false,
            "description": "What an investigation concluded. Written by the agent, never by this worker, and kept verbatim: a later version supersedes it without erasing it, so the same failure diagnosed twice can be compared.",
            "properties": {
              "category": {
                "$ref": "#/definitions/DiagnosisCategoryV1"
              },
              "confidence": {
                "$ref": "#/definitions/ConfidenceV1"
              },
              "missing_evidence": {
                "description": "What would have raised the confidence. An honest `low` with this filled in is a better answer than a guess.",
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              "proposed_fix": {
                "anyOf": [
                  {
                    "$ref": "#/definitions/ProposedFixV1"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "related_groups": {
                "description": "Groups the agent believes share this cause. A suggestion the console shows; nothing is merged on the strength of it.",
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              "reproduction": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "root_cause": {
                "$ref": "#/definitions/RootCauseV1"
              },
              "summary": {
                "description": "One to three sentences, written for a person.",
                "type": "string"
              },
              "version_note": {
                "description": "Drift between the checkout that was read and the version that failed.",
                "type": [
                  "string",
                  "null"
                ]
              }
            },
            "required": [
              "category",
              "confidence",
              "root_cause",
              "summary"
            ],
            "type": "object"
          },
          "EvidenceKindV1": {
            "oneOf": [
              {
                "enum": [
                  "trace",
                  "log"
                ],
                "type": "string"
              },
              {
                "description": "A place in the repository, as a path relative to its root.",
                "enum": [
                  "code"
                ],
                "type": "string"
              }
            ]
          },
          "ProposedFixV1": {
            "additionalProperties": false,
            "properties": {
              "description": {
                "type": "string"
              },
              "files": {
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              "risk": {
                "$ref": "#/definitions/RiskV1"
              },
              "steps": {
                "items": {
                  "type": "string"
                },
                "type": "array"
              }
            },
            "required": [
              "description",
              "files",
              "risk",
              "steps"
            ],
            "type": "object"
          },
          "RiskV1": {
            "enum": [
              "low",
              "medium",
              "high"
            ],
            "type": "string"
          },
          "RootCauseV1": {
            "additionalProperties": false,
            "properties": {
              "description": {
                "type": "string"
              },
              "evidence": {
                "items": {
                  "$ref": "#/definitions/DiagnosisEvidenceV1"
                },
                "type": "array"
              }
            },
            "required": [
              "description",
              "evidence"
            ],
            "type": "object"
          }
        },
        "description": "The agent's one write. There is no `investigation_id` and no `session_id` here on purpose: identity comes from the invocation's baggage, which the agent does not control, so no payload can point a diagnosis at somebody else's investigation.",
        "properties": {
          "diagnosis": {
            "$ref": "#/definitions/DiagnosisV1"
          },
          "group_id": {
            "type": "string"
          }
        },
        "required": [
          "diagnosis",
          "group_id"
        ],
        "title": "DiagnosisRecordRequestV1",
        "type": "object"
      },
      "response_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "additionalProperties": false,
        "definitions": {
          "GroupStatusV1": {
            "description": "The lifecycle of a group. `resolved` and `ignored` are human decisions; `regressed` is the one the ingest makes on its own, and the reason the worker exists.",
            "oneOf": [
              {
                "enum": [
                  "new",
                  "diagnosed",
                  "resolved",
                  "ignored"
                ],
                "type": "string"
              },
              {
                "description": "The first pass of an investigation is running.",
                "enum": [
                  "investigating"
                ],
                "type": "string"
              },
              {
                "description": "A new occurrence after a resolve.",
                "enum": [
                  "regressed"
                ],
                "type": "string"
              }
            ]
          }
        },
        "properties": {
          "diagnosis_id": {
            "type": "string"
          },
          "group_status": {
            "allOf": [
              {
                "$ref": "#/definitions/GroupStatusV1"
              }
            ],
            "description": "Where the group was left. A resolved, ignored or regressed group keeps its state and takes the diagnosis anyway."
          },
          "version": {
            "description": "1 on this investigation's first recording, and up from there.",
            "format": "uint64",
            "minimum": 0,
            "type": "integer"
          }
        },
        "required": [
          "diagnosis_id",
          "group_status",
          "version"
        ],
        "title": "DiagnosisRecordResponseV1",
        "type": "object"
      }
    },
    {
      "description": "Read the frozen evidence of one occurrence: the span tree, the logs of that trace and the session tags, captured before the engine's ring discarded them. Reports pruned when retention has removed it.",
      "metadata": {},
      "name": "sentinel::evidence::get",
      "request_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "additionalProperties": false,
        "properties": {
          "occurrence_id": {
            "type": "string"
          }
        },
        "required": [
          "occurrence_id"
        ],
        "title": "EvidenceGetRequestV1",
        "type": "object"
      },
      "response_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "additionalProperties": false,
        "definitions": {
          "EvidenceBundleV1": {
            "additionalProperties": false,
            "properties": {
              "captured_at_ms": {
                "format": "int64",
                "type": "integer"
              },
              "logs": {
                "items": {
                  "$ref": "#/definitions/EvidenceLogV1"
                },
                "type": "array"
              },
              "origin_span_id": {
                "description": "The leaf error span this bundle is about.",
                "type": "string"
              },
              "propagated_through": {
                "description": "Ancestors that carry the same failure upward. They are context, not groups of their own.",
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              "settled": {
                "description": "True once the settle pass re-read the trace: ancestors that were still open at capture are closed here.",
                "type": "boolean"
              },
              "spans": {
                "items": {
                  "$ref": "#/definitions/EvidenceSpanV1"
                },
                "type": "array"
              },
              "trace_id": {
                "type": "string"
              },
              "trace_tags": {
                "additionalProperties": {
                  "type": "string"
                },
                "type": "object"
              },
              "truncated": {
                "$ref": "#/definitions/EvidenceTruncatedV1"
              },
              "version": {
                "format": "uint32",
                "minimum": 0,
                "type": "integer"
              },
              "worker": {
                "$ref": "#/definitions/EvidenceWorkerV1"
              }
            },
            "required": [
              "captured_at_ms",
              "logs",
              "origin_span_id",
              "propagated_through",
              "settled",
              "spans",
              "trace_id",
              "trace_tags",
              "truncated",
              "version",
              "worker"
            ],
            "type": "object"
          },
          "EvidenceEventV1": {
            "additionalProperties": false,
            "properties": {
              "attributes": {
                "additionalProperties": {
                  "type": "string"
                },
                "type": "object"
              },
              "name": {
                "type": "string"
              },
              "timestamp_unix_nano": {
                "format": "uint64",
                "minimum": 0,
                "type": "integer"
              }
            },
            "required": [
              "attributes",
              "name",
              "timestamp_unix_nano"
            ],
            "type": "object"
          },
          "EvidenceLogV1": {
            "additionalProperties": false,
            "properties": {
              "attributes": {
                "additionalProperties": {
                  "type": "string"
                },
                "type": "object"
              },
              "body": {
                "type": "string"
              },
              "severity_text": {
                "type": "string"
              },
              "span_id": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "timestamp_unix_nano": {
                "format": "uint64",
                "minimum": 0,
                "type": "integer"
              }
            },
            "required": [
              "attributes",
              "body",
              "severity_text",
              "timestamp_unix_nano"
            ],
            "type": "object"
          },
          "EvidenceSpanV1": {
            "additionalProperties": false,
            "properties": {
              "attributes": {
                "additionalProperties": {
                  "type": "string"
                },
                "type": "object"
              },
              "depth": {
                "format": "uint32",
                "minimum": 0,
                "type": "integer"
              },
              "end_time_unix_nano": {
                "description": "Zero while the span is still open — the engine's own convention for a pending span, kept rather than normalized so a half-finished trace reads as one.",
                "format": "uint64",
                "minimum": 0,
                "type": "integer"
              },
              "events": {
                "items": {
                  "$ref": "#/definitions/EvidenceEventV1"
                },
                "type": "array"
              },
              "function_id": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "name": {
                "type": "string"
              },
              "parent_span_id": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "service_name": {
                "type": "string"
              },
              "span_id": {
                "type": "string"
              },
              "start_time_unix_nano": {
                "format": "uint64",
                "minimum": 0,
                "type": "integer"
              },
              "status": {
                "type": "string"
              },
              "status_description": {
                "type": [
                  "string",
                  "null"
                ]
              }
            },
            "required": [
              "attributes",
              "depth",
              "end_time_unix_nano",
              "events",
              "name",
              "service_name",
              "span_id",
              "start_time_unix_nano",
              "status"
            ],
            "type": "object"
          },
          "EvidenceTruncatedV1": {
            "additionalProperties": false,
            "properties": {
              "attributes": {
                "format": "uint32",
                "minimum": 0,
                "type": "integer"
              },
              "logs": {
                "format": "uint32",
                "minimum": 0,
                "type": "integer"
              },
              "spans": {
                "format": "uint32",
                "minimum": 0,
                "type": "integer"
              }
            },
            "required": [
              "attributes",
              "logs",
              "spans"
            ],
            "type": "object"
          },
          "EvidenceWorkerV1": {
            "additionalProperties": false,
            "properties": {
              "service_name": {
                "type": "string"
              },
              "version": {
                "type": [
                  "string",
                  "null"
                ]
              }
            },
            "required": [
              "service_name"
            ],
            "type": "object"
          }
        },
        "properties": {
          "evidence": {
            "anyOf": [
              {
                "$ref": "#/definitions/EvidenceBundleV1"
              },
              {
                "type": "null"
              }
            ],
            "description": "Absent when retention has pruned it: the row stays, the bundle goes."
          },
          "pruned": {
            "type": "boolean"
          }
        },
        "required": [
          "pruned"
        ],
        "title": "EvidenceGetResponseV1",
        "type": "object"
      }
    },
    {
      "description": "Read one error group with its latest occurrence, and whether that occurrence's trace is still readable in the engine or only as the frozen snapshot.",
      "metadata": {},
      "name": "sentinel::groups::get",
      "request_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "additionalProperties": false,
        "properties": {
          "group_id": {
            "type": "string"
          }
        },
        "required": [
          "group_id"
        ],
        "title": "GroupGetRequestV1",
        "type": "object"
      },
      "response_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "additionalProperties": false,
        "definitions": {
          "ConfidenceV1": {
            "enum": [
              "high",
              "medium",
              "low"
            ],
            "type": "string"
          },
          "DiagnosisCategoryV1": {
            "oneOf": [
              {
                "enum": [
                  "bug",
                  "configuration",
                  "dependency",
                  "unknown"
                ],
                "type": "string"
              },
              {
                "description": "Real, but it went away on its own: a timeout, a restart, a race.",
                "enum": [
                  "transient"
                ],
                "type": "string"
              },
              {
                "description": "The failure is the designed behaviour of the code.",
                "enum": [
                  "expected"
                ],
                "type": "string"
              }
            ]
          },
          "DiagnosisEvidenceV1": {
            "additionalProperties": false,
            "description": "One thing the agent is pointing at, and why it matters.",
            "properties": {
              "excerpt": {
                "description": "At most 400 characters of the thing itself.",
                "type": "string"
              },
              "kind": {
                "$ref": "#/definitions/EvidenceKindV1"
              },
              "line": {
                "format": "uint32",
                "minimum": 0,
                "type": [
                  "integer",
                  "null"
                ]
              },
              "path": {
                "description": "Relative to the repository root, for `code`.",
                "type": [
                  "string",
                  "null"
                ]
              },
              "span_id": {
                "description": "The span this points at, for `trace`.",
                "type": [
                  "string",
                  "null"
                ]
              },
              "why": {
                "type": "string"
              }
            },
            "required": [
              "excerpt",
              "kind",
              "why"
            ],
            "type": "object"
          },
          "DiagnosisRecordV1": {
            "additionalProperties": false,
            "description": "A recorded diagnosis with its provenance.",
            "properties": {
              "created_ms": {
                "format": "int64",
                "type": "integer"
              },
              "diagnosis": {
                "anyOf": [
                  {
                    "$ref": "#/definitions/DiagnosisV1"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "group_id": {
                "type": "string"
              },
              "id": {
                "type": "string"
              },
              "investigation_id": {
                "type": "string"
              },
              "model": {
                "type": "string"
              },
              "raw_result": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "session_id": {
                "type": "string"
              },
              "source": {
                "$ref": "#/definitions/DiagnosisSourceV1"
              },
              "turn_id": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "valid": {
                "description": "False when the stored payload no longer parses as a `DiagnosisV1` — the raw text is kept so nothing is lost silently.",
                "type": "boolean"
              }
            },
            "required": [
              "created_ms",
              "group_id",
              "id",
              "investigation_id",
              "model",
              "session_id",
              "source",
              "valid"
            ],
            "type": "object"
          },
          "DiagnosisSourceV1": {
            "oneOf": [
              {
                "description": "Recorded while the automatic first pass was running.",
                "enum": [
                  "first_pass"
                ],
                "type": "string"
              },
              {
                "description": "Recorded later, in the conversation.",
                "enum": [
                  "conversation"
                ],
                "type": "string"
              }
            ]
          },
          "DiagnosisV1": {
            "additionalProperties": false,
            "description": "What an investigation concluded. Written by the agent, never by this worker, and kept verbatim: a later version supersedes it without erasing it, so the same failure diagnosed twice can be compared.",
            "properties": {
              "category": {
                "$ref": "#/definitions/DiagnosisCategoryV1"
              },
              "confidence": {
                "$ref": "#/definitions/ConfidenceV1"
              },
              "missing_evidence": {
                "description": "What would have raised the confidence. An honest `low` with this filled in is a better answer than a guess.",
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              "proposed_fix": {
                "anyOf": [
                  {
                    "$ref": "#/definitions/ProposedFixV1"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "related_groups": {
                "description": "Groups the agent believes share this cause. A suggestion the console shows; nothing is merged on the strength of it.",
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              "reproduction": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "root_cause": {
                "$ref": "#/definitions/RootCauseV1"
              },
              "summary": {
                "description": "One to three sentences, written for a person.",
                "type": "string"
              },
              "version_note": {
                "description": "Drift between the checkout that was read and the version that failed.",
                "type": [
                  "string",
                  "null"
                ]
              }
            },
            "required": [
              "category",
              "confidence",
              "root_cause",
              "summary"
            ],
            "type": "object"
          },
          "ErrorSourceV1": {
            "description": "Where an error event came from. Part of the fingerprint: the same text seen as a span and as a log is two groups, because one has a trace to investigate and the other does not.",
            "oneOf": [
              {
                "enum": [
                  "report"
                ],
                "type": "string"
              },
              {
                "description": "A span with status `error`.",
                "enum": [
                  "trace"
                ],
                "type": "string"
              },
              {
                "description": "An OTel log record at ERROR.",
                "enum": [
                  "log"
                ],
                "type": "string"
              },
              {
                "description": "Reserved for the adapters the spec designs but v1 does not implement.",
                "enum": [
                  "harness-turn"
                ],
                "type": "string"
              }
            ]
          },
          "EvidenceKindV1": {
            "oneOf": [
              {
                "enum": [
                  "trace",
                  "log"
                ],
                "type": "string"
              },
              {
                "description": "A place in the repository, as a path relative to its root.",
                "enum": [
                  "code"
                ],
                "type": "string"
              }
            ]
          },
          "GroupStatusV1": {
            "description": "The lifecycle of a group. `resolved` and `ignored` are human decisions; `regressed` is the one the ingest makes on its own, and the reason the worker exists.",
            "oneOf": [
              {
                "enum": [
                  "new",
                  "diagnosed",
                  "resolved",
                  "ignored"
                ],
                "type": "string"
              },
              {
                "description": "The first pass of an investigation is running.",
                "enum": [
                  "investigating"
                ],
                "type": "string"
              },
              {
                "description": "A new occurrence after a resolve.",
                "enum": [
                  "regressed"
                ],
                "type": "string"
              }
            ]
          },
          "GroupSummaryV1": {
            "additionalProperties": false,
            "description": "A group as the list shows it.",
            "properties": {
              "exception_type": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "fingerprint": {
                "type": "string"
              },
              "first_seen_ms": {
                "format": "int64",
                "type": "integer"
              },
              "first_version": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "function_id": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "has_diagnosis": {
                "type": "boolean"
              },
              "id": {
                "type": "string"
              },
              "ignore_rule": {
                "anyOf": [
                  {
                    "$ref": "#/definitions/IgnoreRuleV1"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "last_seen_ms": {
                "format": "int64",
                "type": "integer"
              },
              "last_version": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "namespace": {
                "type": "string"
              },
              "occurrence_count": {
                "format": "uint64",
                "minimum": 0,
                "type": "integer"
              },
              "regressed_at_ms": {
                "format": "int64",
                "type": [
                  "integer",
                  "null"
                ]
              },
              "relevant": {
                "description": "Whether the default list shows it; see [`RelevanceV1::Relevant`].",
                "type": "boolean"
              },
              "resolve_until_version_change": {
                "type": "boolean"
              },
              "resolved_at_ms": {
                "description": "When the group was last resolved and on which version — what a regression is measured against, so the page can say what came back.",
                "format": "int64",
                "type": [
                  "integer",
                  "null"
                ]
              },
              "resolved_version": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "service_name": {
                "description": "The worker that owns the failing function.",
                "type": "string"
              },
              "sessions_affected": {
                "description": "Distinct sessions this failure touched. Counted from its own table, so it stays true after occurrence rows are pruned.",
                "format": "uint64",
                "minimum": 0,
                "type": "integer"
              },
              "source": {
                "$ref": "#/definitions/ErrorSourceV1"
              },
              "sparkline": {
                "description": "Occurrences per hour for the last day, oldest first.",
                "items": {
                  "format": "uint64",
                  "minimum": 0,
                  "type": "integer"
                },
                "type": "array"
              },
              "status": {
                "$ref": "#/definitions/GroupStatusV1"
              },
              "title": {
                "type": "string"
              },
              "triage": {
                "anyOf": [
                  {
                    "$ref": "#/definitions/GroupTriageV1"
                  },
                  {
                    "type": "null"
                  }
                ],
                "description": "Absent until the group has been triaged."
              }
            },
            "required": [
              "fingerprint",
              "first_seen_ms",
              "has_diagnosis",
              "id",
              "last_seen_ms",
              "namespace",
              "occurrence_count",
              "relevant",
              "service_name",
              "sessions_affected",
              "source",
              "sparkline",
              "status",
              "title"
            ],
            "type": "object"
          },
          "GroupTriageV1": {
            "additionalProperties": false,
            "description": "A hint for ordering and filtering the list. It never moves a group: resolving and ignoring stay human decisions.",
            "properties": {
              "at_ms": {
                "format": "int64",
                "type": "integer"
              },
              "confidence": {
                "description": "Between 0 and 1, as the judge reports it; 1 for a rule.",
                "format": "double",
                "type": "number"
              },
              "kind": {
                "$ref": "#/definitions/TriageKindV1"
              },
              "model": {
                "description": "The judge model that answered.",
                "type": [
                  "string",
                  "null"
                ]
              },
              "source": {
                "$ref": "#/definitions/TriageSourceV1"
              }
            },
            "required": [
              "at_ms",
              "confidence",
              "kind",
              "source"
            ],
            "type": "object"
          },
          "IgnoreRuleV1": {
            "description": "How long an ignore lasts. Every rule keeps counting occurrences; what changes is when the group comes back to the open list.",
            "oneOf": [
              {
                "properties": {
                  "kind": {
                    "enum": [
                      "forever"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "kind"
                ],
                "type": "object"
              },
              {
                "description": "Reopens after this many further occurrences.",
                "properties": {
                  "count": {
                    "format": "uint64",
                    "minimum": 0,
                    "type": "integer"
                  },
                  "kind": {
                    "enum": [
                      "occurrences"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "count",
                  "kind"
                ],
                "type": "object"
              },
              {
                "description": "Reopens when the worker version changes.",
                "properties": {
                  "kind": {
                    "enum": [
                      "version_change"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "kind"
                ],
                "type": "object"
              }
            ]
          },
          "InvestigationModeV1": {
            "description": "How an investigation was opened.",
            "oneOf": [
              {
                "description": "A first pass runs automatically, then the conversation continues.",
                "enum": [
                  "assisted"
                ],
                "type": "string"
              },
              {
                "description": "The session is created with the evidence and nothing runs until a person speaks.",
                "enum": [
                  "chat"
                ],
                "type": "string"
              }
            ]
          },
          "InvestigationStatusV1": {
            "oneOf": [
              {
                "enum": [
                  "failed",
                  "cancelled"
                ],
                "type": "string"
              },
              {
                "description": "The first pass is in flight.",
                "enum": [
                  "running"
                ],
                "type": "string"
              },
              {
                "description": "The first pass ended.",
                "enum": [
                  "completed"
                ],
                "type": "string"
              },
              {
                "description": "A chat-mode session: no first pass ever ran, the conversation is the investigation.",
                "enum": [
                  "open"
                ],
                "type": "string"
              }
            ]
          },
          "InvestigationSummaryV1": {
            "additionalProperties": false,
            "properties": {
              "checkout_ref": {
                "description": "The commit the mapped checkout was on when the pass started.",
                "type": [
                  "string",
                  "null"
                ]
              },
              "cost_usd": {
                "format": "double",
                "type": [
                  "number",
                  "null"
                ]
              },
              "created_ms": {
                "format": "int64",
                "type": "integer"
              },
              "duration_ms": {
                "format": "int64",
                "type": [
                  "integer",
                  "null"
                ]
              },
              "error": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "finished_ms": {
                "format": "int64",
                "type": [
                  "integer",
                  "null"
                ]
              },
              "first_pass_turn_id": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "group_id": {
                "type": "string"
              },
              "id": {
                "type": "string"
              },
              "investigated_version": {
                "description": "The worker version the investigated occurrence ran on.",
                "type": [
                  "string",
                  "null"
                ]
              },
              "mode": {
                "$ref": "#/definitions/InvestigationModeV1"
              },
              "model": {
                "type": "string"
              },
              "occurrence_id": {
                "type": "string"
              },
              "provider": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "repository_id": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "session_id": {
                "description": "The harness session. The console opens this beside the page.",
                "type": "string"
              },
              "status": {
                "$ref": "#/definitions/InvestigationStatusV1"
              },
              "turns": {
                "description": "Observed after the fact, and informative only: this worker imposes no ceiling on an investigation.",
                "format": "uint64",
                "minimum": 0,
                "type": [
                  "integer",
                  "null"
                ]
              }
            },
            "required": [
              "created_ms",
              "group_id",
              "id",
              "mode",
              "model",
              "occurrence_id",
              "session_id",
              "status"
            ],
            "type": "object"
          },
          "OccurrenceSummaryV1": {
            "additionalProperties": false,
            "description": "One recorded instance of a group.",
            "properties": {
              "at_ms": {
                "format": "int64",
                "type": "integer"
              },
              "has_evidence": {
                "description": "Whether the frozen bundle is still kept for this one.",
                "type": "boolean"
              },
              "id": {
                "type": "string"
              },
              "message": {
                "type": "string"
              },
              "namespace_ambiguous": {
                "description": "The owner could not be pinned to one namespace.",
                "type": "boolean"
              },
              "session_id": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "settled": {
                "description": "Whether the trace was re-read after the ancestors closed.",
                "type": "boolean"
              },
              "source": {
                "$ref": "#/definitions/ErrorSourceV1"
              },
              "span_id": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "trace_id": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "turn_id": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "worker_version": {
                "type": [
                  "string",
                  "null"
                ]
              }
            },
            "required": [
              "at_ms",
              "has_evidence",
              "id",
              "message",
              "namespace_ambiguous",
              "settled",
              "source"
            ],
            "type": "object"
          },
          "ProposedFixV1": {
            "additionalProperties": false,
            "properties": {
              "description": {
                "type": "string"
              },
              "files": {
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              "risk": {
                "$ref": "#/definitions/RiskV1"
              },
              "steps": {
                "items": {
                  "type": "string"
                },
                "type": "array"
              }
            },
            "required": [
              "description",
              "files",
              "risk",
              "steps"
            ],
            "type": "object"
          },
          "RiskV1": {
            "enum": [
              "low",
              "medium",
              "high"
            ],
            "type": "string"
          },
          "RootCauseV1": {
            "additionalProperties": false,
            "properties": {
              "description": {
                "type": "string"
              },
              "evidence": {
                "items": {
                  "$ref": "#/definitions/DiagnosisEvidenceV1"
                },
                "type": "array"
              }
            },
            "required": [
              "description",
              "evidence"
            ],
            "type": "object"
          },
          "TriageKindV1": {
            "description": "What kind of failure a group is, as triage reads it.",
            "oneOf": [
              {
                "description": "A bug the reporting worker's maintainer has to fix in code.",
                "enum": [
                  "defect"
                ],
                "type": "string"
              },
              {
                "description": "The worker rejected bad input and said so: working as designed.",
                "enum": [
                  "caller_error"
                ],
                "type": "string"
              },
              {
                "description": "A dependency starting, restarting or timing out; it went away.",
                "enum": [
                  "transient"
                ],
                "type": "string"
              },
              {
                "description": "Local setup: credentials, tokens, files, versions, a missing worker.",
                "enum": [
                  "environment"
                ],
                "type": "string"
              },
              {
                "description": "Tests, probes and deliberately fake identifiers.",
                "enum": [
                  "test_traffic"
                ],
                "type": "string"
              }
            ]
          },
          "TriageSourceV1": {
            "description": "Who decided a triage.",
            "oneOf": [
              {
                "description": "A deterministic check: a missing function that is registered by the time the group is looked at.",
                "enum": [
                  "rule"
                ],
                "type": "string"
              },
              {
                "description": "`judge::evaluate`.",
                "enum": [
                  "judge"
                ],
                "type": "string"
              }
            ]
          }
        },
        "properties": {
          "active_investigation": {
            "anyOf": [
              {
                "$ref": "#/definitions/InvestigationSummaryV1"
              },
              {
                "type": "null"
              }
            ],
            "description": "The first pass running right now, if one is."
          },
          "diagnosis": {
            "anyOf": [
              {
                "$ref": "#/definitions/DiagnosisRecordV1"
              },
              {
                "type": "null"
              }
            ],
            "description": "The diagnosis in force, when an investigation recorded one."
          },
          "group": {
            "$ref": "#/definitions/GroupSummaryV1"
          },
          "latest_investigation": {
            "anyOf": [
              {
                "$ref": "#/definitions/InvestigationSummaryV1"
              },
              {
                "type": "null"
              }
            ],
            "description": "The most recent investigation of any state — what \"Continue in chat\" reopens."
          },
          "latest_occurrence": {
            "anyOf": [
              {
                "$ref": "#/definitions/OccurrenceSummaryV1"
              },
              {
                "type": "null"
              }
            ]
          },
          "message_sample": {
            "description": "The message exactly as it was captured, after redaction.",
            "type": "string"
          },
          "trace_available": {
            "description": "Whether the trace behind the latest occurrence is still in the engine's ring. False means the frozen snapshot is all there is.",
            "type": "boolean"
          }
        },
        "required": [
          "group",
          "message_sample",
          "trace_available"
        ],
        "title": "GroupGetResponseV1",
        "type": "object"
      }
    },
    {
      "description": "Every move a group has made, newest first: what changed it, why, and whether it came from the pipeline, from an agent or from a person.",
      "metadata": {},
      "name": "sentinel::groups::history",
      "request_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "additionalProperties": false,
        "properties": {
          "group_id": {
            "type": "string"
          },
          "limit": {
            "default": null,
            "format": "uint32",
            "minimum": 0,
            "type": [
              "integer",
              "null"
            ]
          },
          "offset": {
            "default": null,
            "format": "uint32",
            "minimum": 0,
            "type": [
              "integer",
              "null"
            ]
          }
        },
        "required": [
          "group_id"
        ],
        "title": "GroupHistoryRequestV1",
        "type": "object"
      },
      "response_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "additionalProperties": false,
        "definitions": {
          "GroupChangeReasonV1": {
            "description": "Why a group changed, for the event siblings subscribe to.",
            "enum": [
              "regression",
              "ignore_expired",
              "resolved",
              "ignored",
              "diagnosed",
              "reopened",
              "investigating"
            ],
            "type": "string"
          },
          "GroupStatusV1": {
            "description": "The lifecycle of a group. `resolved` and `ignored` are human decisions; `regressed` is the one the ingest makes on its own, and the reason the worker exists.",
            "oneOf": [
              {
                "enum": [
                  "new",
                  "diagnosed",
                  "resolved",
                  "ignored"
                ],
                "type": "string"
              },
              {
                "description": "The first pass of an investigation is running.",
                "enum": [
                  "investigating"
                ],
                "type": "string"
              },
              {
                "description": "A new occurrence after a resolve.",
                "enum": [
                  "regressed"
                ],
                "type": "string"
              }
            ]
          },
          "GroupTransitionV1": {
            "additionalProperties": false,
            "description": "One recorded move of a group, for the History tab.",
            "properties": {
              "actor": {
                "description": "A role rather than a person: `ingest`, `agent`, `investigation` or `console`. The console hands this worker no user identity, and a worker uuid here would read as one.",
                "type": "string"
              },
              "at_ms": {
                "format": "int64",
                "type": "integer"
              },
              "from_status": {
                "anyOf": [
                  {
                    "$ref": "#/definitions/GroupStatusV1"
                  },
                  {
                    "type": "null"
                  }
                ],
                "description": "Absent on the row that records the group's own beginning."
              },
              "id": {
                "type": "string"
              },
              "reason": {
                "anyOf": [
                  {
                    "$ref": "#/definitions/GroupChangeReasonV1"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "to_status": {
                "$ref": "#/definitions/GroupStatusV1"
              }
            },
            "required": [
              "actor",
              "at_ms",
              "id",
              "to_status"
            ],
            "type": "object"
          }
        },
        "properties": {
          "total": {
            "format": "uint64",
            "minimum": 0,
            "type": "integer"
          },
          "transitions": {
            "description": "Newest first.",
            "items": {
              "$ref": "#/definitions/GroupTransitionV1"
            },
            "type": "array"
          }
        },
        "required": [
          "total",
          "transitions"
        ],
        "title": "GroupHistoryResponseV1",
        "type": "object"
      }
    },
    {
      "description": "Ignore a group forever, for a number of further occurrences, or until the worker version changes. Occurrences keep counting either way.",
      "metadata": {},
      "name": "sentinel::groups::ignore",
      "request_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "additionalProperties": false,
        "definitions": {
          "IgnoreRuleV1": {
            "description": "How long an ignore lasts. Every rule keeps counting occurrences; what changes is when the group comes back to the open list.",
            "oneOf": [
              {
                "properties": {
                  "kind": {
                    "enum": [
                      "forever"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "kind"
                ],
                "type": "object"
              },
              {
                "description": "Reopens after this many further occurrences.",
                "properties": {
                  "count": {
                    "format": "uint64",
                    "minimum": 0,
                    "type": "integer"
                  },
                  "kind": {
                    "enum": [
                      "occurrences"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "count",
                  "kind"
                ],
                "type": "object"
              },
              {
                "description": "Reopens when the worker version changes.",
                "properties": {
                  "kind": {
                    "enum": [
                      "version_change"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "kind"
                ],
                "type": "object"
              }
            ]
          }
        },
        "properties": {
          "group_id": {
            "type": "string"
          },
          "rule": {
            "$ref": "#/definitions/IgnoreRuleV1"
          }
        },
        "required": [
          "group_id",
          "rule"
        ],
        "title": "IgnoreRequestV1",
        "type": "object"
      },
      "response_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "additionalProperties": false,
        "definitions": {
          "GroupChangeReasonV1": {
            "description": "Why a group changed, for the event siblings subscribe to.",
            "enum": [
              "regression",
              "ignore_expired",
              "resolved",
              "ignored",
              "diagnosed",
              "reopened",
              "investigating"
            ],
            "type": "string"
          },
          "GroupStatusV1": {
            "description": "The lifecycle of a group. `resolved` and `ignored` are human decisions; `regressed` is the one the ingest makes on its own, and the reason the worker exists.",
            "oneOf": [
              {
                "enum": [
                  "new",
                  "diagnosed",
                  "resolved",
                  "ignored"
                ],
                "type": "string"
              },
              {
                "description": "The first pass of an investigation is running.",
                "enum": [
                  "investigating"
                ],
                "type": "string"
              },
              {
                "description": "A new occurrence after a resolve.",
                "enum": [
                  "regressed"
                ],
                "type": "string"
              }
            ]
          }
        },
        "description": "The state a group was left in, and why.",
        "properties": {
          "group_id": {
            "type": "string"
          },
          "reason": {
            "anyOf": [
              {
                "$ref": "#/definitions/GroupChangeReasonV1"
              },
              {
                "type": "null"
              }
            ]
          },
          "status": {
            "$ref": "#/definitions/GroupStatusV1"
          }
        },
        "required": [
          "group_id",
          "status"
        ],
        "title": "GroupStateResponseV1",
        "type": "object"
      }
    },
    {
      "description": "List error groups, regressions first. Filters by state, worker, time window and a search over title, message and function id; defaults to the open states.",
      "metadata": {},
      "name": "sentinel::groups::list",
      "request_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "additionalProperties": false,
        "definitions": {
          "GroupStatusV1": {
            "description": "The lifecycle of a group. `resolved` and `ignored` are human decisions; `regressed` is the one the ingest makes on its own, and the reason the worker exists.",
            "oneOf": [
              {
                "enum": [
                  "new",
                  "diagnosed",
                  "resolved",
                  "ignored"
                ],
                "type": "string"
              },
              {
                "description": "The first pass of an investigation is running.",
                "enum": [
                  "investigating"
                ],
                "type": "string"
              },
              {
                "description": "A new occurrence after a resolve.",
                "enum": [
                  "regressed"
                ],
                "type": "string"
              }
            ]
          },
          "RelevanceV1": {
            "description": "Which side of triage the list shows.",
            "oneOf": [
              {
                "description": "What needs a person: defects, persistent caller errors and environment problems, regressions, and anything not triaged yet.",
                "enum": [
                  "relevant"
                ],
                "type": "string"
              },
              {
                "description": "Everything else.",
                "enum": [
                  "noise"
                ],
                "type": "string"
              }
            ]
          }
        },
        "properties": {
          "limit": {
            "default": null,
            "format": "uint32",
            "minimum": 0,
            "type": [
              "integer",
              "null"
            ]
          },
          "offset": {
            "default": null,
            "format": "uint32",
            "minimum": 0,
            "type": [
              "integer",
              "null"
            ]
          },
          "relevance": {
            "anyOf": [
              {
                "$ref": "#/definitions/RelevanceV1"
              },
              {
                "type": "null"
              }
            ],
            "default": null,
            "description": "Absent lists both sides."
          },
          "search": {
            "default": null,
            "description": "Matches the title, the message sample and the function id.",
            "type": [
              "string",
              "null"
            ]
          },
          "service_name": {
            "default": null,
            "type": [
              "string",
              "null"
            ]
          },
          "since_ms": {
            "default": null,
            "description": "Only groups seen since this moment.",
            "format": "int64",
            "type": [
              "integer",
              "null"
            ]
          },
          "status": {
            "default": null,
            "description": "Defaults to the open states.",
            "items": {
              "$ref": "#/definitions/GroupStatusV1"
            },
            "type": [
              "array",
              "null"
            ]
          }
        },
        "title": "GroupsListRequestV1",
        "type": "object"
      },
      "response_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "additionalProperties": false,
        "definitions": {
          "ErrorSourceV1": {
            "description": "Where an error event came from. Part of the fingerprint: the same text seen as a span and as a log is two groups, because one has a trace to investigate and the other does not.",
            "oneOf": [
              {
                "enum": [
                  "report"
                ],
                "type": "string"
              },
              {
                "description": "A span with status `error`.",
                "enum": [
                  "trace"
                ],
                "type": "string"
              },
              {
                "description": "An OTel log record at ERROR.",
                "enum": [
                  "log"
                ],
                "type": "string"
              },
              {
                "description": "Reserved for the adapters the spec designs but v1 does not implement.",
                "enum": [
                  "harness-turn"
                ],
                "type": "string"
              }
            ]
          },
          "GroupStatusV1": {
            "description": "The lifecycle of a group. `resolved` and `ignored` are human decisions; `regressed` is the one the ingest makes on its own, and the reason the worker exists.",
            "oneOf": [
              {
                "enum": [
                  "new",
                  "diagnosed",
                  "resolved",
                  "ignored"
                ],
                "type": "string"
              },
              {
                "description": "The first pass of an investigation is running.",
                "enum": [
                  "investigating"
                ],
                "type": "string"
              },
              {
                "description": "A new occurrence after a resolve.",
                "enum": [
                  "regressed"
                ],
                "type": "string"
              }
            ]
          },
          "GroupSummaryV1": {
            "additionalProperties": false,
            "description": "A group as the list shows it.",
            "properties": {
              "exception_type": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "fingerprint": {
                "type": "string"
              },
              "first_seen_ms": {
                "format": "int64",
                "type": "integer"
              },
              "first_version": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "function_id": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "has_diagnosis": {
                "type": "boolean"
              },
              "id": {
                "type": "string"
              },
              "ignore_rule": {
                "anyOf": [
                  {
                    "$ref": "#/definitions/IgnoreRuleV1"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "last_seen_ms": {
                "format": "int64",
                "type": "integer"
              },
              "last_version": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "namespace": {
                "type": "string"
              },
              "occurrence_count": {
                "format": "uint64",
                "minimum": 0,
                "type": "integer"
              },
              "regressed_at_ms": {
                "format": "int64",
                "type": [
                  "integer",
                  "null"
                ]
              },
              "relevant": {
                "description": "Whether the default list shows it; see [`RelevanceV1::Relevant`].",
                "type": "boolean"
              },
              "resolve_until_version_change": {
                "type": "boolean"
              },
              "resolved_at_ms": {
                "description": "When the group was last resolved and on which version — what a regression is measured against, so the page can say what came back.",
                "format": "int64",
                "type": [
                  "integer",
                  "null"
                ]
              },
              "resolved_version": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "service_name": {
                "description": "The worker that owns the failing function.",
                "type": "string"
              },
              "sessions_affected": {
                "description": "Distinct sessions this failure touched. Counted from its own table, so it stays true after occurrence rows are pruned.",
                "format": "uint64",
                "minimum": 0,
                "type": "integer"
              },
              "source": {
                "$ref": "#/definitions/ErrorSourceV1"
              },
              "sparkline": {
                "description": "Occurrences per hour for the last day, oldest first.",
                "items": {
                  "format": "uint64",
                  "minimum": 0,
                  "type": "integer"
                },
                "type": "array"
              },
              "status": {
                "$ref": "#/definitions/GroupStatusV1"
              },
              "title": {
                "type": "string"
              },
              "triage": {
                "anyOf": [
                  {
                    "$ref": "#/definitions/GroupTriageV1"
                  },
                  {
                    "type": "null"
                  }
                ],
                "description": "Absent until the group has been triaged."
              }
            },
            "required": [
              "fingerprint",
              "first_seen_ms",
              "has_diagnosis",
              "id",
              "last_seen_ms",
              "namespace",
              "occurrence_count",
              "relevant",
              "service_name",
              "sessions_affected",
              "source",
              "sparkline",
              "status",
              "title"
            ],
            "type": "object"
          },
          "GroupTriageV1": {
            "additionalProperties": false,
            "description": "A hint for ordering and filtering the list. It never moves a group: resolving and ignoring stay human decisions.",
            "properties": {
              "at_ms": {
                "format": "int64",
                "type": "integer"
              },
              "confidence": {
                "description": "Between 0 and 1, as the judge reports it; 1 for a rule.",
                "format": "double",
                "type": "number"
              },
              "kind": {
                "$ref": "#/definitions/TriageKindV1"
              },
              "model": {
                "description": "The judge model that answered.",
                "type": [
                  "string",
                  "null"
                ]
              },
              "source": {
                "$ref": "#/definitions/TriageSourceV1"
              }
            },
            "required": [
              "at_ms",
              "confidence",
              "kind",
              "source"
            ],
            "type": "object"
          },
          "IgnoreRuleV1": {
            "description": "How long an ignore lasts. Every rule keeps counting occurrences; what changes is when the group comes back to the open list.",
            "oneOf": [
              {
                "properties": {
                  "kind": {
                    "enum": [
                      "forever"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "kind"
                ],
                "type": "object"
              },
              {
                "description": "Reopens after this many further occurrences.",
                "properties": {
                  "count": {
                    "format": "uint64",
                    "minimum": 0,
                    "type": "integer"
                  },
                  "kind": {
                    "enum": [
                      "occurrences"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "count",
                  "kind"
                ],
                "type": "object"
              },
              {
                "description": "Reopens when the worker version changes.",
                "properties": {
                  "kind": {
                    "enum": [
                      "version_change"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "kind"
                ],
                "type": "object"
              }
            ]
          },
          "TriageKindV1": {
            "description": "What kind of failure a group is, as triage reads it.",
            "oneOf": [
              {
                "description": "A bug the reporting worker's maintainer has to fix in code.",
                "enum": [
                  "defect"
                ],
                "type": "string"
              },
              {
                "description": "The worker rejected bad input and said so: working as designed.",
                "enum": [
                  "caller_error"
                ],
                "type": "string"
              },
              {
                "description": "A dependency starting, restarting or timing out; it went away.",
                "enum": [
                  "transient"
                ],
                "type": "string"
              },
              {
                "description": "Local setup: credentials, tokens, files, versions, a missing worker.",
                "enum": [
                  "environment"
                ],
                "type": "string"
              },
              {
                "description": "Tests, probes and deliberately fake identifiers.",
                "enum": [
                  "test_traffic"
                ],
                "type": "string"
              }
            ]
          },
          "TriageSourceV1": {
            "description": "Who decided a triage.",
            "oneOf": [
              {
                "description": "A deterministic check: a missing function that is registered by the time the group is looked at.",
                "enum": [
                  "rule"
                ],
                "type": "string"
              },
              {
                "description": "`judge::evaluate`.",
                "enum": [
                  "judge"
                ],
                "type": "string"
              }
            ]
          }
        },
        "properties": {
          "groups": {
            "items": {
              "$ref": "#/definitions/GroupSummaryV1"
            },
            "type": "array"
          },
          "noise_total": {
            "format": "uint64",
            "minimum": 0,
            "type": "integer"
          },
          "relevant_total": {
            "description": "Both sides under the same filters, whatever `relevance` asked for.",
            "format": "uint64",
            "minimum": 0,
            "type": "integer"
          },
          "total": {
            "format": "uint64",
            "minimum": 0,
            "type": "integer"
          }
        },
        "required": [
          "groups",
          "noise_total",
          "relevant_total",
          "total"
        ],
        "title": "GroupsListResponseV1",
        "type": "object"
      }
    },
    {
      "description": "Reopen a resolved or ignored group, clearing the rule that closed it.",
      "metadata": {},
      "name": "sentinel::groups::reopen",
      "request_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "additionalProperties": false,
        "properties": {
          "group_id": {
            "type": "string"
          }
        },
        "required": [
          "group_id"
        ],
        "title": "GroupActionRequestV1",
        "type": "object"
      },
      "response_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "additionalProperties": false,
        "definitions": {
          "GroupChangeReasonV1": {
            "description": "Why a group changed, for the event siblings subscribe to.",
            "enum": [
              "regression",
              "ignore_expired",
              "resolved",
              "ignored",
              "diagnosed",
              "reopened",
              "investigating"
            ],
            "type": "string"
          },
          "GroupStatusV1": {
            "description": "The lifecycle of a group. `resolved` and `ignored` are human decisions; `regressed` is the one the ingest makes on its own, and the reason the worker exists.",
            "oneOf": [
              {
                "enum": [
                  "new",
                  "diagnosed",
                  "resolved",
                  "ignored"
                ],
                "type": "string"
              },
              {
                "description": "The first pass of an investigation is running.",
                "enum": [
                  "investigating"
                ],
                "type": "string"
              },
              {
                "description": "A new occurrence after a resolve.",
                "enum": [
                  "regressed"
                ],
                "type": "string"
              }
            ]
          }
        },
        "description": "The state a group was left in, and why.",
        "properties": {
          "group_id": {
            "type": "string"
          },
          "reason": {
            "anyOf": [
              {
                "$ref": "#/definitions/GroupChangeReasonV1"
              },
              {
                "type": "null"
              }
            ]
          },
          "status": {
            "$ref": "#/definitions/GroupStatusV1"
          }
        },
        "required": [
          "group_id",
          "status"
        ],
        "title": "GroupStateResponseV1",
        "type": "object"
      }
    },
    {
      "description": "Mark a group resolved. With until_version_change, occurrences on the resolved version keep counting without reopening it — the fix is not deployed there yet.",
      "metadata": {},
      "name": "sentinel::groups::resolve",
      "request_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "additionalProperties": false,
        "properties": {
          "group_id": {
            "type": "string"
          },
          "until_version_change": {
            "default": false,
            "description": "Occurrences on the version that was resolved keep counting without reopening the group — the fix is not deployed here yet.",
            "type": "boolean"
          }
        },
        "required": [
          "group_id"
        ],
        "title": "ResolveRequestV1",
        "type": "object"
      },
      "response_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "additionalProperties": false,
        "definitions": {
          "GroupChangeReasonV1": {
            "description": "Why a group changed, for the event siblings subscribe to.",
            "enum": [
              "regression",
              "ignore_expired",
              "resolved",
              "ignored",
              "diagnosed",
              "reopened",
              "investigating"
            ],
            "type": "string"
          },
          "GroupStatusV1": {
            "description": "The lifecycle of a group. `resolved` and `ignored` are human decisions; `regressed` is the one the ingest makes on its own, and the reason the worker exists.",
            "oneOf": [
              {
                "enum": [
                  "new",
                  "diagnosed",
                  "resolved",
                  "ignored"
                ],
                "type": "string"
              },
              {
                "description": "The first pass of an investigation is running.",
                "enum": [
                  "investigating"
                ],
                "type": "string"
              },
              {
                "description": "A new occurrence after a resolve.",
                "enum": [
                  "regressed"
                ],
                "type": "string"
              }
            ]
          }
        },
        "description": "The state a group was left in, and why.",
        "properties": {
          "group_id": {
            "type": "string"
          },
          "reason": {
            "anyOf": [
              {
                "$ref": "#/definitions/GroupChangeReasonV1"
              },
              {
                "type": "null"
              }
            ]
          },
          "status": {
            "$ref": "#/definitions/GroupStatusV1"
          }
        },
        "required": [
          "group_id",
          "status"
        ],
        "title": "GroupStateResponseV1",
        "type": "object"
      }
    },
    {
      "description": "Take a group off the ignore list and back into the open list.",
      "metadata": {},
      "name": "sentinel::groups::unignore",
      "request_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "additionalProperties": false,
        "properties": {
          "group_id": {
            "type": "string"
          }
        },
        "required": [
          "group_id"
        ],
        "title": "GroupActionRequestV1",
        "type": "object"
      },
      "response_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "additionalProperties": false,
        "definitions": {
          "GroupChangeReasonV1": {
            "description": "Why a group changed, for the event siblings subscribe to.",
            "enum": [
              "regression",
              "ignore_expired",
              "resolved",
              "ignored",
              "diagnosed",
              "reopened",
              "investigating"
            ],
            "type": "string"
          },
          "GroupStatusV1": {
            "description": "The lifecycle of a group. `resolved` and `ignored` are human decisions; `regressed` is the one the ingest makes on its own, and the reason the worker exists.",
            "oneOf": [
              {
                "enum": [
                  "new",
                  "diagnosed",
                  "resolved",
                  "ignored"
                ],
                "type": "string"
              },
              {
                "description": "The first pass of an investigation is running.",
                "enum": [
                  "investigating"
                ],
                "type": "string"
              },
              {
                "description": "A new occurrence after a resolve.",
                "enum": [
                  "regressed"
                ],
                "type": "string"
              }
            ]
          }
        },
        "description": "The state a group was left in, and why.",
        "properties": {
          "group_id": {
            "type": "string"
          },
          "reason": {
            "anyOf": [
              {
                "$ref": "#/definitions/GroupChangeReasonV1"
              },
              {
                "type": "null"
              }
            ]
          },
          "status": {
            "$ref": "#/definitions/GroupStatusV1"
          }
        },
        "required": [
          "group_id",
          "status"
        ],
        "title": "GroupStateResponseV1",
        "type": "object"
      }
    },
    {
      "description": "Internal durable queue step: reads one trace or log and records what failed.",
      "metadata": {
        "internal": true,
        "trace_hidden": true
      },
      "name": "sentinel::ingest",
      "request_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "description": "One unit of ingest work. `trace_id` is a field of every variant because the queue groups by it: the span job and the log job of one trace are serialized behind each other rather than racing.",
        "oneOf": [
          {
            "description": "A trace ticked: read it and record what failed.",
            "properties": {
              "kind": {
                "enum": [
                  "trace"
                ],
                "type": "string"
              },
              "trace_id": {
                "type": "string"
              }
            },
            "required": [
              "kind",
              "trace_id"
            ],
            "type": "object"
          },
          {
            "description": "An ERROR log arrived.",
            "properties": {
              "kind": {
                "enum": [
                  "log"
                ],
                "type": "string"
              },
              "log": {
                "default": null
              },
              "trace_id": {
                "type": "string"
              }
            },
            "required": [
              "kind",
              "trace_id"
            ],
            "type": "object"
          },
          {
            "description": "Re-read a trace once, to catch ancestors that were open at capture.",
            "properties": {
              "kind": {
                "enum": [
                  "settle"
                ],
                "type": "string"
              },
              "trace_id": {
                "type": "string"
              }
            },
            "required": [
              "kind",
              "trace_id"
            ],
            "type": "object"
          },
          {
            "description": "A parked log's wait ran out.",
            "properties": {
              "kind": {
                "enum": [
                  "promote"
                ],
                "type": "string"
              },
              "occurrence_id": {
                "type": "string"
              },
              "trace_id": {
                "type": "string"
              }
            },
            "required": [
              "kind",
              "occurrence_id",
              "trace_id"
            ],
            "type": "object"
          }
        ],
        "title": "IngestJob"
      },
      "response_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "properties": {
          "deduped": {
            "format": "uint64",
            "minimum": 0,
            "type": "integer"
          },
          "recorded": {
            "format": "uint64",
            "minimum": 0,
            "type": "integer"
          }
        },
        "required": [
          "deduped",
          "recorded"
        ],
        "title": "IngestResponseV1",
        "type": "object"
      }
    },
    {
      "description": "Open an investigation on a group: a harness session beside the page that starts from the frozen evidence. Mode assisted runs a first pass immediately; mode chat only seats the evidence and waits for a person. A first pass already running is returned rather than duplicated.",
      "metadata": {},
      "name": "sentinel::investigate",
      "request_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "additionalProperties": false,
        "definitions": {
          "InvestigationModeV1": {
            "description": "How an investigation was opened.",
            "oneOf": [
              {
                "description": "A first pass runs automatically, then the conversation continues.",
                "enum": [
                  "assisted"
                ],
                "type": "string"
              },
              {
                "description": "The session is created with the evidence and nothing runs until a person speaks.",
                "enum": [
                  "chat"
                ],
                "type": "string"
              }
            ]
          }
        },
        "properties": {
          "group_id": {
            "type": "string"
          },
          "mode": {
            "anyOf": [
              {
                "$ref": "#/definitions/InvestigationModeV1"
              },
              {
                "type": "null"
              }
            ],
            "default": null,
            "description": "Defaults to `assisted`."
          },
          "model": {
            "default": null,
            "description": "Catalog id, or a raw model id alongside `provider`. Falls back to the configured one.",
            "type": [
              "string",
              "null"
            ]
          },
          "occurrence_id": {
            "default": null,
            "description": "Defaults to the most recent occurrence that still has evidence.",
            "type": [
              "string",
              "null"
            ]
          },
          "provider": {
            "default": null,
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "group_id"
        ],
        "title": "InvestigateRequestV1",
        "type": "object"
      },
      "response_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "additionalProperties": false,
        "properties": {
          "existing": {
            "description": "A first pass was already running: this is that one, not a second.",
            "type": "boolean"
          },
          "first_pass_turn_id": {
            "type": [
              "string",
              "null"
            ]
          },
          "investigation_id": {
            "type": "string"
          },
          "session_id": {
            "description": "What the console opens beside the page.",
            "type": "string"
          }
        },
        "required": [
          "existing",
          "investigation_id",
          "session_id"
        ],
        "title": "InvestigateResponseV1",
        "type": "object"
      }
    },
    {
      "description": "Stop an investigation's first pass. The group returns to the state it was in unless a diagnosis was already recorded.",
      "metadata": {},
      "name": "sentinel::investigations::cancel",
      "request_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "additionalProperties": false,
        "properties": {
          "investigation_id": {
            "type": "string"
          }
        },
        "required": [
          "investigation_id"
        ],
        "title": "InvestigationCancelRequestV1",
        "type": "object"
      },
      "response_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "additionalProperties": false,
        "definitions": {
          "InvestigationModeV1": {
            "description": "How an investigation was opened.",
            "oneOf": [
              {
                "description": "A first pass runs automatically, then the conversation continues.",
                "enum": [
                  "assisted"
                ],
                "type": "string"
              },
              {
                "description": "The session is created with the evidence and nothing runs until a person speaks.",
                "enum": [
                  "chat"
                ],
                "type": "string"
              }
            ]
          },
          "InvestigationStatusV1": {
            "oneOf": [
              {
                "enum": [
                  "failed",
                  "cancelled"
                ],
                "type": "string"
              },
              {
                "description": "The first pass is in flight.",
                "enum": [
                  "running"
                ],
                "type": "string"
              },
              {
                "description": "The first pass ended.",
                "enum": [
                  "completed"
                ],
                "type": "string"
              },
              {
                "description": "A chat-mode session: no first pass ever ran, the conversation is the investigation.",
                "enum": [
                  "open"
                ],
                "type": "string"
              }
            ]
          }
        },
        "properties": {
          "checkout_ref": {
            "description": "The commit the mapped checkout was on when the pass started.",
            "type": [
              "string",
              "null"
            ]
          },
          "cost_usd": {
            "format": "double",
            "type": [
              "number",
              "null"
            ]
          },
          "created_ms": {
            "format": "int64",
            "type": "integer"
          },
          "duration_ms": {
            "format": "int64",
            "type": [
              "integer",
              "null"
            ]
          },
          "error": {
            "type": [
              "string",
              "null"
            ]
          },
          "finished_ms": {
            "format": "int64",
            "type": [
              "integer",
              "null"
            ]
          },
          "first_pass_turn_id": {
            "type": [
              "string",
              "null"
            ]
          },
          "group_id": {
            "type": "string"
          },
          "id": {
            "type": "string"
          },
          "investigated_version": {
            "description": "The worker version the investigated occurrence ran on.",
            "type": [
              "string",
              "null"
            ]
          },
          "mode": {
            "$ref": "#/definitions/InvestigationModeV1"
          },
          "model": {
            "type": "string"
          },
          "occurrence_id": {
            "type": "string"
          },
          "provider": {
            "type": [
              "string",
              "null"
            ]
          },
          "repository_id": {
            "type": [
              "string",
              "null"
            ]
          },
          "session_id": {
            "description": "The harness session. The console opens this beside the page.",
            "type": "string"
          },
          "status": {
            "$ref": "#/definitions/InvestigationStatusV1"
          },
          "turns": {
            "description": "Observed after the fact, and informative only: this worker imposes no ceiling on an investigation.",
            "format": "uint64",
            "minimum": 0,
            "type": [
              "integer",
              "null"
            ]
          }
        },
        "required": [
          "created_ms",
          "group_id",
          "id",
          "mode",
          "model",
          "occurrence_id",
          "session_id",
          "status"
        ],
        "title": "InvestigationSummaryV1",
        "type": "object"
      }
    },
    {
      "description": "Read one investigation and every diagnosis it recorded, newest first.",
      "metadata": {},
      "name": "sentinel::investigations::get",
      "request_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "additionalProperties": false,
        "properties": {
          "investigation_id": {
            "type": "string"
          }
        },
        "required": [
          "investigation_id"
        ],
        "title": "InvestigationGetRequestV1",
        "type": "object"
      },
      "response_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "additionalProperties": false,
        "definitions": {
          "ConfidenceV1": {
            "enum": [
              "high",
              "medium",
              "low"
            ],
            "type": "string"
          },
          "DiagnosisCategoryV1": {
            "oneOf": [
              {
                "enum": [
                  "bug",
                  "configuration",
                  "dependency",
                  "unknown"
                ],
                "type": "string"
              },
              {
                "description": "Real, but it went away on its own: a timeout, a restart, a race.",
                "enum": [
                  "transient"
                ],
                "type": "string"
              },
              {
                "description": "The failure is the designed behaviour of the code.",
                "enum": [
                  "expected"
                ],
                "type": "string"
              }
            ]
          },
          "DiagnosisEvidenceV1": {
            "additionalProperties": false,
            "description": "One thing the agent is pointing at, and why it matters.",
            "properties": {
              "excerpt": {
                "description": "At most 400 characters of the thing itself.",
                "type": "string"
              },
              "kind": {
                "$ref": "#/definitions/EvidenceKindV1"
              },
              "line": {
                "format": "uint32",
                "minimum": 0,
                "type": [
                  "integer",
                  "null"
                ]
              },
              "path": {
                "description": "Relative to the repository root, for `code`.",
                "type": [
                  "string",
                  "null"
                ]
              },
              "span_id": {
                "description": "The span this points at, for `trace`.",
                "type": [
                  "string",
                  "null"
                ]
              },
              "why": {
                "type": "string"
              }
            },
            "required": [
              "excerpt",
              "kind",
              "why"
            ],
            "type": "object"
          },
          "DiagnosisRecordV1": {
            "additionalProperties": false,
            "description": "A recorded diagnosis with its provenance.",
            "properties": {
              "created_ms": {
                "format": "int64",
                "type": "integer"
              },
              "diagnosis": {
                "anyOf": [
                  {
                    "$ref": "#/definitions/DiagnosisV1"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "group_id": {
                "type": "string"
              },
              "id": {
                "type": "string"
              },
              "investigation_id": {
                "type": "string"
              },
              "model": {
                "type": "string"
              },
              "raw_result": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "session_id": {
                "type": "string"
              },
              "source": {
                "$ref": "#/definitions/DiagnosisSourceV1"
              },
              "turn_id": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "valid": {
                "description": "False when the stored payload no longer parses as a `DiagnosisV1` — the raw text is kept so nothing is lost silently.",
                "type": "boolean"
              }
            },
            "required": [
              "created_ms",
              "group_id",
              "id",
              "investigation_id",
              "model",
              "session_id",
              "source",
              "valid"
            ],
            "type": "object"
          },
          "DiagnosisSourceV1": {
            "oneOf": [
              {
                "description": "Recorded while the automatic first pass was running.",
                "enum": [
                  "first_pass"
                ],
                "type": "string"
              },
              {
                "description": "Recorded later, in the conversation.",
                "enum": [
                  "conversation"
                ],
                "type": "string"
              }
            ]
          },
          "DiagnosisV1": {
            "additionalProperties": false,
            "description": "What an investigation concluded. Written by the agent, never by this worker, and kept verbatim: a later version supersedes it without erasing it, so the same failure diagnosed twice can be compared.",
            "properties": {
              "category": {
                "$ref": "#/definitions/DiagnosisCategoryV1"
              },
              "confidence": {
                "$ref": "#/definitions/ConfidenceV1"
              },
              "missing_evidence": {
                "description": "What would have raised the confidence. An honest `low` with this filled in is a better answer than a guess.",
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              "proposed_fix": {
                "anyOf": [
                  {
                    "$ref": "#/definitions/ProposedFixV1"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "related_groups": {
                "description": "Groups the agent believes share this cause. A suggestion the console shows; nothing is merged on the strength of it.",
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              "reproduction": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "root_cause": {
                "$ref": "#/definitions/RootCauseV1"
              },
              "summary": {
                "description": "One to three sentences, written for a person.",
                "type": "string"
              },
              "version_note": {
                "description": "Drift between the checkout that was read and the version that failed.",
                "type": [
                  "string",
                  "null"
                ]
              }
            },
            "required": [
              "category",
              "confidence",
              "root_cause",
              "summary"
            ],
            "type": "object"
          },
          "EvidenceKindV1": {
            "oneOf": [
              {
                "enum": [
                  "trace",
                  "log"
                ],
                "type": "string"
              },
              {
                "description": "A place in the repository, as a path relative to its root.",
                "enum": [
                  "code"
                ],
                "type": "string"
              }
            ]
          },
          "InvestigationModeV1": {
            "description": "How an investigation was opened.",
            "oneOf": [
              {
                "description": "A first pass runs automatically, then the conversation continues.",
                "enum": [
                  "assisted"
                ],
                "type": "string"
              },
              {
                "description": "The session is created with the evidence and nothing runs until a person speaks.",
                "enum": [
                  "chat"
                ],
                "type": "string"
              }
            ]
          },
          "InvestigationStatusV1": {
            "oneOf": [
              {
                "enum": [
                  "failed",
                  "cancelled"
                ],
                "type": "string"
              },
              {
                "description": "The first pass is in flight.",
                "enum": [
                  "running"
                ],
                "type": "string"
              },
              {
                "description": "The first pass ended.",
                "enum": [
                  "completed"
                ],
                "type": "string"
              },
              {
                "description": "A chat-mode session: no first pass ever ran, the conversation is the investigation.",
                "enum": [
                  "open"
                ],
                "type": "string"
              }
            ]
          },
          "InvestigationSummaryV1": {
            "additionalProperties": false,
            "properties": {
              "checkout_ref": {
                "description": "The commit the mapped checkout was on when the pass started.",
                "type": [
                  "string",
                  "null"
                ]
              },
              "cost_usd": {
                "format": "double",
                "type": [
                  "number",
                  "null"
                ]
              },
              "created_ms": {
                "format": "int64",
                "type": "integer"
              },
              "duration_ms": {
                "format": "int64",
                "type": [
                  "integer",
                  "null"
                ]
              },
              "error": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "finished_ms": {
                "format": "int64",
                "type": [
                  "integer",
                  "null"
                ]
              },
              "first_pass_turn_id": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "group_id": {
                "type": "string"
              },
              "id": {
                "type": "string"
              },
              "investigated_version": {
                "description": "The worker version the investigated occurrence ran on.",
                "type": [
                  "string",
                  "null"
                ]
              },
              "mode": {
                "$ref": "#/definitions/InvestigationModeV1"
              },
              "model": {
                "type": "string"
              },
              "occurrence_id": {
                "type": "string"
              },
              "provider": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "repository_id": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "session_id": {
                "description": "The harness session. The console opens this beside the page.",
                "type": "string"
              },
              "status": {
                "$ref": "#/definitions/InvestigationStatusV1"
              },
              "turns": {
                "description": "Observed after the fact, and informative only: this worker imposes no ceiling on an investigation.",
                "format": "uint64",
                "minimum": 0,
                "type": [
                  "integer",
                  "null"
                ]
              }
            },
            "required": [
              "created_ms",
              "group_id",
              "id",
              "mode",
              "model",
              "occurrence_id",
              "session_id",
              "status"
            ],
            "type": "object"
          },
          "ProposedFixV1": {
            "additionalProperties": false,
            "properties": {
              "description": {
                "type": "string"
              },
              "files": {
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              "risk": {
                "$ref": "#/definitions/RiskV1"
              },
              "steps": {
                "items": {
                  "type": "string"
                },
                "type": "array"
              }
            },
            "required": [
              "description",
              "files",
              "risk",
              "steps"
            ],
            "type": "object"
          },
          "RiskV1": {
            "enum": [
              "low",
              "medium",
              "high"
            ],
            "type": "string"
          },
          "RootCauseV1": {
            "additionalProperties": false,
            "properties": {
              "description": {
                "type": "string"
              },
              "evidence": {
                "items": {
                  "$ref": "#/definitions/DiagnosisEvidenceV1"
                },
                "type": "array"
              }
            },
            "required": [
              "description",
              "evidence"
            ],
            "type": "object"
          }
        },
        "properties": {
          "diagnoses": {
            "description": "Newest first.",
            "items": {
              "$ref": "#/definitions/DiagnosisRecordV1"
            },
            "type": "array"
          },
          "investigation": {
            "$ref": "#/definitions/InvestigationSummaryV1"
          }
        },
        "required": [
          "diagnoses",
          "investigation"
        ],
        "title": "InvestigationGetResponseV1",
        "type": "object"
      }
    },
    {
      "description": "List investigations, newest first, optionally narrowed to one group or a set of states.",
      "metadata": {},
      "name": "sentinel::investigations::list",
      "request_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "additionalProperties": false,
        "definitions": {
          "InvestigationStatusV1": {
            "oneOf": [
              {
                "enum": [
                  "failed",
                  "cancelled"
                ],
                "type": "string"
              },
              {
                "description": "The first pass is in flight.",
                "enum": [
                  "running"
                ],
                "type": "string"
              },
              {
                "description": "The first pass ended.",
                "enum": [
                  "completed"
                ],
                "type": "string"
              },
              {
                "description": "A chat-mode session: no first pass ever ran, the conversation is the investigation.",
                "enum": [
                  "open"
                ],
                "type": "string"
              }
            ]
          }
        },
        "properties": {
          "group_id": {
            "default": null,
            "type": [
              "string",
              "null"
            ]
          },
          "limit": {
            "default": null,
            "format": "uint32",
            "minimum": 0,
            "type": [
              "integer",
              "null"
            ]
          },
          "offset": {
            "default": null,
            "format": "uint32",
            "minimum": 0,
            "type": [
              "integer",
              "null"
            ]
          },
          "status": {
            "default": null,
            "items": {
              "$ref": "#/definitions/InvestigationStatusV1"
            },
            "type": [
              "array",
              "null"
            ]
          }
        },
        "title": "InvestigationsListRequestV1",
        "type": "object"
      },
      "response_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "additionalProperties": false,
        "definitions": {
          "InvestigationModeV1": {
            "description": "How an investigation was opened.",
            "oneOf": [
              {
                "description": "A first pass runs automatically, then the conversation continues.",
                "enum": [
                  "assisted"
                ],
                "type": "string"
              },
              {
                "description": "The session is created with the evidence and nothing runs until a person speaks.",
                "enum": [
                  "chat"
                ],
                "type": "string"
              }
            ]
          },
          "InvestigationStatusV1": {
            "oneOf": [
              {
                "enum": [
                  "failed",
                  "cancelled"
                ],
                "type": "string"
              },
              {
                "description": "The first pass is in flight.",
                "enum": [
                  "running"
                ],
                "type": "string"
              },
              {
                "description": "The first pass ended.",
                "enum": [
                  "completed"
                ],
                "type": "string"
              },
              {
                "description": "A chat-mode session: no first pass ever ran, the conversation is the investigation.",
                "enum": [
                  "open"
                ],
                "type": "string"
              }
            ]
          },
          "InvestigationSummaryV1": {
            "additionalProperties": false,
            "properties": {
              "checkout_ref": {
                "description": "The commit the mapped checkout was on when the pass started.",
                "type": [
                  "string",
                  "null"
                ]
              },
              "cost_usd": {
                "format": "double",
                "type": [
                  "number",
                  "null"
                ]
              },
              "created_ms": {
                "format": "int64",
                "type": "integer"
              },
              "duration_ms": {
                "format": "int64",
                "type": [
                  "integer",
                  "null"
                ]
              },
              "error": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "finished_ms": {
                "format": "int64",
                "type": [
                  "integer",
                  "null"
                ]
              },
              "first_pass_turn_id": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "group_id": {
                "type": "string"
              },
              "id": {
                "type": "string"
              },
              "investigated_version": {
                "description": "The worker version the investigated occurrence ran on.",
                "type": [
                  "string",
                  "null"
                ]
              },
              "mode": {
                "$ref": "#/definitions/InvestigationModeV1"
              },
              "model": {
                "type": "string"
              },
              "occurrence_id": {
                "type": "string"
              },
              "provider": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "repository_id": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "session_id": {
                "description": "The harness session. The console opens this beside the page.",
                "type": "string"
              },
              "status": {
                "$ref": "#/definitions/InvestigationStatusV1"
              },
              "turns": {
                "description": "Observed after the fact, and informative only: this worker imposes no ceiling on an investigation.",
                "format": "uint64",
                "minimum": 0,
                "type": [
                  "integer",
                  "null"
                ]
              }
            },
            "required": [
              "created_ms",
              "group_id",
              "id",
              "mode",
              "model",
              "occurrence_id",
              "session_id",
              "status"
            ],
            "type": "object"
          }
        },
        "properties": {
          "investigations": {
            "items": {
              "$ref": "#/definitions/InvestigationSummaryV1"
            },
            "type": "array"
          },
          "total": {
            "format": "uint64",
            "minimum": 0,
            "type": "integer"
          }
        },
        "required": [
          "investigations",
          "total"
        ],
        "title": "InvestigationsListResponseV1",
        "type": "object"
      }
    },
    {
      "description": "Read logs from the live engine through the redactor, for an investigation.",
      "metadata": {},
      "name": "sentinel::logs::list",
      "request_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "additionalProperties": false,
        "properties": {
          "level": {
            "default": null,
            "description": "`error`, `warn`, `info`, … Matched by the engine.",
            "type": [
              "string",
              "null"
            ]
          },
          "limit": {
            "default": null,
            "format": "uint32",
            "minimum": 0,
            "type": [
              "integer",
              "null"
            ]
          },
          "service_name": {
            "default": null,
            "type": [
              "string",
              "null"
            ]
          },
          "since_ms": {
            "default": null,
            "format": "int64",
            "type": [
              "integer",
              "null"
            ]
          },
          "trace_id": {
            "default": null,
            "type": [
              "string",
              "null"
            ]
          }
        },
        "title": "LogsListRequestV1",
        "type": "object"
      },
      "response_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "additionalProperties": false,
        "properties": {
          "logs": {
            "items": true,
            "type": "array"
          },
          "redactions": {
            "format": "uint64",
            "minimum": 0,
            "type": "integer"
          }
        },
        "required": [
          "logs",
          "redactions"
        ],
        "title": "LogsListResponseV1",
        "type": "object"
      }
    },
    {
      "description": "List the recorded occurrences of one group, newest first, each saying whether its frozen evidence is still kept.",
      "metadata": {},
      "name": "sentinel::occurrences::list",
      "request_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "additionalProperties": false,
        "properties": {
          "group_id": {
            "type": "string"
          },
          "limit": {
            "default": null,
            "format": "uint32",
            "minimum": 0,
            "type": [
              "integer",
              "null"
            ]
          },
          "offset": {
            "default": null,
            "format": "uint32",
            "minimum": 0,
            "type": [
              "integer",
              "null"
            ]
          }
        },
        "required": [
          "group_id"
        ],
        "title": "OccurrencesListRequestV1",
        "type": "object"
      },
      "response_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "additionalProperties": false,
        "definitions": {
          "ErrorSourceV1": {
            "description": "Where an error event came from. Part of the fingerprint: the same text seen as a span and as a log is two groups, because one has a trace to investigate and the other does not.",
            "oneOf": [
              {
                "enum": [
                  "report"
                ],
                "type": "string"
              },
              {
                "description": "A span with status `error`.",
                "enum": [
                  "trace"
                ],
                "type": "string"
              },
              {
                "description": "An OTel log record at ERROR.",
                "enum": [
                  "log"
                ],
                "type": "string"
              },
              {
                "description": "Reserved for the adapters the spec designs but v1 does not implement.",
                "enum": [
                  "harness-turn"
                ],
                "type": "string"
              }
            ]
          },
          "OccurrenceSummaryV1": {
            "additionalProperties": false,
            "description": "One recorded instance of a group.",
            "properties": {
              "at_ms": {
                "format": "int64",
                "type": "integer"
              },
              "has_evidence": {
                "description": "Whether the frozen bundle is still kept for this one.",
                "type": "boolean"
              },
              "id": {
                "type": "string"
              },
              "message": {
                "type": "string"
              },
              "namespace_ambiguous": {
                "description": "The owner could not be pinned to one namespace.",
                "type": "boolean"
              },
              "session_id": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "settled": {
                "description": "Whether the trace was re-read after the ancestors closed.",
                "type": "boolean"
              },
              "source": {
                "$ref": "#/definitions/ErrorSourceV1"
              },
              "span_id": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "trace_id": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "turn_id": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "worker_version": {
                "type": [
                  "string",
                  "null"
                ]
              }
            },
            "required": [
              "at_ms",
              "has_evidence",
              "id",
              "message",
              "namespace_ambiguous",
              "settled",
              "source"
            ],
            "type": "object"
          }
        },
        "properties": {
          "occurrences": {
            "items": {
              "$ref": "#/definitions/OccurrenceSummaryV1"
            },
            "type": "array"
          },
          "total": {
            "format": "uint64",
            "minimum": 0,
            "type": "integer"
          }
        },
        "required": [
          "occurrences",
          "total"
        ],
        "title": "OccurrencesListResponseV1",
        "type": "object"
      }
    },
    {
      "description": "Internal configuration doorbell: re-reads the authoritative sentinel entry and swaps the live settings.",
      "metadata": {
        "internal": true
      },
      "name": "sentinel::on-config-change",
      "request_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "description": "Trigger payload for `<worker>::on-config-change`. Advisory only: handlers re-fetch the authoritative value and ignore it, so a direct call can never inject config.",
        "properties": {
          "id": {
            "default": null,
            "description": "Configuration id that changed.",
            "type": [
              "string",
              "null"
            ]
          }
        },
        "title": "OnConfigChangeEvent",
        "type": "object"
      },
      "response_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "description": "Ack returned by the internal `<worker>::on-config-change` handler.",
        "properties": {
          "ok": {
            "type": "boolean"
          }
        },
        "required": [
          "ok"
        ],
        "title": "OnConfigChangeResponse",
        "type": "object"
      }
    },
    {
      "description": "Internal handler for the engine's ERROR-log trigger.",
      "metadata": {
        "internal": true,
        "trace_hidden": true
      },
      "name": "sentinel::on-log",
      "request_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "description": "One ERROR log as the engine's `log` trigger delivers it.\n\nTyped rather than taken as a free value: the published surface is what interface capture records, and an untyped request there tells a reader nothing. Every field is optional and anything unrecognised is carried through, so a newer engine cannot break the handler.",
        "properties": {
          "attributes": {
            "additionalProperties": true,
            "default": {},
            "type": "object"
          },
          "body": {
            "default": "",
            "type": "string"
          },
          "instrumentation_scope_name": {
            "default": null,
            "type": [
              "string",
              "null"
            ]
          },
          "instrumentation_scope_version": {
            "default": null,
            "type": [
              "string",
              "null"
            ]
          },
          "observed_timestamp_unix_nano": {
            "default": 0,
            "format": "uint64",
            "minimum": 0,
            "type": "integer"
          },
          "resource": {
            "additionalProperties": true,
            "default": {},
            "type": "object"
          },
          "service_name": {
            "default": "",
            "type": "string"
          },
          "severity_number": {
            "default": 0,
            "format": "int32",
            "type": "integer"
          },
          "severity_text": {
            "default": "",
            "type": "string"
          },
          "span_id": {
            "default": null,
            "type": [
              "string",
              "null"
            ]
          },
          "timestamp_unix_nano": {
            "default": 0,
            "format": "uint64",
            "minimum": 0,
            "type": "integer"
          },
          "trace_id": {
            "default": null,
            "type": [
              "string",
              "null"
            ]
          }
        },
        "title": "StoredLogEventV1",
        "type": "object"
      },
      "response_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "properties": {
          "phantom_dropped": {
            "description": "Ticks for this worker's own traces, dropped before the queue.",
            "format": "uint64",
            "minimum": 0,
            "type": "integer"
          },
          "queued": {
            "format": "uint64",
            "minimum": 0,
            "type": "integer"
          }
        },
        "required": [
          "phantom_dropped",
          "queued"
        ],
        "title": "QueuedResponseV1",
        "type": "object"
      }
    },
    {
      "description": "Internal daily prune of buckets and archived groups.",
      "metadata": {
        "internal": true,
        "trace_hidden": true
      },
      "name": "sentinel::on-schedule",
      "request_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "title": "ScheduleEventV1",
        "type": "object"
      },
      "response_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "properties": {
          "buckets_removed": {
            "format": "uint64",
            "minimum": 0,
            "type": "integer"
          },
          "evidence_pruned": {
            "format": "uint64",
            "minimum": 0,
            "type": "integer"
          },
          "groups_archived": {
            "format": "uint64",
            "minimum": 0,
            "type": "integer"
          }
        },
        "required": [
          "buckets_removed",
          "evidence_pruned",
          "groups_archived"
        ],
        "title": "PruneResponseV1",
        "type": "object"
      }
    },
    {
      "description": "Internal handler for the engine's error-span trigger; queues the traces worth reading.",
      "metadata": {
        "internal": true,
        "trace_hidden": true
      },
      "name": "sentinel::on-trace-activity",
      "request_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "description": "The tick the engine's `trace` trigger delivers: ids only, coalesced.",
        "properties": {
          "trace_ids": {
            "default": [],
            "items": {
              "type": "string"
            },
            "type": "array"
          }
        },
        "title": "TraceActivityEventV1",
        "type": "object"
      },
      "response_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "properties": {
          "phantom_dropped": {
            "description": "Ticks for this worker's own traces, dropped before the queue.",
            "format": "uint64",
            "minimum": 0,
            "type": "integer"
          },
          "queued": {
            "format": "uint64",
            "minimum": 0,
            "type": "integer"
          }
        },
        "required": [
          "phantom_dropped",
          "queued"
        ],
        "title": "QueuedResponseV1",
        "type": "object"
      }
    },
    {
      "description": "Internal doorbell for a finished investigation turn; the status is re-read rather than trusted.",
      "metadata": {
        "internal": true,
        "trace_hidden": true
      },
      "name": "sentinel::on-turn-completed",
      "request_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "description": "The harness doorbell. Only a wake-up: the truth is re-read from `harness::status`, never taken from this payload.",
        "properties": {
          "reason": {
            "default": null,
            "type": [
              "string",
              "null"
            ]
          },
          "session_id": {
            "default": "",
            "type": "string"
          },
          "status": {
            "default": null,
            "type": [
              "string",
              "null"
            ]
          },
          "terminal": {
            "default": null,
            "type": [
              "boolean",
              "null"
            ]
          },
          "turn_id": {
            "default": null,
            "type": [
              "string",
              "null"
            ]
          }
        },
        "title": "TurnCompletedEventV1",
        "type": "object"
      },
      "response_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "additionalProperties": false,
        "properties": {
          "handled": {
            "description": "Whether this doorbell named an investigation of this worker's.",
            "type": "boolean"
          }
        },
        "required": [
          "handled"
        ],
        "title": "DoorbellResponseV1",
        "type": "object"
      }
    },
    {
      "description": "Health and counters: whether ingest is enabled, the state of the engine's telemetry stores, per-source ingest counters (including values redacted on capture and traces lost before capture), group and investigation counts, and which mapped repositories are present on this machine.",
      "metadata": {},
      "name": "sentinel::status",
      "request_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "additionalProperties": false,
        "title": "StatusRequestV1",
        "type": "object"
      },
      "response_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "additionalProperties": false,
        "definitions": {
          "EngineStatusV1": {
            "additionalProperties": false,
            "properties": {
              "logs": {
                "type": "boolean"
              },
              "trace_store": {
                "$ref": "#/definitions/TraceStoreStateV1"
              }
            },
            "required": [
              "logs",
              "trace_store"
            ],
            "type": "object"
          },
          "GroupCountsV1": {
            "additionalProperties": false,
            "properties": {
              "ignored": {
                "format": "uint64",
                "minimum": 0,
                "type": "integer"
              },
              "last_seen_ms": {
                "description": "The newest occurrence across every group: when ingest last recorded something.",
                "format": "int64",
                "type": [
                  "integer",
                  "null"
                ]
              },
              "open": {
                "format": "uint64",
                "minimum": 0,
                "type": "integer"
              },
              "regressed": {
                "format": "uint64",
                "minimum": 0,
                "type": "integer"
              },
              "resolved": {
                "format": "uint64",
                "minimum": 0,
                "type": "integer"
              }
            },
            "required": [
              "ignored",
              "open",
              "regressed",
              "resolved"
            ],
            "type": "object"
          },
          "IngestStatusV1": {
            "additionalProperties": false,
            "properties": {
              "deduped": {
                "format": "uint64",
                "minimum": 0,
                "type": "integer"
              },
              "dropped_failed": {
                "description": "Jobs that exhausted their retries.",
                "format": "uint64",
                "minimum": 0,
                "type": "integer"
              },
              "dropped_ignored_service": {
                "format": "uint64",
                "minimum": 0,
                "type": "integer"
              },
              "dropped_investigation": {
                "description": "Traces tagged with an investigation session.",
                "format": "uint64",
                "minimum": 0,
                "type": "integer"
              },
              "dropped_not_ready": {
                "description": "Deliveries refused because the durable dependencies were not claimed yet. They are redelivered, not lost.",
                "format": "uint64",
                "minimum": 0,
                "type": "integer"
              },
              "dropped_own_trace": {
                "description": "Traces whose root is this worker — the cut that stops the monitor from monitoring itself.",
                "format": "uint64",
                "minimum": 0,
                "type": "integer"
              },
              "logs_pending_join": {
                "description": "ERROR logs currently waiting for the error span of their trace.",
                "format": "uint64",
                "minimum": 0,
                "type": "integer"
              },
              "logs_unattributed": {
                "description": "Logs promoted without resolving their trace: a bounded, visible gap.",
                "format": "uint64",
                "minimum": 0,
                "type": "integer"
              },
              "lost_before_capture": {
                "description": "Traces that had already left the engine's ring when the job ran.",
                "format": "uint64",
                "minimum": 0,
                "type": "integer"
              },
              "paused_until": {
                "description": "Set while the ingest breaker is open.",
                "format": "int64",
                "type": [
                  "integer",
                  "null"
                ]
              },
              "phantom_ticks_dropped": {
                "description": "Ticks for the ingest's own traces, filtered before the queue.",
                "format": "uint64",
                "minimum": 0,
                "type": "integer"
              },
              "processed_total": {
                "format": "uint64",
                "minimum": 0,
                "type": "integer"
              },
              "queued": {
                "description": "Jobs handed to the durable queue and not yet completed.",
                "format": "uint64",
                "minimum": 0,
                "type": "integer"
              },
              "redactions": {
                "description": "Values rewritten as `[redacted:<kind>]` on capture, all sources.",
                "format": "uint64",
                "minimum": 0,
                "type": "integer"
              }
            },
            "required": [
              "deduped",
              "dropped_failed",
              "dropped_ignored_service",
              "dropped_investigation",
              "dropped_not_ready",
              "dropped_own_trace",
              "logs_pending_join",
              "logs_unattributed",
              "lost_before_capture",
              "phantom_ticks_dropped",
              "processed_total",
              "queued",
              "redactions"
            ],
            "type": "object"
          },
          "InvestigationCountsV1": {
            "additionalProperties": false,
            "properties": {
              "open_sessions": {
                "description": "Investigation sessions that are still open for conversation.",
                "format": "uint64",
                "minimum": 0,
                "type": "integer"
              },
              "running": {
                "description": "First passes running right now.",
                "format": "uint64",
                "minimum": 0,
                "type": "integer"
              }
            },
            "required": [
              "open_sessions",
              "running"
            ],
            "type": "object"
          },
          "RepositoryStatusV1": {
            "additionalProperties": false,
            "properties": {
              "exists": {
                "description": "Whether the checkout is on this machine right now. False disables code access for its workers; grouping and evidence are unaffected.",
                "type": "boolean"
              },
              "id": {
                "type": "string"
              },
              "path": {
                "type": "string"
              },
              "workers": {
                "items": {
                  "type": "string"
                },
                "type": "array"
              }
            },
            "required": [
              "exists",
              "id",
              "path",
              "workers"
            ],
            "type": "object"
          },
          "SourcesStatusV1": {
            "additionalProperties": false,
            "properties": {
              "log": {
                "type": "boolean"
              },
              "trace": {
                "type": "boolean"
              }
            },
            "required": [
              "log",
              "trace"
            ],
            "type": "object"
          },
          "TraceStoreStateV1": {
            "description": "State of the engine's in-memory telemetry stores, as the worker last observed them.",
            "oneOf": [
              {
                "description": "Spans are being served.",
                "enum": [
                  "memory"
                ],
                "type": "string"
              },
              {
                "description": "`engine::traces::*` reports its memory exporter is off: the worker runs on logs alone and the console shows the same empty state the traces page does.",
                "enum": [
                  "disabled"
                ],
                "type": "string"
              },
              {
                "description": "Not observed yet.",
                "enum": [
                  "unknown"
                ],
                "type": "string"
              }
            ]
          }
        },
        "properties": {
          "config_error": {
            "description": "Why the stored configuration was refused, when it was. The worker runs on shipped defaults and stays disabled until a valid value arrives, so a typo reads as a named field here instead of a silent idle worker.",
            "type": [
              "string",
              "null"
            ]
          },
          "enabled": {
            "description": "True once the configuration says so *and* the durable dependencies are claimed. False means nothing is being ingested.",
            "type": "boolean"
          },
          "engine": {
            "$ref": "#/definitions/EngineStatusV1"
          },
          "groups": {
            "$ref": "#/definitions/GroupCountsV1"
          },
          "ingest": {
            "$ref": "#/definitions/IngestStatusV1"
          },
          "investigations": {
            "$ref": "#/definitions/InvestigationCountsV1"
          },
          "repositories": {
            "items": {
              "$ref": "#/definitions/RepositoryStatusV1"
            },
            "type": "array"
          },
          "sources": {
            "$ref": "#/definitions/SourcesStatusV1"
          }
        },
        "required": [
          "enabled",
          "engine",
          "groups",
          "ingest",
          "investigations",
          "repositories",
          "sources"
        ],
        "title": "StatusResponseV1",
        "type": "object"
      }
    },
    {
      "description": "Read a trace from the live engine through the redactor, for an investigation comparing the frozen snapshot with what is there now. Answers null once the trace has left the engine's ring.",
      "metadata": {},
      "name": "sentinel::trace::get",
      "request_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "additionalProperties": false,
        "properties": {
          "include_spans": {
            "default": false,
            "description": "Also return the flat span list, for a trace whose shape matters more than its tree.",
            "type": "boolean"
          },
          "trace_id": {
            "type": "string"
          }
        },
        "required": [
          "trace_id"
        ],
        "title": "TraceGetRequestV1",
        "type": "object"
      },
      "response_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "additionalProperties": false,
        "properties": {
          "redactions": {
            "description": "Values rewritten before the response left this worker.",
            "format": "uint64",
            "minimum": 0,
            "type": "integer"
          },
          "trace": {
            "description": "Null when the trace has already left the engine's ring: the frozen evidence is then all there is."
          }
        },
        "required": [
          "redactions"
        ],
        "title": "TraceGetResponseV1",
        "type": "object"
      }
    },
    {
      "description": "Serve the sentinel worker's injected console UI assets (content function for its console:script / console:style / console:module triggers).",
      "metadata": {
        "internal": true
      },
      "name": "sentinel::ui-content",
      "request_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "description": "Input of the content function: the console asks for one asset by path.",
        "properties": {
          "path": {
            "description": "The asset path from the trigger config (e.g. `state/page.js`).",
            "type": "string"
          }
        },
        "required": [
          "path"
        ],
        "title": "UiContentInput",
        "type": "object"
      },
      "response_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "description": "Output of the content function.",
        "properties": {
          "content": {
            "description": "The asset source, verbatim.",
            "type": "string"
          },
          "content_type": {
            "description": "MIME type the console should serve the asset with.",
            "type": "string"
          }
        },
        "required": [
          "content",
          "content_type"
        ],
        "title": "UiContentResult",
        "type": "object"
      }
    }
  ],
  "triggers": [
    {
      "description": "Fires when an error group is created, takes a new occurrence, or changes state. Config: { group_id?, service_name?, ops? } — ops narrows to created, occurrence or status. Occurrence events are coalesced per group over one second; re-read the group rather than trusting the payload.",
      "invocation_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "definitions": {
          "GroupChangedOpV1": {
            "oneOf": [
              {
                "enum": [
                  "created",
                  "status"
                ],
                "type": "string"
              },
              {
                "description": "A new occurrence on a group that is otherwise unchanged. Coalesced.",
                "enum": [
                  "occurrence"
                ],
                "type": "string"
              }
            ]
          }
        },
        "description": "What a subscriber may narrow `sentinel::group-changed` to.",
        "properties": {
          "group_id": {
            "default": null,
            "type": [
              "string",
              "null"
            ]
          },
          "ops": {
            "default": null,
            "items": {
              "$ref": "#/definitions/GroupChangedOpV1"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "service_name": {
            "default": null,
            "type": [
              "string",
              "null"
            ]
          }
        },
        "title": "GroupChangedConfigV1",
        "type": "object"
      },
      "metadata": {},
      "name": "sentinel::group-changed",
      "return_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "additionalProperties": false,
        "definitions": {
          "GroupChangeReasonV1": {
            "description": "Why a group changed, for the event siblings subscribe to.",
            "enum": [
              "regression",
              "ignore_expired",
              "resolved",
              "ignored",
              "diagnosed",
              "reopened",
              "investigating"
            ],
            "type": "string"
          },
          "GroupChangedOpV1": {
            "oneOf": [
              {
                "enum": [
                  "created",
                  "status"
                ],
                "type": "string"
              },
              {
                "description": "A new occurrence on a group that is otherwise unchanged. Coalesced.",
                "enum": [
                  "occurrence"
                ],
                "type": "string"
              }
            ]
          },
          "GroupStatusV1": {
            "description": "The lifecycle of a group. `resolved` and `ignored` are human decisions; `regressed` is the one the ingest makes on its own, and the reason the worker exists.",
            "oneOf": [
              {
                "enum": [
                  "new",
                  "diagnosed",
                  "resolved",
                  "ignored"
                ],
                "type": "string"
              },
              {
                "description": "The first pass of an investigation is running.",
                "enum": [
                  "investigating"
                ],
                "type": "string"
              },
              {
                "description": "A new occurrence after a resolve.",
                "enum": [
                  "regressed"
                ],
                "type": "string"
              }
            ]
          }
        },
        "description": "The event siblings and the console subscribe to.",
        "properties": {
          "group_id": {
            "type": "string"
          },
          "occurrence_count": {
            "format": "uint64",
            "minimum": 0,
            "type": "integer"
          },
          "op": {
            "$ref": "#/definitions/GroupChangedOpV1"
          },
          "previous_status": {
            "anyOf": [
              {
                "$ref": "#/definitions/GroupStatusV1"
              },
              {
                "type": "null"
              }
            ]
          },
          "reason": {
            "anyOf": [
              {
                "$ref": "#/definitions/GroupChangeReasonV1"
              },
              {
                "type": "null"
              }
            ]
          },
          "status": {
            "$ref": "#/definitions/GroupStatusV1"
          }
        },
        "required": [
          "group_id",
          "occurrence_count",
          "op",
          "status"
        ],
        "title": "GroupChangedEventV1",
        "type": "object"
      }
    },
    {
      "description": "Fires when an investigation is created, starts, or finishes. Config: { group_id? }.",
      "invocation_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "definitions": {
          "GroupChangedOpV1": {
            "oneOf": [
              {
                "enum": [
                  "created",
                  "status"
                ],
                "type": "string"
              },
              {
                "description": "A new occurrence on a group that is otherwise unchanged. Coalesced.",
                "enum": [
                  "occurrence"
                ],
                "type": "string"
              }
            ]
          }
        },
        "description": "What a subscriber may narrow `sentinel::group-changed` to.",
        "properties": {
          "group_id": {
            "default": null,
            "type": [
              "string",
              "null"
            ]
          },
          "ops": {
            "default": null,
            "items": {
              "$ref": "#/definitions/GroupChangedOpV1"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "service_name": {
            "default": null,
            "type": [
              "string",
              "null"
            ]
          }
        },
        "title": "GroupChangedConfigV1",
        "type": "object"
      },
      "metadata": {},
      "name": "sentinel::investigation-changed",
      "return_schema": {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "title": "AnyValue"
      }
    }
  ]
}

Search the registry

Find workers, kits and executables, or jump to a page.