Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 3cde6eb3da |
+17
-32
@@ -71,45 +71,30 @@ jobs:
|
|||||||
- name: Run integration tests
|
- name: Run integration tests
|
||||||
run: python3 -m unittest discover -t . -s tests/integration -v
|
run: python3 -m unittest discover -t . -s tests/integration -v
|
||||||
|
|
||||||
# Combined unit+integration coverage + the diff-coverage gate (the hard
|
# Combined unit+integration coverage report (informational). See
|
||||||
# gate: new/changed lines >= 90%). See docs/decisions/0004-coverage-policy.md.
|
# docs/decisions/0004-coverage-policy.md.
|
||||||
#
|
#
|
||||||
# This runs on a self-hosted KVM runner (label `kvm`), NOT ubuntu-latest,
|
# The hard diff-coverage gate (changed lines >= 90%) is DEFERRED: the
|
||||||
# because the Firecracker backend's subprocess/VM orchestration
|
# Firecracker backend's VM/SSH orchestration is covered by the integration
|
||||||
# (launch/boot/SSH/isolation-probe) is covered by the integration suite,
|
# suite, which needs /dev/kvm + the provisioned TAP/nft pool — a
|
||||||
# and that suite needs `/dev/kvm` + the provisioned TAP/nft pool — which a
|
# container-based runner skips it and those lines read uncovered, so the
|
||||||
# container-based runner doesn't have. On such a runner the firecracker
|
# gate can't pass here. Re-enabling it on a self-hosted KVM runner is
|
||||||
# integration test skips and its ~230 orchestration lines read as
|
# tracked separately (see PRD 0069 / #348 and the ci-runner branch).
|
||||||
# uncovered, so the gate can't pass there.
|
|
||||||
#
|
|
||||||
# Runner prerequisites (provision once on the host; see the README
|
|
||||||
# "Firecracker on Linux" section): the `firecracker` binary on PATH,
|
|
||||||
# `/dev/kvm` accessible to the runner user, Docker, the cached guest
|
|
||||||
# kernel + static dropbear (BOT_BOTTLE_FC_KERNEL / BOT_BOTTLE_FC_DROPBEAR),
|
|
||||||
# and the network pool installed as the persistent systemd unit
|
|
||||||
# (`./cli.py backend setup --backend=firecracker`). The preflight step
|
|
||||||
# below fails fast with instructions if anything is missing.
|
|
||||||
coverage:
|
coverage:
|
||||||
runs-on: [self-hosted, kvm]
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
|
||||||
- name: Preflight — Firecracker host is ready
|
- name: Set up Python
|
||||||
run: |
|
uses: actions/setup-python@v5
|
||||||
command -v firecracker >/dev/null || {
|
with:
|
||||||
echo "firecracker not on PATH — provision the runner (README: Firecracker on Linux)"; exit 1; }
|
python-version: "3.12"
|
||||||
test -e /dev/kvm || { echo "/dev/kvm missing — KVM not available on this runner"; exit 1; }
|
|
||||||
# `backend status` exits non-zero unless the TAP pool is up + no
|
|
||||||
# range overlap; it prints the exact `backend setup` fix.
|
|
||||||
python3 cli.py backend status --backend=firecracker
|
|
||||||
|
|
||||||
- name: Combined coverage (unit + integration, incl. firecracker)
|
- name: Install dev requirements
|
||||||
|
run: python3 -m pip install -r requirements-dev.txt
|
||||||
|
|
||||||
|
- name: Combined coverage report (unit + integration)
|
||||||
run: PYTHON=python3 bash scripts/coverage.sh critical
|
run: PYTHON=python3 bash scripts/coverage.sh critical
|
||||||
|
|
||||||
- name: Diff-coverage gate (changed lines >= 90%)
|
|
||||||
run: |
|
|
||||||
git fetch --no-tags origin main:refs/remotes/origin/main
|
|
||||||
python3 scripts/diff_coverage.py --base origin/main --min 90
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
# bot-bottle
|
# bot-bottle
|
||||||
|
|
||||||
[](https://gitea.dideric.is/didericis/bot-bottle/actions?workflow=test.yml)
|
[](https://gitea.dideric.is/didericis/bot-bottle/actions?workflow=test.yml)
|
||||||
[](https://coverage.readthedocs.io/)
|
[](https://coverage.readthedocs.io/)
|
||||||
[](https://gitea.dideric.is/didericis/bot-bottle/src/branch/main/docs/decisions/0004-coverage-policy.md)
|
[](https://gitea.dideric.is/didericis/bot-bottle/src/branch/main/docs/decisions/0004-coverage-policy.md)
|
||||||
|
|
||||||
**Problem:** Developer wants to run a coding agent without supervision, but they don't want a prompt injected or misbehaving agent wrecking their environment or exfiltrating sensitive data.
|
**Problem:** Developer wants to run a coding agent without supervision, but they don't want a prompt injected or misbehaving agent wrecking their environment or exfiltrating sensitive data.
|
||||||
@@ -90,8 +90,6 @@ BOT_BOTTLE_BACKEND=firecracker ./cli.py start <agent>
|
|||||||
|
|
||||||
> **NixOS:** enable `virtualisation.docker`, ensure the KVM module is loaded (`boot.kernelModules = [ "kvm-intel" ];` or `kvm-amd`), and add your user to the `kvm` and `docker` groups. For the network pool, consume the flake module — `imports = [ inputs.bot-bottle.nixosModules.firecracker-netpool ]; services.bot-bottle-firecracker = { enable = true; owner = "you"; };` — then `nixos-rebuild switch` (imperative nft/TAP rules don't survive a rebuild; channel users can `imports = [ <bot-bottle>/nix/firecracker-netpool.nix ]`). `firecracker` isn't in nixpkgs by default as a user binary — install the release binary (pin the version) and put it on `PATH`.
|
> **NixOS:** enable `virtualisation.docker`, ensure the KVM module is loaded (`boot.kernelModules = [ "kvm-intel" ];` or `kvm-amd`), and add your user to the `kvm` and `docker` groups. For the network pool, consume the flake module — `imports = [ inputs.bot-bottle.nixosModules.firecracker-netpool ]; services.bot-bottle-firecracker = { enable = true; owner = "you"; };` — then `nixos-rebuild switch` (imperative nft/TAP rules don't survive a rebuild; channel users can `imports = [ <bot-bottle>/nix/firecracker-netpool.nix ]`). `firecracker` isn't in nixpkgs by default as a user binary — install the release binary (pin the version) and put it on `PATH`.
|
||||||
|
|
||||||
> **CI:** the coverage gate (`.gitea/workflows/test.yml` → `coverage` job) runs on a self-hosted runner labelled `kvm`, because the Firecracker backend's VM/SSH orchestration is exercised only by the integration suite, which needs `/dev/kvm` + the provisioned pool (a container runner would skip it and read as uncovered). Provision that runner exactly like a normal Firecracker host — `firecracker` on `PATH`, `/dev/kvm`, Docker, the cached guest kernel + static dropbear, and the pool installed as the persistent systemd unit — then register it with the `kvm` label. The unit/lint jobs still run on `ubuntu-latest`.
|
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
./cli.py start <agent> # builds the image on first run, drops you into claude
|
./cli.py start <agent> # builds the image on first run, drops you into claude
|
||||||
```
|
```
|
||||||
|
|||||||
Reference in New Issue
Block a user