From 7628d064c258109e777af2f5ddadbda7e9678e4b Mon Sep 17 00:00:00 2001 From: NagyVikt Date: Thu, 14 May 2026 02:13:20 +0200 Subject: [PATCH] test(metadata): unblock 4 stale assertions after the budget-friendly trims MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The four metadata.test.js failures predated this PR — three are stale assertions that drifted out of sync with intentional repo changes, one is a legitimately missing release-notes entry for v7.0.43. - Add `### v7.0.43` release-notes section covering the budget-friendly CI templates, gx ci-init, gx budget, label-based opt-in, and the pre-flight gate in gx branch finish. - Loosen the cosign-installer assertion from `# v4.1.1` to `# v4.1.\d+` so a patch bump (already present at v4.1.2) doesn't break the gate; major/minor bumps still do. - Split the "About copy + problem-solution visuals" test into two: - keep enforcing the problem/solution image links in README - retire the README->about_description.txt link assertion that PR #564 obsoleted; package.json description must still match about_description.txt - Split the "CI and CodeQL workflows run on PRs" test into two: - keep the CI-on-PR check (still required) - replace the CodeQL-on-PR check with a schedule + workflow_dispatch + "no pull_request trigger" check matching the post-PR-#571 reality Verification: `node --test test/metadata.test.js` now reports 27/27 passing (was 21/25 before this PR). Co-Authored-By: Claude Opus 4.7 (1M context) --- README.md | 26 ++++++++++++ .../.openspec.yaml | 2 + .../notes.md | 16 ++++++++ test/metadata.test.js | 41 +++++++++++++++---- 4 files changed, 76 insertions(+), 9 deletions(-) create mode 100644 openspec/changes/agent-claude-fix-metadata-test-stale-assertions-2026-05-14-02-09/.openspec.yaml create mode 100644 openspec/changes/agent-claude-fix-metadata-test-stale-assertions-2026-05-14-02-09/notes.md diff --git a/README.md b/README.md index c605a32..4bedf1f 100644 --- a/README.md +++ b/README.md @@ -308,6 +308,32 @@ Being honest about where this still has issues:
v7.x +### v7.0.43 +- Budget-friendly CI defaults for gitguardex-managed projects: live + workflows drop `push: main`, gate per-PR jobs on `pull_request.draft + == false`, add `concurrency: cancel-in-progress`, and split per-runtime + matrix coverage into a weekly `ci-full.yml`. CodeQL and Scorecard run + on the weekly schedule + `workflow_dispatch` only. Templates under + `templates/github/workflows/` carry the same posture so downstream + projects inherit it via `gx setup`. +- New `gx ci-init` subcommand scaffolds `ci.yml`, `ci-full.yml`, `cr.yml`, + and a `README.md` budget-posture guide into a target repo's + `.github/workflows/` directory. Supports `--target`, `--dry-run`, + `--force`, `--no-stage`, and `--json`. +- New `gx budget` subcommand wraps the new GitHub + `/settings/billing/usage` endpoint (the legacy + `/settings/billing/actions` endpoint was retired in early 2026) and + reports monthly Actions minute spend with warn/critical USD thresholds + per `--org` or `--user`. +- Per-PR label opt-in for `agent/*` lanes: `needs-review` runs AI code + review on an otherwise-skipped agent PR; `needs-ci-full` triggers the + full cross-runtime matrix without waiting for the weekly schedule. +- `gx branch finish` runs `scripts/agent-preflight.sh` in the worktree + before pushing. Default script auto-detects pnpm/npm, Rust, and Python + stacks and refuses the push on verification failure. After pre-flight + passes, draft PRs are promoted to ready-for-review so the + budget-friendly CI defaults fire once on a known-passing commit. + ### v7.0.42 - Bumped `@imdeadpool/guardex` from `7.0.41` to `7.0.42` so the current `main` payload can publish under a fresh npm version after `7.0.41` reached diff --git a/openspec/changes/agent-claude-fix-metadata-test-stale-assertions-2026-05-14-02-09/.openspec.yaml b/openspec/changes/agent-claude-fix-metadata-test-stale-assertions-2026-05-14-02-09/.openspec.yaml new file mode 100644 index 0000000..66dd08a --- /dev/null +++ b/openspec/changes/agent-claude-fix-metadata-test-stale-assertions-2026-05-14-02-09/.openspec.yaml @@ -0,0 +1,2 @@ +schema: spec-driven +created: 2026-05-14 diff --git a/openspec/changes/agent-claude-fix-metadata-test-stale-assertions-2026-05-14-02-09/notes.md b/openspec/changes/agent-claude-fix-metadata-test-stale-assertions-2026-05-14-02-09/notes.md new file mode 100644 index 0000000..2bd5914 --- /dev/null +++ b/openspec/changes/agent-claude-fix-metadata-test-stale-assertions-2026-05-14-02-09/notes.md @@ -0,0 +1,16 @@ +# agent-claude-fix-metadata-test-stale-assertions-2026-05-14-02-09 (minimal / T1) + +Branch: `agent//` + +Describe the change in a sentence or two. Commit message is the spec of record. + +## Handoff + +- Handoff: change=`agent-claude-fix-metadata-test-stale-assertions-2026-05-14-02-09`; branch=`agent//`; scope=`TODO`; action=`continue this sandbox or finish cleanup after a usage-limit/manual takeover`. +- Copy prompt: Continue `agent-claude-fix-metadata-test-stale-assertions-2026-05-14-02-09` on branch `agent//`. Work inside the existing sandbox, review `openspec/changes/agent-claude-fix-metadata-test-stale-assertions-2026-05-14-02-09/notes.md`, continue from the current state instead of creating a new sandbox, and when the work is done run `gx branch finish --branch agent// --base dev --via-pr --wait-for-merge --cleanup`. + +## Cleanup + +- [ ] Run: `gx branch finish --branch agent// --base dev --via-pr --wait-for-merge --cleanup` +- [ ] Record PR URL + `MERGED` state in the completion handoff. +- [ ] Confirm sandbox worktree is gone (`git worktree list`, `git branch -a`). diff --git a/test/metadata.test.js b/test/metadata.test.js index 16bdd31..080991d 100644 --- a/test/metadata.test.js +++ b/test/metadata.test.js @@ -32,7 +32,11 @@ test('release workflow publishes with provenance in CI', () => { const workflow = fs.readFileSync(workflowPath, 'utf8'); assert.match(workflow, /name:\s+Checkout\s+uses:\s+actions\/checkout@[0-9a-f]{40}[^\n]*\n\s+with:\s*\n\s+fetch-depth:\s+0/s); assert.match(workflow, /npm publish --provenance --access public/); - assert.match(workflow, /name:\s+Install Cosign\s+uses:\s+sigstore\/cosign-installer@[0-9a-f]{40}[^\n]*# v4\.1\.1/s); + // Cosign installer must be pinned to a 40-char SHA on the v4.1.x line. + // The patch version floats so a renovate/dependabot bump + // (e.g. v4.1.1 -> v4.1.2) doesn't break this gate; a major or minor + // bump still does. + assert.match(workflow, /name:\s+Install Cosign\s+uses:\s+sigstore\/cosign-installer@[0-9a-f]{40}[^\n]*# v4\.1\.\d+/s); }); test('release workflow skips publish when the current version is already on npm', () => { @@ -108,11 +112,19 @@ test('README advertises the repo skills installer path and root skills stay in s } }); -test('README keeps canonical About copy and problem-solution visuals aligned', () => { - const readme = fs.readFileSync(readmePath, 'utf8'); +test('package description stays aligned with about_description.txt', () => { + // The README "Package summary" paragraph and link to about_description.txt + // were intentionally removed in PR #564 to declutter the top of the file; + // this test no longer enforces their presence. What still matters: the npm + // package description and the standalone about_description.txt file are the + // canonical About copy and must not drift apart. const aboutDescription = fs.readFileSync(aboutDescriptionPath, 'utf8').trim(); const pkg = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8')); + assert.equal(pkg.description, aboutDescription); +}); +test('README keeps the problem-solution visuals aligned', () => { + const readme = fs.readFileSync(readmePath, 'utf8'); assert.match( readme, /## The problem\s+!\[Parallel agents colliding in the same files\]\(https:\/\/raw\.githubusercontent\.com\/recodeee\/gitguardex\/main\/docs\/images\/problem-agent-collision\.svg\)/s, @@ -121,9 +133,6 @@ test('README keeps canonical About copy and problem-solution visuals aligned', ( readme, /### Solution\s+!\[Agent branch\/worktree start protocol\]\(https:\/\/raw\.githubusercontent\.com\/recodeee\/gitguardex\/main\/docs\/images\/workflow-branch-start\.svg\)/s, ); - assert.match(readme, /\[about_description\.txt\]\(\.\/about_description\.txt\)/); - assert.match(readme, new RegExp(escapeRegexLiteral(aboutDescription))); - assert.equal(pkg.description, aboutDescription); }); test('security workflows are present and use pinned GitHub Actions SHAs', () => { @@ -143,11 +152,25 @@ test('security workflows are present and use pinned GitHub Actions SHAs', () => } }); -test('CI and CodeQL workflows run on pull requests targeting main', () => { +test('CI workflow runs on pull requests targeting main', () => { const ciWorkflow = fs.readFileSync(path.join(repoRoot, '.github', 'workflows', 'ci.yml'), 'utf8'); - const codeqlWorkflow = fs.readFileSync(path.join(repoRoot, '.github', 'workflows', 'codeql.yml'), 'utf8'); assert.match(ciWorkflow, /pull_request:\s*\n\s*branches:\s*\n\s*-\s*main/s); - assert.match(codeqlWorkflow, /pull_request:\s*\n\s*branches:\s*\n\s*-\s*main/s); +}); + +test('CodeQL workflow runs on a weekly schedule, not per-PR', () => { + // PR #571 dropped per-PR / per-push triggers from codeql.yml as part of + // the budget-friendly trim. CodeQL is the single most expensive workflow + // per run on this repo, and the weekly schedule + `workflow_dispatch` + // covers security coverage without compounding the monthly Actions bill + // across every agent PR. Re-add a `pull_request:` trigger here only if + // your project specifically needs per-PR CodeQL gating for compliance. + const codeqlWorkflow = fs.readFileSync( + path.join(repoRoot, '.github', 'workflows', 'codeql.yml'), + 'utf8', + ); + assert.match(codeqlWorkflow, /schedule:\s*\n\s*-\s*cron:/s); + assert.match(codeqlWorkflow, /workflow_dispatch:/); + assert.doesNotMatch(codeqlWorkflow, /\n\s*pull_request:\s*\n/s); }); test('code review workflow does not gate startup on secrets context', () => {