From 50ca5ba0d2ddc9d1f36bd8bed0827f2b816450bf Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 29 Jul 2026 23:04:19 +0000 Subject: [PATCH 1/3] ci: remove stray pnpm-lock.yaml so central coverage evidence passes The central OpenCode review's coverage-evidence job materializes base JavaScript locks with scripts/ci/materialize_base_javascript_packages.py (in ContextualWisdomLab/.github), which hard-fails (exit 1) when a base pnpm-lock.yaml exists whose sibling package.json does not pin an exact `packageManager: pnpm@X.Y.Z`. That aborts every scopeweave PR's coverage evidence before any test runs. scopeweave is an npm project: .github/workflows/server-tests.yml and fuzz.yml use `cache: 'npm'` + `npm ci` + `npm run ...`, package-lock.json is the canonical lock, and no workflow, Dockerfile, or compose file references pnpm. The committed pnpm-lock.yaml is a vestigial second lockfile that only misleads the central materializer into pnpm mode. Removing it lets the central materializer report "no pnpm locks" and exit cleanly, then the coverage sandbox installs via the npm path (`npm ci --ignore-scripts` when package-lock.json is present). No central gate is weakened; this aligns the repo with its own documented and enforced npm toolchain and removes lockfile-drift risk between two competing lockfiles. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01SEAGtwNR96cia2djq7XFCo --- pnpm-lock.yaml | 91 -------------------------------------------------- 1 file changed, 91 deletions(-) delete mode 100644 pnpm-lock.yaml diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml deleted file mode 100644 index bffabf92..00000000 --- a/pnpm-lock.yaml +++ /dev/null @@ -1,91 +0,0 @@ -lockfileVersion: '9.0' - -settings: - autoInstallPeers: true - excludeLinksFromLockfile: false - -importers: - - .: - dependencies: - '@hono/node-server': - specifier: ^1.19.14 - version: 1.19.14(hono@4.12.28) - hono: - specifier: ^4.12.27 - version: 4.12.28 - devDependencies: - '@playwright/test': - specifier: 1.61.1 - version: 1.61.1 - fast-check: - specifier: 4.9.0 - version: 4.9.0 - -packages: - - '@hono/node-server@1.19.14': - resolution: {integrity: sha512-GwtvgtXxnWsucXvbQXkRgqksiH2Qed37H9xHZocE5sA3N8O8O8/8FA3uclQXxXVzc9XBZuEOMK7+r02FmSpHtw==} - engines: {node: '>=18.14.1'} - peerDependencies: - hono: ^4 - - '@playwright/test@1.61.1': - resolution: {integrity: sha512-8nKv6+0RJSL9FE4jYOEGXnPeM/Hg12qZpmqzZjRh3qM0Y7c3z1mrOTfFLids72RDQYVh9WpLEfR5WdpNX4fkig==} - engines: {node: '>=18'} - hasBin: true - - fast-check@4.9.0: - resolution: {integrity: sha512-7ms6T7SybUev/PQITciI0yLM2pOSFy5zpG8Ty7tQofcVaQUvrMXp6CBwqF6fThLCLOrfBtuHAtwq6Yu4XPCllg==} - engines: {node: '>=12.17.0'} - - fsevents@2.3.2: - resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} - engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} - os: [darwin] - - hono@4.12.28: - resolution: {integrity: sha512-YwUvVpSF7m1yOblFPrU3Hbo8XhPheBoiyfGuII6z19LnOr6JpDnyyp7LFNrfV56wS8tpvtBFGRISHN02pDdLOA==} - engines: {node: '>=16.9.0'} - - playwright-core@1.61.1: - resolution: {integrity: sha512-h7Qlt6m4REp25qvIdvbDtVmD4LqVXfpRxhORv9L0jzETM05p4fuPJ3dKyuSXQxDSbXnmS79HAgi9589lGSpLkg==} - engines: {node: '>=18'} - hasBin: true - - playwright@1.61.1: - resolution: {integrity: sha512-DWnY5o3YbLWK4GovuAVwpqL+1VwGNdUGrRr++8j8PtQQzvAVZUIMjKQ90fY689sEJZJBbZVw1rXaOKSTitkzPQ==} - engines: {node: '>=18'} - hasBin: true - - pure-rand@8.4.1: - resolution: {integrity: sha512-c58R2+SPFcSIPXoU834QN/KPDDOSd8sXcSrqf6e83Me6Rrp1EYkxukkjXMVrKvKaADs1SOyNkWdfvLf6zY8qLQ==} - -snapshots: - - '@hono/node-server@1.19.14(hono@4.12.28)': - dependencies: - hono: 4.12.28 - - '@playwright/test@1.61.1': - dependencies: - playwright: 1.61.1 - - fast-check@4.9.0: - dependencies: - pure-rand: 8.4.1 - - fsevents@2.3.2: - optional: true - - hono@4.12.28: {} - - playwright-core@1.61.1: {} - - playwright@1.61.1: - dependencies: - playwright-core: 1.61.1 - optionalDependencies: - fsevents: 2.3.2 - - pure-rand@8.4.1: {} From cab8d56b5046d9fd85a111db15182c1944adf5c0 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 29 Jul 2026 23:08:28 +0000 Subject: [PATCH 2/3] fix(deps): bump @hono/node-server to 2.x to remediate GHSA-frvp-7c67-39w9 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The central trivy-fs security gate reports a real MEDIUM finding (security-severity 5.9) on scopeweave: @hono/node-server 1.19.14 is affected by GHSA-frvp-7c67-39w9 (Windows path-traversal — an encoded backslash %5C in the request path decodes to `\`, which the Windows path resolver treats as a separator, letting an attacker bypass middleware and read static files that should be protected). The advisory's first patched release is 2.0.5. Bump the existing runtime dependency (not a new one — scopeweave's two-runtime- dependency contract is preserved) to ^2.0.12. @hono/node-server 2.x declares peerDependencies { hono: "^4" }, which scopeweave already satisfies (hono ^4.12.27), and scopeweave only uses the stable `serve({ fetch, port }, cb)` entry point, unchanged across the 1.x -> 2.x major. Verified locally on Node v22.22.2: - npm install -> found 0 vulnerabilities - npm run test:unit -> all pure-math suites pass - npm run test:api -> API smoke + rate-limit tests pass (boots the Hono app through @hono/node-server serve(), the exact 2.x-compatibility surface) Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01SEAGtwNR96cia2djq7XFCo --- package-lock.json | 10 +++++----- package.json | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/package-lock.json b/package-lock.json index 21575e82..7abe7165 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,7 +8,7 @@ "name": "scopeweave", "version": "1.0.0", "dependencies": { - "@hono/node-server": "^1.19.14", + "@hono/node-server": "^2.0.12", "hono": "^4.12.27" }, "devDependencies": { @@ -17,12 +17,12 @@ } }, "node_modules/@hono/node-server": { - "version": "1.19.14", - "resolved": "https://registry.npmjs.org/@hono/node-server/-/node-server-1.19.14.tgz", - "integrity": "sha512-GwtvgtXxnWsucXvbQXkRgqksiH2Qed37H9xHZocE5sA3N8O8O8/8FA3uclQXxXVzc9XBZuEOMK7+r02FmSpHtw==", + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/@hono/node-server/-/node-server-2.0.12.tgz", + "integrity": "sha512-eWpQYr67tqJLeaSUl0Q+TquuYfUdTibpOJlUMV2FfUP7+KqCC5TufnwnlXL6mobZBJbGAYRd7ZvEBDCbLInjhg==", "license": "MIT", "engines": { - "node": ">=18.14.1" + "node": ">=20" }, "peerDependencies": { "hono": "^4" diff --git a/package.json b/package.json index 9ae8b292..2f90e2a3 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,7 @@ "fuzz": "node --test tests/fuzz/*.mjs" }, "dependencies": { - "@hono/node-server": "^1.19.14", + "@hono/node-server": "^2.0.12", "hono": "^4.12.27" }, "devDependencies": { From de680cd002392f436362d129d6a64a1c0163ac90 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 29 Jul 2026 23:10:56 +0000 Subject: [PATCH 3/3] fix(sast): suppress verified false-positive ReDoS finding in MS Project parser MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The central Semgrep SAST gate blocks scopeweave PRs on a single WARNING-level finding: javascript.lang.security.audit.detect-non-literal-regexp at cloud-sync.js:743, inside parseMsProjectXml's `tag()` helper. This is a verified false positive. The non-literal RegExp argument `name` is only ever a hardcoded literal tag from this function ('UID', 'Name', 'OutlineLevel', 'PercentComplete', 'PredecessorUID', ...), never user input, so the compiled pattern is fixed. The captured body `[^<]*` is a single linear character-class star with no nested or overlapping quantifiers, so it cannot backtrack catastrophically even on adversarial XML `block` input — there is no ReDoS or regex-injection surface. Add a narrow, documented `nosemgrep` directive on the finding line (the gate is designed to honor suppressions: it filters SARIF results whose suppressions array is non-empty). No behavior change; the MS Project import tests (tests/unit/msproject.test.mjs) still pass. The gate is not weakened — only this one audited false positive is annotated, with the reasoning in-line. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01SEAGtwNR96cia2djq7XFCo --- cloud-sync.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/cloud-sync.js b/cloud-sync.js index 7e44932b..18d057a5 100644 --- a/cloud-sync.js +++ b/cloud-sync.js @@ -740,6 +740,13 @@ function openReportModal() { // hand-edited files ever matter. export function parseMsProjectXml(xml) { const tag = (block, name) => { + // False positive for the non-literal RegExp SAST rule: `name` is only ever + // a hardcoded literal tag from this function ('UID', 'Name', 'OutlineLevel', + // 'PercentComplete', ...), never user input, so the constructed pattern is + // fixed. The `[^<]*` body is a single linear character-class star (no + // nested/overlapping quantifiers), so it cannot backtrack catastrophically + // even on adversarial `block` input — no ReDoS or regex-injection surface. + // nosemgrep: javascript.lang.security.audit.detect-non-literal-regexp.detect-non-literal-regexp const m = block.match(new RegExp(`<${name}>([^<]*)`)); return m ? m[1].trim() : ''; };