Repository navigation
ci: open a fix PR when the nightly audit fails; fold duplicate changelog headings in the back-merge - #158
Merged
Conversation
…log guard A hotfix on main that adds a '### Security' bullet under [Unreleased] meets develop's own '### Security' heading there. merge=union keeps both, git calls the merge clean, and changelog-guard rightly rejects two headings with the same name, so the back-merge ended in a PR for a human to move the bullets under one heading. That is mechanical, with one right answer. scripts/changelog-fold-headings.mjs merges same-named ### subsections inside [Unreleased] only (dated sections are immutable) and returns a clean file byte for byte. backmerge.yml runs it after a clean merge and commits the result separately; a failure of the fold is a warning, and the guard and the PR fallback still apply. Run against the real bad changelog from the #154 back-merge it reproduces the hand-made fix exactly. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012ESxuEjCeVsRAAxAb29Yjr
The nightly strict-audit was red on 22 of 29 scheduled runs in October because Dependabot often opened no security PR, and the fix (update only the vulnerable lockfile entries, add a Security bullet, open a PR) was done by hand each time. audit-remediate.yml runs after a failed nightly (or by hand; manual runs are dry runs by default). scripts/audit-remediate.mjs reads npm audit --json, picks the packages with a moderate+ advisory and a non-major fix, and the workflow runs npm update --package-lock-only for only those, refuses to touch package.json, adds the changelog bullets and opens one PR, into main first, then develop. It never merges, tags or releases, does nothing while its own PR or a Dependabot security PR is open, and fails when npm audit itself fails instead of reading it as all-clear. Run against the lockfile main had before the hand-made hotfixes it finds the same six packages and brings the audit from 6 vulnerabilities to 0. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012ESxuEjCeVsRAAxAb29Yjr
Contributor
Coverage Report
File CoverageNo changed files found. |
This was referenced Oct 30, 2026
Merged
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.
Summary
Two independent fixes for the two things that kept the nightly red and the releases manual. They are separate commits so they can be reviewed one at a time.
1.
audit-remediate.yml: the nightly audit fixes itself where it canstrict-auditwas red on 22 of the 29 scheduled nightlies in October. Dependabot often opened no security PR for these advisories, and each time the same by-hand hotfix followed (AGENTS.md: update only the vulnerable lockfile entries, add a Security bullet, open a PR). Now a workflow does it.Nightly Integration Tests(workflow_run) or by hand. A manual run is a dry run by default (prints the diff and the PR body, pushes nothing).npm audit --omit=dev --json(scripts/audit-remediate.mjs), runsnpm update --package-lock-onlyfor only those (nevernpm audit fix), and fails ifpackage.jsonchanges.### Securitybullets under[Unreleased](without creating a second heading) and opens one PR: intomainfirst (what ships;backmerge.ymlcarries it todevelop), thendevelopfor an advisory that only exists there.auto-release.ymlonly fires for Dependabot merges and this is not one, so a human merges (as a merge commit) and cuts the patch release by hand.dependabot/npm_and_yarn/security-fixes-*) is open; ordinary Dependabot version-update PRs do not block it.npm audit(registry unreachable) fails the run; it is never read as all-clear. Majors and unpatched advisories are reported in the log and left alone.RELEASE_TOKEN(a PR made withGITHUB_TOKENwould not trigger CI), the same secretbackmerge.ymlalready uses to push and rungh pr create.2.
backmerge.yml: fold duplicate###headings in[Unreleased]before the guardA hotfix on
mainthat adds### Securitymeetsdevelop's own### Securitythere;merge=unionkeeps both,changelog-guardrejects it, and the back-merge ends in a PR for a human to move the bullets (19 of the last 30 back-merges failed; #153 was one).scripts/changelog-fold-headings.mjsdoes that mechanical step: it merges same-named subsections inside[Unreleased]only (shipped sections are immutable), returns a clean file byte for byte, and the workflow commits the result separately. A failure of the fold is a warning; the guard and the PR fallback still apply.Verification (real tools, not only mocks)
check(v0.5.5, …)goes from 1 problem to 0.merge=uniondriver, the real guard and a local origin. Previous workflow:conflict=true, nothing pushed. New workflow: fold commit, guard passes, pushed, one### Securityheading holding both bullets.run:blocks executed underbash -ein a throwaway repo seeded with the lockfilemainhad before today's hand-made hotfixes, the real npm registry and realnpm audit(onlyghfaked). It found the same six packages,npm auditwent from 6 vulnerabilities to 0, lockfile entries changed: 8 (the six plus body-parser's owncontent-typeandiconv-lite, as in fix(deps): bump zod, body-parser, fast-uri, ip-address, qs to patched versions #152),package.jsonuntouched, one bot-authored commit, PR created againstmain.develop); registry unreachable (step fails, no PR).tests/automation/fixtures/npm-audit-vulnerable.jsonis that real audit output. 89 automation tests pass (was 60),npm run checkpasses (598 tests), the changelog guard passes against the realv1.0.0-alpha.1baseline tag,npm audit --omit=devreports 0.Not verified / needs your attention
workflow_runworkflows run from the default branch, soaudit-remediate.ymldoes nothing until this ships tomain. After the next release, run it once by hand from the Actions tab (it is a dry run by default) before relying on it.gh pr createand push withRELEASE_TOKENfrom this workflow are untested; only evidence is thatbackmerge.ymlalready does both with that token.npm update --package-lock-onlyshould behave the same but I did not run it there.Type of change
Checklist
npm testpasses locally (598 passed, 29 skipped);node --test tests/automation/*.node-test.mjs89 passednpx tsc --noEmitpasses locallyMerge as a merge commit, never squash or rebase.
Generated by Claude Code