mirror of
https://github.com/pbakaus/impeccable.git
synced 2026-09-19 17:46:36 +03:00
Open the detector: the rule crates join the workspace, the C-ABI goes away
The detector is open source. The rules it ships were already public in this repo's git history and in every npm tarball of the JS engine, so a closed binary bought nothing it could keep; the moat is the service (the catalog, the labs, the review pipeline), not the check functions. Keeping them behind a prebuilt archive cost a C-ABI, an exact toolchain pin, a build-time download, a second release to order ahead of every engine release, and a serde layer that had to serve two encodings. Deleted - crates/core/src/ffi.rs, crates/core/build.rs, crates/core/tests/boundary.rs and the shim modules under src/checks and src/browser. - crates/foundation/src/boundary.rs and the postcard dependency. - DETECTOR_VERSION, scripts/check-detector-release.mjs and its test, the check:detector-release script, the detector gate and IMPECCABLE_SKIP_DETECTOR_CHECK in scripts/release.mjs. - scripts/lib/detector-bundle.mjs and tests/detector-bundle.test.mjs (the vendoring path for the closed browser bundle). - scripts/build-browser-detector.js and the build:browser script (a stub since the JS engine left the tree). - xtask's detector-archive subcommand and its public-repo lookup. Came back - crates/core is now the rule logic itself: every check_* / scan_*, the browser adapters, the visual-contrast decisions. It re-exports foundation as before, so no consumer changed. Its vectors dispatcher is the union of both id tables again, and tests/vectors.rs replays the frozen vectors straight through it. - crates/wasm and crates/xtask join the workspace. cargo xtask bundle builds the in-page bundle from browser-bundle/ plus the wasm core, writes dist/, refreshes the tracked crates/live/assets/detect-antipatterns- browser.js, and writes extension/detector/. bun run build:extension runs it instead of downloading. - crates/live/assets/detect-antipatterns-browser.js is tracked again; live mode embeds it and serves it as /detect.js. - Serde is back to plain derives: no is_human_readable branch in js::json_number, derived Serialize for Rgba and BrowserFinding with their skip_serializing_if attributes. - profile.release has lto = "fat" again; rust-toolchain.toml is plain stable plus the wasm32 target. The rust, rust-windows and oracle CI jobs lose continue-on-error and can be required. Verified - cargo build --workspace --all-targets: clean, no warnings. - cargo test --workspace: 346 pass, 0 fail (the 8 boundary tests are gone with the boundary). - cargo build -p impeccable-wasm --target wasm32-unknown-unknown --release: ok. - cargo xtask bundle && cargo xtask bundle --check: reproducible; the regenerated bundle is committed (it differs from the archived one, which was built with a pinned rustc and lto = false). - cargo build --release -p impeccable: no linker warnings, 12.5 MB (the same source at lto = false is 13.1 MB). - oracle: 795 pass, 0 fail, 0 accepted deltas, 0 missing goldens. - bun run build, bun run build:extension, web-ext lint (0 errors, 8 warnings), bun run test: 363 + 80 + 1 + 1 + 133 + 180 + 4 pass, 0 fail. - impeccable detect --no-config --json tests/fixtures/antipatterns: 128.7 ms median of 5. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Vau2X53xGTjjTCXWMVBoNY
This commit is contained in:
co-authored by
Claude Fable 5.1
parent
298194f787
commit
4369ad538d
+19
-40
@@ -93,13 +93,22 @@ jobs:
|
||||
if: needs.changes.outputs.framework == 'true'
|
||||
run: bun run test:framework
|
||||
|
||||
- name: Rebuild browser detector
|
||||
if: needs.changes.outputs.detector == 'true'
|
||||
run: bun run build:browser
|
||||
|
||||
- name: Build
|
||||
run: bun run build
|
||||
|
||||
# `bun run build:extension` runs `cargo xtask bundle`: the rule core
|
||||
# compiled to wasm plus the page JS in browser-bundle/.
|
||||
- name: Install the pinned toolchain
|
||||
if: needs.changes.outputs.detector == 'true'
|
||||
run: rustup show && rustup target add wasm32-unknown-unknown
|
||||
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
if: needs.changes.outputs.detector == 'true'
|
||||
|
||||
- name: Install wasm-pack
|
||||
if: needs.changes.outputs.detector == 'true'
|
||||
run: cargo install wasm-pack --locked
|
||||
|
||||
- name: Build extension
|
||||
if: needs.changes.outputs.detector == 'true'
|
||||
run: bun run build:extension
|
||||
@@ -112,8 +121,8 @@ jobs:
|
||||
run: npx --yes web-ext@10 lint --source-dir dist/extension-firefox
|
||||
|
||||
- name: Verify generated tracked outputs
|
||||
# cli/engine/ left the tree with the Rust engine swap; the vendored
|
||||
# extension/detector/ path stays listed for when its vendoring lands.
|
||||
# extension/detector/ is gitignored (built by `cargo xtask bundle`);
|
||||
# it stays listed so a stray tracked copy shows up here.
|
||||
run: git diff --exit-code -- .agents .claude .cursor .gemini .github/skills plugin extension/detector
|
||||
|
||||
- name: Upload build artifacts
|
||||
@@ -126,46 +135,29 @@ jobs:
|
||||
!dist/extension-firefox/
|
||||
retention-days: 7
|
||||
|
||||
# The Rust workspace: the engine binary and every crate behind it.
|
||||
# crates/core/build.rs downloads the prebuilt closed detector archive for
|
||||
# the pinned DETECTOR_VERSION (docs/ENGINE.md), so this job needs that
|
||||
# release to exist.
|
||||
#
|
||||
# continue-on-error is a release-time toggle: until detector-v<DETECTOR_VERSION>
|
||||
# is published, the archive cannot be fetched and the job would block every
|
||||
# PR. Once it is live, flip continue-on-error to false so a Rust regression
|
||||
# fails CI instead of only annotating it.
|
||||
# The Rust workspace: the engine binary, the rule core, and every crate
|
||||
# behind them. Everything builds from source with no downloads.
|
||||
rust:
|
||||
runs-on: ubuntu-latest
|
||||
needs: changes
|
||||
if: needs.changes.outputs.rust == 'true'
|
||||
continue-on-error: true
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v7
|
||||
|
||||
# rust-toolchain.toml pins the exact rustc the detector was built with;
|
||||
# `rustup show` installs it. Never override the toolchain here.
|
||||
# rust-toolchain.toml names the channel; `rustup show` installs it.
|
||||
# Never override the toolchain here.
|
||||
- name: Install the pinned toolchain
|
||||
run: rustup show
|
||||
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
|
||||
- name: Build
|
||||
id: build
|
||||
continue-on-error: true
|
||||
run: cargo build --workspace --all-targets
|
||||
|
||||
- name: Test
|
||||
if: steps.build.outcome == 'success'
|
||||
run: cargo test --workspace
|
||||
|
||||
- name: Annotate missing detector release
|
||||
if: steps.build.outcome != 'success'
|
||||
run: |
|
||||
echo "::warning title=Rust workspace not built::cargo build failed. If crates/core/build.rs could not download detector-v$(cat DETECTOR_VERSION), the detector release is not published yet; publish it (tag the private detector repo) and flip this job's continue-on-error to false. Otherwise this is a real build failure."
|
||||
exit 1
|
||||
|
||||
# The engine ships a windows-x64 binary (release-engine.yml), so the
|
||||
# workspace has to build and pass its own tests there. Tests that need a
|
||||
# browser or the oracle skip when those are absent.
|
||||
@@ -173,7 +165,6 @@ jobs:
|
||||
runs-on: windows-latest
|
||||
needs: changes
|
||||
if: needs.changes.outputs.rust == 'true'
|
||||
continue-on-error: true
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v7
|
||||
@@ -188,13 +179,10 @@ jobs:
|
||||
# not on the last published binary). Without this job the oracle only ever
|
||||
# runs on developer laptops: tests/oracle.test.mjs skips cleanly when no
|
||||
# binary is present, so the default suite is silent about it on CI.
|
||||
#
|
||||
# continue-on-error: same release-time toggle as `rust` above.
|
||||
oracle:
|
||||
runs-on: ubuntu-latest
|
||||
needs: changes
|
||||
if: needs.changes.outputs.oracle == 'true' || needs.changes.outputs.rust == 'true'
|
||||
continue-on-error: true
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v7
|
||||
@@ -218,22 +206,13 @@ jobs:
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
|
||||
- name: Build the engine from source
|
||||
id: build
|
||||
continue-on-error: true
|
||||
run: cargo build --release -p impeccable
|
||||
|
||||
- name: Replay oracle goldens
|
||||
if: steps.build.outcome == 'success'
|
||||
env:
|
||||
IMPECCABLE_BIN: ${{ github.workspace }}/target/release/impeccable
|
||||
run: node tests/oracle/run.mjs
|
||||
|
||||
- name: Annotate missing detector release
|
||||
if: steps.build.outcome != 'success'
|
||||
run: |
|
||||
echo "::warning title=Oracle not run::the engine did not build (see the rust job). The oracle behavior gate did NOT run. Expected until detector-v$(cat DETECTOR_VERSION) is published; after that, flip this job's continue-on-error to false."
|
||||
exit 1
|
||||
|
||||
# Release-order guard (triage decision D4). Verifies that the engine release for
|
||||
# the pinned ENGINE_VERSION is fully published — the five dist binaries + .sha256
|
||||
# AND the five @impeccable/cli-<os>-<arch> npm platform packages — before a skill
|
||||
|
||||
@@ -5,8 +5,8 @@ name: release-engine
|
||||
# (cli/bin/cli.js), `impeccable install`, and `bun run fetch:engine` download.
|
||||
#
|
||||
# Trigger: `bun run release:engine` (scripts/release.mjs) verifies
|
||||
# ENGINE_VERSION, the detector release it builds against, and a clean tree,
|
||||
# then pushes the tag. Third-party actions are pinned to commit SHAs so a
|
||||
# ENGINE_VERSION, the npm platform-package pins, and a clean tree, then
|
||||
# pushes the tag. Third-party actions are pinned to commit SHAs so a
|
||||
# moved tag cannot swap the code this workflow runs.
|
||||
on:
|
||||
push:
|
||||
@@ -35,8 +35,8 @@ jobs:
|
||||
set -e
|
||||
want="engine-v$(tr -d '[:space:]' < ENGINE_VERSION)"
|
||||
[ "$GITHUB_REF_NAME" = "$want" ] || { echo "tag $GITHUB_REF_NAME != $want"; exit 1; }
|
||||
# rust-toolchain.toml pins the exact rustc the prebuilt detector was
|
||||
# built with; `rustup show` installs it. Never override the toolchain here.
|
||||
# rust-toolchain.toml names the channel; `rustup show` installs it.
|
||||
# Never override the toolchain here.
|
||||
- name: Install the pinned toolchain
|
||||
shell: bash
|
||||
run: rustup show && rustup target add ${{ matrix.target }}
|
||||
@@ -46,8 +46,6 @@ jobs:
|
||||
run: cargo install cross --locked
|
||||
- name: Build
|
||||
shell: bash
|
||||
# build.rs in crates/core downloads the pinned detector archive for
|
||||
# this target from the detector-v<DETECTOR_VERSION> release.
|
||||
run: ${{ matrix.cross && 'cross' || 'cargo' }} build --release -p impeccable --target ${{ matrix.target }}
|
||||
- name: Smoke the binary
|
||||
if: ${{ !matrix.cross }}
|
||||
|
||||
Reference in New Issue
Block a user