Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 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
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 31 additions & 2 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,6 +156,18 @@ 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"

Expand Down
74 changes: 74 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,19 @@ jobs:
MISMATCH=1
fi
done
# The daemon binaries ship as GitHub Release assets rather than npm
# platform packages, so there are no optionalDependencies to keep in
# step — but 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 +88,67 @@ 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

- 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
11 changes: 11 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,9 @@ packages/*/assets/
# closed-source platform (cloned separately)
/platform

# rust
/target

# WSL/Windows alternate data streams
*:Zone.Identifier
.dev.log
Expand All @@ -100,3 +103,11 @@ COMMIT_MSG.tmp
/canary.env
/integration-suite-state.json
/cli-integration-state.json

# Compressed failproofaid binaries — produced by
# .github/workflows/build-daemon.yml (or a local `cargo build --release` +
# gzip for manual Docker verification), uploaded as release assets, never
# committed. Same for npm-pack tarballs produced anywhere in the repo during
# local packaging tests.
/failproofaid-*.gz
*.tgz
Loading
Loading