Skip to content

bug(verify-preview): distinguish unreadable diff from trigger no_match #308

Description

@pengfei-threemoonslab

Summary

When a committed-ref diff cannot be read, agents-shipgate verify --preview still evaluates the Trigger against empty inputs and reports skip_reason: "no_match".

"No rule matched" is not a valid explanation when the verifier never obtained a readable diff.

Reproduction

A shallow/blobless local PR workflow exposed two input failures:

  1. the base and head had no reachable merge base;
  2. after history was deepened, the partial clone still lacked source blobs needed for the textual diff.

In both shapes, Preview reported fields equivalent to:

{
  "changed_files": [],
  "diff_text_available": false,
  "trigger": {
    "should_run": false,
    "skip": true,
    "skip_reason": "no_match",
    "rationale": "No rules matched; nothing in this PR signals a tool-surface change."
  }
}

The underlying Git errors were respectively:

fatal: <base>...<head>: no merge base
fatal: could not fetch <blob-sha> from promisor remote

The latter occurs because verification intentionally sets GIT_NO_LAZY_FETCH=1, which is the right static/no-implicit-network boundary.

Why this matters

The top-level control result can remain fail-closed (merge_verdict: "unknown", can_merge_without_human: false), but the Trigger explanation is misleading. A user or automation may incorrectly interpret no_match as evidence that the PR is unrelated to agent capabilities.

Expected result

When diff acquisition fails or is incomplete:

  • do not emit skip_reason: "no_match";
  • mark trigger evaluation as not evaluated/incomplete;
  • expose a machine-readable diff-input reason, for example:
    • refs_missing
    • merge_base_missing
    • objects_missing
    • git_failed;
  • preserve the relevant Git failure safely in diagnostics;
  • return the precise next action, such as fetching/deepening history or hydrating required partial-clone blobs.

Illustrative shape:

{
  "diff_status": "objects_missing",
  "trigger": {
    "evaluation_status": "not_evaluated",
    "should_run": null,
    "skip_reason": null
  },
  "merge_verdict": "unknown",
  "can_merge_without_human": false
}

Regression coverage

Please add committed-ref Preview tests for:

  1. no merge base in a shallow clone;
  2. promisor/partial-clone blob unavailable with lazy fetching disabled;
  3. a real agent-related diff that must not be classified as no_match merely because its input is unreadable.

Metadata

Metadata

Assignees

No one assigned

    Labels

    P1Next after P0; blocks other work or ships a misleading resultarea:triggerTrigger catalog and relevance routingarea:verifyverify / preview orchestration and SHIP-VERIFY-* checksbugSomething isn't working

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions