Skip to content

fix(repair): cut over durable cluster intake publication - #873

Closed
RomneyDa wants to merge 1 commit into
codex/cluster-dispatch-recoveryfrom
codex/cluster-fixer-durable-intake
Closed

fix(repair): cut over durable cluster intake publication#873
RomneyDa wants to merge 1 commit into
codex/cluster-dispatch-recoveryfrom
codex/cluster-fixer-durable-intake

Conversation

@RomneyDa

@RomneyDa RomneyDa commented Jul 26, 2026

Copy link
Copy Markdown
Member

Summary

This is 5/5 in the cluster-fixer reliability stack, based on PR 884. This existing PR remains the top layer so its audit and review history are preserved.

  • Cuts the production intake workflow from broad repair:publish-main publication to the durable cluster-intake append/materializer contract.
  • Dispatches through durable materialization instead of directly from an intake checkout.
  • Publishes worker results by exact changed paths, with bounded priority and automatic self-heal retry.
  • Separates target-read and ClawSweeper-state-write credentials and moves untrusted workflow values across environment boundaries.
  • Preserves deterministic mutation, security gates, fail-closed behavior, allow_merge: false, and all existing production gate settings.
  • Updates operator documentation for the durable lifecycle and recovery semantics.

Stack

  1. Candidate selection and historical dedupe
  2. Durable intake queue priority
  3. Durable intake intent contract
  4. Exactly-once dispatch and recovery
  5. This PR — workflow cutover and result publication hardening

Audit evidence

  • PR 813 fixed stale comment-router publication deleting unrelated cluster jobs, but did not move cluster intake off the broad writer lane.
  • 2026-07-24 intake run 30080946899 succeeded after roughly 18 minutes of publication delay.
  • 2026-07-25 intake run 30151799240 waited 30 minutes and failed at writer position 2, losing its checkout-only intent before dispatch.
  • PR 866 made Cloudflare canonical for exact-review records; cluster intake still used repair:publish-main.
  • Historical intake also repeatedly selected completed clusters, result publication starved behind the shared writer, aggregate worker status hid actionable planning outcomes, and low-confidence cluster selection produced little landable work. The lower four PRs address those owner-boundary causes independently.

Validation

  • Every layer was built and tested in isolation.
  • Full stack: pnpm run build:all, pnpm run check:static, lint, formatting, git diff --check, and focused concurrency/stale-checkout/lease-loss/duplicate/recovery/preservation/dispatch/security/ranking suites pass.
  • The complete stacked HEAD has tree 463e53e2ac3fa016b582a8a7ee637028ba815817, exactly matching the rebased unsplit implementation.
  • The prescribed Crabbox configuration resolves provider=aws, but broker/AWS authentication is unavailable on this host; allocation failed before creating a lease. No provider override was used. Hosted Linux checks remain required on every PR.
  • The full macOS aggregate was also run; failures were confined to pre-existing environment-sensitive tests (GNU timeout absent, Linux containment symbols, /private/var aliasing, and load-sensitive timing). Stack-specific suites passed.

Post-merge production acceptance

Do not call the fixer healthy until production verifies two distinct clusters with no duplicate dispatch or state loss, and at least one eligible cluster produces a substantive review-ready PR. If a fresh batch has no eligible candidate, retain the selector rejection report as the correct outcome.

After all five PRs land, preserve current gates and run:

gh workflow run repair-cluster-intake.yml --repo openclaw/clawsweeper --ref main \
  -f enabled=1 \
  -f target_repo=openclaw/openclaw \
  -f limit=2 \
  -f force_store=true

Record append-to-publication and intake-to-dispatch latency, verify unrelated job/ledger hashes are unchanged, verify one planning worker per stable dispatch key, require explicit terminal outcomes, and replay the same store to prove idempotency. Do not enable automerge or merge generated production PRs as part of that proof.

@RomneyDa
RomneyDa requested a review from a team as a code owner July 26, 2026 16:20
@clawsweeper clawsweeper Bot added rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. P2 Normal priority bug or improvement with limited blast radius. labels Jul 26, 2026
@RomneyDa
RomneyDa force-pushed the codex/cluster-fixer-durable-intake branch 5 times, most recently from 7b54925 to 7ecbf77 Compare July 26, 2026 16:47
@clawsweeper clawsweeper Bot added status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. merge-risk: 🚨 availability 🚨 Merging this PR could cause crashes, hangs, restart loops, stalls, or process outages. and removed status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. labels Jul 26, 2026
@clawsweeper

