Skip to content

feat: verifier v2 (APCA, ΔE2000, CVD, ANSI, wavelength scan, README tables) + tests + CI - #10

Merged
crypticpy merged 3 commits into
mainfrom
feat/verifier-v2
Aug 18, 2026
Merged

crypticpy merged 3 commits into
mainfrom
feat/verifier-v2

Conversation

@crypticpy

@crypticpy crypticpy commented Aug 18, 2026 •

Copy link
Copy Markdown
Owner

Summary

PR 2 of docs/plans/2026-08-18-audit-remediation.md. No palette changes; the generated themes are byte-identical.

  • Verifier v2 — new checks alongside the L* ladder / wavelength band / key parity: APCA Lc column + per-role floors (verify.apcaFloors override; Soft declares a scaled set), ΔE2000 on tight gaps, CVD (protan/deutan/tritan) pair table, ANSI pairwise ΔE2000, whole-theme dominant-wavelength scan. New perceptual checks are warnings (14 on the current palette — exactly what PR 3 retunes); severities live in a one-line POLICY map so PR 3 flips them to fail.
  • README tables are verifier-rendered between <!-- verify:<name>:start/end --> markers (ladder, syntax colours, brackets, contrast now WCAG and APCA, new ANSI table). --write-readme re-renders; the default run fails on drift.
  • Modules: scripts/lib/color.mjs (sRGB/Lab, WCAG, APCA 0.0.98G-4, CIEDE2000, Viénot CVD, λd), scripts/lib/build.mjs (generator rules extracted from build-themes.mjs, output unchanged), theme-roles.mjs, readme.mjs.
  • Tests (npm test, node:test, 26 cases): colour-math sanity, generator edge cases, determinism, committed-JSON freshness, $schema, v1.2.0 snapshot parity (PALETTE_CHANGED=1 skips), verifier smoke run.
  • CI: .github/workflows/ci.yml on Node 20/22 — npm ci → build → git diff --exit-code themes/ → verify → test → vsce package (artifact). Dependabot monthly. @vscode/vsce devDependency, npm run package.

Test plan

  • npm run check — 0 failures, 14 warnings (expected pre-retune)
  • npm test — 26/26
  • npx vsce ls still 12 files
  • CI green on this PR (first run of the workflow)

🤖 Generated with Claude Code

Summary by Sourcery

Strengthen palette quality assurance with perceptual verification, generated documentation, reusable validation modules, comprehensive tests, and CI packaging checks.

New Features:

  • Expand palette verification with APCA contrast floors, ΔE2000 perceptual-gap checks, color-vision-deficiency analysis, ANSI separation checks, whole-theme wavelength scanning, and configurable warning/failure policies.
  • Generate and validate verifier-owned README tables from the standard theme, including APCA contrast and ANSI palette data.
  • Add reusable color-analysis, theme-role, README-rendering, and theme-build modules.

Enhancements:

  • Preserve byte-identical generated themes while making generator rules reusable and directly testable.
  • Add safeguards for variant structure, token usage, output filenames, theme key parity, and README drift.

Build:

  • Add VSIX packaging support through the @vscode/vsce development dependency and npm package script.

CI:

  • Add GitHub Actions validation across Node.js 22 and 24 covering theme generation, committed-output freshness, verification, tests, and VSIX packaging.
  • Configure monthly Dependabot updates for npm and GitHub Actions dependencies.

Documentation:

  • Add verifier-owned README tables and document the expanded palette checks and maintenance workflow.
  • Record the verifier, testing, and CI changes in the unreleased changelog.

Tests:

  • Add 26 unit and pipeline tests covering color math, generator behavior, README rendering, determinism, generated-theme freshness, schema presence, snapshot parity, and verifier execution.

…ables) + tests + CI

- scripts/lib/color.mjs: sRGB/XYZ/Lab, WCAG, APCA 0.0.98G-4, CIEDE2000,
  Viénot CVD simulation, dominant wavelength — pure and unit-tested
- scripts/lib/build.mjs: generator substitution/validation extracted from
  build-themes.mjs (output byte-identical); build-themes.mjs is now a thin CLI
- scripts/lib/theme-roles.mjs, scripts/lib/readme.mjs: role extraction and
  marker-block/markdown-table helpers
