@blamejs/core 0.8.72 → 0.8.76

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -8,6 +8,10 @@ upgrading across more than a few patches at a time.
8
8
 
9
9
  ## v0.8.x
10
10
 
11
+ - v0.8.76 (2026-05-10) — CI green-up for v0.8.75. The OSV-Scanner v2 binary refuses to parse SBOMs whose filename doesn't match the CycloneDX recognized-pattern spec — `sbom.cyclonedx.json` is NOT recognized; only `bom.json` / `*.cdx.json` / `*.spdx.json` etc. are. v0.8.75's npm-publish workflow failed with `Failed to parse SBOM "sbom.cyclonedx.json": Invalid SBOM filename`. Renamed the artifact to `sbom.cdx.json` everywhere (workflow generation step, post-process script, OSV scan target, cosign sign target, GH release asset upload, `package.json` `files` array, `scripts/check-pack-against-gitignore.js` allowlist, `.gitignore` allowlist). No primitive surface change versus v0.8.75; published-tarball asset filename changes from `sbom.cyclonedx.json` to `sbom.cdx.json` (consumers reading the SBOM out of the install tree should update the path).
12
+ - v0.8.75 (2026-05-10) — CI green-up for v0.8.73 + v0.8.74. The OSV-Scanner action's v2.3.5 binary removed the `--fail-on-vuln=<severity>` flag; passing it now errors with `flag provided but not defined: -fail-on-vuln` and the entire npm-publish workflow exits 1 before `npm publish` ever runs. v0.8.73 + v0.8.74's npm-publish workflows both failed for this reason (Dependabot bumped osv-scanner-action 2.0.2 → 2.3.5 in PR #8 alongside the v2 flag removal; the workflow was never re-tested under the new binary). v2's default behavior is exit-1-on-ANY-finding — stricter than the v1 `--fail-on-vuln=HIGH` floor, and appropriate for a zero-npm-runtime-dep framework where any surfaced vuln means a vendor refresh is overdue. The framework currently has no findings, so the stricter floor is a no-op at HEAD. No primitive surface change versus v0.8.74.
13
+ - v0.8.74 (2026-05-10) — line-ending fix for shell scripts that run inside Linux containers. The OSS-Fuzz + ClusterFuzzLite `build.sh`, the wiki + release Dockerfile init scripts, the Postgres + Mongo TLS bootstrap scripts, and the vendor-update + dep-confusion-placeholder scripts all execute inside bash inside a Linux container; under a Windows checkout with `core.autocrlf=true` git rewrites them to CRLF on checkout and bash then chokes with `$'\r': command not found` at line 1. Locally reproduced the OSS-Fuzz upstream submission failure (zero artifacts compiled, every `compile_javascript_fuzzer` call failed silently on the CRLF). `.gitattributes` gains an explicit `*.sh text eol=lf` override so every `.sh` checks out LF regardless of platform; existing tracked scripts re-normalized (CRLF stripped) in the same commit. Verified end-to-end: `docker run … gcr.io/oss-fuzz-base/base-builder-javascript bash /src/build.sh` now compiles all 15 fuzz harnesses + zips their seed corpora cleanly. Unblocks the OSS-Fuzz upstream submission.
14
+ - v0.8.73 (2026-05-10) — ClusterFuzzLite + OSS-Fuzz integration replaces the hand-rolled fuzz harness. Every `fuzz/*.fuzz.js` is now a jazzer.js / libFuzzer entry-point (`module.exports.fuzz = function (data) { ... }`) so the engine drives the target with coverage-guided mutation instead of random bytes. Same 15 targets shipped in v0.8.72 (`b.safeJson.parse`, `b.safeUrl.parse`, `b.safeJsonPath.validateExpression`, the seven `b.guardX` surfaces, `b.guardEmail.validateMessage`, the four `b.parsers.X.parse` parsers); each gets a `fuzz/<name>_seed_corpus/` directory with realistic bootstrap inputs that libFuzzer mutates from. The shared `_expected.js` classifies operator-friendly framework throws (codes matching `<domain>/<error>` or `<domain>.<error>` shape; node-builtin error subclasses with input-shape messaging) as expected outcomes; anything else escapes as a finding the engine records + minimizes into a regression-corpus entry. **ClusterFuzzLite (local, free)**: `.clusterfuzzlite/Dockerfile` + `build.sh` + `project.yaml` ride alongside the framework source. Two GH Actions workflows wire it in — `cflite_pr.yml` runs 300s of coverage-guided fuzzing per target on every PR touching `lib/` or `fuzz/`; `cflite_batch.yml` runs the deeper 1800s batch + 600s coverage measurement on a daily 05:17 UTC schedule. Findings surface as PR annotations + SARIF in the Security tab. **OSS-Fuzz (upstream, continuous on Google's infrastructure)**: `oss-fuzz/projects/blamejs/{Dockerfile,build.sh,project.yaml,README.md}` is the submission-ready project config that gets copy-pasted into `projects/blamejs/` in the `google/oss-fuzz` upstream repo. Once accepted, ClusterFuzz fuzzes 24/7 on Google Cloud with permanent corpus persistence, stack-trace dedup, automatic regression testing against every commit, and a public coverage dashboard. The OSS-Fuzz `build.sh` mirrors `.clusterfuzzlite/build.sh` byte-for-byte (modulo comment block) so findings reproduce identically locally. **Coverage gate**: `testParserPrimitivesHaveFuzzHarness` in `test/layer-0-primitives/codebase-patterns.test.js` now verifies the jazzer.js shape (`module.exports.fuzz = ...`) in addition to the missing-harness check — a future parser primitive lands either with a coverage-guided harness or an audited `FUZZ_NOT_REQUIRED` entry. `npm run fuzz` switched to invoke jazzer.js for one-target local dev (`npx @jazzer.js/core fuzz/safe-json.fuzz.js -- -max_total_time=60`); the previous `fuzz/_runner.js` + `fuzz/_run-all.js` random-fuzzer + the standalone `.github/workflows/fuzz.yml` are removed. SECURITY.md threat-model + operator-checklist updated with the new dual-pipeline posture.
11
15
  - v0.8.72 (2026-05-10) — fuzz harness against the parser / validator surface + smoke-time fuzz-coverage gate. New `fuzz/` directory ships hand-rolled fuzz harnesses against the 11 highest-value adversarial-input primitives — `b.safeJson.parse`, `b.safeUrl.parse`, `b.safeJsonPath.validateExpression`, `b.guardCsv.validate`, `b.guardHtml.validate`, `b.guardJson.parse`, `b.guardYaml.parse`, `b.guardXml.validate`, `b.guardSvg.validate`, `b.guardMarkdown.validate`, `b.guardEmail.validateMessage`. Each harness generates random / mutated / bidi-salted / control-char-salted inputs against a per-target seed corpus, runs until `FUZZ_BUDGET_MS` elapses (default 30s; CI: 60s on PR / 300s on schedule), and fails with a reproducer when the target throws an unexpected error (vs. an operator-friendly framework error code in the documented `domain/error` or `domain.error` shape). Native `TypeError` with input-shape messaging, `SyntaxError`, and `RangeError` matching the depth/length/cap contract are accepted; everything else is a finding. New `.github/workflows/fuzz.yml` runs the harness in matrix on every PR touching `lib/` or `fuzz/` and on a daily 05:17 UTC schedule. New Layer 0 detector `testParserPrimitivesHaveFuzzHarness` in `test/layer-0-primitives/codebase-patterns.test.js` enforces that every `lib/safe-*.js` and `lib/guard-*.js` file has a corresponding `fuzz/<name>.fuzz.js` OR an explicit `FUZZ_NOT_REQUIRED` allowlist entry with reason — so a future parser primitive can't silently ship without fuzz coverage. `npm run fuzz` runs every harness sequentially via `fuzz/_run-all.js` for local dev. README OpenSSF Scorecard badge URL fixed (`api.scorecards.dev` → `api.scorecard.dev` — plural-singular typo).
12
16
  - v0.8.71 (2026-05-10) — CI green-up for v0.8.70. The v0.8.70 npm-publish workflow's cosign-sign-blob step couldn't resolve `sigstore/cosign-installer@d7d6e07b3e89342f1d8bcd4f76c2fa5a9d1a1f7e` — the SHA was a typo, not a real commit on the action's repo. Replaced with the actual v3.7.0 commit SHA `dc72c7d5c4d10cd6bcb8cf6e3fd625a9e5e537da`. No primitive surface change versus v0.8.70.
13
17
  - v0.8.70 (2026-05-10) — six-batch additive surface across OAuth/OIDC, FAPI 2.0, browser hardening, MCP safety, compliance postures, and supply-chain. **OAuth/OIDC**: `b.auth.oauth.parseCallback(query, opts?)` validates RFC 9207 AS Issuer Identifier (refuses iss-mismatch and OP `error=` redirects, optional `requireIssParam` to refuse missing iss), `parseJarmResponse(jwt, opts?)` decodes OAuth 2.0 JARM signed authorization responses, and `refreshAccessToken(token, { seen })` accepts an operator-supplied callback that refuses replayed refresh tokens before any HTTP call (RFC 9700 §4.13 / OAuth 2.1 §6.1 one-time-use rotation; returns `refreshTokenRotated: true` on success). **FAPI 2.0 runtime**: `b.fapi2.assertCallback(query)` refuses missing iss when `fapi-2.0` posture is set (and refuses bare-param when `fapi-2.0-message-signing` is set, requiring JARM `response`); `b.fapi2.assertAuthzRequest(authzParams)` refuses non-JAR (bare-param) authorization requests under FAPI 2.0. New `fapi-2.0-message-signing` posture registered. **Browser hardening**: `Permissions-Policy` defaults extend with `storage-access=()`, `browsing-topics=()`, `private-aggregation=()`, `controlled-frame=()`, `captured-surface-control=()`; `b.middleware.cors` gains `allowPrivateNetwork` opt + Private Network Access preflight handling (refuses `Access-Control-Request-Private-Network` by default, sets `Access-Control-Allow-Private-Network: true` when opted in); `b.middleware.requireAuth` / `requireAal` / `requireStepUp` 401 responses now set `Cache-Control: no-store` (RFC 9111 §5.2.2.5). **MCP safety + LLM07/08**: `b.mcp.toolResult.sanitize(result, opts?)` runs prompt-injection regex + dangerous-HTML detection + URL-allowlist on tool outputs (modes `refuse` / `sanitize` / `audit-only`); `b.mcp.capability.create(scopes)` + `satisfiedBy(granted)` formalize least-privilege capability checks; `b.mcp.validateToolInput(toolName, input, schema)` enforces a JSON Schema 2020-12 subset on tool inputs (`type` / `properties` / `required` / `items` / `enum` / `const` / `minLength` / `maxLength` / `minimum` / `maximum`). **Compliance postures**: `modpa` (Maryland Online Data Privacy Act, US-MD privacy), `nydfs-500` (NY DFS Cybersecurity Regulation, US-NY financial), `hipaa-2026` (HHS Final Rule effective 2026, US health), `quebec-25` (Quebec Law 25, CA-QC privacy), and `fapi-2.0-message-signing` (INTL financial). **EU Data Act** (Regulation 2023/2854): new `b.dataAct` primitive — `declareProduct`, `recordUserAccess`, `shareWithThirdParty` (Art 32 §1 refuses sharing with DMA designated gatekeepers without an audited override `acceptGatekeeper.reason`), `recordSwitchRequest` (Art 28 §3 caps notice period at 30 days). **Supply chain**: SBOM bumped to CycloneDX 1.6; npm-publish workflow now runs OSV-Scanner with `--fail-on-vuln=HIGH`, signs the SBOM via Sigstore cosign keyless flow (attaches `.sigstore` bundle to the GH release alongside the JSON); `scripts/publish-dep-confusion-placeholder.sh` claims unscoped names (`blamejs`, `blame-js`, `blamejs-core`) on npm with placeholder packages that exit-1 + redirect to canonical `@blamejs/core` (defends against dependency-confusion typosquats — manual, run on maintainer rotation, refuses overwrite when a different owner already holds the name).
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blamejs/core",
3
- "version": "0.8.72",
3
+ "version": "0.8.76",
4
4
  "description": "The Node framework that owns its stack.",
5
5
  "license": "Apache-2.0",
6
6
  "author": "blamejs contributors",
@@ -66,11 +66,11 @@
66
66
  "MIGRATING.md",
67
67
  "NOTICE",
68
68
  "README.md",
69
- "sbom.cyclonedx.json"
69
+ "sbom.cdx.json"
70
70
  ],
71
71
  "scripts": {
72
72
  "test": "node test/smoke.js",
73
- "fuzz": "node fuzz/_run-all.js",
73
+ "fuzz": "npx --yes @jazzer.js/core fuzz/safe-json.fuzz.js -- -max_total_time=60",
74
74
  "prepack": "node scripts/check-pack-against-gitignore.js",
75
75
  "check:vendor-currency": "node scripts/check-vendor-currency.js"
76
76
  },
@@ -2,10 +2,10 @@
2
2
  "$schema": "http://cyclonedx.org/schema/bom-1.5.schema.json",
3
3
  "bomFormat": "CycloneDX",
4
4
  "specVersion": "1.6",
5
- "serialNumber": "urn:uuid:2ace0ce8-c004-4329-8eed-0ae3c1fb02a6",
5
+ "serialNumber": "urn:uuid:1ec92bb5-ba8c-4adc-90d9-1b3cd5217c8b",
6
6
  "version": 1,
7
7
  "metadata": {
8
- "timestamp": "2026-05-10T19:52:07.485Z",
8
+ "timestamp": "2026-05-11T00:41:22.952Z",
9
9
  "lifecycles": [
10
10
  {
11
11
  "phase": "build"
@@ -19,14 +19,14 @@
19
19
  }
20
20
  ],
21
21
  "component": {
22
- "bom-ref": "@blamejs/core@0.8.72",
22
+ "bom-ref": "@blamejs/core@0.8.76",
23
23
  "type": "library",
24
24
  "name": "blamejs",
25
- "version": "0.8.72",
25
+ "version": "0.8.76",
26
26
  "scope": "required",
27
27
  "author": "blamejs contributors",
28
28
  "description": "The Node framework that owns its stack.",
29
- "purl": "pkg:npm/%40blamejs/core@0.8.72",
29
+ "purl": "pkg:npm/%40blamejs/core@0.8.76",
30
30
  "properties": [],
31
31
  "externalReferences": [
32
32
  {
@@ -54,7 +54,7 @@
54
54
  "components": [],
55
55
  "dependencies": [
56
56
  {
57
- "ref": "@blamejs/core@0.8.72",
57
+ "ref": "@blamejs/core@0.8.76",
58
58
  "dependsOn": []
59
59
  }
60
60
  ]