ADR-168: Auto-diagnosis library shape — YAML rules, regression fixtures, curation policy
Status: Proposed Date: 2026-05-07
Related: warp#1782 (parent EPIC: self-healing fleet), warp#1783 (amendment: self-healing rides the existing agent-executor queue), ADR-167 (sister: structured failure event schema — defines the events this library matches), ADR-169 (sister: auto-swarm dispatch + auto-merge gating — defines what happens after this library files a ticket), ADR-164 / warp#1735 (ticket category axis — the categories library entries declare), ADR-117 (precedent: module guidelines — same versioned-YAML-with-regression-fixture shape), ADR-115 (precedent: principle-aware reviewers — quote the library entry when reviewing auto-filed PRs), ADR-107 / ADR-110 (precedent: gates as playbook primitives + observe-and-file dominant pattern), warp#1779 (today's atomic-deploy regex bug — the first library entry's motivating shape)
TL;DR
The auto-diagnosis library is a directory of versioned YAML rules under gyrum-knowledge-base/auto-diagnosis/<shape>.yaml. Each rule has six required fields (name, trigger, diagnosis, proposed_fix, approval_mode, version), a sister <shape>.fixture.json regression fixture, and a curation policy that gates promotion from approval-needed → auto. The library is read by the detector at startup, hot-reloaded on file change, and validated by gyrum-validate-auto-diagnosis at PR-author time. This ADR locks the rule shape so the first ten library entries (Phase 3 of warp#1782) can ship in parallel without fighting over the YAML format.
Context
ADR-167 locks the wire format every gyrum-* tool emits when it fails. The detector reads that stream and matches against pattern primitives. But primitives alone don't decide what to do — knowing "fire #3 of (deploy-project, fetch-ghcr-versions, regex-no-match:ghcr-tag-list) in the last 10 minutes" is not the same as knowing "this is the atomic-deploy regex bug, propose this PR template, this is safe to auto-merge after fire #5."
The mapping from "matched pattern" to "diagnosis + proposed fix + approval gate" is what the auto-diagnosis library carries. Today's session generated the empirical case: ten distinct break-and-fail events, each diagnosable in ~1 minute by an operator who has seen it before. That diagnosability is institutional knowledge that lives in operator memory and chat scrollback. The library is the substrate that promotes it to durable, queryable, regression-tested artefacts.
Three structural problems force the library to exist as a first-class artefact rather than as inline code in the detector:
Curation cadence ≠ detector release cadence. New failure shapes appear continuously (today: ten in one session). New detector code releases once per few weeks. If the diagnosis-to-action mapping lives in detector source, every new shape forces a detector release; the library's hot-reloadable YAML decouples curation from infrastructure.
Regression fixtures need a stable home. Per warp#1782's pitfalls list: "DON'T let the library become a dumping ground — every entry has a regression test; CI rejects PRs that add entries without tests." A regression fixture pins the trigger pattern + asserts the detector matches it; the fixture lives next to the rule in the same PR. This is the same shape as ADR-117's module guidelines (versioned YAML + regression suite), reused.
Approval-mode is the trust accumulator. Per warp#1782's pitfalls list: "DON'T auto-fire on first occurrence — every new failure shape requires N≥3 operator-handled cycles to validate the pattern + diagnosis BEFORE library entry. Trust must accumulate." The approval mode (
required→required-after-N→auto) is per-entry, evolves over time, and needs an explicit migration path in the library shape — not a hand-edit in detector source.
warp#1783 (the amendment) clarified that the dispatch is handled by the existing agent-executor queue: the library's job is to file the right shape of ticket, then step out. ADR-169 covers the queue-pickup contract; this ADR covers what the library entry contains.
This ADR locks the YAML rule format, the regression-fixture contract, the curation policy, and the validator + reviewer surface that gates additions to the library.
Decision
The auto-diagnosis library is a directory of versioned YAML rules at gyrum-knowledge-base/auto-diagnosis/<shape>.yaml. Each rule has the six required fields below, a sister <shape>.fixture.json regression fixture pinned in the same PR, and a curation policy gating promotion from approval-needed to auto mode. The detector reads the directory at startup, hot-reloads on file change, and rejects malformed entries (failing closed). The validator gyrum-validate-auto-diagnosis runs at PR-author time and as part of gyrum-review-pr's gate set on PRs that touch auto-diagnosis/**.
The shape has six parts: the YAML rule format, the regression-fixture contract, the library location + hot-reload semantics, the curation policy (who adds, who reviews, how entries get promoted), the validator surface, and the migration path for an entry's lifecycle.
1. YAML rule format
# gyrum-knowledge-base/auto-diagnosis/atomic-deploy-regex-404.yaml
name: atomic-deploy-regex-404
version: 1
trigger:
primitive: n-consecutive-same-signature
match:
tool: deploy-project
step: fetch-ghcr-versions
error_signature: regex-no-match:ghcr-tag-list
threshold:
n: 3
window_minutes: 10
diagnosis: |
The atomic-deploy step extracts GHCR image versions via a regex over the
GitHub container registry response. When GHCR's API response shape drifts
(e.g. a field rename, an extra wrapper element, a pagination change) the
regex stops matching and every subsequent deploy fails at the same step.
The signal that this is THIS shape rather than a one-off transient is the
N-consecutive same-signature pattern: the regex is deterministic, so a
flake would not produce identical signatures on consecutive fires.
proposed_fix:
category: approval-needed
ticket_template: |
# atomic-deploy regex bug — fetch-ghcr-versions
Detector observed {{ n_fires }} consecutive failures of
`deploy-project` step `fetch-ghcr-versions` with signature
`regex-no-match:ghcr-tag-list` between {{ window_start }} and
{{ window_end }} on context `{{ context }}`.
## Diagnosis
{{ diagnosis }}
## Proposed fix
Update the GHCR-tag-list regex in
`ansible/roles/atomic-deploy/tasks/fetch.yaml` to match the current
response shape. Sample failing payload captured at
`~/.gyrum/failure-fixtures/{{ event_id }}.json`.
## Verification
- `ansible-playbook deploy-project.yaml` against `{{ context }}` succeeds
- The failing fixture parses with the new regex
- Coverage on the regex matcher does not regress
swarm_brief: |
You are fixing the atomic-deploy GHCR regex.
The failure signature is `regex-no-match:ghcr-tag-list`.
The fixture at `~/.gyrum/failure-fixtures/{{ event_id }}.json` shows
the current GHCR response shape. Update the regex in
`ansible/roles/atomic-deploy/tasks/fetch.yaml` minimally — match
the new shape; do not refactor unrelated code.
Add a regression test pinning the new payload.
Reference warp#{{ ticket_number }} in the PR title and commit message.
verification_spec:
expected_diff_paths:
- ansible/roles/atomic-deploy/tasks/fetch.yaml
- ansible/roles/atomic-deploy/tests/test_fetch.yaml
expected_diff_max_lines: 50
must_pass:
- ansible-lint ansible/roles/atomic-deploy/
- cd ansible && pytest roles/atomic-deploy/tests/
approval_mode:
current: required
promotion_path:
next: required-after-3
after_n_successful_fires: 3
requires_operator_signoff: true
debounce:
window_hours: 1
max_fires_per_day: 3
provenance:
added_by: jon-laptop
added_at: 2026-05-07T13:00:00Z
motivating_ticket: warp#1779
motivating_events: 10 # today's evidence count
reviewer_signoff: pending # operator must approve first promotion
Required fields:
name— globally unique within the library; matches the filename without.yaml. Used as the entry's stable identifier across versions, in audit trails, and in auto-filed ticket bodies. Closed naming convention: kebab-case, ≤60 chars, descriptive of the shape (not the symptom).version— integer starting at 1. Bumped on any semantic change totrigger,diagnosis,proposed_fix, orapproval_mode. Bumping requires a PR with the regression fixture re-run; the fixture's expected output is keyed on the version. Same shape as ADR-117's module-guideline versioning.trigger— declarative match against the event stream defined in ADR-167. Fields:primitive∈{n-consecutive-same-signature, sudden-new-signature, systemic-across-context, stale-success, drift}— closed enum mapped to the detector's pattern primitives in ADR-167 §4.match— selectors over the event fields (tool,step,error_signature,severity,repo,context). Fields not specified are wildcarded.threshold— primitive-specific:n+window_minutesfor n-consecutive;lookback_daysfor sudden-new; etc. Defaults are primitive-specific and validated against the closed schema.
diagnosis— multi-paragraph human-readable string. Embedded in the auto-filed ticket body; consumed by the swarm-dispatched agent's brief. Required to name three things: (a) what condition produces this shape, (b) why this signature distinguishes it from transients / flakes, (c) what category of fix is canonical. Thegyrum-validate-auto-diagnosisvalidator enforces minimum length (200 chars) and rejects placeholder text.proposed_fix— the actionable half of the entry. Sub-fields:category∈ ADR-164's{warning, approval-needed, incident}— locks the kanban + dashboard surface the auto-filed ticket lands in.ticket_template— Mustache-style templated markdown rendered into the ticket body. Variables ({{ n_fires }},{{ context }},{{ event_id }}, etc.) are populated by the detector from the matched events.swarm_brief— the agent's brief; consumed by the staff agent that picks the auto-filed ticket via the existing queue (per warp#1783). The brief MUST name the file paths to touch, the test to add, and the ticket to reference.verification_spec— what the detector inspects after the fix-PR lands to confirm the fix worked. Sub-fields:expected_diff_paths— file paths the fix should touch. ADR-169 uses this for auto-merge gating.expected_diff_max_lines— defence against scope creep; ADR-169 fails-closed if exceeded.must_pass— commands that must exit 0 against the merged fix.
approval_mode— the per-entry trust state. Sub-fields:current∈{required, required-after-N, auto}— what the auto-filed ticket's category is on a fresh fire.promotion_path— declarative description of the next promotion step (e.g. "after 3 successful fires with operator signoff, move to required-after-3"). The library reader does not auto-promote; promotion requires an explicit PR bumpingcurrentandversion. The path field exists so the curator and reviewers can see where this entry is heading.
Required sibling fields (separate top-level blocks):
debounce— sub-fieldswindow_hours(sliding window per(name, match)group; default 1) andmax_fires_per_day(default 3). Per warp#1782's pitfalls list: "DON'T let detector drift cause notification storm — debounce + max-fires-per-day per shape." The detector reads these fields and applies them BEFORE filing the ticket; an entry without explicit debounce inherits the closed defaults.provenance— sub-fieldsadded_by,added_at,motivating_ticket,motivating_events,reviewer_signoff. The audit trail half of the entry. The curation policy (§4 below) gates entries on havingreviewer_signoff: <user>for anyapproval_mode.current=auto.
2. Regression-fixture contract
Every YAML rule has a sister fixture at gyrum-knowledge-base/auto-diagnosis/<name>.fixture.json:
{
"name": "atomic-deploy-regex-404",
"version": 1,
"fixture_events": [
{"tool":"deploy-project","context":"warp","step":"fetch-ghcr-versions","error_signature":"regex-no-match:ghcr-tag-list","input_hash":"sha256:7d8c…","ts":"2026-05-07T12:46:29.728749Z"},
{"tool":"deploy-project","context":"warp","step":"fetch-ghcr-versions","error_signature":"regex-no-match:ghcr-tag-list","input_hash":"sha256:7d8c…","ts":"2026-05-07T12:48:30.000000Z"},
{"tool":"deploy-project","context":"warp","step":"fetch-ghcr-versions","error_signature":"regex-no-match:ghcr-tag-list","input_hash":"sha256:7d8c…","ts":"2026-05-07T12:50:31.000000Z"}
],
"expected_match": true,
"expected_ticket_category": "approval-needed",
"expected_swarm_brief_contains": [
"atomic-deploy GHCR regex",
"ansible/roles/atomic-deploy/tasks/fetch.yaml"
],
"negative_fixtures": [
{"description":"two fires (under threshold) does not match","events":[{},{}],"expected_match":false},
{"description":"different signature does not match","events":[{"error_signature":"http-403:insufficient-scope"}],"expected_match":false}
]
}
Required fields:
name+version— must match the rule file's name + version. CI fails closed on mismatch.fixture_events— sequence of event JSON objects (per ADR-167's wire format) that, when fed to the detector with this rule loaded, produce a match.expected_match— boolean.truefor a positive fixture; mostlytruesince the negative-fixtures sub-array carries the negatives.expected_ticket_category— must equal the rule'sproposed_fix.category. Cross-check.expected_swarm_brief_contains— list of substrings the rendered swarm brief MUST contain. Catches templating regressions where a Mustache variable goes empty.negative_fixtures— array of sub-fixtures assertingexpected_match: false. Required to have ≥1 negative; the validator rejects rules whose fixture lacks negatives.
The CI gate gyrum-validate-auto-diagnosis runs the detector engine against each rule's fixture in dry-run mode and asserts:
- Positive fixture matches and produces the expected ticket category + brief.
- Each negative fixture does NOT match (catches over-broad triggers).
- Rule version matches fixture version.
- The fixture's
fixture_eventsround-trip the wire-format validator (ADR-167's wire-edge validator).
Without the fixture, the rule is "claimed" — somebody believed it would match a class of failures, but no test pins the claim. Per ADR-117's precedent, claimed-without-evidence is the failure mode regression fixtures exist to retire.
3. Library location + hot-reload semantics
Location: gyrum-knowledge-base/auto-diagnosis/. Reuses the existing knowledge-base repo per ADR-116 (RAG layer); the directory is one of several first-class data sources the broker indexes.
Read path: the detector reads the directory at startup. It walks each .yaml file, parses + validates each entry, and registers the rule in an in-memory matcher. On file change (detected via inotify; on systems without inotify, a 30s poll fallback), the detector re-reads the changed file and atomically swaps the in-memory rule. A rule that fails validation on reload is rejected with a warning; the previous version remains active. Failing closed on reload means a malformed YAML cannot take down rules that were healthy; the curator's typo doesn't break the fleet.
Versioning: the library's git history is the authoritative version log. Every PR that adds, modifies, or removes a rule is the audit trail. ADR-115's principle-aware reviewers quote the rule's current version when reviewing auto-filed PRs, so the question "which library version produced this auto-fix?" is structurally answerable.
Out-of-band kill switch: each rule's filename can be renamed to <name>.disabled.yaml to disable the entry without deleting it. The detector skips .disabled.yaml files. This is the "operator can disable a rule mid-fire" surface ADR-169 §6 requires; rename-and-push is faster than draft-PR + merge for emergency disables, and the audit trail (git log) still records the disable + re-enable.
4. Curation policy
Who adds entries: any agent or operator with knowledge-base write access. The PR adding the entry follows the standard gyrum-start-work → gyrum-complete-pr flow.
Who reviews entries: the standard 3-persona panel via gyrum-review-pr. A new principle-aware reviewer (per ADR-115) is recommended — Sasha (substrate-shape reviewer) per warp#1392 — for auto-diagnosis-touching PRs specifically; the existing panel covers the general case until Sasha's expertise is wired in.
Promotion path — the entry's approval_mode.current field starts at required for every new entry. Promotion to required-after-N or auto requires:
- Empirical evidence. The entry must have N≥3 successful auto-filed-ticket fires, each with the proposed fix shipping cleanly. The detector tracks this via
provenance.successful_fires(incremented per fix-PR-merge that closes the auto-filed ticket). - Operator signoff. The promotion PR must be approved by the operator (not by a persona);
provenance.reviewer_signoffrecords the operator handle and the date. - No regressions. The most recent 30 days of fires must have ≥95% diagnosis accuracy (operator-marked "right diagnosis" / "wrong diagnosis" via the auto-filed ticket's resolution comments). The detector tracks this via
provenance.accuracy_30d; a promotion PR that inverts a worsening accuracy trend gets rejected by the validator.
Demotion path — an entry can be demoted (e.g. auto → required) on:
- 1 false-positive in the most recent 7 days, OR
- 3 false-positives in the most recent 30 days, OR
- operator-issued kill switch (the
.disabled.yamlrename).
Demotions ride a one-line PR; per warp#1782 the demotion PR's review gate is intentionally light (the trust direction is unsafe → safer; over-demotion is recoverable).
Curation cron — Phase 5 of warp#1782 (deferred, soak period): a weekly cron reads ADR-167's GET /api/v1/events/uncovered endpoint (signatures with no library match in the last 7 days) and files an approval-needed ticket per signature, prompting the operator to consider whether a new library entry is warranted. This ADR locks the curation policy; the cron is a Phase 5 implementation detail.
5. Validator surface
gyrum-validate-auto-diagnosis is the wire-edge gate. Runs at three points:
- PR-author time, via
gyrum-review-pron PRs touchinggyrum-knowledge-base/auto-diagnosis/**. Validates schema, runs fixtures, cross-checks version + name. - Detector startup time, against the in-memory parsed library. Same validator code; rejected entries log a warning and are not registered.
- Detector reload time, on file-change events. Same validator; rejected entries leave the previous version active.
The validator's checks:
- YAML parses cleanly + matches the locked schema (six required fields + two required sibling blocks).
namematches filename (modulo.yaml).versionis a positive integer.trigger.primitiveis in the closed enum.trigger.matchkeys are subset of ADR-167's wire-format fields.proposed_fix.categoryis in ADR-164's closed enum.proposed_fix.swarm_briefreferences the ticket number variable (catches "agent will ship without back-link" regressions).proposed_fix.verification_spec.expected_diff_max_lines≤ 500 (caps the auto-merge blast radius per ADR-169 §3).approval_mode.currentis in the closed enum.debounce.window_hours≥ 1 ANDdebounce.max_fires_per_day≤ 10 (defence against notification storm).provenance.reviewer_signoffis set whenapproval_mode.currentisauto.- The fixture file exists at the expected path.
- The fixture has ≥1 negative case.
- Running the rule's matcher against each fixture event produces the expected verdict.
6. Migration path for an entry's lifecycle
[no entry]
↓ (operator observes new shape; files manual ticket; ships fix)
↓ (operator authors library PR with fixture + swarm_brief)
↓
[approval_mode: required, version: 1]
↓ (3 successful fires, operator signoff PR)
↓
[approval_mode: required-after-3, version: 2]
↓ (3 more successful fires, operator signoff PR)
↓
[approval_mode: auto, version: 3]
↓ (false-positive observed)
↓
[approval_mode: required, version: 4] (DEMOTION; trust resets)
↓ ...
Every transition is a PR; every PR rides gyrum-review-pr; every change bumps version. The lifecycle is the audit trail.
Consequences
Wins
- Decoupled curation cadence. New library entries land at curator pace; the detector picks them up at hot-reload pace (sub-minute). No detector release required for a new shape.
- Regression fixtures pin every claim. Every entry has a positive + negative fixture; CI rejects entries without them. The library cannot drift into "we said this matches but actually it doesn't" without the fixture failing.
- Trust accumulates per shape. The approval-mode promotion path is structural:
required→required-after-N→autorequires empirical evidence + operator signoff. The library cannot silently auto-merge new shapes the operator hasn't seen succeed first. - Operator kill switch is one rename.
<name>.disabled.yamldisables an entry mid-fire without code changes. Recovery latency is git push, not a detector restart. - Validator catches cap on auto-merge blast radius. The
expected_diff_max_lines ≤ 500enforcement at validation time means an entry whose fix-shape can produce sprawling diffs will be flagged at PR-author time rather than at auto-merge time. - Composes with existing primitives. The shape reuses ADR-117's module-guideline pattern (versioned YAML + fixture), ADR-164's category axis, ADR-167's wire format. No new substrate.
Costs
- Every entry needs a fixture. That's labour per entry; the offset is "every entry has a fixture" — the failure mode of "we wrote a rule that doesn't match what we thought" can't happen.
- Knowledge-base repo gets a new top-level directory. The
gyrum-knowledge-base/auto-diagnosis/directory is additive; no existing path semantics change. The directory will accumulate ~50-100 entries within 6 months of soak per warp#1782's 10-shape starter list × 5-10× growth from the curation cron. - The validator is non-trivial — it parses YAML, runs the matcher engine in dry-run mode, cross-references fixtures. The engine is shared with the detector (one matcher implementation, two callers), so the marginal cost is the validator harness, not a separate engine. Estimated 200-300 LOC for the validator wrapper + ~100 LOC for fixture-runner shim.
- Hot-reload introduces a new failure mode — a malformed YAML on disk could in principle take down the matcher if the reload code were buggy. Mitigated by the "fail-closed on reload, keep previous version active" contract; the worst case is one rule stays at the old version until the curator pushes a fix.
Risks
- Library becomes a dumping ground. The pitfall called out in warp#1782: entries pile up, fixtures get skipped, false positives storm. Mitigated by the validator's hard-fail on missing fixtures, missing negatives, and over-broad debounce; entries that don't survive review never land. A weekly curation cron (Phase 5) reads the entries' accuracy-30d field and auto-files demotion tickets when an entry's accuracy drops below threshold.
- Promotion-path gaming. A hostile or careless curator could land a rule directly at
autoby skipping the promotion path. Mitigated by the validator'sprovenance.reviewer_signoffrequirement whencurrent=autoAND by the persona reviewers (per ADR-115) being instructed to refuseautoPRs without an explicitsuccessful_fires ≥ Nevidence chain in the PR body. - Trigger-collision across rules. Two rules whose
trigger.matchfields overlap could both fire on the same event, producing two auto-filed tickets. Mitigated by the validator's collision check at PR-author time:gyrum-validate-auto-diagnosis --check-collisionsruns the new entry against every existing entry's fixture events and fails if any non-negative fixture matches the new entry's trigger. - Fixture-staleness after detector primitive changes. When the detector's primitive set evolves (e.g. a new
primitive: foolands), existing fixtures still pass but the entry might want to use the new primitive. Mitigated by the version-bump-on-semantic-change contract: a primitive switch is a semantic change, requires version bump, requires fixture re-run, surfaces in the PR diff. - Forgotten kill-switch unlock. An operator disables an entry via
.disabled.yamlrename, fixes the underlying issue, forgets to re-enable. Mitigated by the curation cron: weekly summary lists.disabled.yamlentries with disable-age > 7 days, files anapproval-neededticket per orphan asking "still relevant?".
Mitigations
- Validator at three points (PR-author, detector startup, detector reload) with the same code path. A schema regression cannot bypass any one point.
- Cap on
expected_diff_max_linesat validation time defends against scope creep at auto-merge time. ADR-169 enforces the same cap at merge time as defence-in-depth. - Closed enums everywhere (
primitive,category,approval_mode.current) make typos surface at validation time, not runtime. - Persona reviewer runs the regression fixture in CI on every library PR. Same shape as ADR-117's guideline-regression suite.
- Provenance fields record who added, who signed off, what motivated the entry. Auditable from
git log+ the rule's own provenance block.
Alternatives considered
Inline rules in detector source (compile-time list)
Bake the rules into the detector's source code as a compiled-in []Rule slice; ship via detector releases. Rejected: couples curation cadence to release cadence (every new shape is a deploy), prevents non-developer curators from contributing entries, breaks the operator kill-switch shape (would require code-edit + rebuild + redeploy per emergency disable). The YAML + hot-reload contract was the structural fix for these failure modes in ADR-117's module guidelines; reusing it here is the consistent move.
Database-backed rules (rules in Postgres)
Store rules as rows in a auto_diagnosis_rules table; admin UI for CRUD; detector reads via SQL. Rejected: loses the git audit trail (who-added-what-when becomes a row history reconstruction job), loses the standard PR review gate (no easy way to put admin-UI edits through gyrum-review-pr), loses ADR-115's principle-aware reviewer surface (no PR for the reviewer to read). The "CRUD UI" framing is the wrong shape for an artefact whose primary value is being reviewable + reproducible.
One YAML file with all rules
Single auto-diagnosis.yaml with a top-level array of rules. Rejected: blast radius of a typo is "every rule down" not "one rule down"; PR diff readability degrades with each new entry; concurrent PRs adding entries hit merge conflicts on every push. The per-shape file pattern is the same shape as ADR-117's per-module-type guideline files; reuse the proven shape.
Rules in detector code; fixtures in knowledge-base
Hybrid: rules compile into the detector binary; fixtures live in knowledge-base for testability. Rejected: the rule and the fixture have to ship together (a rule version-bump that doesn't update the fixture is a regression); separating them across two repos doubles the PR shape for every change. The colocation contract (<name>.yaml next to <name>.fixture.json) is what makes the regression-fixture pattern survive contact with curation pressure.
No approval-mode field; everything starts at required and curators graduate manually
Drop approval_mode from the schema; have curators just hand-edit category from approval-needed to auto when they think it's safe. Rejected: loses the structural promotion-path enforcement (no validator check for "≥N successful fires"); makes the promotion decision implicit in a PR diff that touches one field; the "auto-promotion gaming" risk above becomes the default. The explicit approval_mode block with current + promotion_path is what makes "this entry was promoted with evidence" a PR-reviewable claim rather than a category-rename.
Cross-references
- Operator framing 2026-05-07: "Things break and fail, how can we catch the not deploying or working issue structurally so you can raise a fix automatically, dogfooding ultrathink."
- ADR-167 — structured failure event schema. The events this library matches against; the wire-format selectors used in
trigger.match. - ADR-169 — auto-swarm dispatch + auto-merge gating. Consumes the
proposed_fix.swarm_briefandproposed_fix.verification_specfrom this library; defines what happens after the auto-filed ticket lands. - ADR-164 / warp#1735 — ticket category axis. The
proposed_fix.categoryfield is locked to this enum. - ADR-117 — module guidelines. Same versioned-YAML-with-regression-fixture shape; reused intentionally.
- ADR-115 — principle-aware reviewers. Reviewers quote the library entry's version when reviewing auto-filed PRs.
- ADR-116 — RAG layer. The
gyrum-knowledge-base/auto-diagnosis/directory is a first-class indexed data source. - ADR-107 — gates as playbook primitives. Same intuition: lift implicit knowledge to first-class queryable artefact.
- warp#1782 — parent EPIC; Phase 0 sub-ticket S0.2 is this ADR. Phase 3 is the first 5 library entries (S3.1 through S3.5).
- warp#1783 — amendment; the auto-filed ticket rides the existing agent-executor queue.
- warp#1779 — the canonical motivating shape; the example YAML in §1 above is exactly this entry, scheduled to ship as Phase 3 sub-ticket S3.1.
Supersedes: none Superseded by: leave blank until a later ADR reverses this one