- verify-palette.mjs: APCA column + per-role floors (verify.apcaFloors
  override; Soft declares a scaled set), ΔE2000 on tight gaps, CVD pair
  table, ANSI pairwise ΔE2000, whole-theme λd scan, README marker rendering
  with --write-readme; new perceptual checks are warnings via POLICY
- README: ladder / syntax / bracket / contrast (WCAG+APCA) / ANSI tables now
  verifier-rendered between <!-- verify:*:start/end --> markers
- tests/ (node --test): colour math, generator rules, determinism,
  committed-JSON freshness, $schema, v1.2.0 snapshot parity, verifier smoke
- .github/workflows/ci.yml (Node 20/22) + dependabot.yml; @vscode/vsce
  devDependency; npm test / npm run package; CHANGELOG [Unreleased]

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@sourcery-ai

sourcery-ai Bot commented Aug 18, 2026 •

Copy link
Copy Markdown

Reviewer's Guide

Introduces a v2 palette verifier with APCA, ΔE2000, CVD, ANSI, and wavelength scan checks; factors reusable color math and generator logic into testable libraries; wires README tables to be verifier-rendered; adds node:test coverage and a CI workflow that builds, verifies, tests, and packages the VSIX without changing the theme palette.

Sequence diagram for CI build-verify-test-package workflow

sequenceDiagram
  participant GHA as GitHubActions
  participant Node as setup-node
  participant NPM as npm
  participant VSCE as vsce

  GHA->>Node: actions/setup-node@v4 (matrix 20,22)
  GHA->>NPM: npm ci
  GHA->>NPM: npm run build:themes
  GHA->>GHA: git diff --exit-code -- themes/
  GHA->>NPM: npm run verify
  GHA->>NPM: npm test
  GHA->>VSCE: npx vsce package --out alone.vsix
  GHA->>GHA: upload-artifact alone.vsix (Node 22)
Loading

File-Level Changes

Change Details Files
Upgrade palette verifier to v2 with APCA, ΔE2000, CVD, ANSI, wavelength scan, and README-table checks, driven by a POLICY-based severity system.
  • Import reusable colour utilities (Lab, WCAG, APCA, ΔE2000, CVD simulation, dominant wavelength) and theme-role helpers into the verifier to replace inlined math and extraction logic.
  • Add a POLICY map and per-check counters, converting the verifier to a failure/warning model and emitting per-check tallies in the summary line.
  • Extend the L* ladder check to compute ΔE2000 for adjacent roles, flagging tight gaps when either L* or ΔE2000 is below configured thresholds.
  • Introduce APCA Lc floors per role class, configurable per variant via verify.apcaFloors, and report under-floor roles as findings.
  • Add colour-vision-deficiency pair checks using Viénot-based protan/deutan and a tritan simulation, with style-difference exemptions.
  • Add ANSI pairwise ΔE2000 checks over the eight normal ANSI slots with a minimum distance threshold.
  • Add per-variant wavelength band checks plus a whole-theme dominant-wavelength scan over all chromatic hexes, enforcing a minimum wavelength.
  • Add variant key-parity checks reusing shared role/key utilities and report detailed differences via findings().
  • Add README table verification and optional rewriting via --write-readme, using markdown helpers to render and replace marker-delimited blocks.
scripts/verify-palette.mjs
scripts/lib/color.mjs
scripts/lib/theme-roles.mjs
scripts/lib/readme.mjs
README.md
Factor generator token-resolution and variant-validation logic into a reusable build library and keep CLI output byte-identical.
  • Move token substitution, interpolation, and unused-token detection from build-themes.mjs into scripts/lib/build.mjs as pure functions (resolveValue, walk, buildTheme, serializeTheme).
  • Move variant-shape validation and output-path canonicalization into validateVariant(), including type diagnostics and path-escape protection.
  • Simplify scripts/build-themes.mjs to load YAML, call validateVariant/buildTheme/serializeTheme, and enforce cross-variant filename uniqueness using canonical resolved paths.
  • Retain JSON formatting (2-space indent, trailing newline) to keep generated themes byte-identical and compatible with existing snapshots.
