Conversation
|
Mutation testing (cargo-mutants,
|
mise merges config down the directory tree, so every tool in the root mise.toml is also part of the toolset in packages/eql and in languages/typescript/packages/protect-ffi. Their CI jobs run `mise install` (and `mise run`) in those folders, so each one now built cargo-nextest, cargo-llvm-cov, cargo-crap, cargo-mutants, cargo-fuzz and cargo-udeps from source, none of which they use. mise's cargo backend compiles a `cargo:` tool with the runner's default rustc (1.92 on the Ubuntu images), not the root's pinned 1.94.1. So a `latest` that raises its minimum Rust fails the install: cargo-udeps 0.1.61 needs cargo@0.96, which needs rustc 1.93. That broke the protect-ffi integration suite on #1001 and the new udeps job on #1003. The cargo tools move to mise.test.toml, which mise loads only for the `test` environment (`mise x --env test`, or MISE_ENV=test). Nested workspaces no longer inherit them. Each is pinned to an exact version that builds on the runners' rustc; cargo-udeps goes back to 0.1.60. The tasks that call them (crap:*, mutants:*, fuzz:*, and nextest in wasm:guest:test and wasm:auth-guest:test) now run them through `mise x --env test --`, as test:doc and the crap coverage step already did, so `mise run <task>` keeps working locally without MISE_ENV. Rust, Go, golangci-lint and wasm-pack stay in the root mise.toml. They are prebuilt downloads, and plan section 3.5 has protect-ffi inherit the Rust pin. That section's intent holds: the repository pins one version of each cargo tool, reached through mise. The pins now sit in the test environment rather than the default one. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PaY5xYydZUWhv8Nex9Sw8a
`pnpm run test` now reaches the @cipherstash/auth and @cipherstash/profile vitest suites, which load the napi module. Their `test` scripts do not build it, and nothing else in run-tests does, so profile-store.test.ts failed with "Failed to load native binding for linux-x64" on this PR (Run Tests, Node 22 and 24). run-tests now builds both bindings with `build:debug` after the protect-ffi binding, before the test steps. The previous commit has `build:debug` write its typings to the committed native.d.ts, so the build leaves the tree clean. This step and that fix came from the CI port (#1003); they land here because this PR merges first and has to pass on its own. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PaY5xYydZUWhv8Nex9Sw8a
662a4bd to
430e826
Compare
This comment has been minimized.
This comment has been minimized.
430e826 to
c8343ba
Compare
Deliberate-break results for this PRAll 21 breaks from the plan's §1 rule ran on throwaway branches against
The dead check is fixed in PR B
Two checks could not be fully watched
Every throwaway branch, the throwaway draft PR and the caches they made have been deleted. 🤖 Generated with Claude Code |
Adds the root workflows for the imported set (plan section 7.5): tests-crates, crap-crates, mutants, fuzz, miri, tests-golang and udeps, ported from the suite's test-unit (the set's share), test-stack-auth, test-stack-profile, crap-stack-auth, crap-stack-encrypt, mutants, fuzz, miri, test-wasi and test-no-unused-cargo-dependencies. Every job runs mise at the root with `working_directory: .`. The root workspace is tested with nextest only; plain `cargo test` races the stack-kms tests that set environment variables. tests-crates.yml rebuilds both node bindings and fails if that leaves the auth or profile package changed, untracked files included: napi must write native.d.ts and never the hand-written index.d.ts. tests.yml's binding-build step, from the import PR, now points at that check. Registers the new jobs with the workflow guards: the four PR-only gates in workflow-paths-filter-parity, the mutants comment job in workflow-publish-permissions, and the Go live job in ffi-binding-step-order. The EQL rust-cache workspace check now applies to EQL's jobs only, with a non-empty floor. AGENTS.md and docs/fuzzing.md describe the CI that now exists. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PaY5xYydZUWhv8Nex9Sw8a
crates-ci.test.mjs holds that a root workflow reaches every mise task the set defines (or names why not, and fails on a stale exemption), that the imported workflow directory stays gone, that the trybuild ui binary runs somewhere, that NEXTEST_PROFILE names a defined profile, that the Go jobs test the guests whose sha256 the Linux job recorded, and that @cipherstash/profile stays private. Two more, for this repository: every napi build in the auth and profile bindings writes `--dts native.d.ts`, which is committed and diffed by the tests-crates drift guard; and no root step runs plain `cargo test` over the workspace, where the stack-kms env-var tests race. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PaY5xYydZUWhv8Nex9Sw8a
The import PR moved the cargo tools (nextest, llvm-cov, crap, mutants, fuzz, udeps) from the root mise.toml to mise.test.toml, pinned, so that EQL and protect-ffi stop inheriting them. mise loads that file only in the test environment, so every job here that uses one now sets MISE_ENV: test. This also fixes udeps.yml, which built the floating `latest` cargo-udeps (0.1.61, which needs rustc 1.93) with the runner's rustc 1.92; the test environment pins 0.1.60. `mise run` and `mise x` install whatever tool of the toolset is missing, and mise-action caches only what its own install step installed. So tests-crates (rust), tests-golang (wasi-check), crap-crates and fuzz, whose steps go through `mise run` or `mise x`, drop `install_args` and install the whole test toolset, which then shares one cache. mutants and udeps call their tool directly, so they keep a narrow install. The workflows that read mise.test.toml now list it in their path filters. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PaY5xYydZUWhv8Nex9Sw8a
mise merges config down the directory tree, so every tool in the root mise.toml is also part of the toolset in packages/eql and in languages/typescript/packages/protect-ffi. Their CI jobs run `mise install` (and `mise run`) in those folders, so each one now built cargo-nextest, cargo-llvm-cov, cargo-crap, cargo-mutants, cargo-fuzz and cargo-udeps from source, none of which they use. mise's cargo backend compiles a `cargo:` tool with the runner's default rustc (1.92 on the Ubuntu images), not the root's pinned 1.94.1. So a `latest` that raises its minimum Rust fails the install: cargo-udeps 0.1.61 needs cargo@0.96, which needs rustc 1.93. That broke the protect-ffi integration suite on #1001 and the new udeps job on #1003. The cargo tools move to mise.test.toml, which mise loads only for the `test` environment (`mise x --env test`, or MISE_ENV=test). Nested workspaces no longer inherit them. Each is pinned to an exact version that builds on the runners' rustc; cargo-udeps goes back to 0.1.60. The tasks that call them (crap:*, mutants:*, fuzz:*, and nextest in wasm:guest:test and wasm:auth-guest:test) now run them through `mise x --env test --`, as test:doc and the crap coverage step already did, so `mise run <task>` keeps working locally without MISE_ENV. Rust, Go, golangci-lint and wasm-pack stay in the root mise.toml. They are prebuilt downloads, and plan section 3.5 has protect-ffi inherit the Rust pin. That section's intent holds: the repository pins one version of each cargo tool, reached through mise. The pins now sit in the test environment rather than the default one. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PaY5xYydZUWhv8Nex9Sw8a
`pnpm run test` now reaches the @cipherstash/auth and @cipherstash/profile vitest suites, which load the napi module. Their `test` scripts do not build it, and nothing else in run-tests does, so profile-store.test.ts failed with "Failed to load native binding for linux-x64" on this PR (Run Tests, Node 22 and 24). run-tests now builds both bindings with `build:debug` after the protect-ffi binding, before the test steps. The previous commit has `build:debug` write its typings to the committed native.d.ts, so the build leaves the tree clean. This step and that fix came from the CI port (#1003); they land here because this PR merges first and has to pass on its own. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PaY5xYydZUWhv8Nex9Sw8a
bceb0bc to
1ad1055
Compare
c8343ba to
897da0a
Compare
The second run of tests-crates `rust` and tests-golang `wasi-check` on a mise cache key failed with "'cargo-fmt' is not installed for the toolchain '1.94.1-x86_64-unknown-linux-gnu'" (and the same for clippy). mise installs the root's rust as a symlink into ~/.rustup, and mise-action caches ~/.local/share/mise but not ~/.rustup. The ubuntu-2204 runners already carry a 1.94.1 toolchain, so on a cache hit the symlink resolves, mise reports rust as installed, and the components mise.toml declares are never added. The first run on a key misses the cache and installs them, which is why the drafts passed. Both jobs now run `rustup component add rustfmt clippy` after mise-action, as test-eql.yml and bench-eql.yml already do. A guard in crates-ci.test.mjs derives which jobs need it: any job whose root mise-action can restore a cache and that runs `cargo fmt` or `cargo clippy`, directly or through the mise tasks it calls, must add those components before the step. It failed on exactly the two jobs. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PaY5xYydZUWhv8Nex9Sw8a
yujiyokoo
left a comment
There was a problem hiding this comment.
Seems mostly adding workflows for CI. Left one comment but otherwise LGTM
Reviewed with GPT-6-Luna medium
|
|
||
| # Fast pre-flight: fail in seconds if a secret was rotated or cleared. | ||
| # Ordering is asserted by scripts/__tests__/ffi-binding-step-order.test.mjs. | ||
| - uses: ./.github/actions/require-cs-secrets |
There was a problem hiding this comment.
LLM review (GPT-6-Luna medium) says this requires credentials, which is not available to fork PRs.
This PR adds the CI workflows that build and test the Rust crates, bindings and Go module that PR B brings in. It ports them from
cipherstash/cipherstash-suite, and adds tests that keep every check connected to a workflow that runs it.This is PR C of 6 in the stack crates import, which moves this code here from the private suite repository, with its history. The stack crates import plan in Linear lists every step, and Linear issue CIP-4274 tracks the work.
This PR is stacked on PR B, #1001. Its base branch is PR B's branch, so the diff shows only this PR's own changes. It stays a draft until the freeze on Friday 2 October 2026, Pacific time. The freeze is the window in which the six PRs merge in order: #1000, #1001, #1003, #1002, #1009, then #1010. PR C is #1003, so it merges before PR D, #1002.
Read all four commits, starting with the seven workflows
Read each commit in full. Commit 1 is the largest, with 1,241 added lines in 17 files: the seven workflows, their check registrations and the docs. Commit 2 is one new test file of 673 lines. Commits 3 and 4 are small fixes that CI runs found.
Each commit makes one change
04fbaad4ports seven workflows from the suite, and updatesAGENTS.mdanddocs/fuzzing.md. It also adds the new jobs to the lists that the repository's workflow checks keep. Every job runs at the repository root, and tests the root Cargo workspace with nextest only. nextest is a Rust test runner that runs each test in its own process.a8ce61a1addscrates-ci.test.mjs. It checks that a workflow runs every task the crates define, or that the test records why not. It also checks that no workflow runs plaincargo testover the workspace, and that@cipherstash/profilestays private.897da0a2setsMISE_ENV: testin each job that uses a cargo tool. mise is the tool that pins this repository's tool versions and runs its tasks. PR B moved the cargo tools intomise.test.toml, which mise reads only whenMISE_ENVistest. This also fixesudeps.yml, which had built acargo-udepsthat needs a newer Rust than the runner has.c93a39b0addsrustfmtandclippyafter mise restores its cache. CI found this after the rebuild on the newmain. On a cache hit, mise reports Rust as installed, but never adds those two components. So the first run on a cache key passes, and every later run fails. A guard test now works out which jobs need this step, and it failed on exactly the two that lacked it.The seven workflows each cover one kind of check
tests-crates.ymlruns formatting, clippy lints, nextest, doctests, rustdoc and thestack-encryptexamples. It also runs the binding tests, a check that the committed typings match a fresh build, and the WebAssembly tests.tests-golang.ymlbuilds and tests the two Go guests, the Rust crates that the Go module runs as WebAssembly. It runs the WASI checks, which confirm that the WASI builds link no JavaScript-host or native HTTP crate. WASI is the WebAssembly System Interface that the guests target. It also runsgo testand golangci-lint, repeats the Go tests on macOS and Windows, and runs live tests that need credentials.crap-crates.ymlsets a CRAP score limit forstack-authandstack-encrypt. CRAP (Change Risk Anti-Patterns) combines a function's complexity with its test coverage.mutants.ymlrunscargo mutants --in-diff, which changes the lines a PR touches on purpose and checks that a test fails. It posts the result as a comment on the PR.fuzz.ymlfeeds generated input to the parsers. On each PR it replays the saved inputs, and every night it runs a longer campaign that searches for inputs that crash.miri.ymlrunsstack-guest-abiunder Miri, an interpreter that detects undefined behaviour in Rust code.udeps.ymllooks for unused Rust dependencies, with a pinned nightly toolchain.A deliberate break proved that each check can fail
The plan treats a ported check as dead until someone watches it fail. So 21 runs tested the ported checks on throwaway branches. 20 of them pushed a deliberate fault, and 19 of those failed at the expected step. The fuzz campaign run had no fault, and passed as intended.
The
wasm:wasi-checkrun passed with its fault in place, because that check could never fail. PR B, #1001, now fixes it. The full table is in the deliberate-break results comment on this PR.Two checks could not be watched in full. The nightly fuzz run starts only from
main, so its first run comes after this PR merges.tests.ymlcannot be started by hand, so its break run added a manual trigger on the throwaway branch.CI passes, including the Go live test
TestLiveTermOrderIsPlaintextOrderfailed on an earlier run of this PR. It now passes, because the suite history that PR B imports now includes cipherstash/cipherstash-suite#2292, which fixed the test.Merge this PR with a merge commit after PR B
Merge it with a merge commit, which keeps every commit, and never with a squash or a rebase. PR D is built on these exact commits. A squash or a rebase would leave PR D based on commits that are not in
main.🤖 Generated with Claude Code
https://claude.ai/code/session_01PaY5xYydZUWhv8Nex9Sw8a