clawsweeper Bot commented Jul 26, 2026

Copy link
Copy Markdown
Contributor

Codex review: found issues before merge. Reviewed July 27, 2026, 5:16 AM ET / 09:16 UTC.

ClawSweeper review

What this changes

This PR moves cluster-repair intake and result publication to durable state intents, exact-path materialization, scoped GitHub App credentials, retry handling, and updated operator documentation.

Merge readiness

Blocked by patch quality or review findings - 10 items remain

This PR remains necessary, but the revised head still has two P1 workflow failures and one P2 documentation overstatement. The durable-intake direction is maintainer-supported, yet the production cutover should stay open until target identity reaches result publication, publisher reruns cannot halt later recovery, and live recovery proof is provided.

Priority: P1
Reviewed head: 011fdeea7ed8b1cf90db6a477ef4efcf3faf7145

Review scores

Measure Result What it means
Overall readiness 🦪 silver shellfish (2/6) The durable-intake approach is focused, but two confirmed P1 workflow failures and an inaccurate recovery guarantee make the current patch not merge-ready.
Proof confidence 🌊 off-meta tidepool Not applicable: This member-authored PR is not subject to the external-contributor proof gate, but the maintainer has specifically requested redacted real Crabbox or hosted evidence for the dispatch/claim crash window before merge.
Patch quality 🦪 silver shellfish (2/6) 3 actionable review findings remain.

Verification

Check Result Evidence
Real behavior Not applicable Not applicable: This member-authored PR is not subject to the external-contributor proof gate, but the maintainer has specifically requested redacted real Crabbox or hosted evidence for the dispatch/claim crash window before merge.
Evidence reviewed 4 items Target reader remains hard-coded: The result-publication workflow adds a separate target-read token but scopes it to the fixed openclaw/openclaw repository, while the intake workflow validates and accepts any repository under the configured allowed owner. A valid non-default target can therefore be dispatched but later fail when result publication reads its issue or pull-request data.
Self-heal still fails closed on one rerun error: The new failed-publisher retry loop runs under set -euo pipefail. If one gh run rerun call fails, the shell exits before the existing cluster self-heal step, contrary to the requested non-blocking rerun behavior.
Maintainer direction and required proof: The maintainer review supports the durable-intake direction but specifically requests target-derived read tokens, non-blocking publisher reruns, accurate at-least-once dispatch wording, and a real Crabbox run for the dispatch/claim crash window.
Findings 3 actionable findings [P1] Derive the result-reader token from the validated target
[P1] Continue self-heal after a publisher rerun failure
[P2] Describe workflow creation as at-least-once
Security None None.

How this fits together

Cluster repair intake converts a selected GitCrawl cluster into durable repair state, then materializes that state and dispatches a planning worker. This PR changes the boundary between intake, state publication, worker-result publication, and self-heal recovery.

flowchart LR
  A[GitCrawl cluster snapshot] --> B[Cluster intake workflow]
  B --> C[Durable intake queue]
  C --> D[State materializer]
  D --> E[Repair planning worker]
  E --> F[Result publication]
  F --> G[Durable repair state]
Loading

Before merge

  • Derive the result-reader token from the validated target (P1) - The intake accepts any repository under the configured allowed owner and scopes its token to that repository, but this publisher creates its reader token for fixed openclaw/openclaw. A valid non-default target can therefore dispatch successfully and then fail to publish its result. Carry the validated target through the artifact or durable intent and mint this token for that target.
  • Continue self-heal after a publisher rerun failure (P1) - This loop is under set -euo pipefail, so a failed gh run rerun exits the job before the later cluster self-heal step. Handle rerun failures per run and continue so one transient publisher API failure cannot suppress unrelated recovery work.
  • Describe workflow creation as at-least-once (P2) - The documentation promises a worker starts once and is not duplicated, but workflow dispatch creation can be at-least-once across the crash window. State the intended exactly-once worker-execution guarantee and the receipt-based deduplication boundary instead; live proof is still needed for that recovery path.
  • Resolve merge risk (P1) - A configured allowed-owner target other than openclaw/openclaw can complete intake but fail during worker-result publication because the publisher reads with a fixed-repository token.
  • Resolve merge risk (P1) - A transient failure while rerunning one publisher aborts the self-heal shell and prevents subsequent publisher retries and cluster self-heal work.
  • Resolve merge risk (P1) - The intended crash-window recovery semantics still need a redacted real hosted or Crabbox run before this production workflow cutover is trusted.
  • Complete next step (P2) - The remaining code fixes are narrow, but the required real recovery proof and the existing member-authored PR need human review rather than an automated repair handoff.
  • Improve patch quality - Pass the validated target repository into result publication and add a non-default-target regression test.
  • Improve patch quality - Make publisher reruns non-blocking and prove later self-heal still runs after one rerun error.
  • Improve patch quality - Attach redacted live hosted or Crabbox recovery evidence for the dispatch/claim crash window.

Findings

  • [P1] Derive the result-reader token from the validated target — .github/workflows/repair-publish-results.yml:62-63
  • [P1] Continue self-heal after a publisher rerun failure — .github/workflows/repair-self-heal.yml:101
  • [P2] Describe workflow creation as at-least-once — docs/steerable-repair-automation.md:185-187
Agent review details

Security

None.

Review metrics

Metric Value Why it matters
Workflow surface 3 production workflows changed The patch changes the intake, result-publication, and self-heal handoffs that jointly determine whether cluster repair work is dispatched and retained.
Patch size 335 added, 74 removed across 14 files The cutover spans workflow behavior, state-delta tooling, documentation, and focused regression coverage.

Merge-risk options

Maintainer options:

  1. Repair target propagation and recovery continuation (recommended)
    Pass the validated target repository to the publisher and make each rerun failure reportable but non-terminal so later recovery work still executes.
  2. Pause the cutover pending production proof
    Keep the existing publication path until a real recovery run demonstrates the crash-window behavior and the revised token handoff works for a non-default allowed target.

Technical review

Best possible solution:

Carry the validated target repository through the durable worker/result artifact into result publication, handle each publisher-rerun failure without stopping later recovery, document at-least-once workflow creation with intended deduplicated worker execution, and attach redacted live recovery evidence.

Do we have a high-confidence way to reproduce the issue?

Yes, from source: configure an allowed openclaw/<non-default> target, then observe that intake scopes its read token to that target while result publication mints a fixed openclaw/openclaw reader. The rerun failure path is likewise directly visible from set -euo pipefail around the loop.

Is this the best way to solve the issue?

No. The intended durable cutover is appropriate, but the publisher must use the validated target identity and must isolate rerun errors before it can safely replace the existing recovery path.

Full review comments:

  • [P1] Derive the result-reader token from the validated target — .github/workflows/repair-publish-results.yml:62-63
    The intake accepts any repository under the configured allowed owner and scopes its token to that repository, but this publisher creates its reader token for fixed openclaw/openclaw. A valid non-default target can therefore dispatch successfully and then fail to publish its result. Carry the validated target through the artifact or durable intent and mint this token for that target.
    Confidence: 0.99
  • [P1] Continue self-heal after a publisher rerun failure — .github/workflows/repair-self-heal.yml:101
    This loop is under set -euo pipefail, so a failed gh run rerun exits the job before the later cluster self-heal step. Handle rerun failures per run and continue so one transient publisher API failure cannot suppress unrelated recovery work.
    Confidence: 0.98
  • [P2] Describe workflow creation as at-least-once — docs/steerable-repair-automation.md:185-187
    The documentation promises a worker starts once and is not duplicated, but workflow dispatch creation can be at-least-once across the crash window. State the intended exactly-once worker-execution guarantee and the receipt-based deduplication boundary instead; live proof is still needed for that recovery path.
    Confidence: 0.95

Overall correctness: patch is incorrect
Overall confidence: 0.98

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against 7f1696ce8874.

Labels

Label justifications:

  • P1: The remaining failures can block valid production repair jobs from publishing results or recovering after transient workflow errors.
  • merge-risk: 🚨 compatibility: The new repository-token path supports configured non-default targets at intake but not at result publication.
  • merge-risk: 🚨 availability: One failed publisher rerun can stop the self-heal job before it handles later failed publishers or cluster runs.
  • rating: 🦪 silver shellfish: Overall readiness is 🦪 silver shellfish; proof is 🌊 off-meta tidepool and patch quality is 🦪 silver shellfish.
  • status: ⏳ waiting on author: ClawSweeper has contributor-facing work open and is waiting for author action. Not applicable: This member-authored PR is not subject to the external-contributor proof gate, but the maintainer has specifically requested redacted real Crabbox or hosted evidence for the dispatch/claim crash window before merge.

Evidence

What I checked:

  • Target reader remains hard-coded: The result-publication workflow adds a separate target-read token but scopes it to the fixed openclaw/openclaw repository, while the intake workflow validates and accepts any repository under the configured allowed owner. A valid non-default target can therefore be dispatched but later fail when result publication reads its issue or pull-request data. (.github/workflows/repair-publish-results.yml:62, 011fdeea7ed8)
  • Self-heal still fails closed on one rerun error: The new failed-publisher retry loop runs under set -euo pipefail. If one gh run rerun call fails, the shell exits before the existing cluster self-heal step, contrary to the requested non-blocking rerun behavior. (.github/workflows/repair-self-heal.yml:101, 011fdeea7ed8)
  • Maintainer direction and required proof: The maintainer review supports the durable-intake direction but specifically requests target-derived read tokens, non-blocking publisher reruns, accurate at-least-once dispatch wording, and a real Crabbox run for the dispatch/claim crash window.
  • Related merged contract history: The merged durable-intent contract establishes the accepted-intent substrate this cutover uses; the current open dispatch/recovery layer remains the adjacent prerequisite rather than a replacement for this PR. (src/repair, 1aaed03c8d41)

Likely related people:

  • RomneyDa: Authored the active cutover and the merged durable candidate, queue, and intake-contract layers that this workflow builds upon. (role: recent area contributor; confidence: high; commits: d1c837ea2f63, 390d52176b82, 1aaed03c8d41; files: .github/workflows/repair-cluster-intake.yml, .github/workflows/repair-publish-results.yml, .github/workflows/repair-self-heal.yml)
  • steipete: Authored the canonical durable-state record cutover and supplied the concrete review direction for preserving canonical state authority and validating this production recovery path. (role: adjacent architecture contributor; confidence: high; commits: a22af2903582, 655dbd6ceee2; files: .github/workflows/repair-publish-results.yml, docs/steerable-repair-automation.md)

Rating scale

Score Internal tier Crab rank Meaning
6/6 S 🦀 challenger crab Exceptional readiness
5/6 A 🦞 diamond lobster Very strong readiness
4/6 B 🐚 platinum hermit Good normal PR; ordinary maintainer review
3/6 C 🦐 gold shrimp Useful, but confidence is limited
2/6 D 🦪 silver shellfish Proof or implementation needs work
1/6 F 🧂 unranked krab Not merge-ready
N/A NA 🌊 off-meta tidepool Rating does not apply

Overall follows the weaker of proof and patch quality.
Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

Workflow

  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.

History

Review history (4 earlier review cycles)
  • reviewed 2026-07-26T16:51:56.715Z sha 7ecbf77 :: needs changes before merge. :: [P1] Keep workflow-dispatch payloads below the input limit
  • reviewed 2026-07-26T17:04:38.435Z sha 5f52f30 :: needs maintainer review before merge. :: none
  • reviewed 2026-07-27T05:16:07.036Z sha 210fa53 :: needs maintainer review before merge. :: none
  • reviewed 2026-07-27T09:09:17.643Z sha 69dea88 :: found issues before merge. :: [P1] Derive the result-reader token from the validated target | [P1] Continue self-heal after a publisher rerun failure | [P2] State the workflow-dispatch guarantee accurately

@RomneyDa
RomneyDa force-pushed the codex/cluster-fixer-durable-intake branch 2 times, most recently from 943b32a to 5f52f30 Compare July 26, 2026 17:01
@clawsweeper clawsweeper Bot added status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. and removed status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. labels Jul 26, 2026
@RomneyDa
RomneyDa force-pushed the codex/cluster-fixer-durable-intake branch from 5f52f30 to b17912e Compare July 27, 2026 04:51
@RomneyDa RomneyDa changed the title fix(repair): make cluster intake durable and selective fix(repair): cut over durable cluster intake publication Jul 27, 2026
@RomneyDa
RomneyDa changed the base branch from main to codex/cluster-dispatch-recovery July 27, 2026 04:53
@RomneyDa
RomneyDa force-pushed the codex/cluster-dispatch-recovery branch from e65c5bd to 363d5df Compare July 27, 2026 05:12
@RomneyDa
RomneyDa force-pushed the codex/cluster-fixer-durable-intake branch from b17912e to 210fa53 Compare July 27, 2026 05:12
@steipete

