Repository navigation
Conversation
Squash of the five reviewed commits on this branch (982c602, bb811c5, 553cdb6, a7bf7db, d4e9bb0), rebased onto current main. Root `npm ci` in CI goes through .github/scripts/npm-ci.mjs, which retries once, after 1-5 s of jitter, only when npm exits 1 with the contiguous Linux-x64 C2PA release-download / workspace-fallback block for the version the root lockfile installs. Cancellation aborts the wait and is forwarded to npm's process group; complete logs stay in a private runner-local directory. The changeset scope check exempts only the exact install-command substitution in the storyboard workflow and reads base content at the merge-base. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…tail main now locks @contentauth/c2pa-node 0.10.0, whose postinstall.cjs is byte-identical to 0.9.7's and whose Cargo manifest still inherits workspace fields. Adds 0.10.0 to the version matrix and mixed-version pairs, and a fixture with the verbatim unhandled-rejection tail npm printed after the signature in #8804's failed install, which must still retry once. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
d4e9bb0 to
3c98bfc
Compare
There was a problem hiding this comment.
Ladon verdict: Escalate to human review
Escalate — gated paths touched without required approval.
This PR adds a CI-only npm ci wrapper to handle C2PA prebuilt-download/workspace-fallback failures. The reviewer found no actionable issues (no protocol surface touched, fail-closed retry logic well-tested at 74/74 + scope tests, changeset scope correct). The diff itself looks clean.
However, the PR modifies seven files under .github/workflows/**, which are declared gated paths (gated_paths: true). The required review status is REVIEW_REQUIRED, not APPROVED. Per decision table row 2, a PR touching gated paths cannot be auto-approved until a human/CODEOWNERS approval is recorded.
Escalation reasons
- Modifies gated workflow files (
.github/workflows/broken-links.yml,build-check.yml,external-smoke.yml,migration-smoke-test.yml,training-agent-storyboards.yml,validate-schema-bundle.yml,verify-matched-v4-runtime-attestation.yml) under hard approval gate.github/workflows/**;review_decisionisREVIEW_REQUIRED. Human/CODEOWNERS review required before merge.
No blocking code findings — this is purely the deterministic gated-path approval gate. Once a human approval lands, a clean re-run falls through to approve.
Why human review
- Modifies gated workflow files under
.github/workflows/**(broken-links.yml, build-check.yml, external-smoke.yml, migration-smoke-test.yml, training-agent-storyboards.yml, validate-schema-bundle.yml, verify-matched-v4-runtime-attestation.yml) while review_decision is REVIEW_REQUIRED, not APPROVED — human/CODEOWNERS review required (decision table row 2). - This PR touches a path under a hard, non-overridable approval gate (.github/workflows/broken-links.yml (modified) matches
.github/workflows/**; .github/workflows/build-check.yml (modified) matches.github/workflows/**; .github/workflows/external-smoke.yml (modified) matches.github/workflows/**; .github/workflows/migration-smoke-test.yml (modified) matches.github/workflows/**; .github/workflows/training-agent-storyboards.yml (modified) matches.github/workflows/**; .github/workflows/validate-schema-bundle.yml (modified) matches.github/workflows/**; .github/workflows/verify-matched-v4-runtime-attestation.yml (modified) matches.github/workflows/**) and the current GitHub review decision is 'REVIEW_REQUIRED', not APPROVED. This is a hard gate enforced in code — Ladon cannot auto-approve until a human/CODEOWNERS approval is recorded, regardless of how clean the diff is.
CI's root
npm cinow runs through.github/scripts/npm-ci.mjs. It runs a normalnpm ciand retries once in one case only: npm exits 1 with the contiguous Linux-x64 C2PA block, which is the prebuilt-binary download failing, the Rust fallback starting, and the published Cargo manifest failing to find a workspace root. The release URL in that block must be built from the exact@contentauth/c2pa-nodeversion in the rootpackage-lock.json. Anything else fails without a retry and keeps npm's exit status or signal: missing or invalid lock metadata, a version mismatch, other npm errors or paths, a log-capture failure, or cancellation.Why now. This failure took out four shards of #8804's first Build Check attempt on 2026-11-08. Other shards in the same run installed fine, and a rerun passed.
Refresh (2026-11-08)
fafe043b. The tree before the rebase matched the old headd4e9bb0dexactly, and the rebase applied with no conflicts.scripts/postinstall.cjsis byte-identical to 0.9.7's, itsCargo.tomlstill hasrust-version.workspace = true, and the 0.10.0 release asset URL resolves. So the fingerprint still applies with the version substituted.npm cidirectly, on purpose:apps/weband the checked-outsdk/, which have separate package graphs;release.ymlanddeploy.yml, which publish and deploy;--ignore-scriptsinstalls, which never run this postinstall.Review notes
npm ciruns, with an integer delay of 1,000–5,000 ms between them. A delay outside that range throws before a second install. Each retry is a full reinstall, so the second download happens about 40–105 s after the first, judging by the 36–100 s install times on docs(agents): pin the base SHA and lease exactly when working in parallel worktrees #8804. A sustained outage fails both attempts, the same as today.adcp-npm-ci-*directory (0700, files 0600) underRUNNER_TEMP. Nothing is uploaded, and there is no environment or config dump. A test checks that a planted env secret never appears.training-agent-storyboards.ymlcounts as protocol-scoped. The classifier exempts only the exactrun: npm ci→run: node .github/scripts/npm-ci.mjssubstitution in that file, and any other edit there is still scoped. The classifier now reads base content at the merge-base, matching its three-dot diff.--has-protocol-scoped-changesreports none for this PR, so no changeset is needed.Validation on
3c98bfc1node --test .github/scripts/npm-ci.test.cjs: 74/74 pass.node tests/changeset-protocol-scope.test.cjspasses.server/tests/unit/external-smoke.test.tsandmatched-v4-provider-billing-reconciliation.test.ts: 61/61 pass.tests/test-coverage-registration.test.cjsandtests/release-workflow-immutability.test.cjspass.I haven't seen a real 0.10.0 download failure, only the matching 0.9.7 failure plus the identical installer source.
Brian authored this PR, so a different maintainer has to approve it.
🤖 Generated with Claude Code