Skip to content

Commit 92fa3bd

Browse files
committed
chore: establish true main snapshot
0 parents  commit 92fa3bd

1,277 files changed

Lines changed: 294844 additions & 0 deletions

File tree

Some content is hidden

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

.agents/skills

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../skills

.cargo/audit.toml

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# cargo-audit ignore list.
2+
#
3+
# Each entry must name a RUSTSEC ID, the crate involved, and WHY we can't
4+
# fix it ourselves. The rule: only ignore advisories where the fix lives
5+
# in an upstream dep we don't control (Tauri / webkit / GTK / unic-*).
6+
# Anything that lands in our own code must be fixed, not ignored.
7+
8+
[advisories]
9+
ignore = [
10+
# --- rand unsoundness (RUSTSEC-2026-0097) ------------------------------
11+
# Affects rand 0.7.3, 0.8.5, 0.9.2. Reached via:
12+
# - tauri-utils/kuchikiki (0.7.3) -- Tauri
13+
# - tauri / reqwest / quinn-proto (0.9.2) -- Tauri + reqwest
14+
# - tokio-unix-ipc / tungstenite (0.8.5) -- upstream; service not
15+
# using custom loggers so we don't hit the unsound path
16+
# Unsound only with a custom logger calling rand::rng(); we don't.
17+
"RUSTSEC-2026-0097",
18+
19+
# --- glib VariantStrIter unsoundness (RUSTSEC-2024-0429) ---------------
20+
# Via webkit2gtk -> wry -> Tauri on Linux. Upstream has not cut a glib
21+
# 0.19+ release that Tauri's wry pins, and we don't use VariantStrIter.
22+
"RUSTSEC-2024-0429",
23+
24+
# --- Unmaintained unic-* crates (via urlpattern -> tauri-utils) --------
25+
# RUSTSEC-2025-0081 unic-char-property
26+
# RUSTSEC-2025-0075 unic-char-range
27+
# RUSTSEC-2025-0080 unic-common
28+
# RUSTSEC-2025-0100 unic-ucd-ident
29+
# RUSTSEC-2025-0098 unic-ucd-version
30+
# urlpattern 0.3 depends on the whole unic tree; Tauri 2.10 pins it.
31+
# Unmaintained != vulnerable; tracked so we drop this when Tauri updates.
32+
"RUSTSEC-2025-0081",
33+
"RUSTSEC-2025-0075",
34+
"RUSTSEC-2025-0080",
35+
"RUSTSEC-2025-0100",
36+
"RUSTSEC-2025-0098",
37+
38+
# --- rustls-pemfile 2.x unmaintained (RUSTSEC-2025-0134) ---------------
39+
# Used by capsem-core for cert loading. Author archived the crate; the
40+
# API is stable and we only call from_pem on trusted input. Swap target
41+
# is rustls-pki-types readers; tracked but not blocking.
42+
"RUSTSEC-2025-0134",
43+
]

.cargo/config.toml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
[target.'cfg(target_os = "macos")']
2+
runner = "scripts/run_signed.sh"
3+
4+
[target.aarch64-unknown-linux-musl]
5+
linker = "rust-lld"
6+
7+
[target.x86_64-unknown-linux-musl]
8+
linker = "rust-lld"
9+
10+
[target.x86_64-unknown-linux-gnu]
11+
linker = "x86_64-linux-gnu-gcc"
12+
13+
[target.aarch64-unknown-linux-gnu]
14+
linker = "aarch64-linux-gnu-gcc"

.claude/skills

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../skills

.config/nextest.toml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
[profile.ci.junit]
2+
path = "junit.xml"
3+
report-name = "capsem-tests"
4+
store-success-output = false
5+
store-failure-output = true

.dockerignore

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# Ignore massive host build artifacts
2+
target/
3+
node_modules/
4+
.venv/
5+
.pytest_cache/
6+
.ruff_cache/
7+
.astro/
8+
coverage/
9+
dist/
10+
site/node_modules/
11+
frontend/node_modules/
12+
frontend/dist/
13+
*.db
14+
*.sqlite
15+
*.log
16+
.DS_Store

.gemini/settings.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"mcpServers": {
3+
"capsem": {
4+
"command": "/Users/elieb/git/capsem-next/target/debug/capsem-mcp",
5+
"args": []
6+
}
7+
}
8+
}

.github/workflows/ci.yaml

Lines changed: 282 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,282 @@
1+
name: CI
2+
on:
3+
pull_request:
4+
push:
5+
branches: [main]
6+
7+
permissions:
8+
contents: read
9+
10+
jobs:
11+
# ---------------------------------------------------------------------------
12+
# Linux: compile + test KVM hypervisor backend (cfg(target_os = "linux"))
13+
# ---------------------------------------------------------------------------
14+
test-linux:
15+
runs-on: ubuntu-24.04-arm
16+
steps:
17+
- uses: actions/checkout@v5
18+
19+
- uses: dtolnay/rust-toolchain@stable
20+
with:
21+
components: llvm-tools
22+
23+
- uses: Swatinem/rust-cache@v2
24+
25+
# Try to enable KVM for integration tests. GitHub-hosted runners don't
26+
# always expose nested virt -- when /dev/kvm is absent the udev trigger
27+
# fails with "Failed to open the device 'kvm': Invalid argument". We
28+
# let that pass and fall through to a compile-only/no-KVM run; the
29+
# release pipeline owns real-KVM coverage. See sprints/done/ci-green.
30+
- name: Enable KVM (best-effort)
31+
continue-on-error: true
32+
run: |
33+
echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules
34+
sudo udevadm control --reload-rules
35+
sudo udevadm trigger --name-match=kvm
36+
37+
- name: Install tools
38+
run: |
39+
cargo install cargo-nextest --locked
40+
cargo install cargo-llvm-cov --locked
41+
42+
# Library + service crate tests with coverage (capsem-core includes KVM backend on Linux).
43+
# capsem-app (Tauri shell) and capsem-tray (macOS muda menu-bar) are macOS-only; every
44+
# other host crate is portable and runs here so it gets Linux-specific regression coverage.
45+
- name: Unit tests (KVM backend) with coverage
46+
run: |
47+
cargo llvm-cov nextest --no-cfg-coverage --profile ci --codecov --output-path codecov-linux.json --fail-under-lines 70 -p capsem-core -p capsem-agent -p capsem-logger -p capsem-proto -p capsem-guard -p capsem-gateway -p capsem-service -p capsem -p capsem-mcp -p capsem-mcp-aggregator -p capsem-mcp-builtin -p capsem-process
48+
cargo llvm-cov report --no-cfg-coverage --summary-only -p capsem-core -p capsem-agent -p capsem-logger -p capsem-proto -p capsem-guard -p capsem-gateway -p capsem-service -p capsem -p capsem-mcp -p capsem-mcp-aggregator -p capsem-mcp-builtin -p capsem-process 2>&1 | tee coverage-summary-linux.txt
49+
50+
- name: Upload Linux coverage
51+
if: ${{ !cancelled() }}
52+
uses: codecov/codecov-action@v5
53+
with:
54+
files: codecov-linux.json
55+
flags: linux-unit
56+
token: ${{ secrets.CODECOV_TOKEN }}
57+
fail_ci_if_error: false
58+
59+
# Note KVM exercise status. Hosted ARM runners may lack /dev/kvm; the
60+
# compile-only path still catches Linux build/lint regressions, and
61+
# real-KVM coverage runs in the release pipeline. Surfacing as a
62+
# warning (not an error) keeps CI honest about what was actually
63+
# exercised without false-failing on a runner-fleet limitation.
64+
- name: Note KVM exercise status
65+
run: |
66+
if [ -e /dev/kvm ]; then
67+
echo "KVM is available at /dev/kvm -- KVM-backed tests exercised."
68+
else
69+
echo "::warning::/dev/kvm not available on this runner -- compile + non-KVM tests only. Real-KVM coverage runs in release pipeline."
70+
fi
71+
72+
- name: Test summary
73+
if: always()
74+
run: |
75+
KVM_STATUS="available"
76+
[ -e /dev/kvm ] || KVM_STATUS="not available"
77+
COV=$(grep 'TOTAL' coverage-summary-linux.txt 2>/dev/null | awk '{print $(NF)}' || echo "?")
78+
79+
cat >> "$GITHUB_STEP_SUMMARY" << EOF
80+
## Linux Test Results
81+
82+
| Metric | Result |
83+
|--------|--------|
84+
| Runner | ubuntu-24.04-arm (aarch64) |
85+
| /dev/kvm | $KVM_STATUS |
86+
| Line coverage | $COV |
87+
| KVM backend | compiled (real-KVM tests run only when /dev/kvm is present) |
88+
EOF
89+
90+
# T5: preserve test artifacts on failure (Linux job).
91+
- name: Upload test artifacts on failure (Linux)
92+
if: failure()
93+
uses: actions/upload-artifact@v4
94+
with:
95+
name: test-artifacts-linux-${{ github.run_attempt }}
96+
path: |
97+
test-artifacts/
98+
frontend/test-artifacts/
99+
retention-days: 7
100+
if-no-files-found: ignore
101+
102+
# ---------------------------------------------------------------------------
103+
# macOS: full test suite (Apple VZ backend, frontend, Python, coverage)
104+
# ---------------------------------------------------------------------------
105+
test:
106+
runs-on: macos-14
107+
steps:
108+
- uses: actions/checkout@v5
109+
110+
- uses: dtolnay/rust-toolchain@stable
111+
with:
112+
targets: aarch64-unknown-linux-musl,x86_64-unknown-linux-musl
113+
components: llvm-tools
114+
115+
- uses: Swatinem/rust-cache@v2
116+
117+
- uses: pnpm/action-setup@v5
118+
with:
119+
version: 10
120+
- uses: actions/setup-node@v5
121+
with:
122+
node-version: 24
123+
cache: pnpm
124+
cache-dependency-path: frontend/pnpm-lock.yaml
125+
- run: cd frontend && pnpm install --frozen-lockfile
126+
127+
- uses: astral-sh/setup-uv@v5
128+
- run: uv sync
129+
130+
- name: Dependency audit
131+
run: |
132+
cargo install cargo-audit --locked
133+
cargo audit
134+
cd frontend && pnpm audit
135+
136+
- name: Install tools
137+
run: |
138+
cargo install cargo-llvm-cov --locked
139+
cargo install cargo-nextest --locked
140+
141+
# Unit tests: all crates with coverage + JUnit XML for test analytics.
142+
# capsem-app (Tauri bin) is macOS-only; capsem-mcp-aggregator and
143+
# capsem-mcp-builtin are thin binaries that pull capsem-core logic.
144+
- name: Unit tests with coverage
145+
run: |
146+
cargo llvm-cov nextest --no-cfg-coverage --profile ci --codecov --output-path codecov-unit.json --fail-under-lines 70 -p capsem-core -p capsem-agent -p capsem-logger -p capsem-proto -p capsem-guard -p capsem-gateway -p capsem-service -p capsem -p capsem-mcp -p capsem-mcp-aggregator -p capsem-mcp-builtin -p capsem-tray -p capsem-app -p capsem-process
147+
cargo llvm-cov report --no-cfg-coverage --summary-only -p capsem-core -p capsem-agent -p capsem-logger -p capsem-proto -p capsem-guard -p capsem-gateway -p capsem-service -p capsem -p capsem-mcp -p capsem-mcp-aggregator -p capsem-mcp-builtin -p capsem-tray -p capsem-app -p capsem-process 2>&1 | tee coverage-summary.txt
148+
149+
# Integration tests (tests/ directory, cross-crate)
150+
- name: Integration tests with coverage
151+
run: |
152+
cargo llvm-cov nextest --no-cfg-coverage --profile ci --codecov --output-path codecov-integration.json -p capsem-core --test '*' || true
153+
154+
# Frontend tests with coverage + JUnit output
155+
- name: Frontend type-check, test, and build
156+
run: |
157+
cd frontend
158+
pnpm run check
159+
npx vitest run --coverage --reporter=default --reporter=junit --outputFile=../frontend-junit.xml
160+
pnpm run build
161+
162+
# Python schema tests with coverage
163+
- name: Python schema tests with coverage
164+
run: uv run python -m pytest tests/ --cov=src/capsem --cov-report=xml:codecov-python.xml --cov-fail-under=90 --junitxml=python-junit.xml
165+
166+
# Python integration tests that need no VM
167+
- name: Python integration tests (non-VM suites)
168+
run: |
169+
uv run python -m pytest tests/capsem-bootstrap/ tests/capsem-codesign/ tests/capsem-rootfs-artifacts/ -v --tb=short
170+
171+
# Verify all integration test suites import cleanly (catches broken imports/syntax)
172+
- name: Verify all integration test imports
173+
run: |
174+
uv run python -m pytest tests/capsem-*/ --collect-only -q
175+
176+
# Schema drift check
177+
- name: Schema drift check
178+
run: |
179+
uv run python scripts/generate_schema.py
180+
git diff --exit-code config/settings-schema.json
181+
182+
# Upload coverage with flags
183+
- name: Upload Rust unit test coverage
184+
if: ${{ !cancelled() }}
185+
uses: codecov/codecov-action@v5
186+
with:
187+
files: codecov-unit.json
188+
flags: unit
189+
token: ${{ secrets.CODECOV_TOKEN }}
190+
fail_ci_if_error: true
191+
192+
- name: Upload Rust integration test coverage
193+
if: ${{ !cancelled() }}
194+
uses: codecov/codecov-action@v5
195+
with:
196+
files: codecov-integration.json
197+
flags: integration
198+
token: ${{ secrets.CODECOV_TOKEN }}
199+
fail_ci_if_error: false
200+
201+
- name: Upload frontend coverage
202+
if: ${{ !cancelled() }}
203+
uses: codecov/codecov-action@v5
204+
with:
205+
files: coverage/frontend/coverage-final.json
206+
flags: unit
207+
token: ${{ secrets.CODECOV_TOKEN }}
208+
fail_ci_if_error: false
209+
210+
- name: Upload Python coverage
211+
if: ${{ !cancelled() }}
212+
uses: codecov/codecov-action@v5
213+
with:
214+
files: codecov-python.xml
215+
flags: unit
216+
token: ${{ secrets.CODECOV_TOKEN }}
217+
fail_ci_if_error: false
218+
219+
# Upload test results for test analytics
220+
- name: Upload test results to Codecov
221+
if: ${{ !cancelled() }}
222+
uses: codecov/test-results-action@v1
223+
with:
224+
files: target/nextest/ci/junit.xml,frontend-junit.xml,python-junit.xml
225+
token: ${{ secrets.CODECOV_TOKEN }}
226+
227+
# T5: preserve every test artifact (service.log / process.log /
228+
# session.db etc.) on failure so PR reviewers can debug without
229+
# rerunning. preserve_tmp_dir_on_failure() in tests/helpers/service.py
230+
# populates `test-artifacts/` only on red runs; if-no-files-found
231+
# is "ignore" so green runs don't bloat the workflow.
232+
- name: Upload test artifacts on failure
233+
if: failure()
234+
uses: actions/upload-artifact@v4
235+
with:
236+
name: test-artifacts-${{ runner.os }}-${{ github.run_attempt }}
237+
path: |
238+
test-artifacts/
239+
frontend/test-artifacts/
240+
retention-days: 7
241+
if-no-files-found: ignore
242+
243+
# Check-only (no link) -- actual cross-compile runs on Linux in release workflow
244+
- name: Cross-compile check (guest binaries)
245+
run: |
246+
cargo check --release --target aarch64-unknown-linux-musl -p capsem-agent
247+
cargo check --release --target x86_64-unknown-linux-musl -p capsem-agent
248+
249+
- name: Test summary
250+
if: always()
251+
run: |
252+
COV=$(grep 'TOTAL' coverage-summary.txt 2>/dev/null | awk '{print $(NF)}' || echo "?")
253+
254+
cat >> "$GITHUB_STEP_SUMMARY" << EOF
255+
## Test Results
256+
257+
| Metric | Result |
258+
|--------|--------|
259+
| Line coverage | $COV |
260+
| Test results | See Codecov test analytics |
261+
| Cross-compile | aarch64-unknown-linux-musl |
262+
| Audit | cargo audit + pnpm audit |
263+
264+
> Coverage covers library crates + gateway (capsem-core, agent, logger, proto, gateway).
265+
> Full workspace coverage runs in the release pipeline.
266+
EOF
267+
268+
# ---------------------------------------------------------------------------
269+
# Install e2e: Docker-based install layout + systemd tests (Linux)
270+
# ---------------------------------------------------------------------------
271+
test-install:
272+
runs-on: ubuntu-24.04-arm
273+
steps:
274+
- uses: actions/checkout@v5
275+
276+
- uses: extractions/setup-just@v3
277+
278+
- name: Build host builder Docker image
279+
run: just build-host-image
280+
281+
- name: Run install e2e tests
282+
run: just test-install

0 commit comments

Comments
 (0)