Skip to content

Commit cb1a1e1

Browse files
committed
feat: improve local run reliability and coverage
Add agent readiness probing, interrupted-run recovery, stable finding review keys, expanded dashboard review controls, local packaging assets, and usage-focused integration coverage.
1 parent e758e6a commit cb1a1e1

17 files changed

Lines changed: 1693 additions & 39 deletions

File tree

.github/workflows/ci.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,3 +30,5 @@ jobs:
3030
- name: Test
3131
run: cargo test
3232

33+
- name: Packaging Smoke
34+
run: scripts/check-packaging.sh

.github/workflows/release.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@ jobs:
4646
cp "target/release/${{ matrix.binary }}" "dist/vuln-daemon-${{ matrix.name }}"
4747
chmod +x "dist/vuln-daemon-${{ matrix.name }}"
4848
tar -C dist -czf "dist/vuln-daemon-${{ matrix.name }}.tar.gz" "vuln-daemon-${{ matrix.name }}"
49+
if [[ "${{ matrix.os }}" == macos-* ]]; then
50+
./scripts/package-macos-app.sh "target/release/${{ matrix.binary }}" dist "Vulnerability Daemon-${{ matrix.name }}.app"
51+
fi
4952
5053
- name: Upload artifact
5154
uses: actions/upload-artifact@v4
@@ -67,4 +70,3 @@ jobs:
6770
uses: softprops/action-gh-release@v2
6871
with:
6972
files: dist/**/*.tar.gz
70-

README.md

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ brand mark, and the top-right review queue button:
2222
- Rotates across configured targets.
2323
- Uses local agent CLIs: `codex`, `claude`, or `cursor-agent`.
2424
- Randomizes agents when `agent` is set to `random`.
25+
- Probes agent readiness and excludes non-ready agents from random selection.
2526
- Stores markdown reports, normalized findings, raw logs, run metadata, and SARIF.
2627
- Tracks critical review state: `new`, `reviewed`, `accepted`, `false_positive`, `fixed`.
2728
- Serves a local dashboard and JSON API on `127.0.0.1`.
@@ -51,8 +52,10 @@ cargo install --path .
5152

5253
During development, use `cargo run --` in place of `vuln-daemon`.
5354

54-
This is still a source install. Packaged `.app`, Homebrew, and signed release
55-
binaries are planned so users do not need Rust installed.
55+
Release automation builds platform tarballs, and macOS release jobs also produce
56+
a `.app` bundle. A Homebrew formula template lives at
57+
[packaging/homebrew/vulnerability-daemon.rb.template](./packaging/homebrew/vulnerability-daemon.rb.template).
58+
Signed release binaries are still planned.
5659

5760
## Quick Start
5861

@@ -135,6 +138,12 @@ Reparse existing reports after upgrading parser logic:
135138
vuln-daemon reindex --config ./vuln-daemon.config.json
136139
```
137140

141+
Check local agent readiness and config posture:
142+
143+
```bash
144+
vuln-daemon doctor --config ./vuln-daemon.config.json
145+
```
146+
138147
## Config
139148

140149
See [config.example.json](./config.example.json).
@@ -152,7 +161,7 @@ Important fields:
152161
- `targets[].prompt_pack`: one of `generic`, `webapp`, `backend`, `smart-contract`, or `chain`.
153162

154163
`agent: "random"` chooses one installed agent from `codex`, `claude`, and
155-
`cursor-agent`.
164+
`cursor-agent` after a non-interactive readiness probe succeeds.
156165

157166
Set `model` only when you want to force a provider-specific model flag. Leave it
158167
as `null` to let each local agent use its own default model.
@@ -173,8 +182,11 @@ The daemon binds only to `127.0.0.1`.
173182
- `GET /api/runs/<run_id>/report`
174183
- `GET /api/findings`
175184
- `GET /api/sarif`
185+
- `GET /api/agent-health`
186+
- `GET /api/config`
176187
- `POST /api/run`
177188
- `POST /api/cancel`
189+
- `POST /api/open-config`
178190
- `POST /api/findings/<finding_id>/review`
179191

180192
Review request body:
@@ -263,5 +275,5 @@ private or sensitive repositories.
263275
- redacted public mode
264276
- per-project report retention policies
265277
- signed run metadata
266-
- direct GitHub/GitLab issue creation
278+
- local-first GitHub/GitLab handoff that makes network export explicit
267279
- prompt-pack marketplace

docs/product-v0.2.md

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
# Product Plan v0.2
2+
3+
## Positioning
4+
5+
Vulnerability Daemon is a local operator tool for protocol team leads who want
6+
recurring AI-assisted security review over local protocol repositories.
7+
8+
The product metric is accepted findings: a run is useful when it produces
9+
findings the team accepts as worth fixing, documenting, or explicitly rejecting.
10+
11+
## Policy Decisions
12+
13+
- Primary user: protocol team lead.
14+
- Agent policy: random among ready local agents by default; configurable to a
15+
specific agent.
16+
- Confidence policy: prefer `confirmed_by_code`; strong suspicious leads are
17+
allowed only when labelled `hypothesis`.
18+
- Privacy policy: strict local dashboard and artifact storage. External
19+
integrations stay opt-in and off by default.
20+
- Distribution priority: macOS app bundle and Homebrew formula.
21+
22+
## v0.2 Scope
23+
24+
1. Run trust
25+
- Probe local agents before use.
26+
- Exclude non-ready agents from random selection.
27+
- Recover long-stale `running` run metadata as `interrupted`.
28+
- Keep the HTTP dashboard bound to `127.0.0.1`.
29+
30+
2. Triage trust
31+
- Add stable finding fingerprints per target.
32+
- Preserve review state across reruns when the same finding reappears.
33+
- Track accepted findings in the dashboard.
34+
- Review all severities, not only criticals.
35+
36+
3. Local operations
37+
- Surface config path and agent health in the dashboard.
38+
- Keep source, reports, reviews, and issue drafts on local disk by default.
39+
40+
4. Distribution
41+
- Produce a macOS `.app` bundle from release builds.
42+
- Maintain a Homebrew formula template for tap publication.
43+
44+
## Deferred
45+
46+
- Hosted storage or hosted scheduling.
47+
- Multi-user auth.
48+
- Public redacted dashboard mode.
49+
- Direct GitHub/GitLab issue creation that sends vulnerability details off the
50+
machine.
51+
- Prompt-pack marketplace.
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
class VulnerabilityDaemon < Formula
2+
desc "Local-first AI vulnerability research daemon for recurring audits"
3+
homepage "https://github.com/NibiruChain/vulnerability-daemon"
4+
url "https://github.com/NibiruChain/vulnerability-daemon/archive/refs/tags/vVERSION.tar.gz"
5+
sha256 "SHA256"
6+
license "MIT"
7+
8+
depends_on "rust" => :build
9+
10+
def install
11+
system "cargo", "install", "--locked", "--path", ".", "--root", prefix
12+
end
13+
14+
service do
15+
run [opt_bin/"vuln-daemon", "serve", "--config", etc/"vulnerability-daemon/config.json"]
16+
keep_alive true
17+
log_path var/"log/vulnerability-daemon.stdout.log"
18+
error_log_path var/"log/vulnerability-daemon.stderr.log"
19+
end
20+
21+
test do
22+
assert_match "Local-first AI vulnerability research daemon", shell_output("#{bin}/vuln-daemon --help")
23+
end
24+
end

scripts/check-packaging.sh

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
#!/usr/bin/env bash
2+
set -euo pipefail
3+
4+
binary="${1:-target/debug/vuln-daemon}"
5+
6+
if [[ ! -x "$binary" ]]; then
7+
cargo build
8+
fi
9+
10+
tmpdir="$(mktemp -d)"
11+
trap 'rm -rf "$tmpdir"' EXIT
12+
13+
bash -n scripts/package-macos-app.sh
14+
artifact="$(scripts/package-macos-app.sh "$binary" "$tmpdir" "Vulnerability Daemon-smoke.app")"
15+
16+
test -f "$artifact"
17+
tar -tzf "$artifact" | grep -F "Vulnerability Daemon-smoke.app/Contents/Info.plist" >/dev/null
18+
tar -tzf "$artifact" | grep -F "Vulnerability Daemon-smoke.app/Contents/MacOS/vuln-daemon" >/dev/null
19+
tar -tzf "$artifact" | grep -F "Vulnerability Daemon-smoke.app/Contents/Resources/vulnerability-daemon-icon.svg" >/dev/null
20+
21+
formula="packaging/homebrew/vulnerability-daemon.rb.template"
22+
grep -F "class VulnerabilityDaemon < Formula" "$formula" >/dev/null
23+
grep -F "service do" "$formula" >/dev/null
24+
grep -F "test do" "$formula" >/dev/null
25+
26+
if command -v ruby >/dev/null 2>&1; then
27+
ruby -c "$formula" >/dev/null
28+
fi
29+
30+
echo "Packaging smoke checks passed"

scripts/package-macos-app.sh

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
#!/usr/bin/env bash
2+
set -euo pipefail
3+
4+
binary="${1:-target/release/vuln-daemon}"
5+
dist_dir="${2:-dist}"
6+
app_name="${3:-Vulnerability Daemon.app}"
7+
8+
if [[ ! -x "$binary" ]]; then
9+
echo "binary is not executable: $binary" >&2
10+
exit 1
11+
fi
12+
13+
app_dir="$dist_dir/$app_name"
14+
contents_dir="$app_dir/Contents"
15+
macos_dir="$contents_dir/MacOS"
16+
resources_dir="$contents_dir/Resources"
17+
18+
rm -rf "$app_dir"
19+
mkdir -p "$macos_dir" "$resources_dir"
20+
21+
cp "$binary" "$macos_dir/vuln-daemon"
22+
chmod +x "$macos_dir/vuln-daemon"
23+
cp "docs/assets/vulnerability-daemon-icon.svg" "$resources_dir/vulnerability-daemon-icon.svg"
24+
25+
cat > "$contents_dir/Info.plist" <<'PLIST'
26+
<?xml version="1.0" encoding="UTF-8"?>
27+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
28+
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
29+
<plist version="1.0">
30+
<dict>
31+
<key>CFBundleDevelopmentRegion</key>
32+
<string>en</string>
33+
<key>CFBundleExecutable</key>
34+
<string>vuln-daemon</string>
35+
<key>CFBundleIdentifier</key>
36+
<string>com.vulnerability-daemon.app</string>
37+
<key>CFBundleInfoDictionaryVersion</key>
38+
<string>6.0</string>
39+
<key>CFBundleName</key>
40+
<string>Vulnerability Daemon</string>
41+
<key>CFBundlePackageType</key>
42+
<string>APPL</string>
43+
<key>CFBundleShortVersionString</key>
44+
<string>0.1.0</string>
45+
<key>CFBundleVersion</key>
46+
<string>0.1.0</string>
47+
<key>LSMinimumSystemVersion</key>
48+
<string>12.0</string>
49+
<key>LSUIElement</key>
50+
<true/>
51+
<key>NSHighResolutionCapable</key>
52+
<true/>
53+
</dict>
54+
</plist>
55+
PLIST
56+
57+
tar -C "$dist_dir" -czf "$dist_dir/vulnerability-daemon-macos-app.tar.gz" "$app_name"
58+
echo "$dist_dir/vulnerability-daemon-macos-app.tar.gz"

0 commit comments

Comments
 (0)