Start every workflow with permissions: {} and grant the minimum
required per job, following Astral's defense-in-depth pattern so a
newly added job can't silently inherit repo read access.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds a ci nextest profile (30s slow-timeout, terminate-after 4, 2s leak-
timeout) and wires rust.yml's test and test-macos jobs to use it. Local
invocations keep using the tight default profile.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Default nextest emits a PASS line per test, which scrolls thousands of
lines in CI. `slow` shows only slow/failing tests plus the summary.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
actions/checkout v4 → v6.0.2, actions/upload-artifact v4 → v7.0.1,
actions/download-artifact v4 → v8.0.1. Silences the Node 20 deprecation
warnings ahead of the June 2026 forced cutover. All pins are full
commit SHAs with version comments.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- rust.yml: move clippy to nightly-2026-04-14 (was stable); also pin
fmt to the same nightly date for consistency. Both jobs now use the
dated nightly and the run-step uses `cargo +nightly-2026-04-14 ...`.
- AGENTS.md: update developer commands to match CI.
- Duration constructors: replace `Duration::from_secs(N * 60)` /
`Duration::from_millis(N * 1000)` with `from_mins` / `from_secs` /
`from_hours` across the workspace to satisfy clippy's new
`duration_suboptimal_units` lint. std::time::Duration only — custom
`settings::duration::Duration` sites kept on `from_secs`.
- map/unwrap_or cleanup: `.map(f).unwrap_or(v)` → `.map_or(v, f)`,
`.map(f).unwrap_or(false)` on Result → `.is_ok_and(f)`, per
`clippy::map_unwrap_or`.
- Misc lints: collapse nested `if` into match guard in
handler/llm/api.rs and run_state.rs; replace `columns.len() > 0`
with `!columns.is_empty()`; switch a pair of `sort_by` calls to
`sort_by_key`.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Addresses supply chain hardening items from #160:
- Pin taiki-e/install-action to commit SHA
- Pin rust:1-bookworm and oven/bun:1 to image digests
- Pin mintlify to 4.2.507
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Move async subprocess paths to Tokio or spawn_blocking, document the
intentional synchronous std::process::Command callsites, and make CI run
Clippy with --all-targets so the guardrail applies to test code too.
## Summary
- **Unify foreground and detach code paths**: Both `fabro run` modes now
go through the same `create_run() + start_run()` pipeline, with
foreground adding `attach_run()`. Only `--preflight` remains as a
special case.
- **Fix three bugs in create→start→attach path**: (1) `_run_engine`
crashed for `.fabro` workflows by hardcoding `run.toml` — now falls back
to `graph.fabro`; (2) `attach_run` couldn't detect crashed engines due
to zombie processes — `start_run` now returns the `Child` handle; (3)
`create_run` ignored `--run-id`.
- **Configure nextest slow-timeout profiles**: Tighten unit test timeout
to 2s slow / 4s kill, add `e2e` profile with 10s/30s. Switch CI and docs
to `cargo nextest run`.
## Test plan
- [ ] `cargo nextest run --workspace` passes with new timeout profiles
- [ ] `fabro run <workflow>` works in foreground mode (create + start +
attach)
- [ ] `fabro run --detach <workflow>` prints run ID and exits
- [ ] `fabro attach <run>` works standalone (without child handle)
- [ ] `fabro resume <run>` works for both `.toml` and `.fabro` workflows
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: Fabro <noreply@fabro.sh>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Remove rust-toolchain/rust-cache setup (pre-installed on self-hosted),
disable checkout clean, enable sccache and incremental compilation.
Split macOS tests into a separate job that only runs on workflow_dispatch
since release.yml already gates on macOS tests.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add release.yml: tag-triggered (v*) workflow that cross-compiles
for aarch64-apple-darwin and x86_64-unknown-linux-gnu, packages
archives with SHA256 checksums, and creates a GitHub Release
- Add workflow_dispatch, concurrency groups, and cache-on-failure
to rust.yml and typescript.yml
- Run clippy and test on both ubuntu-latest and macos-15
- Add release profile with thin LTO and strip to Cargo.toml
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
ubuntu-latest-16-cores requires a GitHub Team/Enterprise org plan and
was causing all jobs to stay queued indefinitely.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Updated: Cargo.toml workspace members, CI workflow paths, Dockerfile
COPY, AGENTS.md, skill mapping, and doc references.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Rust workflow runs fmt, clippy, and test on crate/cargo/openapi changes.
TypeScript workflow runs typecheck, test, and build on apps/packages changes.
Both use path filters so changes don't cross-trigger.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>