Copy link
Copy Markdown
Contributor

Thanks for this stack — the durable-intake direction is exactly where the codebase is going, and the bottom three PRs are being landed now (#881 as-is, #882/#883 with bounded maintainer fixes: append-window priority starvation guard, accepted-intent provenance in the durable contract, strict v2 ledger validation).

#884 and this PR need one structural rework before they can land, plus a few scoped fixes:

Dispatch authority (blocking, #884): after the queue row is acked, mutable git ledger/job files become the recovery source, and recovery uses the materializer secret to bless that state into a fresh dispatch. That means a state writer (or plain state corruption) can manufacture a pending ledger + policy-valid job. Recovery should derive from canonical DO state, or verify an immutable accepted-intent receipt (what #883 will now carry) before dispatching. This mirrors the records cutover we just completed in #879/#885 — git is projection, never authority.

Also for #884: isolate malformed cluster_intake rows (one poison row currently re-fails the whole drain — same pattern as the record-tuple dead-lettering), persist the claim before the side effect, and align dispatch-receipt-owner.sh with the TS observer (they disagree on what counts as a successful prior run, which permits a duplicate planning pass).

For this PR: mint target-read tokens for the validated target rather than hard-coding openclaw; use a read-only, non-persisted state credential in intake; make publisher-rerun failures non-blocking to subsequent self-heal; and soften the exactly-once docs — GitHub workflow_dispatch gives at-least-once creation with intended exactly-once worker execution, and the crash window between dispatch and claim publication needs live proof (a real Crabbox run) rather than mocked tests.

Both will also want a rebase once #881#883 land. Happy to pair on the recovery model — the canonical tuples endpoint from #879 is probably the right substrate for the accepted-intent receipt.

@RomneyDa
RomneyDa force-pushed the codex/cluster-dispatch-recovery branch from 363d5df to d83b6c1 Compare July 27, 2026 09:02
@RomneyDa
RomneyDa force-pushed the codex/cluster-fixer-durable-intake branch from 210fa53 to 06c463b Compare July 27, 2026 09:04
@RomneyDa
RomneyDa force-pushed the codex/cluster-dispatch-recovery branch from d83b6c1 to 555e25d Compare July 27, 2026 09:05
@RomneyDa
RomneyDa force-pushed the codex/cluster-fixer-durable-intake branch from 06c463b to 69dea88 Compare July 27, 2026 09:05
@clawsweeper clawsweeper Bot added rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. P1 Urgent regression or broken agent/channel workflow affecting real users now. merge-risk: 🚨 compatibility 🚨 Merging this PR could break existing users, config, migrations, defaults, or upgrades. and removed rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. P2 Normal priority bug or improvement with limited blast radius. labels Jul 27, 2026
@RomneyDa
RomneyDa force-pushed the codex/cluster-dispatch-recovery branch from 555e25d to 8b0733d Compare July 27, 2026 09:12
@RomneyDa
RomneyDa force-pushed the codex/cluster-fixer-durable-intake branch from 69dea88 to 011fdee Compare July 27, 2026 09:13
@clawsweeper clawsweeper Bot added rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. and removed rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. labels Jul 27, 2026
steipete added a commit that referenced this pull request Jul 27, 2026
Rework of the #873 cutover layer on top of the #900 dispatch rework:

- Result publication resolves the validated target repositories from the
  downloaded worker artifacts (result.repo, fail-closed against the
  allowed owner) and mints its target-read token for those repositories
  instead of hard-coding openclaw/openclaw.
- Intake hydrates state with a read-only, non-persisted credential and
  drops its contents-write grants; it never publishes from its checkout.
- Result publication narrows the ClawSweeper app token and workflow
  permissions to read (state writes use the state credential).
- A failed publisher rerun in self-heal is reported per run and never
  aborts subsequent publisher retries or cluster self-heal work.
- Docs state the accurate guarantee: at-least-once workflow creation
  with exactly-once worker execution intent, receipt-gated worker-side
  dedupe, and job-path-only worker concurrency.
@steipete

Copy link
Copy Markdown
Contributor

Superseded by #901 (merged) — thank you @RomneyDa for the whole stack! Everything landed: #881 as-is, #882/#883 with maintainer fixes, #884 via #900, and this cutover via #901 with a live proof that also caught and fixed a latent owner-list bug on main. Deferred proof: the first naturally selected cluster dispatch will exercise the claim->dispatch->recovery window live (watch results/cluster-repair-intake/*.json for dispatch_claimed->dispatched and exactly one planning run).

steipete added a commit that referenced this pull request Jul 27, 2026
) (#901)

* fix(repair): cut over durable cluster intake publication

* fix(repair): rework cluster intake cutover per maintainer review

Rework of the #873 cutover layer on top of the #900 dispatch rework:

- Result publication resolves the validated target repositories from the
  downloaded worker artifacts (result.repo, fail-closed against the
  allowed owner) and mints its target-read token for those repositories
  instead of hard-coding openclaw/openclaw.
- Intake hydrates state with a read-only, non-persisted credential and
  drops its contents-write grants; it never publishes from its checkout.
- Result publication narrows the ClawSweeper app token and workflow
  permissions to read (state writes use the state credential).
- A failed publisher rerun in self-heal is reported per run and never
  aborts subsequent publisher retries or cluster self-heal work.
- Docs state the accurate guarantee: at-least-once workflow creation
  with exactly-once worker execution intent, receipt-gated worker-side
  dedupe, and job-path-only worker concurrency.

* fix(repair): honor the CLAWSWEEPER_ALLOWED_OWNER owner-list contract across the cluster cutover lanes

The production CLAWSWEEPER_ALLOWED_OWNER variable is a comma-separated owner
list (openclaw,steipete; issue #604 / allowedRepairOwners), but three cutover
gates treated it as a single owner and failed closed on every dispatch:

- repair-cluster-intake.yml 'Resolve target repository' rejected the list
  outright (live proof run 30302458881 failed here).
- resolve-result-targets rejected the list before minting the reader token;
  it now validates every result owner against the parsed list and fails
  closed when results span multiple owners, since one publication mints one
  reader token.
- restore-cluster-intake-job compared the job-path owner against the raw
  list string, which could never match.

Proof enablement, no-op on main: the intake wake and worker dispatch now run
on the invoking revision (GITHUB_REF_NAME / CLAWSWEEPER_DISPATCH_REF), and
repair-publish-results gains a validated workflow_dispatch lane for a
completed worker run while workflow_run events stay pinned to trusted
default-branch code.

* fix(repair): accept the pnpm-forwarded -- separator in publish-cluster-intake

The hosted runner's pnpm forwards the literal -- from
'pnpm run repair:publish-cluster-intake -- <intent>', so the CLI read '--'
as the intent path and durable acceptance failed with
ENOENT '.../--' (live proof run 30303202343). Use the first real
positional and cover the separator in a CLI regression test.

* fix(repair): only offer clusters that satisfy the durable acceptance contract

The cluster-intake acceptance policy (#900) requires at least two candidate
references, but the importer offered single-open-member clusters and the
selector could choose one, failing the whole intake run at durable
acceptance with 'cluster intake job reference policy mismatch' (live proof
run 30304188033). Filter selection to clusters with >= 2 open members and
skip single-candidate clusters defensively in the job loop.

* fix(repair): publish results from the event's trusted ref instead of a hard main pin

The mid-job 'git checkout -B main origin/main' pin mixed main's package.json
with a branch-built dist/ on the manual publication lane, so
repair:state-delta-paths was missing at 'Commit result ledger' (live proof
run 30308450188). workflow_run events keep publishing default-branch code;
a workflow_dispatch publishes its own write-gated ref.

---------

Co-authored-by: Dallin Romney <dallinromney@gmail.com>
@steipete steipete closed this Jul 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

merge-risk: 🚨 availability 🚨 Merging this PR could cause crashes, hangs, restart loops, stalls, or process outages. merge-risk: 🚨 compatibility 🚨 Merging this PR could break existing users, config, migrations, defaults, or upgrades. P1 Urgent regression or broken agent/channel workflow affecting real users now. rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants