Skip to content

Commit 4a4241a

Browse files
committed
feat: skillward — fused deterministic skill-scanner ensemble
0 parents  commit 4a4241a

48 files changed

Lines changed: 8786 additions & 0 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitattributes

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
* text=auto eol=lf
2+
3+
# SARIF fixtures are checked-in test data — never normalize line endings.
4+
*.sarif binary
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
---
2+
name: Bug report
3+
about: A scan, verdict, or exit code that behaves wrong
4+
title: ""
5+
labels: bug
6+
---
7+
8+
## What happened
9+
10+
The scan, verdict, or exit code that misbehaved, and what it should have been instead.
11+
12+
## Reproduce
13+
14+
```sh
15+
# the exact command
16+
skillward ...
17+
```
18+
19+
- Exit code: `$?`
20+
- Target: the skill, directory, or https URL (a small sample skill helps)
21+
22+
## Environment
23+
24+
- skillward version: `skillward --version`
25+
- OS + arch:
26+
- `--sandbox` mode: docker / host (and Docker version if relevant)
27+
28+
## Logs
29+
30+
The error line and any stderr output (run without `--no-color` stripping).
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
---
2+
name: Feature request
3+
about: A new scanner, output format, or capability
4+
title: ""
5+
labels: enhancement
6+
---
7+
8+
## Problem
9+
10+
What skillward cannot do today — a detection axis no bundled tool covers, an output
11+
format, a target type.
12+
13+
## Proposed change
14+
15+
The desired behavior. For a new scanner: the tool, its license, whether it runs
16+
deterministically and offline, and the unique axis it adds over the current ensemble.
17+
18+
## Alternatives
19+
20+
Workarounds already tried, or other tools that handle this.

.github/PULL_REQUEST_TEMPLATE.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
## Summary
2+
3+
-
4+
5+
## Test plan
6+
7+
- [ ] `cargo fmt --check && cargo clippy --all-targets --locked -- -D warnings && cargo test --locked` passes
8+
- [ ]

.github/dependabot.yml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
version: 2
2+
updates:
3+
- package-ecosystem: cargo
4+
directory: "/"
5+
schedule:
6+
interval: weekly
7+
groups:
8+
cargo:
9+
patterns: ["*"]
10+
11+
- package-ecosystem: github-actions
12+
directory: "/"
13+
schedule:
14+
interval: weekly
15+
groups:
16+
actions:
17+
patterns: ["*"]

.github/workflows/ci.yml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: [main]
6+
tags: ['*']
7+
pull_request:
8+
workflow_dispatch:
9+
10+
jobs:
11+
ci:
12+
uses: coroboros/ci/.github/workflows/rust-packages.yml@v0
13+
permissions:
14+
contents: write # GitHub Release + commit-back on tag
15+
id-token: write # crates.io + npm OIDC publish on tag
16+
secrets:
17+
# First publish of a new crate only — drop once Trusted Publishing is configured.
18+
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
19+
# Binary distribution ([package.metadata.dist] in Cargo.toml) — both optional:
20+
HOMEBREW_TAP_TOKEN: ${{ secrets.HOMEBREW_TAP_TOKEN }}
21+
NPM_PACKAGE_REGISTRY_TOKEN: ${{ secrets.NPM_PACKAGE_REGISTRY_TOKEN }}

.gitignore

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/target
2+
**/*.rs.bk
3+
*.pdb
4+
5+
# Local agent + editor noise
6+
.claude/settings.local.json
7+
.claude/output/
8+
CLAUDE.local.md
9+
10+
# Per-project credentials (see multi-account rule)
11+
.envrc
12+
.envrc.local
13+
14+
# OS
15+
.DS_Store
16+
*.log
17+
18+
# Scan reports written into the repo root during local runs (test fixtures under
19+
# tests/fixtures/sarif/ are tracked).
20+
/*.sarif
21+
/report.json

.tva

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
FOR ALL TIME. ALWAYS.

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# Changelog

CLAUDE.md

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
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

Comments
 (0)