|
| 1 | +# skillward |
| 2 | + |
| 3 | +A Rust CLI that vets an agent skill before you install it: orchestrates a Docker |
| 4 | +bundle of nine deterministic scanners, runs them offline, and fuses their findings |
| 5 | +into one verdict. The binary orchestrates; the bundle detects. |
| 6 | + |
| 7 | +## Canonical rules |
| 8 | + |
| 9 | +Follows the Coroboros engineering global rules. Repo-specific divergences are stated |
| 10 | +inline below. |
| 11 | + |
| 12 | +> **Public-repo hygiene:** ships into a public community repo. Never reference |
| 13 | +> private rule paths, local machine paths, or internal tooling here — keep it |
| 14 | +> generic. |
| 15 | +
|
| 16 | +## Tech Stack |
| 17 | +- Rust, edition 2024, toolchain pinned in `rust-toolchain.toml` |
| 18 | +- `clap` (derive) for the surface; `anstream` + `anstyle` for color; `rayon` for the parallel batch; `serde_json` for SARIF and the JSON report |
| 19 | +- Detection lives in the scanner bundle image, built in the GitLab repo `coroboros/infrastructure/skillward-bundle` from pinned sources — never re-authored here |
| 20 | +- `cargo fmt` / `cargo clippy` for format/lint; `assert_cmd` + `predicates` for CLI tests |
| 21 | + |
| 22 | +## Commands |
| 23 | +- `cargo build --release` — optimized binary (`strip`, thin LTO) |
| 24 | +- `cargo test` — unit + integration (fusion corpus, CLI contract) |
| 25 | +- `cargo clippy --all-targets -- -D warnings` — no-panic lints are deny-level |
| 26 | +- `cargo fmt --check` |
| 27 | +- The scanner bundle image is built and smoke-tested in `coroboros/infrastructure/skillward-bundle` (GitLab), not here. |
| 28 | + |
| 29 | +## Important Files |
| 30 | +- `src/main.rs` — parse, dispatch, map errors to exit codes |
| 31 | +- `src/error.rs` — `SkillwardError` and the stable exit-code map (`10`/`11`/`12`/`13`/`20`) |
| 32 | +- `src/scanners/mod.rs` — the nine adapters; their argv must mirror the bundle repo's `smoke-test.sh` |
| 33 | +- `src/sandbox.rs` — the hardened `docker run` wrapper (the isolation floor) |
| 34 | +- `src/bundle.rs` — the bundle image ref (the pinned, cosign-signed GitLab image; digest-pinnable) |
| 35 | +- `src/fusion.rs` — dedup, cross-tool correlation, verdict |
| 36 | +- `src/sarif.rs` — SARIF 2.1.0 in/out |
| 37 | +- `src/skills/mod.rs` — the bundled agent-skill registry; embeds `skills/skillward/SKILL.md` |
| 38 | +- `skills/skillward/SKILL.md` — the agent skill, installable via `npx skills add coroboros/skillward` |
| 39 | +- `tests/fusion.rs` + `tests/fixtures/sarif/` — the fusion completeness corpus |
| 40 | + |
| 41 | +## Rules |
| 42 | +- **No panics.** Every user-facing failure and every misbehaving tool routes through `SkillwardError` or a `tool-error` note; `unwrap`/`expect`/`panic` are deny-level lints. |
| 43 | +- **Exit codes are a contract.** The `error.rs` map is stable — never change a code, only add. Argument errors are clap's (exit `2`). |
| 44 | +- **Determinism at the sandbox, not the tool.** Every scan runs `--network=none --read-only --cap-drop=ALL --security-opt=no-new-privileges`; never trust a tool to stay offline on its own. |
| 45 | +- **Per-tool isolation.** A missing, crashed, or timed-out scanner is a `tool-error`, never an aborted run — and never a silent PASS (`all_engine_failed` catches a dead engine). |
| 46 | +- **Detection rules are inherited.** Bump pins in the bundle repo's `Dockerfile`; never author detection rules here. |
| 47 | +- **Adapters mirror the smoke test.** A change to an adapter's argv in `src/scanners/mod.rs` must land in the bundle repo's `smoke-test.sh` too. |
| 48 | +- **One skill source.** The agent skill lives once in `skills/skillward/SKILL.md`, embedded via `include_str!` for `skills get` and published for `npx skills add`; never duplicate its content. |
| 49 | +- Run `cargo fmt && cargo clippy --all-targets -- -D warnings && cargo test` before every commit. |
| 50 | + |
| 51 | +## CI overrides |
| 52 | +All other rules in `~/.agents/rules/git-conventions.md` apply. Divergences: |
| 53 | +- **CI** — consumes `coroboros/ci/.github/workflows/rust-packages.yml@v0` (see `.github/workflows/ci.yml`). The shared pipeline pins the version, generates the CHANGELOG, cuts the release, and imposes the cargo-deny policy centrally — so this repo carries **no `release-plz.toml` and no consumer `deny.toml`** (a local one is ignored). |
| 54 | +- **Branch model** — main-only: feature branch → PR → squash-merge → tag. |
| 55 | +- **Scanner bundle** — the image is built in a separate GitLab source-of-truth repo, `coroboros/infrastructure/skillward-bundle`, via the `coroboros/ci` container-images template: multi-arch, container-scanned, cosign-signed with a CycloneDX SBOM. It is published to `ghcr.io/coroboros/skillward-bundle` (mirrored to Docker Hub); the CLI pins that ref in `src/bundle.rs` (digest-pinnable via `SKILLWARD_BUNDLE_IMAGE`) and is versioned independently of the image. |
0 commit comments