dispatch_allow silently fails under infra#179 — make dispatch-eligibility verified, not best-effort #51

Closed
opened 2026-07-04 10:43:08 +00:00 by mathias · 1 comment
Owner

Problem

The dispatch_allow parameter (added in #43) injects a .dispatch-allow file via the same best-effort upsertRetry path as placeholder substitution. When infra#179 makes the branch unwritable in time, .dispatch-allow silently doesn't land — exactly what happened creating mathias/parallax with dispatch_allow: true: the file was absent from the generated repo and had to be added by hand (parallax#1).

Why this is worse than a normal partial failure

The entire purpose of dispatch_allow: true is to make the new repo dispatch-eligible in one step. If the file silently doesn't land, the caller believes the repo is dispatch-eligible when it is not. The failure is invisible at exactly the moment it matters — you'd only discover it when a dispatch job never gets picked up, with no obvious reason why. A silently-missing opt-in file defeats the parameter's whole reason for existing.

Design question

Should dispatch-eligibility be verified/guaranteed rather than best-effort? Options to consider (technique TBD here):

  • After creation with dispatch_allow: true, explicitly verify .dispatch-allow exists on the default branch and surface a distinct, loud error if it doesn't (not buried in a general partial_failure string).
  • Or fold it into whatever durable-substitution technique wins in #50 — if substitution becomes reliable, so does this, and .dispatch-allow should be part of that same guaranteed set.
  • At minimum: when dispatch_allow: true was requested but the file didn't land, say so explicitly and separately, so the caller knows the repo is NOT dispatch-eligible.

Acceptance

  • With dispatch_allow: true, either the repo is verifiably dispatch-eligible (.dispatch-allow present on default branch) on return, or the tool clearly and specifically reports that dispatch-eligibility was NOT achieved.
  • No silent success.

Related

  • #43 (added dispatch_allow)
  • #50 (shared root cause: substitution not durable against infra#179)
  • infra#179 (underlying)
  • parallax#1 (evidence: .dispatch-allow silently absent)
## Problem The `dispatch_allow` parameter (added in #43) injects a `.dispatch-allow` file via the same best-effort `upsertRetry` path as placeholder substitution. When infra#179 makes the branch unwritable in time, `.dispatch-allow` **silently doesn't land** — exactly what happened creating `mathias/parallax` with `dispatch_allow: true`: the file was absent from the generated repo and had to be added by hand (parallax#1). ## Why this is worse than a normal partial failure The entire purpose of `dispatch_allow: true` is to make the new repo dispatch-eligible in one step. If the file silently doesn't land, the caller believes the repo is dispatch-eligible when it is not. The failure is invisible at exactly the moment it matters — you'd only discover it when a dispatch job never gets picked up, with no obvious reason why. A silently-missing opt-in file defeats the parameter's whole reason for existing. ## Design question Should dispatch-eligibility be **verified/guaranteed** rather than best-effort? Options to consider (technique TBD here): - After creation with `dispatch_allow: true`, explicitly verify `.dispatch-allow` exists on the default branch and surface a distinct, loud error if it doesn't (not buried in a general `partial_failure` string). - Or fold it into whatever durable-substitution technique wins in #50 — if substitution becomes reliable, so does this, and `.dispatch-allow` should be part of that same guaranteed set. - At minimum: when `dispatch_allow: true` was requested but the file didn't land, say so explicitly and separately, so the caller knows the repo is NOT dispatch-eligible. ## Acceptance - With `dispatch_allow: true`, either the repo is verifiably dispatch-eligible (`.dispatch-allow` present on default branch) on return, or the tool clearly and specifically reports that dispatch-eligibility was NOT achieved. - No silent success. ## Related - #43 (added `dispatch_allow`) - #50 (shared root cause: substitution not durable against infra#179) - infra#179 (underlying) - parallax#1 (evidence: `.dispatch-allow` silently absent)
Author
Owner

Fixed in v0.9.0 (b288462), bundled with #50 since it's the same file and root cause.

Two changes:

  1. dispatch_allow_failure — a distinct result field. Dispatch injection failures no longer land in the same partial_failure string as substitution failures. Substitution can succeed while dispatch-eligibility independently fails (or vice versa) — the caller can now tell them apart. Test: TestCreateProject_DispatchAllowFailure_IsDistinctField.
  2. injectDispatchAllow is now idempotent — read-before-write: creates .dispatch-allow if absent, updates it (with the current sha) if present but different, leaves it untouched if already correct. This was the actual root cause of the parallax#1 silent-fail risk you're describing: a naive create-only write (no sha) errors when re-invoked against a path that already exists — which is exactly what would happen if a caller resumed (#50) with dispatch_allow: true after a prior attempt had already landed the file. Test: TestCreateProject_Resume_DispatchAllowIdempotent (two-phase test capturing the real written content from a first call, no hardcoded knowledge of the internal constant).

Verified via independent adversarial review (PASS, no blocking findings) and task check (exit 0, 0 FAIL — verified). Closing #51.

Fixed in v0.9.0 (`b288462`), bundled with #50 since it's the same file and root cause. Two changes: 1. **`dispatch_allow_failure` — a distinct result field.** Dispatch injection failures no longer land in the same `partial_failure` string as substitution failures. Substitution can succeed while dispatch-eligibility independently fails (or vice versa) — the caller can now tell them apart. Test: `TestCreateProject_DispatchAllowFailure_IsDistinctField`. 2. **`injectDispatchAllow` is now idempotent** — read-before-write: creates `.dispatch-allow` if absent, updates it (with the current sha) if present but different, leaves it untouched if already correct. This was the actual root cause of the parallax#1 silent-fail risk you're describing: a naive create-only write (no sha) errors when re-invoked against a path that already exists — which is exactly what would happen if a caller resumed (#50) with `dispatch_allow: true` after a prior attempt had already landed the file. Test: `TestCreateProject_Resume_DispatchAllowIdempotent` (two-phase test capturing the real written content from a first call, no hardcoded knowledge of the internal constant). Verified via independent adversarial review (PASS, no blocking findings) and `task check` (exit 0, 0 FAIL — verified). Closing #51.
Sign in to join this conversation.
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: mathias/gitea-mcp#51