091-an-unclassified-review-failure-blocks-the-merge

An unclassified review failure blocks the merge

Lifecycle approvedImplementation completeVerification unknownQualification unknown

The AI review job classifies a failed reviewer invocation into two outcomes, and its fall-through is a pass. On 2026-09-20 the provider returned "Your organization does not have access to Claude. Please login again or contact your administrator." and the job matched it against a token allowlist (`authentication_error`, `permission_error`, `unauthorized`, `forbidden`, and three more), found no match, set `review_status=api_failure`, exited 0, and `ci-gate` went green on PR #267 with no review. The refusal was prose and the allowlist reads tokens, so an access refusal took the transient-outage branch. Two further holes sit beside it: `review_status=ok` is set from exit status alone, so a reviewer that exits 0 having written nothing publishes an empty review the gate reads as reviewed, and the transient notice swallows a failed `gh pr comment` with a warning, so the one artifact that makes a skip visible can be absent while the gate still passes. This spec states the classification policy the job must implement: success and failure are separated by exit status before any text is read, refusal signals outrank transient signals inside a failed invocation, transient signals are recognized only in the contextual forms their emitting layer produces, and everything else blocks. It is defended by a test that executes the workflow's own script rather than a copy of its patterns, so inverting a blocking branch is caught even when its regexes are untouched.

Read the full pinned specification ↗

Relationships

Claimed units

  • establishes
    {
      "kind": "file",
      "path": "crates/spec-spine-core/tests/ai_review_policy.rs"
    }

Source headings

  1. 091: An unclassified review failure blocks the merge
  2. 1. Purpose
  3. 1.1 What was observed
  4. 1.2 The misclassification
  5. 1.3 Two adjacent holes, in scope
  6. 1.4 What this spec does not fix
  7. 2. Territory
  8. 2.1 What coupling and a behavioral test each protect
  9. 3. Behavior
  10. 3.1 Success and failure are separated before any text is read
  11. 3.2 Class 1, structural skip, unchanged
  12. 3.3 Class 2, secret unset, unchanged
  13. 3.4 Class 3, a review was produced and published
  14. 3.5 Class 4, access refusal
  15. 3.6 Class 5, recognized transient
  16. 3.6.1 A timeout is not a recognized transient signal
  17. 3.7 Class 6, unclassified, blocks
  18. 3.8 The policy test executes the workflow's own script
  19. 3.8.1 Fixture matrix
  20. 3.8.2 The inversion regression check
  21. 3.9 Precedence
  22. 3.10 Acceptance
  23. 4. Out of scope
  24. 5. Resolved decisions
  25. Verification

Frozen anchors

No frozen anchors declared.