scripts/build-themes.mjs
scripts/lib/build.mjs
Wire README documentation to the new verifier-rendered sections and describe updated tooling and CI behaviour.
  • Wrap the L* ladder, syntax colours, bracket list, contrast table, and new ANSI table in verify: marker comments and adjust prose to explain verifier ownership and APCA metrics.
  • Update numerical values in README tables to match verifier outputs (e.g., L* values, bracket L*, ANSI slots, APCA Lc column) and ensure formatting matches mdTable output.
  • Expand the tooling section to document npm run verify, npm run check, npm test, and the --write-readme workflow, and mention CI behaviour.
  • Add an Unreleased section to the changelog describing verifier v2, library extraction, tests, and CI configuration as internal changes without palette modifications.
README.md
CHANGELOG.md
Add node:test coverage for colour math, build rules, README helpers, the real pipeline, and the verifier.
  • Add colour.test.mjs to validate WCAG contrast, CIE L*, Lab/Lch behaviour, APCA Lc, ΔE2000, CVD simulation behaviour, dominant wavelength estimates, and basic hex helpers.
  • Add build.test.mjs to exercise resolveValue/walk token substitution, variant validation (shape, filename rules, containment), unused-token errors, and serialization format.
  • Add pipeline.test.mjs to run over the real _src tree, checking variant validation, deterministic builds, committed JSON freshness, $schema presence, snapshot parity (with PALETTE_CHANGED escape hatch), and a verifier smoke test.
  • Add readme.test.mjs to check mdTable formatting and the correctness of marker block rendering, discovery, and replacement, including error paths.
