Repository navigation
nuxt-cloudflare: a reuse proof counts only from a Required job the callable wrote - #227
Merged
Merged
Conversation
…llable wrote findProof honoured a Required or E2E proof when a same-repository pull_request run had a job named `... Required` with the publish step name. Any workflow can write those names, and a pull_request run executes the merge ref's workflow, which a writer controls through the PR's base branch. A main push could therefore reuse a forged proof. - The attesting job's runner setup header (`Uses: ...nuxt-cloudflare.yml@<sha>` before `Complete job name:`, which no step can write) must name the SHA this run itself uses (its own referenced_workflows). It is read from a ranged job-log download that needs only actions: read. - The job must be `<caller job> / Required`. - The jobs record is re-read after 2 s and 5 s while a green Required job lists no proof step yet (fleet#1180: about half of main pushes missed reuse). taskgraph.yml's byte-equal copy of the store client follows. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…s caller-written Review of #227: the runner logs every caller-supplied input between its own Uses: line and Complete job name:, so an input value could carry a forged Uses: line. Both the store client and taskgraph's engine (shipped in #226) now take the first Uses: line only. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
narduk-lane-automation Bot
added a commit
that referenced
this pull request
Oct 30, 2026
…tHub's record (#229) * nuxt-cloudflare: Required and E2E proofs reuse with no store, from GitHub's record 36 of the 43 nuxt-cloudflare callers that do not reuse a PR's Required on main pass no CI_ARTIFACTS_R2_* secrets. Some are in the clients org, which never receives them. Without a pointer, a main push ran the full gate. The PR's `Publish ... proof <key>` step already runs, and passes, without credentials (it just records nothing), and #227 bound it to the callable's own runner header. So on a push with no pointer, Reuse plan and E2E plan now find the merged pull request's run on GitHub. The PR comes from the push's subject (a merge commit names its branch; a squash subject is the PR title, i.e. the run's display_title), or from a PR head that already held the pushed tree. The run must pass the same rules as a pointer's run (attestedRun). It needs only actions: read. Opt-in is unchanged (required-reuse-pr-results / e2e-reuse-pr-results). taskgraph.yml's byte-equal store-client copy follows. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * store-free reuse: a Dependabot run never vouches; correct the no-store texts Opus verify (no blockers) on this branch: - A Dependabot pull request gets no NVAULT_TOKEN or store secrets, so it never vouches in findProofOnGitHub (actor or triggering actor). - Texts and log messages that said a run without the store publishes no proof and that the push runs in full now say what happens. A store error still throws and runs the full gate; the comment no longer says it falls back. - e2e-reuse-pr-results (default true) now reuses E2E on a store-less caller's push too; its description says so. - Tests: Dependabot actor and triggering actor, a tree the run did not test, and attempt 2. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Logan Renz <narduk@mac.com> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
nuxt-cloudflare.yml'sfindProofhonoured a Required or full-E2E proof whenever a same-repopull_requestrun had a job ending inRequiredwith the stepPublish Required proof <key>. Any workflow can write those names. Apull_requestrun also executes the workflow from its merge ref, which a writer controls through the PR's base branch. So a writer could open a PR from an unchanged branch into a branch whoseci.ymlfakes that job, and the default-branch push would reuse the forged proof.The Opus verify on workflows#226 found this class in
taskgraph.yml, and #226 fixed it there. This PR applies the same rule to the store client thatnuxt-cloudflare.ymlandtaskgraph.ymlshare.Change
Complete job name:, must sayUses: narduk-enterprises/workflows/.github/workflows/nuxt-cloudflare.yml@<sha>, and no step can write there.<sha>must equal the SHA this run itself uses, taken from its ownreferenced_workflows. This needs onlyactions: read, whichreuse-planande2e-planalready have.<caller job> / Required.taskgraph.yml's byte-equal copy of the store client follows.Proof
test_e2e_reuse.py,test_fast_path.pyandtest_ci_artifact_store.pynow cover:Requiredjob;Uses:line printed by a step afterComplete job name:;headerNamesCallablewas run on a real familystat-usci / Requiredlog (run 41105845419, first 64 KiB). It returns true for that run'sreferenced_workflowsSHA (17b2490) and false for any other.taskgraph.yml, confirmed on gonogo#370 (run 41134850603).Review fix: only the first
Uses:line countsThe independent review (Sonnet 5.5) found one blocker. Between its own
Uses:line andComplete job name:, the runner echoes every caller-writtenwith:input (##[group] Inputs). An input value could carry a forgedUses: ...nuxt-cloudflare.yml@<sha>line. The check now accepts only the firstUses:line, which is always the runner's.taskgraph.yml's engine, which shipped the looser check in taskgraph: targeted FAST_BASE_REF tasks and store-free whole-run reuse #226.test_e2e_reuse.pyandtest_taskgraph.pynow include a log whose firstUses:names another workflow and whose echoed inputs carry the right line. Both are refused.Gates
scripts/precheckon 4698e20: exit 0, 40/40 commands passed. Its timed lines:PASS 11.85s bash scripts/install-actionlint-native-alerts.sh actionlint
PASS 0.85s actionlint -no-color -oneline .github/workflows/*.yml
PASS 0.31s python3 scripts/lint_callables.py
PASS 0.76s python3 scripts/test_actionlint_native_permissions.py
PASS 20.04s python3 scripts/test_apple_gate.py
PASS 1.22s python3 scripts/test_artifact_budget.py
PASS 0.77s python3 scripts/test_cache_paths.py
PASS 4.99s python3 scripts/test_ci_admission.py
PASS 5.13s python3 scripts/test_ci_artifact_store.py
PASS 6.69s python3 scripts/test_dependency_audit.py
PASS 1.49s python3 scripts/test_design_ledger.py
PASS 0.28s python3 scripts/test_design_publish.py
PASS 2.40s python3 scripts/test_e2e_build_artifact.py
PASS 4.78s python3 scripts/test_e2e_mode.py
PASS 5.72s python3 scripts/test_e2e_pr_subset.py
PASS 1.00s python3 scripts/test_e2e_quarantine.py
PASS 11.85s python3 scripts/test_e2e_reuse.py
PASS 17.38s python3 scripts/test_e2e_skip_paths.py
PASS 1.17s python3 scripts/test_eslint_cache.py
PASS 0.50s python3 scripts/test_exact_candidate.py
PASS 0.41s python3 scripts/test_extra_env.py
PASS 27.67s python3 scripts/test_fast_path.py
PASS 0.60s python3 scripts/test_flake_digest.py
PASS 4.18s python3 scripts/test_foundation_check.py
PASS 5.26s python3 scripts/test_package_auth_cleanup.py
PASS 0.76s python3 scripts/test_package_batch_metadata.py
PASS 0.89s python3 scripts/test_permission_ceiling.py
PASS 1.44s python3 scripts/test_playwright_toolchain.py
PASS 13.78s python3 scripts/test_preview_gate.py
PASS 1.49s python3 scripts/test_production_upload.py
PASS 0.09s python3 scripts/test_python_static_gate.py
PASS 1.08s python3 scripts/test_quality_gates.py
PASS 2.13s python3 scripts/test_red_main_listener.py
PASS 0.09s python3 scripts/test_required_gate.py
PASS 0.75s python3 scripts/test_reusable_browser_tests.py
PASS 7.98s python3 scripts/test_runner_default.py
PASS 16.46s python3 scripts/test_script_gates.py
PASS 1.22s python3 scripts/test_store_placement.py
PASS 17.81s python3 scripts/test_taskgraph.py
PASS 0.05s python3 scripts/test_tee_pipefail.py
Refs fleet#1180
🤖 Generated with Claude Code