Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
156 commits
Select commit Hold shift + click to select a range
eb49456
[failproofaid] Add empty Rust workspace and gated CI plumbing
NiveditJain Jul 31, 2026
933d9fc
[failproofaid] Add the daemon skeleton and IPC wire protocol
NiveditJain Jul 31, 2026
515bff2
[failproofaid] Wire the warm worker, TS daemon-client, and fail-close…
NiveditJain Jul 31, 2026
cea6600
docs: add CHANGELOG entry for the failproofaid split (#632)
NiveditJain Jul 31, 2026
cd45633
fix(ci): install bun in rust-quality before cargo test
NiveditJain Jul 31, 2026
3c79a53
[failproofaid] Install failproofaid as a real OS service from failpro…
NiveditJain Jul 31, 2026
2e0f3d8
[failproofaid] npm packaging, cross-compile CI, and warm-path fixes f…
NiveditJain Jul 31, 2026
4db91e1
docs: update CLAUDE.md for the failproofaid daemon split
NiveditJain Jul 31, 2026
e989a52
[failproofaid] Fix 11 review findings on the daemon split, four enfor…
NiveditJain Jul 31, 2026
35daeb1
docs(changelog): fold the --locked release build into the CI entry
NiveditJain Jul 31, 2026
bd6ed8f
[failproofaid] Ship the daemon from GitHub Releases, not npm platform…
NiveditJain Jul 31, 2026
fbd21bc
[failproofaid] Static musl binaries and a system-scope service
NiveditJain Jul 31, 2026
d9ab303
test(daemon): stop the service tests reaching the real release
NiveditJain Jul 31, 2026
5435c8f
[failproofaid] Prompt for sudo in-process, and ask for the daemon first
NiveditJain Jul 31, 2026
9cf8d50
[failproofaid] Close three review findings in the service install
NiveditJain Jul 31, 2026
f24f518
feat: reconcile cloud-managed policy generations
chhhee10 Jul 31, 2026
61658a1
feat(failproofaid): poll cloud-managed policy deployments
chhhee10 Jul 31, 2026
ceb8cdb
fix: let setup continue with no policy bundles selected
chhhee10 Aug 2, 2026
8218812
feat: pause enforcement for one session, time-boxed
chhhee10 Aug 3, 2026
54c1f28
fix: stop the wizard tests writing into the repo's own config
chhhee10 Aug 3, 2026
c979c7a
feat: show a paused machine in the dashboard
chhhee10 Aug 3, 2026
d9f787f
feat: enrol a machine with Failproof Cloud from the CLI
chhhee10 Aug 3, 2026
c4afd28
feat: attribute each decision to the policy that made it
chhhee10 Aug 3, 2026
98dec6d
feat: chart enforcement over time on the activity view
chhhee10 Aug 3, 2026
1b06043
feat: observe mode for cloud-managed policies
chhhee10 Aug 3, 2026
ee0cfdc
fix(audit): capture pi's tool events and hermes's working directory
SiddarthAA Aug 3, 2026
36f7891
docs(changelog): add the pi/hermes audit-adapter fixes (#639)
SiddarthAA Aug 3, 2026
2bd32ed
[collector] Add the fault-isolated collector host, inert until config…
SiddarthAA Aug 3, 2026
973d506
docs(changelog): add the collector host entry (#640)
SiddarthAA Aug 3, 2026
eca5df9
Revert "feat: chart enforcement over time on the activity view"
chhhee10 Aug 3, 2026
0565006
[collector] Add ingest config and the spool writer
SiddarthAA Aug 3, 2026
2d9d3d4
docs(changelog): add the ingest config and spool writer entry (#640)
SiddarthAA Aug 3, 2026
6146017
[collector] Add the uploader, completing the delivery path
SiddarthAA Aug 3, 2026
549728e
docs(changelog): add the uploader entry (#640)
SiddarthAA Aug 3, 2026
c107707
[collector] Add the watcher and sweeper, completing P0
SiddarthAA Aug 3, 2026
4b6cfb1
docs(changelog): add the watcher and sweeper entry (#640)
SiddarthAA Aug 3, 2026
feeeab4
fix: stop claiming nothing is pulled when a daemon is plainly running
chhhee10 Aug 3, 2026
294b452
[collector] Add the hook-activity source (P1)
SiddarthAA Aug 3, 2026
64b0918
docs(changelog): add the hook-activity source entry (#640)
SiddarthAA Aug 3, 2026
6e856be
[collector] Add the filetail engine and the Claude source (P2)
SiddarthAA Aug 3, 2026
0338f9e
docs(changelog): add the filetail engine and Claude source entry (#640)
SiddarthAA Aug 3, 2026
bcec2e2
[collector] Implement the redaction the config already promised
SiddarthAA Aug 3, 2026
3d1cdc0
[collector] Add the wizard step that turns collection on
SiddarthAA Aug 3, 2026
5b3387e
docs(changelog): add the redaction and wizard-step entry (#640)
SiddarthAA Aug 3, 2026
60024df
[collector] Add per-source health and the SQLite polling engine
SiddarthAA Aug 3, 2026
70f20fa
style: format health.rs and sqlitepoll.rs
SiddarthAA Aug 3, 2026
aee52c9
[collector] Add the remaining eight sources and wire per-source health
SiddarthAA Aug 3, 2026
dac7399
docs(changelog): add the eight-source and health entry (#640)
SiddarthAA Aug 3, 2026
8c9af51
Merge the collector host and its nine sources (#640) into the cloud work
chhhee10 Aug 3, 2026
3c9101d
[collector] Complete the Claude source, and fix a token-attribution b…
SiddarthAA Aug 3, 2026
c27c1e9
fix: carry decision attribution through the collector
chhhee10 Aug 3, 2026
2145acc
feat: one step to connect a machine to Failproof Cloud
chhhee10 Aug 3, 2026
8fa9f01
Merge the completed Claude source (#640) into the cloud work
chhhee10 Aug 3, 2026
2ad735e
fix: close three high-severity holes found by the adversarial sweep
chhhee10 Aug 3, 2026
c3c0263
fix: stop the uploader following redirects and trusting any 2xx
chhhee10 Aug 3, 2026
29896ba
fix: close ANSI-C quoting in block-self-pause too
chhhee10 Aug 3, 2026
9bdd39a
fix: make block-self-pause resist shell-string reconstruction
chhhee10 Aug 3, 2026
7d5f8b8
fix: anchor the generation rollback guard on the server, not local state
chhhee10 Aug 3, 2026
c073531
Merge branch 'failproofaid' into feat/failproofaid-with-collector
chhhee10 Aug 3, 2026
28bf9aa
fix: also strip backslash-newline line continuation in block-self-pause
chhhee10 Aug 3, 2026
5cf3cfc
Merge branch 'failproofaid' into feat/failproofaid-with-collector
chhhee10 Aug 3, 2026
6efdd02
Merge pull request #640 from FailproofAI/feat/failproofaid-collector
NiveditJain Aug 3, 2026
bf3495d
fix(deps): bump brace-expansion override to 5.0.9 for GHSA-rgw5-rvv9-…
NiveditJain Aug 3, 2026
46ad0e5
Merge branch 'main' into failproofaid
NiveditJain Aug 3, 2026
b5c9271
docs(changelog): move post-beta.2 entries under a 1.0.0-beta.3 heading
NiveditJain Aug 3, 2026
74b51c9
fix(deps): clear the undici advisories and land Dependabot #641-#649
NiveditJain Aug 4, 2026
45d0236
docs(changelog): point the dependency entries at #650
NiveditJain Aug 4, 2026
00216d8
Merge pull request #650 from FailproofAI/luv-legion-650
NiveditJain Aug 4, 2026
469aad4
feat: stamp the machine id on every collected event
chhhee10 Aug 4, 2026
dcf13d7
feat(release): ship failproofaid through npm and put the CLI tarball …
NiveditJain Aug 4, 2026
4bcc2f6
fix(daemon): ignore a platform package built for a different CLI version
NiveditJain Aug 4, 2026
ec75874
fix(release): keep the daemon artifacts out of the published CLI tarball
NiveditJain Aug 4, 2026
678d936
chore: ignore the release-pipeline scratch dirs a manual run leaves b…
NiveditJain Aug 4, 2026
cc6d069
fix: start the collector when config becomes enabled, not only at sta…
chhhee10 Aug 4, 2026
1b3250c
Merge origin/failproofaid (release pipeline + dependency work) into t…
chhhee10 Aug 4, 2026
d49e7a6
style: format the machine_id spool asserts
chhhee10 Aug 4, 2026
df96b95
style: satisfy clippy 1.97 on the machine_id stamping code
chhhee10 Aug 4, 2026
0681e79
fix(release): refuse to publish a version that is already on npm
NiveditJain Aug 4, 2026
3671a0c
fix(release): verify a release by installing it, on every platform
NiveditJain Aug 4, 2026
a8040e4
fix: bind the imported cloud policy bytes to the verified digest
chhhee10 Aug 4, 2026
6d6d262
test: assert the machine_id stamp never overwrites an existing value
chhhee10 Aug 4, 2026
968320a
feat: collect Factory (droid) sessions
chhhee10 Aug 4, 2026
4bdc1c1
feat: collect Antigravity, Devin and Cursor sessions (the last 3 of 12)
chhhee10 Aug 4, 2026
a6f2cb5
Merge remote-tracking branch 'origin/main' into failproofaid
chhhee10 Aug 4, 2026
61ddaa2
feat: rework first-run setup so it cannot half-configure a machine
SiddarthAA Aug 4, 2026
7c33abd
feat: add the layout-2 path and config modules
SiddarthAA Aug 4, 2026
f9eb79b
feat: move every TypeScript consumer onto the layout-2 paths
SiddarthAA Aug 4, 2026
ef48eb6
feat: move the daemon onto the layout-2 paths and TOML config
SiddarthAA Aug 4, 2026
feb1547
feat: reset stale layouts, gate cloud behind mode, and self-heal the …
SiddarthAA Aug 4, 2026
720b209
test: add the layout-2 end-to-end harnesses
SiddarthAA Aug 4, 2026
1eb3e26
docs(changelog): add the layout-2 reorganisation entry (#653)
SiddarthAA Aug 4, 2026
1eb57ac
fix(ci): clippy -D warnings, and repoint the e2e suite at layout 2
SiddarthAA Aug 5, 2026
c72aea1
fix(ci): read daemonConfigured from config.toml in the sudo-gated test
SiddarthAA Aug 5, 2026
5392b91
fix(ci): install worker dependencies in the rust-quality job
SiddarthAA Aug 5, 2026
ab74176
collect: stamp the daemon's OS user on every event
chhhee10 Aug 5, 2026
4cd9ad0
build(deps-dev): bump react to 19.2.8 and @types/react to 19.2.18
NiveditJain Aug 5, 2026
4e883d7
enroll: mint a stable machine id, take the hostname as a label
chhhee10 Aug 5, 2026
7e548c9
feat: send transcripts by default, with an explicit opt-out
SiddarthAA Aug 5, 2026
c618df7
dashboard: bind loopback, pin Host, and refuse cross-origin writes
chhhee10 Aug 5, 2026
bcf077a
telemetry: add a config-file opt-out the daemon can actually honour
chhhee10 Aug 5, 2026
724226c
daemon: read the cloud credential from credentials.toml
chhhee10 Aug 5, 2026
704c9d8
audit: add the [audit] config surface, a headless run, and a cross-pr…
chhhee10 Aug 5, 2026
debe7b4
audit: publish the lock file atomically, not empty-then-filled
chhhee10 Aug 5, 2026
26f700e
fix: a protocol mismatch must fall back, not deny the whole machine
SiddarthAA Aug 5, 2026
f74a004
daemon: give the service a FAILPROOFAI_CLI_CMD, and rewrite units tha…
chhhee10 Aug 5, 2026
06e642d
feat: track the daemon version, reinstall on skew, prune old binaries
SiddarthAA Aug 5, 2026
343c5e6
daemon: let a failed unit refresh undo itself instead of stranding th…
chhhee10 Aug 5, 2026
665bb5a
daemon: run the scheduled audit from its own lane, in its own process
chhhee10 Aug 5, 2026
7ffebfb
daemon: say once, not every minute, that the audit schedule cannot be…
chhhee10 Aug 5, 2026
52e5548
daemon: report its own lifecycle, so failproofaid stops being the bli…
chhhee10 Aug 5, 2026
894e55b
audit: never reset a user's home from the scheduled run
chhhee10 Aug 5, 2026
75415cc
Merge remote-tracking branch 'origin/failproofaid' into feat/machine-…
chhhee10 Aug 5, 2026
50f0aec
fix: make cloud-managed policy actually reach a machine, and check th…
SiddarthAA Aug 5, 2026
87b59cd
Merge origin/main into feat/failproofaid-daemon-ux
SiddarthAA Aug 5, 2026
e38f300
Merge remote-tracking branch 'origin/failproofaid' into feat/machine-…
chhhee10 Aug 5, 2026
5faf3bc
daemon: never let a refused thread take the daemon down
chhhee10 Aug 5, 2026
4c74357
audit: report a scheduled scan's findings without reporting its contents
chhhee10 Aug 5, 2026
79c3677
Merge branch 'main' into failproofaid
NiveditJain Aug 5, 2026
924f45e
dashboard: add a /settings surface for scheduled audit and email reports
chhhee10 Aug 5, 2026
f96cfda
audit: put every cache writer behind the one lock, dashboard included
chhhee10 Aug 5, 2026
9818b6d
Merge remote-tracking branch 'origin/failproofaid' into feat/machine-…
chhhee10 Aug 5, 2026
aa74a04
fix: clear systemd's start-limit before the daemon-service refresh re…
chhhee10 Aug 5, 2026
06ac4fc
test: stop unit tests reaching the network, and make it impossible to…
SiddarthAA Aug 5, 2026
e0d3b04
Merge PR #639: capture pi's tool events and hermes's working directory
SiddarthAA Aug 5, 2026
76af4d8
fix: close the review's blocking findings across the reset, daemon an…
SiddarthAA Aug 6, 2026
e9f2c92
fix: close the should-fix findings in the collector, pause and layout…
SiddarthAA Aug 6, 2026
a309e8c
fix: harden the unit file, the worker's shutdown and the collector's …
SiddarthAA Aug 6, 2026
2d49994
fix: probe the daemon before setting the flag, not inside the install
SiddarthAA Aug 6, 2026
36a090d
refactor: keep the machine scan local, and drop the CLI's second fron…
SiddarthAA Aug 6, 2026
25f9c4f
fix: write the policy shim where the user can actually write it
chhhee10 Aug 6, 2026
bb35a49
chore: bump the version to 1.0.0-beta.6
chhhee10 Aug 6, 2026
2926252
fix: one evaluator on a daemon machine, and stop setup relaunching fo…
SiddarthAA Aug 6, 2026
e76a585
Merge remote-tracking branch 'origin/failproofaid' into feat/failproo…
SiddarthAA Aug 6, 2026
de55d51
chore: bump the version to 1.0.0-beta.7
SiddarthAA Aug 6, 2026
496e0c6
fix: let setup finish against a daemon that is working, and bump to 1…
chhhee10 Aug 6, 2026
7541fc1
feat: add `failproofai uninstall`, and stop a removed install from th…
chhhee10 Aug 6, 2026
969e918
fix: unblock first-run setup, and stop block-sudo being defeated by a…
SiddarthAA Aug 6, 2026
c3949c2
docs: describe what block-sudo actually does, and what it cannot
SiddarthAA Aug 6, 2026
8644a69
fix: never gate the unit on an ExecStart that carries arguments
chhhee10 Aug 6, 2026
0bfeb1c
Merge remote-tracking branch 'origin/failproofaid' into feat/failproo…
SiddarthAA Aug 6, 2026
69ae811
Merge remote-tracking branch 'origin/failproofaid' into feat/failproo…
SiddarthAA Aug 6, 2026
4e23c37
fix: carry a machine's decision history across the layout upgrade
SiddarthAA Aug 6, 2026
3a5204d
docs: correct the hook-activity paths, which describe a design two la…
SiddarthAA Aug 6, 2026
e418183
fix: one hostname, one prompt — default ingest to the dashboard origin
chhhee10 Aug 6, 2026
8376937
chore: bump to 1.0.0-beta.9 and split the changelog at the beta.8 cut
chhhee10 Aug 6, 2026
0c86bcd
fix: make a config change reach the running daemon, and bump to 1.0.0…
chhhee10 Aug 6, 2026
0bbfac1
fix: reload the collector when its config changes, in the DAEMON
chhhee10 Aug 6, 2026
b8af8ee
feat: add `failproofai backfill`, and make it reach past seven days
chhhee10 Aug 6, 2026
35a30bd
style: cargo fmt
chhhee10 Aug 6, 2026
3972979
daemon: never let a refused thread deny the machine it guards
SiddarthAA Aug 6, 2026
7f11c3c
collect: stop redaction eating data, and health reporting a dead gene…
SiddarthAA Aug 6, 2026
c85185d
hooks: make the outermost error boundary actually fail closed
SiddarthAA Aug 6, 2026
04b53f8
daemon: reinstalling must replace the daemon, not just its unit file
SiddarthAA Aug 6, 2026
ba353ae
dashboard: refuse origin-less writes when the bind is not loopback
SiddarthAA Aug 6, 2026
41371db
ci: serialize publishes, and stop leaking two tokens into the build
SiddarthAA Aug 6, 2026
56f24a8
daemon: close the five remaining review findings across cloud, bind a…
SiddarthAA Aug 6, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
113 changes: 0 additions & 113 deletions .failproofai/policies/block-version-bumps-policies.mjs

This file was deleted.

3 changes: 1 addition & 2 deletions .failproofai/policies/workflow-policies.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,7 @@ customPolicies.add({
"Before creating the PR, ensure CHANGELOG.md entries land under a versioned section so the PR ships release-ready:\n" +
" 1. Read `version` from package.json (e.g. `0.0.10-beta.10`).\n" +
" 2. Ensure your changelog entries are under a `## <version> — <today's date in YYYY-MM-DD>` heading. If that heading does not exist yet, create it above the previous version's section. There is NO `## Unreleased` section — entries always go under a dated, versioned heading.\n" +
" 3. If you are on a `luv-cut-X.Y.Z` branch, the cut PR handles version bump itself.\n" +
" 4. Do NOT bump `package.json`'s `version` outside of `luv-cut-*` branches — that is enforced by `block-version-bumps`."
" 3. If you are on a `luv-cut-X.Y.Z` branch, the cut PR handles version bump itself."
);
},
});
17 changes: 17 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,20 @@ updates:
interval: weekly
day: monday
open-pull-requests-limit: 5

# The Rust workspace. Absent until the daemon shipped, so `Cargo.lock` was
# updated only by hand — for a dependency tree that includes the TLS stack
# compiled into a root-installed system service.
- package-ecosystem: cargo
directory: /
schedule:
interval: weekly
day: monday
open-pull-requests-limit: 5
groups:
# One PR for the whole tree rather than five a week: these crates are
# verified together by `cargo test --workspace`, and splitting them means
# each PR rebuilds the same lockfile the others just changed.
rust-dependencies:
patterns:
- "*"
35 changes: 32 additions & 3 deletions .github/workflows/build-daemon.yml
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,19 @@ jobs:
# architectures (including a native arm64 runner) rather than
# `cross`/Docker cross-compilation — a real linker for the target
# triple, no QEMU emulation overhead.
- target: x86_64-unknown-linux-gnu
#
# musl, NOT gnu: a glibc build links against the runner's own libc,
# and `ubuntu-latest` is 24.04 (glibc 2.39), so the 1.0.0-beta.0
# binaries refused to start on Ubuntu 22.04, Debian 12, RHEL 9 and
# Amazon Linux 2023 with `version GLIBC_2.39 not found` — measured,
# not predicted. Pinning an older runner would only move the floor
# (22.04 is glibc 2.35, still above RHEL 9's 2.34); a static musl
# binary has no floor at all. The daemon is a socket supervisor with
# no NSS or dlopen use, which is what makes static linking safe here.
- target: x86_64-unknown-linux-musl
os: ubuntu-latest
platform: linux-x64
- target: aarch64-unknown-linux-gnu
- target: aarch64-unknown-linux-musl
os: ubuntu-24.04-arm
platform: linux-arm64
# macOS cannot be cross-compiled reliably from Linux (system
Expand All @@ -90,6 +99,14 @@ jobs:

- run: rustup target add ${{ matrix.target }}

# `rustup target add` ships the musl std library but not a musl linker;
# without musl-tools the leg fails at link time with
# `linker 'musl-gcc' not found`. Both Linux runners are native to their
# own target, so the distro package is the right linker for the triple.
- name: Install the musl toolchain
if: contains(matrix.target, 'musl')
run: sudo apt-get update -qq && sudo apt-get install -y -qq musl-tools

# Split restore/save rather than `actions/cache@v6`, which does both.
# This job runs on `pull_request` AND on the release path (via
# `workflow_call` from publish.yml, where `github.event_name` is the
Expand Down Expand Up @@ -139,10 +156,22 @@ jobs:
run: |
BIN="target/${{ matrix.target }}/release/failproofaid"
"$BIN" --version
# A dynamically linked "static" build would reintroduce the glibc
# floor silently — the binary still runs here, on the runner that
# built it, and only fails on the users' older distros. Assert the
# property on the artifact itself.
if [[ "${{ matrix.target }}" == *musl* ]]; then
file "$BIN"
if ldd "$BIN" 2>&1 | grep -qv "not a dynamic executable\|statically linked"; then
echo "::error::${{ matrix.platform }} is not statically linked — it would inherit the runner's glibc floor"
ldd "$BIN" || true
exit 1
fi
fi
gzip -9 -c "$BIN" > "failproofaid-${{ matrix.platform }}.gz"
ls -l "failproofaid-${{ matrix.platform }}.gz"

- uses: actions/upload-artifact@v4
- uses: actions/upload-artifact@v7
with:
name: failproofaid-${{ matrix.platform }}
path: failproofaid-${{ matrix.platform }}.gz
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/build-image.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ jobs:
uses: docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c # v4.2.0

- name: Log in to GHCR
uses: docker/login-action@abd2ef45e78c5afb21d64d4ca52ee8550d9572c7 # v4.5.1
uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4.6.0
with:
registry: ghcr.io
username: ${{ github.actor }}
Expand Down
97 changes: 97 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,24 @@ jobs:
MISMATCH=1
fi
done
# The daemon binaries DO ship as npm platform packages
# (@failproofai/failproofaid-<os>-<arch>), but their pins are injected
# into package.json at publish time by
# scripts/build-daemon-packages.mjs — the same invocation that
# publishes them, so they cannot drift — and are deliberately absent
# from the committed tree. Nothing to check here.
#
# The Cargo version still has to match, because the release tag the
# CLI builds its download URL from is the npm version, and the binary
# at that URL reports the Cargo one.
# Check the Cargo workspace version (failproofaid) against root package.json
if [ -f Cargo.toml ]; then
CARGO_VERSION=$(grep -m1 '^version = ' Cargo.toml | sed -E 's/version = "(.*)"/\1/')
if [ "$CARGO_VERSION" != "$ROOT_VERSION" ]; then
echo "::error file=Cargo.toml::Version mismatch: Cargo.toml has $CARGO_VERSION, expected $ROOT_VERSION"
MISMATCH=1
fi
fi
if [ "$MISMATCH" -eq 1 ]; then
echo "::error::Version mismatch detected across package.json files"
exit 1
Expand All @@ -75,6 +93,85 @@ jobs:
timeout_minutes: 5
command: bunx tsc --noEmit

rust-quality:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7.0.1
with:
# This job runs `cargo clippy`/`cargo test` over the full
# dependency tree, executing third-party build scripts. The
# default (`true`) would leave GITHUB_TOKEN in .git/config where
# any of them could read it; nothing here needs push access.
persist-credentials: false

# Stage 1 lands an empty Cargo workspace (zero crates/*/Cargo.toml) so
# the CI plumbing itself can go green before any Rust code exists.
# `cargo build/clippy/test --workspace` (and even `cargo fmt --all`)
# all hard-error on a zero-member workspace ("the workspace has no
# members"), so every real step below is gated on at least one crate
# being present rather than relying on any of them to no-op cleanly.
- name: Detect crates
id: crates
run: |
if ls crates/*/Cargo.toml >/dev/null 2>&1; then
echo "present=true" >> "$GITHUB_OUTPUT"
else
echo "present=false" >> "$GITHUB_OUTPUT"
echo "No crates/*/Cargo.toml yet — rust-quality has nothing to check."
fi

- if: steps.crates.outputs.present == 'true'
run: rustup show

# cargo test spawns the real TS worker via `bun bin/failproofai-worker.mjs`
# (crates/failproofaid/src/server.rs's live end-to-end test) — bun has to
# be on PATH for that test, not just for the TS-side jobs.
- if: steps.crates.outputs.present == 'true'
uses: oven-sh/setup-bun@v2
with:
bun-version: latest

# …and bun on PATH is not enough on its own. That worker runs the raw
# TypeScript, so it resolves the handler's real dependency tree at
# runtime rather than a bundle's. The moment anything under src/hooks
# imports a third-party package, this job fails with a bun ENOENT that
# reads like a Rust problem — the failure surfaces as "worker process
# exited before creating its socket". Production is unaffected, because
# dist/worker.mjs bundles those deps; only this path needs them on disk.
- if: steps.crates.outputs.present == 'true'
uses: actions/cache@v6
with:
path: ~/.bun/install/cache
key: bun-${{ runner.os }}-${{ hashFiles('bun.lock') }}
restore-keys: bun-${{ runner.os }}-

- if: steps.crates.outputs.present == 'true'
name: Install worker dependencies
run: bun install --frozen-lockfile --ignore-scripts

- if: steps.crates.outputs.present == 'true'
uses: actions/cache@v6
with:
path: |
~/.cargo/registry/index
~/.cargo/registry/cache
~/.cargo/git/db
target
key: cargo-${{ runner.os }}-${{ hashFiles('rust-toolchain.toml', 'Cargo.lock', 'crates/*/Cargo.toml') }}
restore-keys: cargo-${{ runner.os }}-

- name: cargo fmt --check
if: steps.crates.outputs.present == 'true'
run: cargo fmt --all -- --check

- name: cargo clippy
if: steps.crates.outputs.present == 'true'
run: cargo clippy --workspace --all-targets -- -D warnings

- name: cargo test
if: steps.crates.outputs.present == 'true'
run: cargo test --workspace

test:
runs-on: ubuntu-latest
strategy:
Expand Down
7 changes: 6 additions & 1 deletion .github/workflows/osv-scanner.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,13 @@ jobs:
with:
# No git ops after checkout; don't leave the token in .git/config.
persist-credentials: false
- name: Scan bun.lock for known-vulnerable / malicious dependencies
# Both lockfiles, in one scan. `Cargo.lock`'s 238 packages were covered by
# nothing at all — not this job, which was only ever given `bun.lock`, and
# not Dependabot, which had no `cargo` ecosystem — for a TLS stack that
# compiles into a root-installed system service.
- name: Scan bun.lock and Cargo.lock for known-vulnerable / malicious dependencies
uses: google/osv-scanner-action/osv-scanner-action@9fd1bcce27f67e3bd819a0a7620e332803dc43bc # v2.3.8
with:
scan-args: |-
--lockfile=bun.lock
--lockfile=Cargo.lock
Loading