tests/color.test.mjs
tests/build.test.mjs
tests/pipeline.test.mjs
tests/readme.test.mjs
Introduce CI pipeline and packaging support that runs build, verification, tests, and packages the VSIX on Node 20 and 22.
  • Add a GitHub Actions workflow that runs npm ci, builds themes, enforces no uncommitted changes under themes/, runs the verifier and node:test suite, and packages a VSIX artifact via vsce on Node 20 and 22.
  • Configure the workflow matrix with fail-fast disabled and restrict permissions to read-only contents, uploading the VSIX artifact only from the Node 22 job.
  • Add Dependabot configuration for npm and GitHub Actions with monthly update cadence and a grouped dev-dependencies rule.
  • Add @vscode/vsce as a devDependency, define npm test (node --test tests/*.test.mjs), and npm run package (vsce package) scripts in package.json, updating package-lock.json accordingly.
.github/workflows/ci.yml
.github/dependabot.yml
package.json
package-lock.json
Adjust variant configuration for Alone Soft to support lowered APCA floors in line with its intentionally reduced contrast.
  • Extend the Alone Soft variant YAML verify block with apcaFloors that scale down the default APCA thresholds for body, syntax, special, punctuation, and comments.
  • Document the rationale inline in the YAML (Soft being ~0.7× contrast and targeting extreme dark adaptation) to guide future adjustments.
themes/_src/variants/alone-soft.yaml

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 10 security issues, 1 other issue, and left some high level feedback:

Security issues:

  • SEE LICENSE IN LICENSE.txt: Open-source license could not be identified (link)
  • SEE LICENSE IN LICENSE.txt: Open-source license could not be identified (link)
  • SEE LICENSE IN LICENSE.txt: Open-source license could not be identified (link)
  • SEE LICENSE IN LICENSE.txt: Open-source license could not be identified (link)
  • SEE LICENSE IN LICENSE.txt: Open-source license could not be identified (link)
  • SEE LICENSE IN LICENSE.txt: Open-source license could not be identified (link)
  • SEE LICENSE IN LICENSE.txt: Open-source license could not be identified (link)
  • SEE LICENSE IN LICENSE.txt: Open-source license could not be identified (link)
  • SEE LICENSE IN LICENSE.txt: Open-source license could not be identified (link)
  • SEE LICENSE IN LICENSE.txt: Open-source license could not be identified (link)

General comments:

  • scripts/verify-palette.mjs has grown quite large and multi-responsibility; consider splitting the individual checks (ladder/APCA/CVD/ANSI/wavelength/README) into separate modules or functions to keep the verifier easier to read and evolve.
  • The README prose still embeds hard-coded numeric descriptions of ladder gaps (e.g. specific L* deltas) that are not verifier-rendered, so these can silently drift from the new computed ladder; it may be worth either making this prose non-literal or having the verifier emit those numbers too.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- scripts/verify-palette.mjs has grown quite large and multi-responsibility; consider splitting the individual checks (ladder/APCA/CVD/ANSI/wavelength/README) into separate modules or functions to keep the verifier easier to read and evolve.
- The README prose still embeds hard-coded numeric descriptions of ladder gaps (e.g. specific L* deltas) that are not verifier-rendered, so these can silently drift from the new computed ladder; it may be worth either making this prose non-literal or having the verifier emit those numbers too.

## Individual Comments

### Comment 1
<location path="scripts/lib/color.mjs" line_range="238" />
<code_context>
+    // Solve W + t·d = P1 + u·(P2 − P1). t > 0 → same side as the colour.
+    const t = ((x1 - WHITE_XY[0]) * ey - (y1 - WHITE_XY[1]) * ex) / den;
+    const u = ((x1 - WHITE_XY[0]) * dy - (y1 - WHITE_XY[1]) * dx) / den;
+    if (t > 0 && u >= 0 && u <= 1) {
+      best = { lambda: l1 + u * (l2 - l1), purity: 1 / t };
+    }
</code_context>
<issue_to_address>
**suggestion (bug_risk):** `dominantWavelength` returns excitation purity as `1 / t` without clamping, which can exceed 1 for near-locus colours.

Here purity is computed as `1 / t`, so for points near the spectral locus (small `t`) this can exceed 1 even though excitation purity is conventionally in [0, 1]. Callers currently only use `lambda`, but this may confuse future users relying on purity. Please either clamp to 1 or document that this is an unbounded radial factor rather than textbook excitation purity.

Suggested implementation:

```javascript
    // Solve W + t·d = P1 + u·(P2 − P1). t > 0 → same side as the colour.
    const t = ((x1 - WHITE_XY[0]) * ey - (y1 - WHITE_XY[1]) * ex) / den;
    const u = ((x1 - WHITE_XY[0]) * dy - (y1 - WHITE_XY[1]) * dx) / den;
    if (t > 0 && u >= 0 && u <= 1) {
      // Clamp excitation purity to [0, 1] to match conventional definition.
      best = { lambda: l1 + u * (l2 - l1), purity: Math.min(1, 1 / t) };
    }

```

To implement the suggestion:
1. We keep the geometric meaning of `t` as the radial factor and continue using it to derive purity.
2. We clamp `1 / t` using `Math.min(1, 1 / t)` so that reported excitation purity is always in [0, 1], avoiding confusing values > 1 for near-locus colours.
3. A brief inline comment is added to clarify that this is textbook excitation purity and intentionally clamped.
</issue_to_address>

### Comment 2
<location path="package-lock.json" line_range="616-634" />
<code_context>

</code_context>
<issue_to_address>
**security (license/@vscode/vsce-sign):** SEE LICENSE IN LICENSE.txt: Open-source license could not be identified

The obligations of the `SEE LICENSE IN LICENSE.txt` license for this code could not be determined automatically. Unknown licenses may carry obligations or restrictions and should be reviewed manually to ensure compliance

*Source: trivy*
</issue_to_address>

### Comment 3
<location path="package-lock.json" line_range="635-648" />
<code_context>

</code_context>
<issue_to_address>
**security (license/@vscode/vsce-sign-alpine-arm64):** SEE LICENSE IN LICENSE.txt: Open-source license could not be identified

The obligations of the `SEE LICENSE IN LICENSE.txt` license for this code could not be determined automatically. Unknown licenses may carry obligations or restrictions and should be reviewed manually to ensure compliance

*Source: trivy*
</issue_to_address>

### Comment 4
<location path="package-lock.json" line_range="649-662" />
<code_context>

</code_context>
<issue_to_address>
**security (license/@vscode/vsce-sign-alpine-x64):** SEE LICENSE IN LICENSE.txt: Open-source license could not be identified

The obligations of the `SEE LICENSE IN LICENSE.txt` license for this code could not be determined automatically. Unknown licenses may carry obligations or restrictions and should be reviewed manually to ensure compliance

*Source: trivy*
</issue_to_address>

### Comment 5
<location path="package-lock.json" line_range="663-676" />
<code_context>

</code_context>
<issue_to_address>
**security (license/@vscode/vsce-sign-darwin-arm64):** SEE LICENSE IN LICENSE.txt: Open-source license could not be identified

The obligations of the `SEE LICENSE IN LICENSE.txt` license for this code could not be determined automatically. Unknown licenses may carry obligations or restrictions and should be reviewed manually to ensure compliance

*Source: trivy*
</issue_to_address>

### Comment 6
<location path="package-lock.json" line_range="677-690" />
<code_context>

</code_context>
<issue_to_address>
**security (license/@vscode/vsce-sign-darwin-x64):** SEE LICENSE IN LICENSE.txt: Open-source license could not be identified

The obligations of the `SEE LICENSE IN LICENSE.txt` license for this code could not be determined automatically. Unknown licenses may carry obligations or restrictions and should be reviewed manually to ensure compliance

*Source: trivy*
</issue_to_address>

### Comment 7
<location path="package-lock.json" line_range="691-704" />
<code_context>

</code_context>
<issue_to_address>
**security (license/@vscode/vsce-sign-linux-arm):** SEE LICENSE IN LICENSE.txt: Open-source license could not be identified

The obligations of the `SEE LICENSE IN LICENSE.txt` license for this code could not be determined automatically. Unknown licenses may carry obligations or restrictions and should be reviewed manually to ensure compliance

*Source: trivy*
</issue_to_address>

### Comment 8
<location path="package-lock.json" line_range="705-718" />
<code_context>

</code_context>
<issue_to_address>
**security (license/@vscode/vsce-sign-linux-arm64):** SEE LICENSE IN LICENSE.txt: Open-source license could not be identified

The obligations of the `SEE LICENSE IN LICENSE.txt` license for this code could not be determined automatically. Unknown licenses may carry obligations or restrictions and should be reviewed manually to ensure compliance

*Source: trivy*
</issue_to_address>

### Comment 9
<location path="package-lock.json" line_range="719-732" />
<code_context>

</code_context>
<issue_to_address>
**security (license/@vscode/vsce-sign-linux-x64):** SEE LICENSE IN LICENSE.txt: Open-source license could not be identified

The obligations of the `SEE LICENSE IN LICENSE.txt` license for this code could not be determined automatically. Unknown licenses may carry obligations or restrictions and should be reviewed manually to ensure compliance

*Source: trivy*
</issue_to_address>

### Comment 10
<location path="package-lock.json" line_range="733-746" />
<code_context>

</code_context>
<issue_to_address>
**security (license/@vscode/vsce-sign-win32-arm64):** SEE LICENSE IN LICENSE.txt: Open-source license could not be identified

The obligations of the `SEE LICENSE IN LICENSE.txt` license for this code could not be determined automatically. Unknown licenses may carry obligations or restrictions and should be reviewed manually to ensure compliance

*Source: trivy*
</issue_to_address>

### Comment 11
<location path="package-lock.json" line_range="747-760" />
<code_context>

</code_context>
<issue_to_address>
**security (license/@vscode/vsce-sign-win32-x64):** SEE LICENSE IN LICENSE.txt: Open-source license could not be identified

The obligations of the `SEE LICENSE IN LICENSE.txt` license for this code could not be determined automatically. Unknown licenses may carry obligations or restrictions and should be reviewed manually to ensure compliance

*Source: trivy*
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread scripts/lib/color.mjs
Comment thread package-lock.json
Comment on lines +616 to +634
"node_modules/@vscode/vsce-sign": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/@vscode/vsce-sign/-/vsce-sign-2.1.0.tgz",
"integrity": "sha512-9AQrqazrBgTgRSuwleLVXUrIUphY02/SFCh2TKYoLV/xifJAdblhdmEmw5gUrYSPQ3sRwNs9iyCMD14sATEE6g==",
"dev": true,
"hasInstallScript": true,
"license": "SEE LICENSE IN LICENSE.txt",
"optionalDependencies": {
"@vscode/vsce-sign-alpine-arm64": "2.0.6",
"@vscode/vsce-sign-alpine-x64": "2.0.6",
"@vscode/vsce-sign-darwin-arm64": "2.0.6",
"@vscode/vsce-sign-darwin-x64": "2.0.6",
"@vscode/vsce-sign-linux-arm": "2.0.6",
"@vscode/vsce-sign-linux-arm64": "2.0.6",
"@vscode/vsce-sign-linux-x64": "2.0.6",
"@vscode/vsce-sign-win32-arm64": "2.0.6",
"@vscode/vsce-sign-win32-x64": "2.0.6"
}
},

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

security (license/@vscode/vsce-sign): SEE LICENSE IN LICENSE.txt: Open-source license could not be identified

The obligations of the SEE LICENSE IN LICENSE.txt license for this code could not be determined automatically. Unknown licenses may carry obligations or restrictions and should be reviewed manually to ensure compliance

Source: trivy

Comment thread package-lock.json
Comment on lines +635 to +648
"node_modules/@vscode/vsce-sign-alpine-arm64": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/@vscode/vsce-sign-alpine-arm64/-/vsce-sign-alpine-arm64-2.0.6.tgz",
"integrity": "sha512-wKkJBsvKF+f0GfsUuGT0tSW0kZL87QggEiqNqK6/8hvqsXvpx8OsTEc3mnE1kejkh5r+qUyQ7PtF8jZYN0mo8Q==",
"cpu": [
"arm64"
],
"dev": true,
"license": "SEE LICENSE IN LICENSE.txt",
"optional": true,
"os": [
"alpine"
]
},

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

security (license/@vscode/vsce-sign-alpine-arm64): SEE LICENSE IN LICENSE.txt: Open-source license could not be identified

The obligations of the SEE LICENSE IN LICENSE.txt license for this code could not be determined automatically. Unknown licenses may carry obligations or restrictions and should be reviewed manually to ensure compliance

Source: trivy

Comment thread package-lock.json
Comment on lines +649 to +662
"node_modules/@vscode/vsce-sign-alpine-x64": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/@vscode/vsce-sign-alpine-x64/-/vsce-sign-alpine-x64-2.0.6.tgz",
"integrity": "sha512-YoAGlmdK39vKi9jA18i4ufBbd95OqGJxRvF3n6ZbCyziwy3O+JgOpIUPxv5tjeO6gQfx29qBivQ8ZZTUF2Ba0w==",
"cpu": [
"x64"
],
"dev": true,
"license": "SEE LICENSE IN LICENSE.txt",
"optional": true,
"os": [
"alpine"
]
},

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

security (license/@vscode/vsce-sign-alpine-x64): SEE LICENSE IN LICENSE.txt: Open-source license could not be identified

The obligations of the SEE LICENSE IN LICENSE.txt license for this code could not be determined automatically. Unknown licenses may carry obligations or restrictions and should be reviewed manually to ensure compliance

Source: trivy

Comment thread package-lock.json
Comment on lines +663 to +676
"node_modules/@vscode/vsce-sign-darwin-arm64": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/@vscode/vsce-sign-darwin-arm64/-/vsce-sign-darwin-arm64-2.0.6.tgz",
"integrity": "sha512-5HMHaJRIQuozm/XQIiJiA0W9uhdblwwl2ZNDSSAeXGO9YhB9MH5C4KIHOmvyjUnKy4UCuiP43VKpIxW1VWP4tQ==",
"cpu": [
"arm64"
],
"dev": true,
"license": "SEE LICENSE IN LICENSE.txt",
"optional": true,
"os": [
"darwin"
]
},

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

security (license/@vscode/vsce-sign-darwin-arm64): SEE LICENSE IN LICENSE.txt: Open-source license could not be identified

The obligations of the SEE LICENSE IN LICENSE.txt license for this code could not be determined automatically. Unknown licenses may carry obligations or restrictions and should be reviewed manually to ensure compliance

Source: trivy

Comment thread package-lock.json
Comment on lines +691 to +704
"node_modules/@vscode/vsce-sign-linux-arm": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/@vscode/vsce-sign-linux-arm/-/vsce-sign-linux-arm-2.0.6.tgz",
"integrity": "sha512-UndEc2Xlq4HsuMPnwu7420uqceXjs4yb5W8E2/UkaHBB9OWCwMd3/bRe/1eLe3D8kPpxzcaeTyXiK3RdzS/1CA==",
"cpu": [
"arm"
],
"dev": true,
"license": "SEE LICENSE IN LICENSE.txt",
"optional": true,
"os": [
"linux"
]
},

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

security (license/@vscode/vsce-sign-linux-arm): SEE LICENSE IN LICENSE.txt: Open-source license could not be identified

The obligations of the SEE LICENSE IN LICENSE.txt license for this code could not be determined automatically. Unknown licenses may carry obligations or restrictions and should be reviewed manually to ensure compliance

Source: trivy

Comment thread package-lock.json
Comment on lines +705 to +718
"node_modules/@vscode/vsce-sign-linux-arm64": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/@vscode/vsce-sign-linux-arm64/-/vsce-sign-linux-arm64-2.0.6.tgz",
"integrity": "sha512-cfb1qK7lygtMa4NUl2582nP7aliLYuDEVpAbXJMkDq1qE+olIw/es+C8j1LJwvcRq1I2yWGtSn3EkDp9Dq5FdA==",
"cpu": [
"arm64"
],
"dev": true,
"license": "SEE LICENSE IN LICENSE.txt",
"optional": true,
"os": [
"linux"
]
},

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

security (license/@vscode/vsce-sign-linux-arm64): SEE LICENSE IN LICENSE.txt: Open-source license could not be identified

The obligations of the SEE LICENSE IN LICENSE.txt license for this code could not be determined automatically. Unknown licenses may carry obligations or restrictions and should be reviewed manually to ensure compliance

Source: trivy

Comment thread package-lock.json
Comment on lines +719 to +732
"node_modules/@vscode/vsce-sign-linux-x64": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/@vscode/vsce-sign-linux-x64/-/vsce-sign-linux-x64-2.0.6.tgz",
"integrity": "sha512-/olerl1A4sOqdP+hjvJ1sbQjKN07Y3DVnxO4gnbn/ahtQvFrdhUi0G1VsZXDNjfqmXw57DmPi5ASnj/8PGZhAA==",
"cpu": [
"x64"
],
"dev": true,
"license": "SEE LICENSE IN LICENSE.txt",
"optional": true,
"os": [
"linux"
]
},

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

security (license/@vscode/vsce-sign-linux-x64): SEE LICENSE IN LICENSE.txt: Open-source license could not be identified

The obligations of the SEE LICENSE IN LICENSE.txt license for this code could not be determined automatically. Unknown licenses may carry obligations or restrictions and should be reviewed manually to ensure compliance

Source: trivy

Comment thread package-lock.json
Comment on lines +733 to +746
"node_modules/@vscode/vsce-sign-win32-arm64": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/@vscode/vsce-sign-win32-arm64/-/vsce-sign-win32-arm64-2.0.6.tgz",
"integrity": "sha512-ivM/MiGIY0PJNZBoGtlRBM/xDpwbdlCWomUWuLmIxbi1Cxe/1nooYrEQoaHD8ojVRgzdQEUzMsRbyF5cJJgYOg==",
"cpu": [
"arm64"
],
"dev": true,
"license": "SEE LICENSE IN LICENSE.txt",
"optional": true,
"os": [
"win32"
]
},

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

security (license/@vscode/vsce-sign-win32-arm64): SEE LICENSE IN LICENSE.txt: Open-source license could not be identified

The obligations of the SEE LICENSE IN LICENSE.txt license for this code could not be determined automatically. Unknown licenses may carry obligations or restrictions and should be reviewed manually to ensure compliance

Source: trivy

Comment thread package-lock.json
Comment on lines +747 to +760
"node_modules/@vscode/vsce-sign-win32-x64": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/@vscode/vsce-sign-win32-x64/-/vsce-sign-win32-x64-2.0.6.tgz",
"integrity": "sha512-mgth9Kvze+u8CruYMmhHw6Zgy3GRX2S+Ed5oSokDEK5vPEwGGKnmuXua9tmFhomeAnhgJnL4DCna3TiNuGrBTQ==",
"cpu": [
"x64"
],
"dev": true,
"license": "SEE LICENSE IN LICENSE.txt",
"optional": true,
"os": [
"win32"
]
},

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

security (license/@vscode/vsce-sign-win32-x64): SEE LICENSE IN LICENSE.txt: Open-source license could not be identified

The obligations of the SEE LICENSE IN LICENSE.txt license for this code could not be determined automatically. Unknown licenses may carry obligations or restrictions and should be reviewed manually to ensure compliance

Source: trivy

Addresses sourcery-ai review on PR #10.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b7065e5ce6

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread .github/workflows/ci.yml Outdated
strategy:
fail-fast: false
matrix:
node: [20, 22]

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Use a supported Node version for the packaging job

The Node 20 matrix leg installs and runs the newly locked VSCE dependency tree, but that tree includes multiple packages declaring Node >=22.0.0—for example @azure/abort-controller and @typespec/ts-http-runtime in package-lock.json lines 36–47 and 555–567. Consequently, this leg fails at npm ci wherever engine enforcement is enabled and otherwise packages with an unsupported runtime; pin Node-20-compatible transitive dependencies or run packaging only on Node 22.

Useful? React with 👍 / 👎.

@crypticpy

Copy link
Copy Markdown
Owner Author

Re the ten license/@vscode/vsce-sign* flags: those are transitive optional deps of @vscode/vsce (Microsoft's VSIX signing binaries, one per platform). They are devDependencies only — used by npm run package and CI, never shipped in the VSIX (.vscodeignore excludes node_modules/**; vsce ls shows 12 files, none from node_modules). Their LICENSE.txt is Microsoft's standard binary EULA for the signing tool. Leaving as-is.

@vscode/vsce's transitive tree declares engines >=22 (@azure/abort-controller,
@typespec/ts-http-runtime); Node 20 is past EOL. Addresses Codex review on
PR #10.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@crypticpy

Copy link
Copy Markdown
Owner Author

Re Sourcery review 4957732175 general comments:

  • Splitting verify-palette.mjs: the colour math, role tables and README rendering are already in scripts/lib/{color,theme-roles,readme}.mjs; the remaining 430 lines are the seven check bodies + reporting. Leaving as one file for this PR — will split per-check into scripts/lib/checks/ when the next variant (Roman, PR 5) adds its own checks and pushes it past ~500 lines.
  • Hard-coded ladder-gap numbers in README prose: agreed it can drift. The 2.0.0 palette PR (next up, branched from this one) makes that paragraph non-literal — the exact per-rung L* and gaps live only in the verifier-rendered ladder block, which the default run hard-fails on if stale.

The purity clamp is in 3ef146a; the Node 20 → 22/24 matrix change (Codex) is in 2d2baab.

@crypticpy
crypticpy merged commit f99062d into main Aug 18, 2026
2 of 3 checks passed
crypticpy added a commit that referenced this pull request Aug 18, 2026
… verifier hard-fail (#14)

* feat(palette): 2.0.0 retune — neutrals, comments, ANSI, accents, CVD

- Neutrals shifted at constant L* to drop residual blue-subpixel drive
  (fg #C4B8A4→#C8B89A, ops #D4C8B8→#D8C8A8, bright #E8DCD0→#EDDCC4, …).
- Comments #5C544A→#6E665B (Lc 16→23), doc comments →#787062,
  line numbers →#56504A; Soft comments →#625A50.
- Ghost text fg #6B635A + translucent bg (new tokenized
  editorGhostText.background).
- Badge/remote fills #D4A048→#A87C34; defaultLibrary/this #B89860→#B08C50.
- Numbers #E0A850→#DEA64E (Variables→Numbers gap ≥ 3 L*).
- Parameters #BCA890→#B8AA9C (CVD vs Variables 4.7→6.6);
  Soft Functions #9A6D53→#976D56.
- ANSI blue #9C948E, cyan #C08868, brightBlue #B2AAA3, brightCyan
  #CEA284 (normal-8 pairwise ΔE2000 ≥ 10); terminal/* mirrored.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* chore: verifier hard-fail policy, structural snapshot test, docs, v2.0.0

- POLICY: every check now `fail` (tightGap/apca/cvd/ansi/wavelengthScan).
- pipeline test checks v1.2.0 snapshot structure (keys, rules, scopes,
  fontStyles) instead of hex equality; PALETTE_CHANGED gate removed.
- README verifier blocks re-rendered; ladder/terminal prose updated.
- CHANGELOG [2.0.0]; version bump.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* docs: make ladder prose non-literal (numbers live in the verifier-rendered block)

Addresses Sourcery general comment on PR #10.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* test: make snapshot check order-insensitive and additions-tolerant (Sourcery on PR #14)

Compare the v1.2.0 snapshot by name-keyed rule signatures and colour-key
membership instead of sorted-array deepEqual, so rule reordering and new
VS Code colour keys/rules/selectors don't fail the test while drops and
restyles still do.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* test: compare semantic-token style flags, not fontStyle (Codex on PR #14)

semanticTokenColors entries carry italic/bold/underline/strikethrough as
booleans, so the previous fontStyle read was always null and the style
comparison was vacuous.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant