diff --git a/.github/workflows/gitnexus-skill-evolution.yml b/.github/workflows/gitnexus-skill-evolution.yml index 936b46a92..66e87ad18 100644 --- a/.github/workflows/gitnexus-skill-evolution.yml +++ b/.github/workflows/gitnexus-skill-evolution.yml @@ -151,6 +151,17 @@ jobs: test "$("${canary_runtime}/node_modules/@anthropic-ai/claude-code-linux-x64/claude" --version)" = \ '2.1.214 (Claude Code)' + - name: Install monorepo root dependencies + run: | + set -euo pipefail + # The benchmark's task bindings sandbox-copy node_modules from the + # monorepo root as well as gitnexus-shared and gitnexus (see the + # sandbox_copy entries in tasks.scenarios.yaml). The two steps below + # install the subpackage trees; the root tree needs its own install + # or capture_task_dependency_binding aborts at task binding on the + # missing root node_modules. + npm ci + - name: Build pinned shared runtime run: | set -euo pipefail diff --git a/gitnexus/test/unit/skill-evolution-workflow.test.ts b/gitnexus/test/unit/skill-evolution-workflow.test.ts index 50b93ec02..c2c3240fe 100644 --- a/gitnexus/test/unit/skill-evolution-workflow.test.ts +++ b/gitnexus/test/unit/skill-evolution-workflow.test.ts @@ -59,6 +59,20 @@ describe('gitnexus skill-evolution workflow contract', () => { expect(provision).toContain('${HOME}/GitNexus'); }); + it('installs node_modules for the monorepo root, gitnexus-shared, and gitnexus', () => { + // The benchmark sandbox-copies node_modules from all three (tasks.scenarios.yaml). + // The root tree was absent on the first real run because only the two subpackage + // steps ran, so capture_task_dependency_binding aborted at task binding. + const rootStep = evolveJob?.steps?.find( + ({ name }) => name === 'Install monorepo root dependencies', + ); + expect(rootStep).toBeDefined(); + expect(rootStep).not.toHaveProperty('working-directory'); // installs at the repo root + expect(String(rootStep?.run)).toContain('npm ci'); + expect(stepRun('Build pinned shared runtime')).toContain('npm ci'); + expect(stepRun('Install and build pinned GitNexus runtime')).toContain('npm ci'); + }); + it('names the promotion branch with the run attempt for re-run recovery', () => { const openPr = stepRun('Open the promotion PR'); expect(openPr).toContain('${GITHUB_RUN_ID}-${GITHUB_RUN_ATTEMPT}');