Skip to content

ISS-13963: Validate a pushed commit in a cloud worker - #423

Merged
shafty023 merged 4 commits into
mainfrom
feat/iss-13963-cloud-validate
Nov 10, 2026
Merged

shafty023 merged 4 commits into
mainfrom
feat/iss-13963-cloud-validate

Conversation

@shafty023

@shafty023 shafty023 commented Nov 10, 2026 •

Copy link
Copy Markdown
Collaborator

Purpose

ISS-13963, acceptance criteria 6 and the validation case of 7, plus the location half of 4. Criteria 1 to 3 (fleet board placement enforcement) are in a separate PR that is rewriting board.mjs, and are not touched here.

On main, cloud-worker.mjs can only start an implementation turn based on main: the Claude start passes only the repository URL, the brief says "Base: main", Codex hard-codes --branch main, and the lane check refuses a checkout or install. So when the test machine went down, there was no cloud way to validate a pushed PR head.

What changed

  • cloud-worker.mjs validate --request <file> (vibe-core). The request names repository, branch, commit (full SHA), model, lanes ([{name, command}]) and worktree (a local checkout of the repository, for the origin check and the receipt). No Vibe session is needed.
    • It reuses the existing plumbing: the same startClaude (RemoteTrigger create, connector clearing, run), pollTask and run log. Nothing parallel.
    • The brief fetches refs/heads/<branch>, runs git checkout --detach <commit>, confirms git rev-parse HEAD, installs the way CI does (uv sync --frozen --group dev, or pnpm install --frozen-lockfile for symphony-alpha), runs each lane, changes no file, and ends with one VIBE_VALIDATION_RESULT {json} line.
    • The parser refuses a result whose commit differs from the requested one, one whose git status --porcelain lists any file, and one that misses a lane or an exit code. Otherwise it returns per-lane exit codes bound to the commit.
    • Lanes go through the same entry-point and no-shell-control check as record-evidence (now one shared helper).
    • A receipt in the checkout's git directory lets a rerun resume the same session instead of starting another.
    • Codex is refused with a named error: codex cloud (0.167) has exec, status, list, diff and apply and none returns the task's report, so lane results could not be bound to a commit.
  • Implementation dispatch unchanged. startClaude gained an optional routine name whose default is the old ticket name. The brief, the sources and the Codex --branch main are as before.
  • fleet-orchestrator SKILL.md, Cloud workers. It now says ../vibe/scripts/cloud-worker.mjs is a wrapper for vibe-core's lib/vibe/scripts/cloud-worker.mjs, and that the placement check is vibe-core's lib/fleet-orchestrator/scripts/cloud-placement.mjs. It adds one line for validate. vibe Markdown is 72 words longer (measured with instruction-words.mjs).
  • Versions: vibe-core 1.0.3, vibe 1.1.79 (after ISS-13899: Launch vibe roles that need no session #420, ISS-13944, ISS-13949: Review unit criteria in code and visual QA #421 and ISS-13947: Check PR body claims and comment leftovers #419 in merge order) (README line, Python and vibe-bench pins).

VIBE_CORE_MIN moves from main's 1.0.2 to 1.0.3, the first vibe-core with validate, because the skill now documents it. The bundled dist/ workers were rebuilt; their only change is that constant.

Live attempt

Against PR #420's head (fix/iss-13899-sessionless-launch at a85ef364cf20ee97af92ecfc2e93aa8b1c79ef29), validate exited 2 after 30 seconds with RemoteTrigger create failed: HTTP 401. No routine was created and nothing fell back to local. Follow-up on the same day: the 401 comes from the environment id cloud-worker.mjs hard-codes (env_01V3WaRD75hgdYdtKUQZz8MW), which is not the operator's. GitHub was already connected through the Claude GitHub App. A routine created directly against the account's Default environment cloned the private repository, checked out PR #420 at 3347c0a1, ran a test file 6/6 and finished clean. Making the environment configurable is ISS-13963 criterion 7, outside this PR. This PR does not claim criterion 5.

Tests

  • New plugins/vibe-core/lib/vibe/scripts/cloud-worker.test.mjs, 5 tests:
    • a validate request starts a Claude session bound to the branch and exact commit;
    • Codex, a short commit and shell-control lanes are refused before anything starts;
    • a result for another commit is refused, both in the parser and end to end;
    • a result showing a changed file is refused;
    • implementation dispatch is unchanged.
  • Mutation checks, each restored afterwards. Each mutation failed exactly the named test and no other:
    • brief checks out the branch instead of the commit: test 1 fails;
    • commit guard removed: test 3 fails;
    • status guard removed: test 4 fails;
    • implementation routine name default changed: test 5 fails;
    • Codex refusal removed: test 2 fails.
  • node --test over every vibe and vibe-core suite: 1786 tests, 1782 pass. The 3 that fail (docker-disk-admission.test.mjs 1, e2e-lock.test.mjs 2) fail the same way on a clean main checkout on this machine. The fourth failure was a changelog wording test, which is fixed.
  • uv run pytest plugins/vibe/tools/python: 610 passed. vibe-bench reply-checker.test.ts: 4 passed, tsc --noEmit clean. Pre-push ruff and pyright passed.

- Add cloud-worker.mjs validate: start a Claude cloud session that
  checks out the requested branch and exact commit, installs, runs
  the named lanes, changes no file and prints one result line
- Refuse a result whose commit differs from the requested one, that
  shows any git status line, or that misses a lane
- Refuse Codex validation by name: codex cloud returns no task report
- Keep the implementation dispatch unchanged and share the lane
  command check with record-evidence
- Name the vibe-core location of cloud-worker.mjs and
  cloud-placement.mjs in the fleet-orchestrator skill
- Bump vibe-core to 1.0.3 and vibe to 1.1.76

Testing: node --test for cloud-worker, vibe-triage, fleet, pr-create
guard and the full vibe and vibe-core suites; pytest
plugins/vibe/tools/python; each new guard mutation-checked
Risks: None identified; the new action is opt-in
…validate

# Conflicts:
#	CHANGELOG.md
#	plugins/vibe/.claude-plugin/plugin.json
#	plugins/vibe/.codex-plugin/plugin.json
#	plugins/vibe/README.md
#	plugins/vibe/tools/python/test_pr_takeover_skill_contract.py
#	plugins/vibe/tools/python/test_vibe_ws8_load_contract.py
#	tools/vibe-bench/src/reply-checker.test.ts
…validate

# Conflicts:
#	CHANGELOG.md
#	plugins/vibe-core/.claude-plugin/plugin.json
#	plugins/vibe-core/.codex-plugin/plugin.json
#	plugins/vibe/.claude-plugin/plugin.json
#	plugins/vibe/.codex-plugin/plugin.json
#	plugins/vibe/README.md
#	plugins/vibe/tools/python/test_pr_takeover_skill_contract.py
#	plugins/vibe/tools/python/test_vibe_ws8_load_contract.py
#	tools/vibe-bench/src/reply-checker.test.ts
@shafty023
shafty023 merged commit 397210d into main Nov 10, 2026
12 checks passed
@shafty023
shafty023 deleted the feat/iss-13963-cloud-validate branch November 10, 2026 23:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant