Skip to content

classify-infra-failure: substring path discards its matched error type — carry it as a new error_type projection key #253

Description

@kyle-sexton

Problem

On the substring-fallback detection path, classify-infra-failure.sh knows exactly which published error type it matched (the allowlist at lines ~71-77: authentication_error, billing_error, permission_error, …) and then discards it. The emitted projection carries api_error_status: null on that path, so an operator triaging a class=auth failure gets no discriminator at all — 401 vs 402 vs 403 prescribe three different remedies (rotate token / fix billing in Console / fix key permissions and workspace access), and the operator gets a three-way checklist instead of the specific one.

This is not 402-specific: a substring-detected 403 reproduces it. Independently verified during the #250 ratification review (2026-07-26).

Proposed fix

Carry the matched allowlist token into the structured projection as a NEW key — error_type, deliberately distinct from api_error_status, so an inferred (substring-matched) value is never conflated with an observed numeric status.

Verified safe and non-breaking before filing:

  • Additive only. The projection is built at classify-infra-failure.sh:~81-89; a new key leaves class and api_error_status untouched, and class=<token> remains a bare separate term in the ::error annotation (claude-review.yml:~484), so Incident aggregator: dead-credential detection from consumer review-run annotations (scheduled, zero new secrets) #238's aggregator written against today's shape does not break.
  • Log-hygiene safe by construction. The value comes from the closed published-type allowlist, never from raw model/SDK text.
  • Existing suite passes. Test 20 (classify-infra-failure.test.sh:~140-144) asserts key presence plus a result/errors leak denylist; it does not pin an exact key set. The new key should get its own presence assertion.

Scope

Refs

#250 (ratification review that surfaced this), #238 (consumer), #248/#249/#251 (classifier lineage).


Filed by an AI agent (work-items:attend-queue lane) as raw intake — untriaged.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    needs-humanHuman-in-the-loop required; autonomous sessions must not resolve items carrying this.priority: highSignificant impact, or blocks an imminent release; staff this cycle.status: readyTriaged, unblocked, and fully specified; eligible to pick up.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions