diff --git a/.github/workflows/runner-full-stack-e2e.yml b/.github/workflows/runner-full-stack-e2e.yml index dc353c27c8..4542d837ef 100644 --- a/.github/workflows/runner-full-stack-e2e.yml +++ b/.github/workflows/runner-full-stack-e2e.yml @@ -495,7 +495,7 @@ jobs: node-version: 24 cache: pnpm - - run: pnpm install --frozen-lockfile + - run: pnpm install --frozen-lockfile --ignore-scripts # build:typescript also builds the eval-kernel dependency, so the two # TypeScript trees are compiled at most once in this campaign. @@ -617,7 +617,7 @@ jobs: cache: pnpm - if: needs.catalog.outputs.needs_remote_provider_pack == 'true' - run: pnpm install --frozen-lockfile + run: pnpm install --frozen-lockfile --ignore-scripts - name: Download immutable shared campaign outputs if: needs.catalog.outputs.needs_remote_provider_pack == 'true' diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f658db0b99..250a7e0238 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1099,8 +1099,8 @@ importers: specifier: 0.48.0 version: 0.48.0(typescript@7.0.2) lucide-react: - specifier: ^1.32.0 - version: 1.32.0(react@19.2.8) + specifier: ^1.38.0 + version: 1.38.0(react@19.2.8) mermaid: specifier: ^11.17.2 version: 11.17.2 @@ -6825,8 +6825,8 @@ packages: lru_map@0.4.1: resolution: {integrity: sha512-I+lBvqMMFfqaV8CJCISjI3wbjmwVu/VyOoU7+qtu9d7ioW5klMgsTTiUOUp+DJvfTTzKXoPbyC6YfgkNcyPSOg==} - lucide-react@1.32.0: - resolution: {integrity: sha512-txX56hMFnRxPi1f9/nH69YN8uvAO6a7Y1KSWKjCDAtdD9+soEgmWuCt6iRm1pkxUZo2+YntSdsE1L6bIuKoY8Q==} + lucide-react@1.38.0: + resolution: {integrity: sha512-xZCyBd/wiVUDactoCc+42TjL0aB7EBOXsuX+tjz+W/sGzw2KhHpL1NOH3FIaVUcpimvUBpIYfz34Ofj9S5JEzQ==} peerDependencies: react: ^19.2.8 @@ -14064,7 +14064,7 @@ snapshots: lru_map@0.4.1: {} - lucide-react@1.32.0(react@19.2.8): + lucide-react@1.38.0(react@19.2.8): dependencies: react: 19.2.8 diff --git a/tests/runner-e2e/README.md b/tests/runner-e2e/README.md index 167c7265af..be091a341a 100644 --- a/tests/runner-e2e/README.md +++ b/tests/runner-e2e/README.md @@ -280,10 +280,14 @@ job checks out the resolved commit and regenerates `pnpm-lock.yaml` once with lockfile under a run-attempt-scoped artifact ID and records its SHA-256. Catalog, image, shared-build, provider-pack, and paid test jobs download the artifact by ID, verify its digest, and restore it before setup or a frozen -install. The paid test job disables dependency lifecycle scripts, and provider -secrets are introduced only in the final test step. This permits an authorized -target branch to exercise an intentionally uncommitted workspace patch while -keeping every target job on one identical dependency resolution. Report +install. The shared-build, provider-pack, and paid test jobs all disable +dependency lifecycle scripts, and provider secrets are introduced only in the +final test step. This permits an authorized target branch to exercise an +intentionally uncommitted workspace patch while keeping every target job on one +identical dependency resolution. The shared-build job compiles the selected +campaign's TypeScript outputs and native binaries once, then each paid cell +verifies and extracts the immutable bundle. Remote native cells similarly reuse +one verified provider pack. Report sanitization and AWS history publication do not consume the target lockfile; they explicitly check out and install from the trusted workflow commit. The workflow definition, runner-group permission, and protected-environment diff --git a/tests/runner-e2e/SECURITY.md b/tests/runner-e2e/SECURITY.md index 6148d71d1c..05105a305d 100644 --- a/tests/runner-e2e/SECURITY.md +++ b/tests/runner-e2e/SECURITY.md @@ -27,9 +27,12 @@ then uploads the file under a run-attempt-scoped artifact ID. Catalog, image, shared-build, provider-pack, and paid test jobs download that exact artifact by ID, verify its recorded SHA-256, and restore it before setup or a frozen dependency install. The lock resolver receives no provider credentials and -must never run repository lifecycle scripts. The paid test job also installs -with lifecycle scripts disabled, and provider secrets are scoped only to its -final test step rather than dependency setup. Report sanitization and AWS +must never run repository lifecycle scripts. The shared-build and provider-pack +jobs also receive no provider credentials and disable dependency lifecycle +scripts; they package outputs with SHA-256 sidecars that consumers verify +before extraction. The paid test job installs with lifecycle scripts disabled, +and provider secrets are scoped only to its final test step rather than +dependency setup. Report sanitization and AWS history publication explicitly use the trusted workflow commit and do not consume the target lockfile. Never run the workflow definition from the target branch. diff --git a/tests/runner-e2e/history.test.ts b/tests/runner-e2e/history.test.ts index 0ae98fb272..8a6cec4c7c 100644 --- a/tests/runner-e2e/history.test.ts +++ b/tests/runner-e2e/history.test.ts @@ -68,16 +68,16 @@ describe("runner E2E campaign history", () => { expected: breadth.map((execution) => execution.id), results: breadth.map((execution) => result(execution, "passed")), }); - expect(campaign).toMatchObject({ complete: false, passed: 12, failed: 0 }); + expect(campaign).toMatchObject({ complete: false, passed: 11, failed: 0 }); expect(campaign.suites[0]).toMatchObject({ suiteId: "openrouter-model-breadth", complete: true, - selected: 12, + selected: 11, }); expect(campaign.billing).toMatchObject({ - reportedLlmCostUsd: 0.12, - llm: { inputTokens: 1_200, outputTokens: 300 }, + llm: { inputTokens: 1_100, outputTokens: 275 }, }); + expect(campaign.billing.reportedLlmCostUsd).toBeCloseTo(0.11, 10); const history = mergeRunnerHistory( emptyRunnerHistory(), campaignHistoryRecord(campaign, "https://history.example/runner-e2e"), diff --git a/tests/runner-e2e/workflow-security.test.ts b/tests/runner-e2e/workflow-security.test.ts index 7ce47a3c42..caf5398dee 100644 --- a/tests/runner-e2e/workflow-security.test.ts +++ b/tests/runner-e2e/workflow-security.test.ts @@ -297,6 +297,9 @@ describe("public repository paid workflow security", () => { expect(buildJob).toMatch(buildRemoteProviderPackNeeds); expect(buildJob).not.toContain("environment:"); expect(buildJob).not.toContain("secrets."); + expect( + buildJob.match(/pnpm install --frozen-lockfile --ignore-scripts/g), + ).toHaveLength(2); expect(buildJob).toContain( "pnpm --filter @paperclipai/paperclip-runner build:typescript", ); diff --git a/ui/package.json b/ui/package.json index d9b1bf32a5..16cb5e9669 100644 --- a/ui/package.json +++ b/ui/package.json @@ -59,7 +59,7 @@ "cmdk": "^1.1.1", "i18next": "^26.3.6", "lexical": "0.48.0", - "lucide-react": "^1.32.0", + "lucide-react": "^1.38.0", "mermaid": "^11.17.2", "motion": "^12.42.2", "radix-ui": "^1.6.7",