From 6fce4b4621e9466f8022160b2186d6b20c19978f Mon Sep 17 00:00:00 2001 From: "tmt-homelab-agent[bot]" Date: Fri, 23 Oct 2026 20:35:53 -0700 Subject: [PATCH 1/3] feat(harness): a build-test-fix cycle for every component Every component now owns setup/build/lint/test/fix/cycle in its own Makefile and the root Makefile is the umbrella. The interpreter is pinned to 3.12 and ruff to 0.17.1 inside every venv, so local and CI finally agree. - corvus-v2: the harness moves into corvus-v2/Makefile and gains the "fix" target the old "Build > Test > Fix" comment promised but never had. "build" is now a real proof (health + authenticated read + the 401 control) in scripts/dev_check.py. Deps floored at the tested versions, capped at the next major. - corvus-sdk: new harness; 54 tests (was 35), client.py and models.py at 100%. - corvus-cli: new harness; 50 tests from zero, main.py and config.py at 100%. - corvus-server / corvus-hooks: lint + import guards only. v1 is archived at v1-archive and not deployed; no tests are resurrected for it. - corvus-splunk: config validation (conf/xml/csv/py). - CI: a matrix over all six components, plus a phase-gates job for the mutation and conformance targets that BUILD-PLAN.md requires of CI but that CI had never run. The metrics drift guard now gates the test count. It previously compared only coverage percent (tolerance 7.0) and line totals, so the committed 108-tests/79.1% file passed against a 90-test/73.0% run. The tolerance is recalibrated to 1.0 now that the interpreter is pinned on both sides. Also: ruff --fix repaired 26 pre-existing violations in the archived corvus-hooks scripts. They are mechanical and behavior-preserving (IOError->OSError is the same object; Optional/Dict -> X | None under "from __future__ import annotations"), but they are a real diff on archived code, called out here so a reviewer sees them coming. docs/DEV-READINESS-REVIEW.md: the plan and vision against what the harness can prove today, with every claim instrumented. --- .github/workflows/ci-v2.yaml | 75 +++-- Makefile | 148 ++++---- corvus-cli/.gitignore | 9 + corvus-cli/Makefile | 47 +++ corvus-cli/pyproject.toml | 4 +- corvus-cli/tests/conftest.py | 82 +++++ corvus-cli/tests/test_config.py | 76 +++++ corvus-cli/tests/test_main.py | 428 ++++++++++++++++++++++++ corvus-hooks/.gitignore | 5 + corvus-hooks/Makefile | 48 +++ corvus-hooks/adapters/cline_hooks.py | 3 +- corvus-hooks/adapters/codex_hooks.py | 3 +- corvus-hooks/adapters/windsurf_hooks.py | 3 +- corvus-hooks/corvus-event-emit.py | 2 +- corvus-hooks/corvus-governance.py | 2 +- corvus-hooks/corvus-lifecycle.py | 2 +- corvus-hooks/corvus_core.py | 20 +- corvus-hooks/pyproject.toml | 25 ++ corvus-sdk/.gitignore | 4 + corvus-sdk/Makefile | 44 +++ corvus-sdk/pyproject.toml | 6 +- corvus-sdk/tests/test_client.py | 158 +++++++++ corvus-sdk/tests/test_models.py | 248 ++++++++++++++ corvus-server/.gitignore | 5 + corvus-server/Makefile | 56 ++++ corvus-splunk/.gitignore | 3 + corvus-splunk/Makefile | 28 ++ corvus-splunk/validate.py | 197 +++++++++++ corvus-v2/Makefile | 72 ++++ corvus-v2/coverage.json | 2 +- corvus-v2/junit.xml | 2 +- corvus-v2/requirements.txt | 11 +- corvus-v2/scripts/check_metrics.py | 67 ++-- corvus-v2/scripts/dev_check.py | 73 ++++ docs/DEV-READINESS-REVIEW.md | 213 ++++++++++++ docs/canonical-path/dev-metrics.json | 16 +- 36 files changed, 2038 insertions(+), 149 deletions(-) create mode 100644 corvus-cli/.gitignore create mode 100644 corvus-cli/Makefile create mode 100644 corvus-cli/tests/conftest.py create mode 100644 corvus-cli/tests/test_config.py create mode 100644 corvus-cli/tests/test_main.py create mode 100644 corvus-hooks/.gitignore create mode 100644 corvus-hooks/Makefile create mode 100644 corvus-hooks/pyproject.toml create mode 100644 corvus-sdk/.gitignore create mode 100644 corvus-sdk/Makefile create mode 100644 corvus-sdk/tests/test_models.py create mode 100644 corvus-server/.gitignore create mode 100644 corvus-server/Makefile create mode 100644 corvus-splunk/.gitignore create mode 100644 corvus-splunk/Makefile create mode 100644 corvus-splunk/validate.py create mode 100644 corvus-v2/Makefile create mode 100644 corvus-v2/scripts/dev_check.py create mode 100644 docs/DEV-READINESS-REVIEW.md diff --git a/.github/workflows/ci-v2.yaml b/.github/workflows/ci-v2.yaml index c736496..b17e125 100644 --- a/.github/workflows/ci-v2.yaml +++ b/.github/workflows/ci-v2.yaml @@ -1,9 +1,14 @@ name: CI v2 # NO paths filter (the adversarial review's high finding): a PR touching only -# corvus-sdk or the Makefile got ZERO CI — the blind spot. The suite is fast -# (the test ~16s, the smoke ~5s): every PR and main push runs everything. +# corvus-sdk or the Makefile got ZERO CI — the blind spot. The suite is fast: +# every PR and main push runs everything. # workflow_dispatch stays as the manual re-run lever for any sha. +# +# EVERY component runs its own harness. The live three (v2, sdk, cli) run a real +# build > lint > test cycle; the legacy/config three run their guards. The +# interpreter is pinned to 3.12 here and in the Makefiles — a mismatch changes the +# coverage number and used to hide behind a 7-point tolerance. on: push: branches: [main] @@ -11,7 +16,36 @@ on: workflow_dispatch: jobs: - test: + harness: + name: harness (${{ matrix.component }}) + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + component: + - corvus-v2 + - corvus-sdk + - corvus-cli + - corvus-server + - corvus-hooks + - corvus-splunk + defaults: + run: + working-directory: ${{ matrix.component }} + steps: + - uses: actions/checkout@v5 + - uses: actions/setup-python@v6 + with: + python-version: "3.12" + - name: Setup (pinned venv + deps) + run: make setup + - name: Build > Lint > Test + run: make cycle + + phase-gates: + # The P1 capability gate, actually gated: BUILD-PLAN.md requires 'the + # conformance suite runs green in CI with the mutation evidence'. At HEAD + # neither ran in CI — they were manual targets. They are manual no longer. runs-on: ubuntu-latest defaults: run: @@ -21,32 +55,17 @@ jobs: - uses: actions/setup-python@v6 with: python-version: "3.12" - - name: Install - run: | - python -m venv .venv - . .venv/bin/activate - pip install -r requirements.txt - pip install pytest pytest-cov httpx ruff==0.17.1 - - name: Lint - run: | - . .venv/bin/activate - ruff check corvus/ tests/ - - name: Tests with coverage - run: | - . .venv/bin/activate - pytest tests/ -v --cov=corvus --cov-report=term --cov-report=json:coverage.json --junitxml=junit.xml - - name: The metrics drift guard - run: | - . .venv/bin/activate - python scripts/gen_metrics.py --coverage coverage.json --junit junit.xml \ - --out /tmp/metrics-check.json --source "$GITHUB_SHA" - python scripts/check_metrics.py --expected ../docs/canonical-path/dev-metrics.json \ - --actual /tmp/metrics-check.json - - name: Coverage summary - run: | - . .venv/bin/activate - python -c 'import json; c = json.load(open("coverage.json")); t = c["totals"]; print("coverage: %.1f%% (%d/%d lines)" % (t["percent_covered"], t["covered_lines"], t["num_statements"]))' + - name: Setup + run: make setup + - name: Mutation evidence + run: make mutation + - name: Conformance run + run: make conformance + smoke: + # Kept from the original gate: the components install and import cleanly. + # Each component's build step now proves this too, but this job stays as the + # independent cross-component check that a packaging change cannot silently break. runs-on: ubuntu-latest steps: - uses: actions/checkout@v5 diff --git a/Makefile b/Makefile index e952af1..f46ff52 100644 --- a/Makefile +++ b/Makefile @@ -1,66 +1,82 @@ -# The Corvus dev harness — the Build > Test > Fix cycle, one command per step. -# `make cycle` is the full loop; every step is idempotent and fresh-clone safe. - -VENV := corvus-v2/.venv -PY := $(VENV)/bin/python -PIP := $(VENV)/bin/pip -METRICS := docs/canonical-path/dev-metrics.json - -.PHONY: setup lint test metrics run check cycle clean - -setup: ## Bootstrap the venv + the deps (fresh-clone safe) - python3 -m venv $(VENV) - $(PIP) install --quiet --upgrade pip - $(PIP) install --quiet -r corvus-v2/requirements.txt - $(PIP) install --quiet pytest pytest-cov ruff httpx - @echo "setup: ok" - -lint: ## Ruff over the v2 package and the tests - $(PY) -m ruff check corvus-v2/corvus/ corvus-v2/tests/ - @echo "lint: ok" - -test: ## The tests with the coverage measurement - cd corvus-v2 && .venv/bin/python -m pytest tests/ -q \ - --cov=corvus --cov-report=term --cov-report=json:coverage.json \ - --junitxml=junit.xml - @echo "test: ok" - -metrics: ## Regenerate the dev-metrics artifact from the last test run - $(PY) corvus-v2/scripts/gen_metrics.py \ - --coverage corvus-v2/coverage.json --junit corvus-v2/junit.xml --out $(METRICS) \ - --source "$$(git rev-parse --short HEAD)" --duration "$$(cd corvus-v2 && .venv/bin/python -c "import json;print(json.load(open('coverage.json')).get('duration',0) if False else 0)")" - @echo "metrics: regenerated" - -metrics-check: ## The drift guard: the committed metrics must match the fresh run - $(PY) corvus-v2/scripts/gen_metrics.py \ - --coverage corvus-v2/coverage.json --junit corvus-v2/junit.xml --out /tmp/metrics-check.json \ - --source "$$(git rev-parse --short HEAD)" - $(PY) corvus-v2/scripts/check_metrics.py --expected $(METRICS) --actual /tmp/metrics-check.json - -run: ## The server up + the live health check (the dev loop's "build" step) - cd corvus-v2 && .venv/bin/python -c "\ -import sys, threading, time, json, urllib.request;\ -sys.path.insert(0, '.');\ -from corvus.app import create_app;\ -from corvus.config import FleetConfig;\ -cfg = FleetConfig(name='dev-fleet', node_id='dev-1', api_key='dev-local-key');\ -app = create_app(config=cfg, db_path=':memory:');\ -t = threading.Thread(target=lambda: __import__('uvicorn').run(app, host='127.0.0.1', port=8932, log_level='error'), daemon=True);\ -t.start(); time.sleep(1.5);\ -r = json.loads(urllib.request.urlopen(urllib.request.Request('http://127.0.0.1:8932/health', headers={'X-Corvus-Key': 'dev-key'}), timeout=5).read());\ -assert r['status'] == 'ok', r;\ -print('run: ok —', r['fleet'])" - -check: lint test metrics-check ## The gates the CI runs (identical locally) - -cycle: check run ## THE Build > Test > Fix loop, one command - -clean: ## The artifacts - rm -rf $(VENV) corvus-v2/.pytest_cache corvus-v2/coverage.json /tmp/metrics-check.json - -# WP14: the mutation evidence + the conformance run (the phase-gate targets) -mutation: - cd corvus-v2 && .venv/bin/python -c "import sys; sys.path.insert(0, '.'); from corvus.conformance import run_mutation_suite; import json; r = run_mutation_suite(); print(json.dumps(r, indent=1)); exit(0 if r['all_mutants_caught'] else 1)" - -conformance: - cd corvus-v2 && .venv/bin/python -m corvus.engine_shim --port 8933 & sleep 2; .venv/bin/python -c "import sys; sys.path.insert(0, '.'); from corvus.conformance import conformance_run; import json; r = conformance_run('http://127.0.0.1:8933'); print(json.dumps(r, indent=1)); exit(0 if r['failed'] == 0 else 1)"; pkill -f "engine_shim --port 8933" || true +# The Corvus dev harness — the Build > Test > Fix cycle for EVERY component. +# Each component owns its cycle in /Makefile; this file is the umbrella +# that runs them all, so "does the repo work?" has one answer. +# +# Live components (real harnesses): corvus-v2, corvus-sdk, corvus-cli +# Legacy/config guards: corvus-server, corvus-hooks, corvus-splunk +# v1 is archived at branch v1-archive and is NOT deployed; its guards exist only +# so archived code cannot silently rot. No tests are resurrected for it. +# +# The component lists below are NOT cosmetic: the legacy three do not declare +# build/test (nothing to build or test), and corvus-splunk has no lint/fix (it is +# config, not Python). Looping a target over a component that lacks it aborts the +# whole umbrella with "No rule to make target", so each target runs over exactly +# the components that define it. +# +# The interpreter is PINNED to python3.12 (CI uses 3.12). Bare `python3` on this +# host is 3.15, and running the suite on it changes the coverage number enough to +# matter — that mismatch is what the pin removes. + +PYTHON ?= python3.12 + +# Live three: the full harness. +LIVE := corvus-v2 corvus-sdk corvus-cli +# Everything: setup, cycle and clean exist everywhere. +ALL := $(LIVE) corvus-server corvus-hooks corvus-splunk +# Python components: they lint and autofix. corvus-splunk is config (validate only). +PY := $(LIVE) corvus-server corvus-hooks + +V2 := corvus-v2 + +export PYTHON + +.PHONY: help setup build lint test fix cycle check clean metrics metrics-check run mutation conformance + +help: ## This list + @grep -E '^[a-z-]+:.*##' $(MAKEFILE_LIST) | sed 's/:.*##/ —/' + +setup: ## Bootstrap every component's venv + deps (fresh-clone safe) + @for c in $(ALL); do printf '\n== %s ==\n' "$$c"; $(MAKE) -C $$c setup || exit 1; done + @echo "\nsetup: all components ok" + +build: ## The live three's build proof (the legacy guards have nothing to build) + @for c in $(LIVE); do printf '\n== %s ==\n' "$$c"; $(MAKE) -C $$c build || exit 1; done + @echo "\nbuild: all live components ok" + +lint: ## Ruff over every Python component + @for c in $(PY); do printf '\n== %s ==\n' "$$c"; $(MAKE) -C $$c lint || exit 1; done + @echo "\nlint: all Python components ok" + +test: ## The live three's tests (the legacy guards have no tests by design) + @for c in $(LIVE); do printf '\n== %s ==\n' "$$c"; $(MAKE) -C $$c test || exit 1; done + @echo "\ntest: all live components ok" + +fix: ## The autofix step across every Python component + @for c in $(PY); do printf '\n== %s ==\n' "$$c"; $(MAKE) -C $$c fix || exit 1; done + @echo "\nfix: all Python components ok — run `make lint` to confirm" + +cycle: setup ## THE loop: setup, then every component's build > lint > test + @for c in $(ALL); do printf '\n===== %s =====\n' "$$c"; $(MAKE) -C $$c cycle || exit 1; done + @echo "\ncycle: ALL COMPONENTS OK" + +check: cycle ## The full gate set (what CI runs) — identical to cycle + +clean: ## Remove every component's regenerable state + @for c in $(ALL); do $(MAKE) -C $$c clean; done + @echo "clean: ok — run `make setup` to rebuild" + +# ── v2-specific targets, kept at the root for continuity ──────────────────── +metrics: ## Regenerate the committed dev-metrics artifact + $(MAKE) -C $(V2) metrics + +metrics-check: ## The metrics drift guard + $(MAKE) -C $(V2) metrics-check + +run: ## The engine up + the live proof + $(MAKE) -C $(V2) build + +mutation: ## The mutation evidence (the phase-gate target) + $(MAKE) -C $(V2) mutation + +conformance: ## The conformance run (the phase-gate target) + $(MAKE) -C $(V2) conformance diff --git a/corvus-cli/.gitignore b/corvus-cli/.gitignore new file mode 100644 index 0000000..7c5cc03 --- /dev/null +++ b/corvus-cli/.gitignore @@ -0,0 +1,9 @@ +# corvus-cli harness artifacts (component-local: the root .gitignore is not ours to edit) +.venv/ +.pytest_cache/ +.ruff_cache/ +.coverage +coverage.json +junit.xml +__pycache__/ +*.egg-info/ diff --git a/corvus-cli/Makefile b/corvus-cli/Makefile new file mode 100644 index 0000000..21a0767 --- /dev/null +++ b/corvus-cli/Makefile @@ -0,0 +1,47 @@ +# corvus-cli dev harness — the Build > Test > Fix cycle, one command per step. +# Every target is idempotent and fresh-clone safe; run from this directory (make -C corvus-cli ...). + +PYTHON ?= python3.12 +VENV := .venv +PY := $(VENV)/bin/python +PIP := $(VENV)/bin/pip +RUFF := $(VENV)/bin/ruff + +.PHONY: setup build lint test fix cycle clean + +setup: ## Create the 3.12 venv, install the deps and the pinned tooling + @test -d $(VENV) || $(PYTHON) -m venv $(VENV) + $(PIP) install --quiet --upgrade pip + $(PIP) install --quiet -e . + $(PIP) install --quiet ruff==0.17.1 pytest pytest-cov + @echo "setup: ok" + +build: setup ## Editable install + proof the entrypoint dispatches + $(PIP) install --quiet -e . + $(PIP) check # the resolved dependency set must be internally consistent + $(PY) -c "import corvus_cli.main as m; assert m.app is not None; print('import: ok')" + $(VENV)/bin/corvus --help > /dev/null + $(VENV)/bin/corvus check-target --help > /dev/null + @echo "build: ok" + +lint: ## Ruff over the package and the tests + $(RUFF) check src/ tests/ + @echo "lint: ok" + +test: ## The tests with coverage + junit evidence + $(PY) -m pytest tests/ -q --cov=corvus_cli --cov-report=term \ + --cov-report=json:coverage.json --junitxml=junit.xml + @echo "test: ok" + +fix: ## Apply the ruff autofixes (no `ruff format` — the repo does not use it) + $(RUFF) check --fix src/ tests/ + @echo "fix: ok" + +cycle: build lint test ## The one command: build, lint, test + +# clean removes only artifacts this harness generates (venv, caches, reports); nothing tracked +# or hand-written is in that list. PREFLIGHT:rollback-written — the rollback is `make setup && make cycle`. +clean: ## Drop the venv and the test artifacts + rm -rf $(VENV) .pytest_cache .ruff_cache src/corvus_cli/__pycache__ tests/__pycache__ + rm -f .coverage coverage.json junit.xml + @echo "clean: ok" diff --git a/corvus-cli/pyproject.toml b/corvus-cli/pyproject.toml index 3624fdd..281a257 100644 --- a/corvus-cli/pyproject.toml +++ b/corvus-cli/pyproject.toml @@ -3,7 +3,9 @@ name = "corvus-cli" version = "0.1.0" requires-python = ">=3.11" description = "CLI for the Corvus operational governance API" -dependencies = ["httpx>=0.27", "typer>=0.15", "rich>=13"] +# Floors are the versions the harness tested (python3.12), capped at the next +# MAJOR so a breaking release fails at install time rather than silently. +dependencies = ["httpx>=0.28,<1.0", "typer>=0.27,<1.0", "rich>=15,<16"] [project.scripts] corvus = "corvus_cli.main:app" diff --git a/corvus-cli/tests/conftest.py b/corvus-cli/tests/conftest.py new file mode 100644 index 0000000..a661cca --- /dev/null +++ b/corvus-cli/tests/conftest.py @@ -0,0 +1,82 @@ +"""Fixtures for the CLI suite: a hermetic environment and an in-memory HTTP transport. + +No test ever opens a socket - every httpx.Client the CLI builds gets a MockTransport. +""" + +from __future__ import annotations + +import json +from dataclasses import dataclass, field +from typing import Any + +import httpx +import pytest + +from corvus_cli import main + + +@pytest.fixture(autouse=True) +def isolated_env(monkeypatch, tmp_path): + """Hermetic env: no real ~/.corvus.json and no inherited CORVUS_* variables.""" + monkeypatch.setenv("HOME", str(tmp_path)) + monkeypatch.delenv("CORVUS_URL", raising=False) + monkeypatch.delenv("CORVUS_TOKEN", raising=False) + return tmp_path + + +@dataclass +class Call: + """One request the CLI actually sent.""" + + method: str + url: str + path: str + headers: dict + params: dict + body: Any = None + + +@dataclass +class FakeAPI: + """A route table plus a record of what was requested.""" + + routes: dict = field(default_factory=dict) + calls: list = field(default_factory=list) + + def on(self, method: str, path: str, payload: Any, status: int = 200) -> FakeAPI: + self.routes[(method.upper(), path)] = (status, payload) + return self + + def handler(self, request: httpx.Request) -> httpx.Response: + self.calls.append( + Call( + method=request.method, + url=str(request.url), + path=request.url.path, + headers=dict(request.headers), + params=dict(request.url.params), + body=json.loads(request.content) if request.content else None, + ) + ) + status, payload = self.routes.get((request.method, request.url.path), (404, {"detail": "no route"})) + return httpx.Response(status, json=payload) + + def call(self, method: str, path: str) -> Call: + """The one recorded call to (method, path).""" + matches = [c for c in self.calls if c.method == method.upper() and c.path == path] + assert len(matches) == 1, f"expected exactly one {method} {path}, recorded {self.calls}" + return matches[0] + + +@pytest.fixture +def api(monkeypatch) -> FakeAPI: + """Route every httpx.Client through an in-memory transport (never a live server).""" + fake = FakeAPI() + real_client = httpx.Client + + def factory(*args, **kwargs): + kwargs["transport"] = httpx.MockTransport(fake.handler) + return real_client(*args, **kwargs) + + monkeypatch.setattr(main.httpx, "Client", factory) + return fake diff --git a/corvus-cli/tests/test_config.py b/corvus-cli/tests/test_config.py new file mode 100644 index 0000000..ae5603d --- /dev/null +++ b/corvus-cli/tests/test_config.py @@ -0,0 +1,76 @@ +"""config.py - resolution order is env var, then ~/.corvus.json, then the default.""" + +from __future__ import annotations + +import json + +from corvus_cli import config + + +def _write_config(home, payload: dict) -> None: + (home / ".corvus.json").write_text(json.dumps(payload)) + + +def test_base_url_defaults_to_localhost_when_nothing_configured(): + assert config.get_base_url() == "http://localhost:8000" + + +def test_base_url_comes_from_env(monkeypatch): + monkeypatch.setenv("CORVUS_URL", "http://corvus.test:9420/") + assert config.get_base_url() == "http://corvus.test:9420" + + +def test_base_url_strips_every_trailing_slash(monkeypatch): + monkeypatch.setenv("CORVUS_URL", "http://corvus.test:9420///") + assert config.get_base_url() == "http://corvus.test:9420" + + +def test_base_url_comes_from_config_file(isolated_env): + _write_config(isolated_env, {"url": "https://corvus.example/"}) + assert config.get_base_url() == "https://corvus.example" + + +def test_base_url_config_file_without_url_key_falls_back(isolated_env): + _write_config(isolated_env, {"token": "t"}) + assert config.get_base_url() == "http://localhost:8000" + + +def test_base_url_env_wins_over_config_file(monkeypatch, isolated_env): + _write_config(isolated_env, {"url": "https://from-file"}) + monkeypatch.setenv("CORVUS_URL", "https://from-env") + assert config.get_base_url() == "https://from-env" + + +def test_empty_env_url_falls_through_to_config_file(monkeypatch, isolated_env): + _write_config(isolated_env, {"url": "https://from-file"}) + monkeypatch.setenv("CORVUS_URL", "") + assert config.get_base_url() == "https://from-file" + + +def test_token_comes_from_env(monkeypatch): + monkeypatch.setenv("CORVUS_TOKEN", "env-token") + assert config.get_token() == "env-token" + + +def test_token_comes_from_config_file(isolated_env): + _write_config(isolated_env, {"token": "file-token"}) + assert config.get_token() == "file-token" + + +def test_token_defaults_to_empty_string(): + assert config.get_token() == "" + + +def test_token_env_wins_over_config_file(monkeypatch, isolated_env): + _write_config(isolated_env, {"token": "file-token"}) + monkeypatch.setenv("CORVUS_TOKEN", "env-token") + assert config.get_token() == "env-token" + + +def test_load_config_file_returns_empty_dict_when_absent(): + assert config._load_config_file() == {} + + +def test_load_config_file_reads_the_json(isolated_env): + _write_config(isolated_env, {"url": "https://corvus.example", "token": "abc"}) + assert config._load_config_file() == {"url": "https://corvus.example", "token": "abc"} diff --git a/corvus-cli/tests/test_main.py b/corvus-cli/tests/test_main.py new file mode 100644 index 0000000..39c5a62 --- /dev/null +++ b/corvus-cli/tests/test_main.py @@ -0,0 +1,428 @@ +"""main.py - every command exercised through typer's CliRunner against a mocked HTTP layer.""" + +from __future__ import annotations + +import runpy +import sys +import warnings + +import pytest +from typer.testing import CliRunner + +from corvus_cli.main import app + +runner = CliRunner() + + +def run(*args: str): + """Invoke the CLI and fail loudly on a non-zero exit.""" + result = runner.invoke(app, list(args)) + assert result.exit_code == 0, f"exit {result.exit_code}: {result.stdout} {result.stderr}" + return result + + +# -- Pre-action checks -- + + +def test_check_target_reports_recommendation_and_counts(api): + api.on("GET", "/ops/events/targets/caddy/status", { + "recommendation": "GO", + "active_changes": [{}, {}], + "recent_incidents": [{}], + }) + out = run("check-target", "caddy").stdout + assert "GO" in out + assert "caddy" in out + assert "Active changes: 2" in out + assert "Recent incidents: 1" in out + + +def test_check_target_unknown_recommendation_has_no_count_lines(api): + api.on("GET", "/ops/events/targets/caddy/status", {}) + out = run("check-target", "caddy").stdout + assert "UNKNOWN" in out + assert "Active changes" not in out + assert "Recent incidents" not in out + + +def test_unrouted_request_exits_1_and_names_the_status(api): + result = runner.invoke(app, ["metrics"]) + assert result.exit_code == 1 + assert "Error 404" in result.stdout + + +def test_server_error_body_is_printed_and_exits_1(api): + api.on("GET", "/ops/events/context", {"detail": "boom"}, status=500) + result = runner.invoke(app, ["context"]) + assert result.exit_code == 1 + assert "Error 500" in result.stdout + assert "boom" in result.stdout + + +def test_blast_radius_with_no_dependencies(api): + api.on("GET", "/ops/graph/blast-radius/redis", {"affected": []}) + out = run("blast-radius", "redis").stdout + assert "redis" in out + assert "No downstream dependencies found" in out + + +def test_blast_radius_renders_a_table_and_handles_missing_fields(api): + api.on("GET", "/ops/graph/blast-radius/caddy", { + "affected": [ + {"name": "redis", "host": "tmtdockp01", "depth": 2}, + {"name": "db"}, + ], + }) + out = run("blast-radius", "caddy").stdout + assert "Blast Radius: caddy" in out + assert "redis" in out + assert "tmtdockp01" in out + assert "db" in out + assert "?" in out + + +def test_dependency_chain_prints_the_payload(api): + api.on("GET", "/ops/graph/dependency-chain/caddy", {"service": "caddy", "upstream": ["dns", "proxy"]}) + out = run("dependency-chain", "caddy").stdout + assert "caddy" in out + assert "upstream" in out + assert "dns" in out + + +# -- Context -- + + +def test_context_summarises_events_incidents_changes_and_gaps(api): + api.on("GET", "/ops/events/context", { + "events_24h": [{}, {}, {}], + "active_incidents": [ + {"id": "INC-1", "target": "caddy", "severity": "critical", "title": "Down"}, + ], + "active_changes": [{}], + "gaps": {"total_open_gaps": 7}, + }) + out = run("context").stdout + assert "Events (24h): 3" in out + assert "Active incidents: 1" in out + assert "Active changes: 1" in out + assert "Open gaps: 7" in out + assert "INC-1" in out + assert "critical" in out + + +def test_context_with_no_incidents_skips_the_table(api): + api.on("GET", "/ops/events/context", {"events_24h": [], "active_incidents": [], "active_changes": []}) + out = run("context").stdout + assert "Open gaps: 0" in out + assert "Active Incidents" not in out + + +# -- Changes -- + + +def test_create_change_splits_comma_separated_targets(api): + api.on("POST", "/ops/changes", {"id": "CHG-1"}) + out = run("create-change", "caddy, redis ,db", "-d", "drain the pool").stdout + assert "Change created: CHG-1" in out + body = api.call("POST", "/ops/changes").body + assert body["targets"] == ["caddy", "redis", "db"] + assert body["description"] == "drain the pool" + assert body["created_by"] == "corvus-cli" + assert body["rollback_plan"] == "" + assert body["project"] == "" + + +def test_create_change_sends_the_optional_fields(api): + api.on("POST", "/ops/changes", {"id": "CHG-2"}) + run( + "create-change", "caddy", "-d", "drain", + "--operator", "todd", "--rollback", "restart caddy", "--project", "ai", + ) + body = api.call("POST", "/ops/changes").body + assert body["created_by"] == "todd" + assert body["rollback_plan"] == "restart caddy" + assert body["project"] == "ai" + + +def test_close_change_defaults_to_completed(api): + api.on("PATCH", "/ops/changes/CHG-1", {"id": "CHG-1"}) + out = run("close-change", "CHG-1").stdout + assert "Change closed: CHG-1" in out + assert api.call("PATCH", "/ops/changes/CHG-1").body == {"status": "completed", "outcome": "completed"} + + +def test_close_change_uses_the_given_outcome(api): + api.on("PATCH", "/ops/changes/CHG-9", {"id": "CHG-9"}) + run("close-change", "CHG-9", "--outcome", "failed") + assert api.call("PATCH", "/ops/changes/CHG-9").body["outcome"] == "failed" + + +def test_changes_with_none_active(api): + api.on("GET", "/ops/changes/active", []) + assert "No active changes" in run("changes").stdout + + +def test_changes_parses_targets_given_as_a_json_string(api): + api.on("GET", "/ops/changes/active", [ + {"id": "CHG-1", "targets": '["caddy", "redis"]', "description": "drain", "created_by": "todd"}, + {"id": "CHG-2", "targets": ["db"], "description": "restart", "created_by": "bot"}, + ]) + out = run("changes").stdout + assert "CHG-1" in out + assert "caddy, redis" in out + assert "CHG-2" in out + assert "db" in out + + +# -- Events -- + + +def test_emit_event_sends_the_payload(api): + api.on("POST", "/ops/events", {"id": "EVT-1"}) + out = run( + "emit-event", "-s", "agent", "-t", "change.started", + "--target", "proxy", "--severity", "warning", + ).stdout + assert "Event emitted: EVT-1" in out + assert api.call("POST", "/ops/events").body == { + "source": "agent", + "type": "change.started", + "target": "proxy", + "severity": "warning", + "data": {}, + } + + +def test_emit_event_defaults_target_and_severity(api): + api.on("POST", "/ops/events", {"id": "EVT-2"}) + run("emit-event", "--source", "agent", "--type", "session.started") + body = api.call("POST", "/ops/events").body + assert body["target"] == "" + assert body["severity"] == "info" + + +# -- Incidents -- + + +def test_incidents_with_none_found_sends_no_filters(api): + api.on("GET", "/ops/incidents", []) + assert "No incidents found" in run("incidents").stdout + assert api.call("GET", "/ops/incidents").params == {} + + +def test_incidents_sends_every_filter_as_a_param(api): + api.on("GET", "/ops/incidents", []) + run("incidents", "--status", "open", "--target", "caddy", "--severity", "critical") + assert api.call("GET", "/ops/incidents").params == { + "status": "open", + "target": "caddy", + "severity": "critical", + } + + +def test_incidents_renders_a_table(api): + api.on("GET", "/ops/incidents", [ + {"id": "INC-1", "target": "caddy", "severity": "critical", "status": "open", "title": "Down"}, + ]) + out = run("incidents").stdout + assert "Incidents" in out + assert "INC-1" in out + assert "caddy" in out + assert "open" in out + + +def test_create_incident_sends_the_payload(api): + api.on("POST", "/ops/incidents", {"id": "INC-2"}) + out = run( + "create-incident", "caddy", "-t", "Down", + "--description", "502s", "--severity", "critical", "--detected-by", "agent", + ).stdout + assert "Incident created: INC-2" in out + assert api.call("POST", "/ops/incidents").body == { + "target": "caddy", + "title": "Down", + "description": "502s", + "severity": "critical", + "detected_by": "agent", + } + + +# -- CMDB -- + + +def test_services_with_none_registered(api): + api.on("GET", "/ops/cmdb", []) + assert "No services found" in run("services").stdout + assert api.call("GET", "/ops/cmdb").params == {} + + +def test_services_filters_and_marks_critical(api): + api.on("GET", "/ops/cmdb", [ + {"name": "caddy", "service_type": "proxy", "host": "tmtdockp01", "critical": True}, + {"name": "db", "critical": False}, + ]) + out = run("services", "--service-type", "proxy", "--host", "tmtdockp01").stdout + assert api.call("GET", "/ops/cmdb").params == {"service_type": "proxy", "host": "tmtdockp01"} + assert "caddy" in out + assert "🔴" in out + assert "db" in out + assert "-" in out + + +def test_service_prints_the_details(api): + api.on("GET", "/ops/cmdb/caddy", {"name": "caddy", "critical": True, "host": "tmtdockp01"}) + out = run("service", "caddy").stdout + assert "caddy" in out + assert "critical" in out + assert "tmtdockp01" in out + + +# -- Triage -- + + +def test_triage_renders_the_full_diagnosis(api): + api.on("POST", "/ops/runbooks/triage", { + "status": "triaged", + "triage_id": "TRG-1", + "diagnosis": "port 443 closed", + "confidence": 0.87, + "escalation_required": True, + }) + out = run("triage", "caddy", "--host", "tmtdockp01", "--service-type", "proxy").stdout + assert "triaged — TRG-1" in out + assert "Diagnosis: port 443 closed" in out + assert "Confidence: 87%" in out + assert "Escalation required" in out + assert api.call("POST", "/ops/runbooks/triage").body == { + "target": "caddy", + "host": "tmtdockp01", + "service_type": "proxy", + } + + +def test_triage_minimal_response(api): + api.on("POST", "/ops/runbooks/triage", {}) + out = run("triage", "caddy").stdout + assert "unknown — ?" in out + assert "Diagnosis" not in out + assert "Escalation" not in out + + +# -- Metrics, gaps, signal quality -- + + +def test_metrics_reports_every_field(api): + api.on("GET", "/ops/metrics", { + "events_24h": 42, + "open_incidents": 2, + "active_changes": 1, + "false_positive_rate": 3.5, + "compliance_rate": 91.2, + "total_services": 12, + }) + out = run("metrics").stdout + assert "Events (24h): 42" in out + assert "Open incidents: 2" in out + assert "Active changes: 1" in out + assert "FP rate: 3.5%" in out + assert "Compliance rate: 91.2%" in out + assert "Total services: 12" in out + + +def test_metrics_defaults_to_zero(api): + api.on("GET", "/ops/metrics", {}) + out = run("metrics").stdout + assert "Events (24h): 0" in out + assert "FP rate: 0%" in out + + +def test_gaps_lists_the_workstream_breakdown(api): + api.on("GET", "/ops/gaps", {"total_open_gaps": 5, "by_workstream": {"accuracy": 2, "coverage": 3}}) + out = run("gaps").stdout + assert "Open gaps: 5" in out + assert "accuracy: 2" in out + assert "coverage: 3" in out + + +def test_gaps_without_a_workstream_breakdown(api): + api.on("GET", "/ops/gaps", {"total_open_gaps": 0}) + out = run("gaps").stdout + assert "Open gaps: 0" in out + + +def test_signal_quality_defaults_to_seven_days(api): + api.on("GET", "/ops/signal-quality", { + "total_resolved": 10, + "false_positives": 1, + "false_positive_rate": 10.0, + }) + out = run("signal-quality").stdout + assert "Total resolved (7d): 10" in out + assert "False positives: 1" in out + assert "FP rate: 10.0%" in out + assert api.call("GET", "/ops/signal-quality").params == {"days": "7"} + + +def test_signal_quality_honours_a_custom_window(api): + api.on("GET", "/ops/signal-quality", {"total_resolved": 4}) + out = run("signal-quality", "--days", "30").stdout + assert "Total resolved (30d): 4" in out + assert api.call("GET", "/ops/signal-quality").params == {"days": "30"} + + +# -- The HTTP client -- + + +def test_bearer_token_is_sent_when_configured(api, monkeypatch): + monkeypatch.setenv("CORVUS_TOKEN", "secret-token") + api.on("GET", "/ops/metrics", {}) + run("metrics") + assert api.call("GET", "/ops/metrics").headers.get("authorization") == "Bearer secret-token" + + +def test_no_authorization_header_without_a_token(api): + api.on("GET", "/ops/metrics", {}) + run("metrics") + assert "authorization" not in api.call("GET", "/ops/metrics").headers + + +def test_base_url_from_the_environment_reaches_the_request(api, monkeypatch): + monkeypatch.setenv("CORVUS_URL", "http://corvus.test:9420/") + api.on("GET", "/ops/events/context", {}) + run("context") + assert api.call("GET", "/ops/events/context").url == "http://corvus.test:9420/ops/events/context" + + +# -- The entrypoint -- + + +def test_help_lists_every_command(): + out = run("--help").stdout + for name in ( + "check-target", + "blast-radius", + "dependency-chain", + "context", + "create-change", + "close-change", + "changes", + "emit-event", + "incidents", + "create-incident", + "services", + "service", + "triage", + "metrics", + "gaps", + "signal-quality", + ): + assert name in out, f"{name} missing from --help" + + +def test_module_runs_as_main(monkeypatch): + monkeypatch.setattr(sys, "argv", ["corvus", "--help"]) + with warnings.catch_warnings(): + warnings.simplefilter("ignore", RuntimeWarning) + with pytest.raises(SystemExit) as exc: + runpy.run_module("corvus_cli.main", run_name="__main__") + assert exc.value.code == 0 diff --git a/corvus-hooks/.gitignore b/corvus-hooks/.gitignore new file mode 100644 index 0000000..8b5fb9a --- /dev/null +++ b/corvus-hooks/.gitignore @@ -0,0 +1,5 @@ +# Component-local artifacts (the root .gitignore is owned elsewhere) +.venv/ +__pycache__/ +*.pyc +.ruff_cache/ diff --git a/corvus-hooks/Makefile b/corvus-hooks/Makefile new file mode 100644 index 0000000..4b3f054 --- /dev/null +++ b/corvus-hooks/Makefile @@ -0,0 +1,48 @@ +# The corvus-hooks guard — legacy v1 hooks must lint and import cleanly. +# +# v1 is ARCHIVED (branch v1-archive) and NOT deployed. This is rot protection, not +# a test suite: there are deliberately no tests here. The hooks are stdlib-only +# (json/os/sys/re/subprocess/urllib/platform/typing) so setup installs tooling only. +# +# Most files are scripts with hyphens in the name (corvus-governance.py, ...) and so +# are not importable as modules; corvus_core.py is the one real importable module. + +PYTHON ?= python3.12 +VENV := .venv +PY := $(VENV)/bin/python +PIP := $(VENV)/bin/pip +RUFF := $(VENV)/bin/ruff + +.PHONY: setup lint import fix cycle clean + +# Auto-bootstrap: any target that needs the venv triggers setup exactly once, so +# `make cycle` is genuinely the one command on a fresh clone (this is a real file +# target, not .PHONY — it is a no-op while .venv/bin/ruff exists). +$(VENV)/bin/ruff: + $(MAKE) setup + +setup: ## Bootstrap the pinned 3.12 venv + tooling (the hooks need no third-party deps) + $(PYTHON) -m venv $(VENV) + $(PIP) install --quiet --upgrade pip + $(PIP) install --quiet ruff==0.17.1 pytest pytest-cov + @echo "setup: ok — hooks are stdlib-only, no requirements file to install" + +lint: $(VENV)/bin/ruff ## Ruff over every hook, adapter and the shared core (config in pyproject.toml) + $(RUFF) check . + +import: $(VENV)/bin/ruff ## The real proof: byte-compile every script, then import the shared core + $(PY) -c "import pathlib, py_compile; \ +files = sorted(p for p in pathlib.Path('.').rglob('*.py') if '.venv' not in p.parts); \ +[py_compile.compile(str(p), doraise=True) for p in files]; \ +print(f'import: byte-compiled {len(files)} scripts')" + $(PY) -c "import sys; sys.path.insert(0, '.'); import corvus_core as c; \ +assert all(hasattr(c, n) for n in ('check_target', 'emit_event', 'classify_intent', 'is_destructive_mcp_tool')); \ +print('import: ok — corvus_core imported, public API present')" + +fix: $(VENV)/bin/ruff ## Ruff autofixes (no ruff format — this repo does not use it) + $(RUFF) check --fix . + +cycle: lint import ## The guard, one command + +clean: ## The venv + the lint/byte-compile artifacts + rm -rf $(VENV) .ruff_cache __pycache__ adapters/__pycache__ diff --git a/corvus-hooks/adapters/cline_hooks.py b/corvus-hooks/adapters/cline_hooks.py index 589cdbb..1a154bc 100644 --- a/corvus-hooks/adapters/cline_hooks.py +++ b/corvus-hooks/adapters/cline_hooks.py @@ -45,7 +45,6 @@ import os import sys - sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) import corvus_core as core @@ -200,7 +199,7 @@ def main(): else: print(f"Unknown mode: {mode}", file=sys.stderr) sys.exit(1) - except (json.JSONDecodeError, IOError): + except (OSError, json.JSONDecodeError): respond() diff --git a/corvus-hooks/adapters/codex_hooks.py b/corvus-hooks/adapters/codex_hooks.py index 8ca59f2..391ac9b 100644 --- a/corvus-hooks/adapters/codex_hooks.py +++ b/corvus-hooks/adapters/codex_hooks.py @@ -32,7 +32,6 @@ import os import sys - # Add parent dir to path for corvus_core import sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) import corvus_core as core @@ -162,7 +161,7 @@ def main(): else: print(f"Unknown mode: {mode}", file=sys.stderr) sys.exit(1) - except (json.JSONDecodeError, IOError): + except (OSError, json.JSONDecodeError): sys.exit(0) diff --git a/corvus-hooks/adapters/windsurf_hooks.py b/corvus-hooks/adapters/windsurf_hooks.py index 94350f2..180018f 100644 --- a/corvus-hooks/adapters/windsurf_hooks.py +++ b/corvus-hooks/adapters/windsurf_hooks.py @@ -44,7 +44,6 @@ import os import sys - sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) import corvus_core as core @@ -129,7 +128,7 @@ def cmd_stdin_check(): """Read JSON from stdin (for pipe-based integration).""" try: data = json.loads(sys.stdin.read()) - except (json.JSONDecodeError, IOError): + except (OSError, json.JSONDecodeError): sys.exit(0) # Support both command-style and tool-style input diff --git a/corvus-hooks/corvus-event-emit.py b/corvus-hooks/corvus-event-emit.py index 197bff9..16a8e71 100755 --- a/corvus-hooks/corvus-event-emit.py +++ b/corvus-hooks/corvus-event-emit.py @@ -25,7 +25,7 @@ def main(): try: raw = sys.stdin.read() data = json.loads(raw) - except (json.JSONDecodeError, IOError): + except (OSError, json.JSONDecodeError): sys.exit(0) tool_name = data.get("tool_name", "") diff --git a/corvus-hooks/corvus-governance.py b/corvus-hooks/corvus-governance.py index bea8f28..403881a 100755 --- a/corvus-hooks/corvus-governance.py +++ b/corvus-hooks/corvus-governance.py @@ -27,7 +27,7 @@ def main(): try: raw = sys.stdin.read() data = json.loads(raw) - except (json.JSONDecodeError, IOError): + except (OSError, json.JSONDecodeError): sys.exit(0) tool_name = data.get("tool_name", "") diff --git a/corvus-hooks/corvus-lifecycle.py b/corvus-hooks/corvus-lifecycle.py index 5a88bbc..7fd31a8 100755 --- a/corvus-hooks/corvus-lifecycle.py +++ b/corvus-hooks/corvus-lifecycle.py @@ -92,7 +92,7 @@ def main(): try: raw = sys.stdin.read() data = json.loads(raw) - except (json.JSONDecodeError, IOError): + except (OSError, json.JSONDecodeError): sys.exit(0) prompt = data.get("user_prompt", "") diff --git a/corvus-hooks/corvus_core.py b/corvus-hooks/corvus_core.py index 6ea591c..6e83553 100644 --- a/corvus-hooks/corvus_core.py +++ b/corvus-hooks/corvus_core.py @@ -19,7 +19,7 @@ import subprocess import urllib.error import urllib.request -from typing import Any, Dict, Optional, Tuple +from typing import Any # --------------------------------------------------------------------------- # Configuration @@ -41,7 +41,7 @@ # --------------------------------------------------------------------------- -def get_api_key() -> Optional[str]: +def get_api_key() -> str | None: """Retrieve Corvus API key. Tries macOS keychain, then env var.""" # macOS keychain if platform.system() == "Darwin": @@ -65,7 +65,7 @@ def get_api_key() -> Optional[str]: # --------------------------------------------------------------------------- -def check_target(target: str, api_key: Optional[str] = None) -> Optional[Dict[str, Any]]: +def check_target(target: str, api_key: str | None = None) -> dict[str, Any] | None: """Call Corvus GET /ops/events/targets/{target}/status. Returns dict with keys: target, recommendation (GO/CAUTION/STOP), @@ -95,8 +95,8 @@ def emit_event( target: str, source: str = "ai-assistant", severity: str = "info", - data: Optional[Dict[str, Any]] = None, - api_key: Optional[str] = None, + data: dict[str, Any] | None = None, + api_key: str | None = None, ) -> bool: """POST an event to Corvus. Returns True on success.""" if not api_key: @@ -182,7 +182,7 @@ def emit_event( } -def extract_target_from_command(command: str) -> Optional[str]: +def extract_target_from_command(command: str) -> str | None: """Extract infrastructure target from a shell command. Returns container/volume/network/stack name, or None if not destructive. @@ -216,7 +216,7 @@ def extract_target_from_command(command: str) -> Optional[str]: return None -def extract_action_from_command(command: str) -> Optional[Tuple[str, str]]: +def extract_action_from_command(command: str) -> tuple[str, str] | None: """Extract (action, target) from a shell command for event emission. Returns (action, target) tuple or None. @@ -275,7 +275,7 @@ def normalize_mcp_tool_name(tool_name: str) -> str: return tool_name -def extract_target_from_mcp(tool_name: str, tool_input: Dict[str, Any]) -> Optional[str]: +def extract_target_from_mcp(tool_name: str, tool_input: dict[str, Any]) -> str | None: """Extract target from an MCP tool call's input dict.""" canonical = normalize_mcp_tool_name(tool_name) primary = MCP_TARGET_FIELDS.get(canonical) @@ -295,7 +295,7 @@ def is_destructive_mcp_tool(tool_name: str) -> bool: return canonical in MCP_TARGET_FIELDS -def get_mcp_event_type(tool_name: str) -> Optional[str]: +def get_mcp_event_type(tool_name: str) -> str | None: """Get the Corvus event type for an MCP tool.""" canonical = normalize_mcp_tool_name(tool_name) return MCP_EVENT_MAP.get(canonical) @@ -384,7 +384,7 @@ def get_mcp_event_type(tool_name: str) -> Optional[str]: ] -def classify_intent(prompt: str) -> Optional[str]: +def classify_intent(prompt: str) -> str | None: """Classify user intent: 'incident', 'change', 'design', or None.""" for pattern in INCIDENT_PATTERNS: if pattern.search(prompt): diff --git a/corvus-hooks/pyproject.toml b/corvus-hooks/pyproject.toml new file mode 100644 index 0000000..72a1000 --- /dev/null +++ b/corvus-hooks/pyproject.toml @@ -0,0 +1,25 @@ +# Ruff config for the legacy v1 governance hooks. +# +# v1 is ARCHIVED (branch v1-archive) and not deployed — this file exists so the +# hooks cannot silently rot. The rule set is pinned EXPLICITLY rather than left to +# ruff's defaults, because those drift: ruff 0.15 enabled 59 rules by default and +# ruff 0.17 enables 407, which would flip this guard red on a tool upgrade alone. +# +# The select list matches corvus-server/pyproject.toml so both legacy components +# are held to one standard. It is ruff-only — there is deliberately no [project] +# table, so this file cannot be mistaken for an installable package. +[tool.ruff] +line-length = 120 +target-version = "py312" + +[tool.ruff.lint] +select = ["E", "F", "W", "I", "N", "UP", "S", "B", "A", "C4", "SIM"] +ignore = [ + "S310", # urlopen against the operator-configured Corvus URL is the hook's whole job + "S603", # shelling out to the local git/installer binaries is intentional + "S607", # ditto — the hooks resolve git from PATH by design + "SIM102", # 2 nested ifs in the archived adapters; ruff marks the collapse UNSAFE, so the dead code stays untouched +] + +[tool.ruff.lint.isort] +known-first-party = ["corvus_core"] diff --git a/corvus-sdk/.gitignore b/corvus-sdk/.gitignore new file mode 100644 index 0000000..eb9f454 --- /dev/null +++ b/corvus-sdk/.gitignore @@ -0,0 +1,4 @@ +# Component-local artifacts (the root .gitignore already covers .venv/) +.venv/ +coverage.json +junit.xml diff --git a/corvus-sdk/Makefile b/corvus-sdk/Makefile new file mode 100644 index 0000000..168e532 --- /dev/null +++ b/corvus-sdk/Makefile @@ -0,0 +1,44 @@ +# corvus-sdk dev harness — the build > lint > test loop, one command per step. +# python3.12 is PINNED: bare python3 on this host is 3.15 and breaks parity with CI. + +PYTHON ?= python3.12 +VENV := .venv +PY := $(VENV)/bin/python +PIP := $(VENV)/bin/pip +RUFF := $(VENV)/bin/ruff + +.PHONY: setup build lint test fix cycle clean + +setup: ## Bootstrap the 3.12 venv, the component deps and the pinned tooling + $(PYTHON) -m venv $(VENV) + $(PIP) install --quiet --upgrade pip + $(PIP) install --quiet -e ".[dev]" + $(PIP) install --quiet ruff==0.17.1 pytest pytest-cov + @echo "setup: ok" + +build: ## The editable install plus a real import + client/model proof + $(PIP) install --quiet -e . + $(PIP) check # the resolved dependency set must be internally consistent + $(PY) -c 'import corvus_sdk as s; c = s.CorvusClient("http://corvus:8000/", token="t"); assert c._base_url == "http://corvus:8000", c._base_url; assert s.Event("E-1", "t0", "src", "change.completed", "tg").data == {}; assert issubclass(s.CorvusError, Exception); print("build: ok —", s.__version__)' + @echo "build: ok" + +lint: ## Ruff over the package and the tests + $(RUFF) check src/ tests/ + @echo "lint: ok" + +test: ## The tests with the coverage measurement + $(PY) -m pytest tests/ -q --cov=corvus_sdk --cov-report=term --cov-report=json:coverage.json --junitxml=junit.xml + @echo "test: ok" + +fix: ## Apply the auto-fixable lint findings + $(RUFF) check --fix src/ tests/ + @echo "fix: ok" + +cycle: build lint test ## THE one command: build > lint > test + +# clean only touches artifacts this harness created: the venv and the test reports. +# PREFLIGHT:rollback-written — the rollback is `make setup` (and `make test`), which +# recreates every deleted artifact from pyproject.toml in one command. +clean: ## The venv and the test artifacts (recoverable: make setup + make test) + rm -rf $(VENV) .coverage coverage.json junit.xml .pytest_cache .ruff_cache + @echo "clean: ok" diff --git a/corvus-sdk/pyproject.toml b/corvus-sdk/pyproject.toml index 5bdebda..686e611 100644 --- a/corvus-sdk/pyproject.toml +++ b/corvus-sdk/pyproject.toml @@ -3,10 +3,12 @@ name = "corvus-sdk" version = "0.1.0" requires-python = ">=3.11" description = "Lightweight Python SDK for the Corvus operational governance API" -dependencies = ["httpx>=0.27"] +# Floors are the versions the harness tested (python3.12), capped at the next +# MAJOR so a breaking release fails at install time rather than silently. +dependencies = ["httpx>=0.28,<1.0"] [project.optional-dependencies] -dev = ["pytest>=8", "pytest-asyncio>=1", "respx>=0.22"] +dev = ["pytest>=9,<10", "pytest-asyncio>=1.4,<2", "respx>=0.23,<1"] [build-system] requires = ["hatchling"] diff --git a/corvus-sdk/tests/test_client.py b/corvus-sdk/tests/test_client.py index cbf305f..81a3693 100644 --- a/corvus-sdk/tests/test_client.py +++ b/corvus-sdk/tests/test_client.py @@ -1,5 +1,7 @@ """Tests for CorvusClient — all API operations.""" +import json + import httpx import pytest import respx @@ -514,3 +516,159 @@ async def test_500_error(self, client): async with client as c: with pytest.raises(CorvusError): await c.metrics() + + +# --------------------------------------------------------------------------- +# Step submission + triage continuation +# --------------------------------------------------------------------------- + + +class TestStepFlow: + @respx.mock + async def test_submit_step_posts_its_result(self, client): + route = respx.post(f"{BASE}/ops/runbooks/steps/STEP-1/result").mock( + return_value=httpx.Response(200, json={ + "step_id": "STEP-1", + "status": "submitted", + "triage_id": "TRG-1", + "all_steps_complete": True, + "total_steps": 2, + "pending_steps": 0, + }) + ) + async with client as c: + step = await c.submit_step("STEP-1", output={"stdout": "ok"}) + assert step.all_steps_complete is True + assert json.loads(route.calls.last.request.content) == { + "output": {"stdout": "ok"}, + "error": None, + "success": True, + } + + @respx.mock + async def test_submit_step_reports_a_failed_step(self, client): + route = respx.post(f"{BASE}/ops/runbooks/steps/STEP-2/result").mock( + return_value=httpx.Response(200, json={ + "step_id": "STEP-2", + "status": "submitted", + "triage_id": "TRG-1", + "all_steps_complete": False, + "total_steps": 2, + "pending_steps": 1, + }) + ) + async with client as c: + step = await c.submit_step("STEP-2", error="command timed out", success=False) + assert step.pending_steps == 1 + body = json.loads(route.calls.last.request.content) + assert body["error"] == "command timed out" + assert body["success"] is False + + @respx.mock + async def test_continue_triage(self, client): + respx.post(f"{BASE}/ops/runbooks/steps/triage/TRG-1/continue").mock( + return_value=httpx.Response(200, json={ + "status": "triaged", + "triage_id": "TRG-1", + "target": "caddy", + "service_type": "proxy", + "diagnosis": "config_drift", + "root_cause": "stale Caddyfile", + "confidence": 0.8, + "escalation_required": True, + "restart_safe": False, + }) + ) + async with client as c: + result = await c.continue_triage("TRG-1") + assert result.diagnosis == "config_drift" + assert result.escalation_required is True + assert result.restart_safe is False + + @respx.mock + async def test_pending_steps_filters_by_triage(self, client): + route = respx.get(f"{BASE}/ops/runbooks/steps/pending").mock( + return_value=httpx.Response(200, json=[{"id": "STEP-1", "command": "docker logs caddy"}]) + ) + async with client as c: + assert len(await c.pending_steps()) == 1 + assert dict(route.calls.last.request.url.params) == {} + assert len(await c.pending_steps("TRG-1")) == 1 + assert dict(route.calls.last.request.url.params) == {"triage_id": "TRG-1"} + + +# --------------------------------------------------------------------------- +# List filters — the query params the server filters on +# --------------------------------------------------------------------------- + + +class TestListFilters: + @respx.mock + async def test_list_incidents_sends_its_filters(self, client): + route = respx.get(f"{BASE}/ops/incidents").mock( + return_value=httpx.Response(200, json=[]) + ) + async with client as c: + await c.list_incidents(status="open", target="vllm", severity="warning") + params = route.calls.last.request.url.params + assert (params["status"], params["target"], params["severity"]) == ("open", "vllm", "warning") + + @respx.mock + async def test_list_services_sends_its_filters(self, client): + route = respx.get(f"{BASE}/ops/cmdb").mock( + return_value=httpx.Response(200, json=[]) + ) + async with client as c: + await c.list_services(service_type="proxy", host="host-01", critical=False) + params = route.calls.last.request.url.params + assert params["service_type"] == "proxy" + assert params["host"] == "host-01" + assert params["critical"] == "false" + + @respx.mock + async def test_compliance_audit_sends_its_filters(self, client): + route = respx.get(f"{BASE}/ops/metrics/compliance").mock( + return_value=httpx.Response(200, json={"coverage_rate": 95.0}) + ) + async with client as c: + await c.compliance_audit(since="2026-03-01", source="corvus-sdk") + params = route.calls.last.request.url.params + assert params["since"] == "2026-03-01" + assert params["source"] == "corvus-sdk" + + +# --------------------------------------------------------------------------- +# Dual-shape server fields — JSON-string or native list +# --------------------------------------------------------------------------- + + +class TestDualShapeFields: + @respx.mock + async def test_create_change_accepts_native_list_targets(self, client): + respx.post(f"{BASE}/ops/changes").mock( + return_value=httpx.Response(200, json={ + "id": "CHG-2", + "created_at": "2026-03-31T10:00:00", + "created_by": "corvus-sdk", + "status": "active", + "targets": ["caddy", "litellm"], + "description": "Rolling restart", + }) + ) + async with client as c: + change = await c.create_change(["caddy", "litellm"], "Rolling restart") + assert change.targets == ["caddy", "litellm"] + + @respx.mock + async def test_get_service_accepts_native_list_dependencies(self, client): + respx.get(f"{BASE}/ops/cmdb/litellm").mock( + return_value=httpx.Response(200, json={ + "id": "SVC-2", + "name": "litellm", + "dependencies": ["postgresql"], + }) + ) + async with client as c: + svc = await c.get_service("litellm") + assert svc.dependencies == ["postgresql"] + assert svc.alert_policy == "default" diff --git a/corvus-sdk/tests/test_models.py b/corvus-sdk/tests/test_models.py new file mode 100644 index 0000000..4ef8c4f --- /dev/null +++ b/corvus-sdk/tests/test_models.py @@ -0,0 +1,248 @@ +"""Tests for the response models — required fields, defaults and per-instance state.""" + +import pytest + +import corvus_sdk +from corvus_sdk.models import ( + Change, + Event, + Incident, + Problem, + Service, + StepResult, + TriageResult, +) + + +def test_change_defaults_and_optionals(): + change = Change( + id="CHG-1", + created_at="2026-03-31T10:00:00", + created_by="corvus-sdk", + status="active", + targets=["caddy"], + description="Update Caddyfile", + ) + assert (change.rollback_plan, change.project) == ("", "") + assert change.expires_at is None + assert change.completed_at is None + assert change.outcome is None + + closed = Change( + id="CHG-2", + created_at="2026-03-31T10:00:00", + created_by="ops", + status="completed", + targets=["vllm"], + description="Restart", + rollback_plan="restart --previous", + project="inference", + expires_at="2026-03-31T11:00:00", + completed_at="2026-03-31T10:20:00", + outcome="success", + ) + assert closed.rollback_plan == "restart --previous" + assert closed.completed_at == "2026-03-31T10:20:00" + assert closed.outcome == "success" + + +def test_event_defaults_and_optionals(): + event = Event( + id="EVT-1", timestamp="2026-03-31T10:00:00", source="corvus-sdk", type="change.started", target="caddy" + ) + assert event.severity == "info" + assert event.data == {} + assert event.related_incident_id is None + assert event.related_change_id is None + + linked = Event( + id="EVT-2", + timestamp="2026-03-31T10:00:00", + source="corvus-sdk", + type="incident.opened", + target="vllm", + severity="warning", + data={"reason": "oom"}, + related_incident_id="INC-1", + related_change_id="CHG-1", + ) + assert linked.severity == "warning" + assert linked.data == {"reason": "oom"} + assert linked.related_incident_id == "INC-1" + assert linked.related_change_id == "CHG-1" + + +def test_incident_defaults_and_optionals(): + incident = Incident( + id="INC-1", + created_at="2026-03-31T10:00:00", + detected_by="corvus-sdk", + target="vllm", + status="open", + severity="warning", + title="GPU OOM", + ) + assert incident.description is None + assert incident.root_cause is None + assert incident.remediation_applied is None + assert incident.resolved_at is None + assert incident.resolution_time_minutes is None + + resolved = Incident( + id="INC-2", + created_at="2026-03-31T10:00:00", + detected_by="corvus-sdk", + target="vllm", + status="resolved", + severity="critical", + title="GPU OOM", + description="VRAM exhausted", + root_cause="kv-cache leak", + remediation_applied="restart", + resolved_at="2026-03-31T10:12:00", + resolution_time_minutes=12, + ) + assert resolved.root_cause == "kv-cache leak" + assert resolved.remediation_applied == "restart" + assert resolved.resolution_time_minutes == 12 + + +def test_problem_defaults_and_optionals(): + problem = Problem(id="PRB-1", created_at="2026-03-31T10:00:00", status="identified", title="Recurring GPU OOM") + assert problem.pattern is None + assert problem.root_cause is None + assert problem.workstream is None + assert problem.severity == "medium" + assert problem.correlated_incidents == [] + + tracked = Problem( + id="PRB-2", + created_at="2026-03-31T10:00:00", + status="in_progress", + title="Config drift", + pattern="caddy reloads weekly", + root_cause="out-of-band edit", + severity="high", + correlated_incidents=["INC-1", "INC-2"], + workstream="CI", + ) + assert tracked.correlated_incidents == ["INC-1", "INC-2"] + assert tracked.workstream == "CI" + + +def test_service_defaults_and_optionals(): + service = Service(id="SVC-1", name="caddy") + assert service.host is None + assert service.service_type is None + assert service.critical is False + assert service.dependencies == [] + assert service.baseline_behavior == {} + assert service.alert_policy == "default" + + registered = Service( + id="SVC-2", + name="litellm", + host="host-01", + service_type="proxy", + critical=True, + dependencies=["postgresql"], + baseline_behavior={"p99_ms": 120}, + alert_policy="strict", + ) + assert registered.critical is True + assert registered.dependencies == ["postgresql"] + assert registered.alert_policy == "strict" + + +def test_step_result_carries_all_counters(): + step = StepResult( + step_id="STEP-1", + status="submitted", + triage_id="TRG-1", + all_steps_complete=False, + total_steps=3, + pending_steps=2, + ) + assert step.step_id == "STEP-1" + assert step.all_steps_complete is False + assert (step.total_steps, step.pending_steps) == (3, 2) + + +def test_triage_result_defaults_and_optionals(): + triage = TriageResult(status="pending_steps", triage_id="TRG-1", target="caddy", service_type="proxy") + assert triage.runbook_name is None + assert triage.diagnosis is None + assert triage.root_cause is None + assert triage.confidence == 0.0 + assert triage.escalation_required is False + assert triage.restart_safe is None + assert triage.pending_steps == [] + + completed = TriageResult( + status="triaged", + triage_id="TRG-2", + target="vllm", + service_type="inference", + runbook_name="inference-oom.yaml", + diagnosis="gpu_oom", + root_cause="VRAM exhaustion", + confidence=0.9, + escalation_required=True, + restart_safe=False, + pending_steps=[{"id": "STEP-1"}], + ) + assert completed.runbook_name == "inference-oom.yaml" + assert completed.confidence == 0.9 + assert completed.escalation_required is True + assert completed.restart_safe is False + assert completed.pending_steps == [{"id": "STEP-1"}] + + +def test_required_fields_are_enforced(): + """A missing required field must raise, not silently default.""" + with pytest.raises(TypeError): + Service(id="SVC-1") # name is required + with pytest.raises(TypeError): + StepResult(step_id="STEP-1") # status/triage_id/counters are required + + +def test_mutable_defaults_are_per_instance(): + """field(default_factory=...) must not hand every instance the same object.""" + event_a = Event(id="EVT-1", timestamp="t0", source="s", type="t", target="x") + event_b = Event(id="EVT-2", timestamp="t0", source="s", type="t", target="x") + event_a.data["leak"] = True + assert event_b.data == {} + + service_a = Service(id="SVC-1", name="a") + service_b = Service(id="SVC-2", name="b") + service_a.dependencies.append("dep") + service_a.baseline_behavior["cpu"] = 1 + assert service_b.dependencies == [] + assert service_b.baseline_behavior == {} + + problem_a = Problem(id="PRB-1", created_at="t0", status="open", title="a") + problem_b = Problem(id="PRB-2", created_at="t0", status="open", title="b") + problem_a.correlated_incidents.append("INC-1") + assert problem_b.correlated_incidents == [] + + triage_a = TriageResult(status="s", triage_id="TRG-1", target="x", service_type="y") + triage_b = TriageResult(status="s", triage_id="TRG-2", target="x", service_type="y") + triage_a.pending_steps.append({"id": "STEP-1"}) + assert triage_b.pending_steps == [] + + +def test_public_surface_is_reexported(): + assert set(corvus_sdk.__all__) == { + "CorvusClient", + "CorvusError", + "Change", + "Event", + "Incident", + "Problem", + "Service", + "StepResult", + "TriageResult", + } + assert corvus_sdk.Change is Change + assert corvus_sdk.TriageResult is TriageResult + assert corvus_sdk.__version__ == "0.1.0" diff --git a/corvus-server/.gitignore b/corvus-server/.gitignore new file mode 100644 index 0000000..8b5fb9a --- /dev/null +++ b/corvus-server/.gitignore @@ -0,0 +1,5 @@ +# Component-local artifacts (the root .gitignore is owned elsewhere) +.venv/ +__pycache__/ +*.pyc +.ruff_cache/ diff --git a/corvus-server/Makefile b/corvus-server/Makefile new file mode 100644 index 0000000..936d048 --- /dev/null +++ b/corvus-server/Makefile @@ -0,0 +1,56 @@ +# The corvus-server guard — legacy v1 platform (FastAPI) must lint and import cleanly. +# +# v1 is ARCHIVED (branch v1-archive) and NOT deployed; the live product of record is +# corvus-v2. There are deliberately NO tests here — this is rot protection, not a suite. +# +# LAYOUT NOTE: the repo-root CLAUDE.md documents a src/ layout (src/app.py, routers/, +# middleware/, models/...). That doc is STALE — none of it exists on this branch. The +# real corvus-server is two modules: +# cli/corvus_cli.py the typer CLI (builds app = typer.Typer(...) at import) +# modules/soc2/module.py the SOC 2 APIRouter (builds router = APIRouter() at import) +# There is therefore no package to `pip install -e .` and no app factory to import, so +# this harness has lint + import rather than build + test. See the report for the gap. +# +# python3.12 is PINNED: bare `python3` on this host is 3.15 and would break parity with +# the CI, which runs 3.12. + +PYTHON ?= python3.12 +VENV := .venv +PY := $(VENV)/bin/python +PIP := $(VENV)/bin/pip +RUFF := $(VENV)/bin/ruff + +.PHONY: setup lint import fix cycle clean + +# Auto-bootstrap: any target that needs the venv triggers setup exactly once, so +# `make cycle` is genuinely the one command on a fresh clone (this is a real file +# target, not .PHONY — it is a no-op while .venv/bin/ruff exists). +$(VENV)/bin/ruff: + $(MAKE) setup + +setup: ## Bootstrap the pinned 3.12 venv + the component deps + the tooling + $(PYTHON) -m venv $(VENV) + $(PIP) install --quiet --upgrade pip + $(PIP) install --quiet -r requirements.txt + $(PIP) install --quiet ruff==0.17.1 pytest pytest-cov + @echo "setup: ok" + +lint: $(VENV)/bin/ruff ## Ruff over both modules, using corvus-server/pyproject.toml's own config + $(RUFF) check cli/ modules/ + +import: $(VENV)/bin/ruff ## The real proof: import both modules and assert the objects they build + $(PY) -c "import sys; sys.path.insert(0, '.'); \ +assert sys.version_info[:2] == (3, 12), f'expected 3.12 (CI parity), got {sys.version.split()[0]}'; \ +import modules.soc2.module as soc2; import cli.corvus_cli as cli; \ +from fastapi import APIRouter; import typer; \ +assert isinstance(soc2.router, APIRouter), type(soc2.router); \ +assert isinstance(cli.app, typer.Typer), type(cli.app); \ +print(f'import: ok on {sys.version.split()[0]} — soc2 APIRouter({len(soc2.router.routes)} routes), typer app {cli.app.info.name!r} ({len(cli.app.registered_commands)} commands)')" + +fix: $(VENV)/bin/ruff ## Ruff autofixes (no ruff format — this repo does not use it) + $(RUFF) check --fix cli/ modules/ + +cycle: lint import ## The guard, one command + +clean: ## The venv + the lint artifacts + rm -rf $(VENV) .ruff_cache __pycache__ cli/__pycache__ modules/__pycache__ modules/soc2/__pycache__ diff --git a/corvus-splunk/.gitignore b/corvus-splunk/.gitignore new file mode 100644 index 0000000..d505c5a --- /dev/null +++ b/corvus-splunk/.gitignore @@ -0,0 +1,3 @@ +# Component-local artifacts (the root .gitignore is owned elsewhere) +__pycache__/ +*.pyc diff --git a/corvus-splunk/Makefile b/corvus-splunk/Makefile new file mode 100644 index 0000000..1a14888 --- /dev/null +++ b/corvus-splunk/Makefile @@ -0,0 +1,28 @@ +# The corvus-splunk guard — a config-only Splunk app, so `validate` IS the whole guard. +# +# There is deliberately NO venv: validate.py is stdlib-only (json, csv, xml.etree), so +# there is nothing to install and the VENV/PY/PIP/RUFF variables have no meaning here. +# It still runs on the pinned python3.12 for CI parity — bare `python3` on this host is +# 3.15, and a syntax check under the wrong interpreter proves the wrong thing. +# +# Proves: every default/*.conf parses, every dashboard XML is well-formed, every lookup +# CSV has a consistent column count, the transforms/props/nav cross-references resolve, +# and bin/ compiles. +# Cannot prove: that Splunk accepts the app, that the SPL is valid, or that the +# dashboards render — those need a live Splunk instance. + +PYTHON ?= python3.12 + +.PHONY: setup validate cycle clean + +setup: ## Nothing to install — validate.py is stdlib-only, so there is no venv + @echo "setup: ok — no venv by design: validate.py imports only json/csv/xml.etree" + +validate: ## Parse every conf/XML/CSV, resolve the cross-references, compile bin/ + $(PYTHON) validate.py + +cycle: validate ## The guard, one command + +clean: ## The byte-compile artifacts (validate.py itself writes nothing) + rm -rf __pycache__ bin/__pycache__ .pytest_cache + @echo "clean: ok — validate.py writes no artifacts of its own" diff --git a/corvus-splunk/validate.py b/corvus-splunk/validate.py new file mode 100644 index 0000000..900abc8 --- /dev/null +++ b/corvus-splunk/validate.py @@ -0,0 +1,197 @@ +#!/usr/bin/env python3 +"""Validate the corvus-splunk Splunk app. + +This app is config-only, so this script IS the whole guard. It proves: + * every default/*.conf parses as a [stanza] / key = value file + * every dashboard/nav XML is well-formed + * every lookup CSV has a header and a consistent column count + * the transforms.conf -> lookups/, props.conf -> transforms.conf and + nav/default.xml -> views/ cross-references all resolve + * every bin/*.py compiles + * any JSON/YAML that appears parses (there are none today) + +It CANNOT prove: that Splunk accepts the app, that the SPL in the saved searches is +valid, or that the dashboards render. Those all need a live Splunk instance. + +Stdlib only by design — no venv, no dependencies. +""" + +from __future__ import annotations + +import csv +import json +import sys +import xml.etree.ElementTree as ET +from pathlib import Path + +ROOT = Path(__file__).resolve().parent +DEFAULT = ROOT / "default" +LOOKUPS = ROOT / "lookups" +VIEWS = DEFAULT / "data" / "ui" / "views" + +# Views Splunk ships itself: a nav reference to one of these needs no file here. +BUILTIN_VIEWS = {"search", "dashboards", "reports", "alerts", "help", "launcher"} + +REQUIRED = [ + DEFAULT / "app.conf", + DEFAULT / "indexes.conf", + DEFAULT / "macros.conf", + DEFAULT / "props.conf", + DEFAULT / "savedsearches.conf", + DEFAULT / "transforms.conf", + ROOT / "metadata" / "default.meta", + LOOKUPS, +] + +errors: list[str] = [] + + +def check(ok: bool, message: str) -> bool: + if not ok: + errors.append(message) + return ok + + +def parse_conf(path: Path) -> dict[str, dict[str, str]]: + """Parse a Splunk .conf into {stanza: {key: value}}. + + Handles '#' comments, blank lines and backslash line continuations. The + continuations matter: savedsearches.conf splits long SPL across lines, and a + naive one-key-per-line parser false-fails on them. + """ + stanzas: dict[str, dict[str, str]] = {} + current: dict[str, str] | None = None + pending = "" + for lineno, raw in enumerate(path.read_text(encoding="utf-8").splitlines(), 1): + line = pending + raw + pending = "" + if line.rstrip().endswith("\\"): + pending = line.rstrip()[:-1] + " " + continue + stripped = line.strip() + if not stripped or stripped.startswith("#"): + continue + if stripped.startswith("[") and stripped.endswith("]"): + name = stripped[1:-1].strip() + if not name: + errors.append(f"{path.name}:{lineno}: empty stanza name") + elif name in stanzas: + errors.append(f"{path.name}:{lineno}: duplicate stanza [{name}]") + current = stanzas.setdefault(name, {}) + continue + if current is None: + errors.append(f"{path.name}:{lineno}: content before the first [stanza]") + continue + if "=" not in stripped: + errors.append(f"{path.name}:{lineno}: not a 'key = value' line: {stripped[:60]!r}") + continue + key, _, value = stripped.partition("=") + current[key.strip()] = value.strip() + if pending: + errors.append(f"{path.name}: file ends inside a line continuation") + return stanzas + + +def main() -> int: + counts = {"conf": 0, "xml": 0, "csv": 0, "py": 0} + + # 1. the metadata files a Splunk app cannot ship without + for path in REQUIRED: + check(path.exists(), f"missing required path: {path.relative_to(ROOT)}") + + # 2. every .conf parses + confs: dict[str, dict[str, dict[str, str]]] = {} + for path in sorted(DEFAULT.glob("*.conf")): + confs[path.name] = parse_conf(path) + counts["conf"] += 1 + print(f" conf default/{path.name}: {len(confs[path.name])} stanza(s)") + + # 3. every XML is well-formed + for path in sorted(DEFAULT.rglob("*.xml")): + counts["xml"] += 1 + try: + ET.parse(path) + print(f" xml {path.relative_to(ROOT)}: well-formed") + except ET.ParseError as exc: + errors.append(f"{path.relative_to(ROOT)}: malformed XML: {exc}") + + # 4. every lookup CSV has a header and a consistent column count + for path in sorted(LOOKUPS.glob("*.csv")): + counts["csv"] += 1 + rows = list(csv.reader(path.read_text(encoding="utf-8").splitlines())) + if not rows: + errors.append(f"lookups/{path.name}: empty CSV") + continue + width = len(rows[0]) + for lineno, row in enumerate(rows[1:], start=2): + if len(row) != width: + errors.append(f"lookups/{path.name}:{lineno}: {len(row)} columns, header has {width}") + print(f" csv lookups/{path.name}: {len(rows) - 1} row(s) x {width} col(s)") + + # 5. transforms.conf filename = X must exist under lookups/ + transforms = confs.get("transforms.conf", {}) + for stanza, keys in transforms.items(): + filename = keys.get("filename") + if filename: + check((LOOKUPS / filename).exists(), f"transforms.conf [{stanza}] points at missing lookup {filename!r}") + + # 6. props.conf LOOKUP- = ... must resolve + for stanza, keys in confs.get("props.conf", {}).items(): + for key, value in keys.items(): + if not key.upper().startswith("LOOKUP-"): + continue + target = value.split()[0] if value.split() else "" + check(target in transforms, f"props.conf [{stanza}] {key} references unknown transforms stanza {target!r}") + + # 7. nav/default.xml view references must resolve to views/.xml + nav = DEFAULT / "data" / "ui" / "nav" / "default.xml" + if nav.exists(): + for view in ET.parse(nav).getroot().iter("view"): + name = view.get("name") or "" + if name in BUILTIN_VIEWS: + continue + check((VIEWS / f"{name}.xml").exists(), f"nav/default.xml references view {name!r} with no views/{name}.xml") + + # 8. every bin/ script compiles (in memory — writes nothing) + for path in sorted((ROOT / "bin").glob("*.py")): + counts["py"] += 1 + try: + compile(path.read_text(encoding="utf-8"), str(path), "exec") + print(f" py bin/{path.name}: compiles") + except SyntaxError as exc: + errors.append(f"bin/{path.name}: syntax error: {exc}") + + # 9. JSON, and YAML if any appears (there are none today) + for path in sorted(ROOT.rglob("*.json")): + try: + json.loads(path.read_text(encoding="utf-8")) + except json.JSONDecodeError as exc: + errors.append(f"{path.relative_to(ROOT)}: malformed JSON: {exc}") + yamls = sorted(ROOT.rglob("*.yaml")) + sorted(ROOT.rglob("*.yml")) + if yamls: + try: + import yaml + except ImportError: + errors.append("YAML files present but PyYAML is unavailable — refusing to skip them silently") + else: + for path in yamls: + try: + yaml.safe_load(path.read_text(encoding="utf-8")) + except yaml.YAMLError as exc: + errors.append(f"{path.relative_to(ROOT)}: malformed YAML: {exc}") + + if errors: + print(f"\nvalidate: FAILED — {len(errors)} problem(s)", file=sys.stderr) + for problem in errors: + print(f" - {problem}", file=sys.stderr) + return 1 + + print( + f"\nvalidate: ok — {counts['conf']} conf, {counts['xml']} xml, " + f"{counts['csv']} csv, {counts['py']} py, 0 json, {len(yamls)} yaml" + ) + return 0 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/corvus-v2/Makefile b/corvus-v2/Makefile new file mode 100644 index 0000000..54d8491 --- /dev/null +++ b/corvus-v2/Makefile @@ -0,0 +1,72 @@ +# The corvus-v2 dev harness — the Build > Test > Fix cycle, one command per step. +# The engine is the deployed artifact (image corvus-v2:): its harness is the +# gate that decides whether a change is deployable. Every step is idempotent. + +PYTHON ?= python3.12 +VENV := .venv +PY := $(VENV)/bin/python +PIP := $(VENV)/bin/pip +RUFF := $(VENV)/bin/ruff +METRICS := ../docs/canonical-path/dev-metrics.json +SRC := corvus/ tests/ + +.PHONY: setup build lint test fix metrics metrics-check run check cycle clean mutation conformance + +setup: ## Bootstrap the venv + the deps (fresh-clone safe, pinned interpreter) + $(PYTHON) -m venv $(VENV) + $(PIP) install --quiet --upgrade pip + $(PIP) install --quiet -r requirements.txt + $(PIP) install --quiet pytest pytest-cov ruff==0.17.1 httpx + @echo "setup: ok ($$($(PY) --version))" + +build: ## The engine up + the live proof: health, an authenticated read, and the 401 control + $(PIP) check # the resolved dependency set must be internally consistent + $(PY) scripts/dev_check.py + +lint: ## Ruff over the package and the tests + $(RUFF) check $(SRC) + @echo "lint: ok" + +test: ## The tests with the coverage measurement + $(PY) -m pytest tests/ -q \ + --cov=corvus --cov-report=term --cov-report=json:coverage.json \ + --junitxml=junit.xml + @echo "test: ok" + +fix: ## The autofix step — ruff repairs what it can, then lint proves it + $(RUFF) check --fix $(SRC) + @echo "fix: ok (run `make lint` to confirm)" + +metrics: ## Regenerate the dev-metrics artifact from the last test run + $(PY) scripts/gen_metrics.py \ + --coverage coverage.json --junit junit.xml --out $(METRICS) \ + --source "$$(git rev-parse --short HEAD)" \ + --duration "$$($(PY) -c 'import xml.etree.ElementTree as ET; r=ET.parse("junit.xml").getroot(); s=r.find("testsuite") if r.tag=="testsuites" else r; print(round(float(s.get("time",0)),2))')" + @echo "metrics: regenerated" + +metrics-check: ## The drift guard: the committed metrics must match a fresh run + $(PY) scripts/gen_metrics.py \ + --coverage coverage.json --junit junit.xml --out /tmp/metrics-check.json \ + --source "$$(git rev-parse --short HEAD)" + $(PY) scripts/check_metrics.py --expected $(METRICS) --actual /tmp/metrics-check.json + +run: build ## Alias: the live check is the build step + +check: lint test metrics-check ## The full gate set (what CI runs) + +cycle: build lint test metrics-check ## THE Build > Test > Fix loop, one command + +mutation: ## The mutation evidence (the phase-gate target) + $(PY) -c "import sys; sys.path.insert(0, '.'); from corvus.conformance import run_mutation_suite; import json; r = run_mutation_suite(); print(json.dumps(r, indent=1)); exit(0 if r['all_mutants_caught'] else 1)" + +conformance: ## The conformance run against the engine shim (the phase-gate target) + $(PY) -m corvus.engine_shim --port 8933 & sleep 2; \ + $(PY) -c "import sys; sys.path.insert(0, '.'); from corvus.conformance import conformance_run; import json; r = conformance_run('http://127.0.0.1:8933'); print(json.dumps(r, indent=1)); exit(0 if r['failed'] == 0 else 1)"; \ + pkill -f "engine_shim --port 8933" || true + +# PREFLIGHT:rollback-written — clean deletes only REGENERABLE state (the venv and the +# pytest cache); `make setup` and `make test` recreate both. It deliberately does NOT +# delete coverage.json / junit.xml, which are tracked artifacts feeding dev-metrics.json. +clean: ## The regenerable artifacts only (never the tracked metrics inputs) + rm -rf $(VENV) .pytest_cache + @echo "clean: ok — run `make setup` to rebuild" diff --git a/corvus-v2/coverage.json b/corvus-v2/coverage.json index 4a677e9..969824e 100644 --- a/corvus-v2/coverage.json +++ b/corvus-v2/coverage.json @@ -1 +1 @@ -{"meta": {"format": 3, "version": "7.16.2", "timestamp": "2026-10-18T13:37:14.949232", "branch_coverage": false, "show_contexts": false}, "files": {"corvus/__init__.py": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 0, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "functions": {"": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 0, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1}}, "classes": {"": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 0, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1}}}, "corvus/app.py": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 78, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 78, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [15, 17, 18, 19, 20, 21, 23, 25, 26, 27, 29, 30, 31, 34, 35, 36, 37, 38, 39, 42, 43, 44, 45, 46, 47, 48, 51, 52, 53, 54, 55, 58, 59, 60, 61, 62, 64, 67, 68, 70, 71, 72, 75, 76, 77, 78, 79, 80, 81, 82, 83, 85, 86, 88, 90, 91, 92, 93, 95, 96, 97, 98, 99, 101, 103, 105, 106, 107, 108, 109, 110, 112, 113, 114, 116, 117, 119, 121], "excluded_lines": [], "functions": {"_auth_key": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 4, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 4, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [52, 53, 54, 55], "excluded_lines": [], "start_line": 51}, "create_app": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 21, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 21, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [59, 60, 61, 62, 64, 67, 70, 71, 75, 76, 85, 86, 90, 91, 105, 106, 112, 113, 116, 117, 121], "excluded_lines": [], "start_line": 58}, "create_app.require_key": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 1, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [68], "excluded_lines": [], "start_line": 67}, "create_app.health": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 1, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [72], "excluded_lines": [], "start_line": 71}, "create_app.ingest": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 7, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 7, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [77, 78, 79, 80, 81, 82, 83], "excluded_lines": [], "start_line": 76}, "create_app.events": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 1, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [88], "excluded_lines": [], "start_line": 86}, "create_app.stream": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 4, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 4, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [92, 93, 95, 103], "excluded_lines": [], "start_line": 91}, "create_app.stream.gen": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 5, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 5, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [96, 97, 98, 99, 101], "excluded_lines": [], "start_line": 95}, "create_app.open_change": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 4, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 4, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [107, 108, 109, 110], "excluded_lines": [], "start_line": 106}, "create_app.active_changes": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 1, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [114], "excluded_lines": [], "start_line": 113}, "create_app.conflict_check": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 1, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [119], "excluded_lines": [], "start_line": 117}, "": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 28, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 28, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [15, 17, 18, 19, 20, 21, 23, 25, 26, 27, 29, 30, 31, 34, 35, 36, 37, 38, 39, 42, 43, 44, 45, 46, 47, 48, 51, 58], "excluded_lines": [], "start_line": 1}}, "classes": {"EventIn": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 0, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 34}, "ChangeIn": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 0, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 42}, "": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 78, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 78, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [15, 17, 18, 19, 20, 21, 23, 25, 26, 27, 29, 30, 31, 34, 35, 36, 37, 38, 39, 42, 43, 44, 45, 46, 47, 48, 51, 52, 53, 54, 55, 58, 59, 60, 61, 62, 64, 67, 68, 70, 71, 72, 75, 76, 77, 78, 79, 80, 81, 82, 83, 85, 86, 88, 90, 91, 92, 93, 95, 96, 97, 98, 99, 101, 103, 105, 106, 107, 108, 109, 110, 112, 113, 114, 116, 117, 119, 121], "excluded_lines": [], "start_line": 1}}}, "corvus/config.py": {"executed_lines": [7, 9, 10, 11, 15, 36, 37, 38, 39, 40, 41, 43, 44, 45, 48], "summary": {"covered_lines": 15, "num_statements": 23, "percent_covered": 65.21739130434783, "percent_covered_display": "65", "missing_lines": 8, "excluded_lines": 0, "percent_statements_covered": 65.21739130434783, "percent_statements_covered_display": "65"}, "missing_lines": [55, 56, 57, 58, 66, 67, 68, 73], "excluded_lines": [], "functions": {"FleetConfig.event_types": {"executed_lines": [45], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 44}, "load_config": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 8, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 8, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [55, 56, 57, 58, 66, 67, 68, 73], "excluded_lines": [], "start_line": 48}, "": {"executed_lines": [7, 9, 10, 11, 15, 36, 37, 38, 39, 40, 41, 43, 44, 48], "summary": {"covered_lines": 14, "num_statements": 14, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1}}, "classes": {"FleetConfig": {"executed_lines": [45], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 37}, "": {"executed_lines": [7, 9, 10, 11, 15, 36, 37, 38, 39, 40, 41, 43, 44, 48], "summary": {"covered_lines": 14, "num_statements": 22, "percent_covered": 63.63636363636363, "percent_covered_display": "64", "missing_lines": 8, "excluded_lines": 0, "percent_statements_covered": 63.63636363636363, "percent_statements_covered_display": "64"}, "missing_lines": [55, 56, 57, 58, 66, 67, 68, 73], "excluded_lines": [], "start_line": 1}}}, "corvus/core.py": {"executed_lines": [9, 11, 12, 13, 14, 15, 17, 18, 19, 22, 23, 26, 29, 30, 33, 34, 35, 36, 37, 41, 42, 43, 44, 45, 46, 47, 48, 49, 60, 61, 66, 69, 82, 83, 84, 85, 87, 88, 96, 97, 101, 105, 107, 108, 113, 117, 121, 122, 130, 134, 136, 137, 138, 139, 140, 141, 142, 143, 144, 148, 149, 150, 151], "summary": {"covered_lines": 63, "num_statements": 70, "percent_covered": 90.0, "percent_covered_display": "90", "missing_lines": 7, "excluded_lines": 0, "percent_statements_covered": 90.0, "percent_statements_covered_display": "90"}, "missing_lines": [70, 71, 76, 78, 86, 146, 147], "excluded_lines": [], "functions": {"_now_iso": {"executed_lines": [23], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 22}, "sign_event": {"executed_lines": [29, 30], "summary": {"covered_lines": 2, "num_statements": 2, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 26}, "CorvusCore.__init__": {"executed_lines": [35, 36, 37], "summary": {"covered_lines": 3, "num_statements": 3, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 34}, "CorvusCore.ingest_event": {"executed_lines": [42, 43, 44, 45, 46, 47, 48, 49, 60, 61, 66], "summary": {"covered_lines": 11, "num_statements": 11, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 41}, "CorvusCore.query_events": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 4, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 4, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [70, 71, 76, 78], "excluded_lines": [], "start_line": 69}, "CorvusCore.open_change": {"executed_lines": [83, 84, 85, 87, 88, 96, 97, 101, 105], "summary": {"covered_lines": 9, "num_statements": 10, "percent_covered": 90.0, "percent_covered_display": "90", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 90.0, "percent_statements_covered_display": "90"}, "missing_lines": [86], "excluded_lines": [], "start_line": 82}, "CorvusCore.active_changes_for": {"executed_lines": [108, 113], "summary": {"covered_lines": 2, "num_statements": 2, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 107}, "CorvusCore.conflict_check": {"executed_lines": [121, 122, 130, 134, 136, 137, 138, 139, 140, 141, 142, 143, 144, 148, 149, 150, 151], "summary": {"covered_lines": 17, "num_statements": 19, "percent_covered": 89.47368421052632, "percent_covered_display": "89", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 89.47368421052632, "percent_statements_covered_display": "89"}, "missing_lines": [146, 147], "excluded_lines": [], "start_line": 117}, "": {"executed_lines": [9, 11, 12, 13, 14, 15, 17, 18, 19, 22, 26, 33, 34, 41, 69, 82, 107, 117], "summary": {"covered_lines": 18, "num_statements": 18, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1}}, "classes": {"CorvusCore": {"executed_lines": [35, 36, 37, 42, 43, 44, 45, 46, 47, 48, 49, 60, 61, 66, 83, 84, 85, 87, 88, 96, 97, 101, 105, 108, 113, 121, 122, 130, 134, 136, 137, 138, 139, 140, 141, 142, 143, 144, 148, 149, 150, 151], "summary": {"covered_lines": 42, "num_statements": 49, "percent_covered": 85.71428571428571, "percent_covered_display": "86", "missing_lines": 7, "excluded_lines": 0, "percent_statements_covered": 85.71428571428571, "percent_statements_covered_display": "86"}, "missing_lines": [70, 71, 76, 78, 86, 146, 147], "excluded_lines": [], "start_line": 33}, "": {"executed_lines": [9, 11, 12, 13, 14, 15, 17, 18, 19, 22, 23, 26, 29, 30, 33, 34, 41, 69, 82, 107, 117], "summary": {"covered_lines": 21, "num_statements": 21, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1}}}, "corvus/hlc.py": {"executed_lines": [8, 9, 10, 13, 14, 19, 20, 21, 26, 27, 30, 31, 32, 33, 34, 35, 37, 38, 39, 40, 41, 42, 45, 47, 50, 51, 52, 53, 61], "summary": {"covered_lines": 29, "num_statements": 39, "percent_covered": 74.35897435897436, "percent_covered_display": "74", "missing_lines": 10, "excluded_lines": 0, "percent_statements_covered": 74.35897435897436, "percent_statements_covered_display": "74"}, "missing_lines": [22, 23, 24, 44, 54, 55, 56, 57, 59, 60], "excluded_lines": [], "functions": {"HLCTimestamp.__lt__": {"executed_lines": [20, 21], "summary": {"covered_lines": 2, "num_statements": 5, "percent_covered": 40.0, "percent_covered_display": "40", "missing_lines": 3, "excluded_lines": 0, "percent_statements_covered": 40.0, "percent_statements_covered_display": "40"}, "missing_lines": [22, 23, 24], "excluded_lines": [], "start_line": 19}, "HLCTimestamp.to_string": {"executed_lines": [27], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 26}, "HLC.__init__": {"executed_lines": [32, 33, 34, 35], "summary": {"covered_lines": 4, "num_statements": 4, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 31}, "HLC.now": {"executed_lines": [38, 39, 40, 41, 42, 45], "summary": {"covered_lines": 6, "num_statements": 7, "percent_covered": 85.71428571428571, "percent_covered_display": "86", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 85.71428571428571, "percent_statements_covered_display": "86"}, "missing_lines": [44], "excluded_lines": [], "start_line": 37}, "HLC.merge": {"executed_lines": [50, 51, 52, 53, 61], "summary": {"covered_lines": 5, "num_statements": 11, "percent_covered": 45.45454545454545, "percent_covered_display": "45", "missing_lines": 6, "excluded_lines": 0, "percent_statements_covered": 45.45454545454545, "percent_statements_covered_display": "45"}, "missing_lines": [54, 55, 56, 57, 59, 60], "excluded_lines": [], "start_line": 47}, "": {"executed_lines": [8, 9, 10, 13, 14, 19, 26, 30, 31, 37, 47], "summary": {"covered_lines": 11, "num_statements": 11, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1}}, "classes": {"HLCTimestamp": {"executed_lines": [20, 21, 27], "summary": {"covered_lines": 3, "num_statements": 6, "percent_covered": 50.0, "percent_covered_display": "50", "missing_lines": 3, "excluded_lines": 0, "percent_statements_covered": 50.0, "percent_statements_covered_display": "50"}, "missing_lines": [22, 23, 24], "excluded_lines": [], "start_line": 14}, "HLC": {"executed_lines": [32, 33, 34, 35, 38, 39, 40, 41, 42, 45, 50, 51, 52, 53, 61], "summary": {"covered_lines": 15, "num_statements": 22, "percent_covered": 68.18181818181819, "percent_covered_display": "68", "missing_lines": 7, "excluded_lines": 0, "percent_statements_covered": 68.18181818181819, "percent_statements_covered_display": "68"}, "missing_lines": [44, 54, 55, 56, 57, 59, 60], "excluded_lines": [], "start_line": 30}, "": {"executed_lines": [8, 9, 10, 13, 14, 19, 26, 30, 31, 37, 47], "summary": {"covered_lines": 11, "num_statements": 11, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1}}}, "corvus/state.py": {"executed_lines": [8, 10, 11, 12, 14, 59, 62, 63, 64, 65, 66, 67, 68, 70, 71, 72, 73, 74, 75], "summary": {"covered_lines": 19, "num_statements": 19, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "functions": {"State.__init__": {"executed_lines": [63, 64, 65, 66, 67, 68], "summary": {"covered_lines": 6, "num_statements": 6, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 62}, "State.execute": {"executed_lines": [71, 72, 73, 74, 75], "summary": {"covered_lines": 5, "num_statements": 5, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 70}, "": {"executed_lines": [8, 10, 11, 12, 14, 59, 62, 70], "summary": {"covered_lines": 8, "num_statements": 8, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1}}, "classes": {"State": {"executed_lines": [63, 64, 65, 66, 67, 68, 71, 72, 73, 74, 75], "summary": {"covered_lines": 11, "num_statements": 11, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 59}, "": {"executed_lines": [8, 10, 11, 12, 14, 59, 62, 70], "summary": {"covered_lines": 8, "num_statements": 8, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1}}}}, "totals": {"covered_lines": 126, "num_statements": 229, "percent_covered": 55.02183406113537, "percent_covered_display": "55", "missing_lines": 103, "excluded_lines": 0, "percent_statements_covered": 55.02183406113537, "percent_statements_covered_display": "55"}} \ No newline at end of file +{"meta": {"format": 3, "version": "7.17.0", "timestamp": "2026-10-23T20:34:30.782572", "branch_coverage": false, "show_contexts": false}, "files": {"corvus/__init__.py": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 0, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "functions": {"": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 0, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1}}, "classes": {"": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 0, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1}}}, "corvus/adapter.py": {"executed_lines": [17, 19, 20, 21, 22, 23, 26, 31, 32, 36, 39, 41, 42, 43, 44, 45, 47, 49, 50, 51, 52, 55, 57, 58, 59, 60, 62, 63, 64, 65, 66, 70, 71, 72, 74, 75, 79, 80, 81, 85, 86, 91, 95, 98, 100, 101, 102, 104, 106, 108, 109, 110, 111, 112, 114], "summary": {"covered_lines": 55, "num_statements": 58, "percent_covered": 94.82758620689656, "percent_covered_display": "95", "missing_lines": 3, "excluded_lines": 0, "percent_statements_covered": 94.82758620689656, "percent_statements_covered_display": "95"}, "missing_lines": [69, 82, 113], "excluded_lines": [], "functions": {"Adapter.solve": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 0, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 32}, "ClefFlashAdapter.__init__": {"executed_lines": [41, 42, 43, 44, 45], "summary": {"covered_lines": 5, "num_statements": 5, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 39}, "ClefFlashAdapter.solve": {"executed_lines": [49, 50, 51, 52, 55, 57, 58, 59, 60, 62, 63, 64, 65, 66, 70, 71, 72, 74, 75, 79, 80, 81, 85, 86, 91], "summary": {"covered_lines": 25, "num_statements": 27, "percent_covered": 92.5925925925926, "percent_covered_display": "93", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 92.5925925925926, "percent_statements_covered_display": "93"}, "missing_lines": [69, 82], "excluded_lines": [], "start_line": 47}, "StubAdapter.__init__": {"executed_lines": [100, 101, 102], "summary": {"covered_lines": 3, "num_statements": 3, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 98}, "StubAdapter.solve": {"executed_lines": [106, 108, 109, 110, 111, 112, 114], "summary": {"covered_lines": 7, "num_statements": 8, "percent_covered": 87.5, "percent_covered_display": "88", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 87.5, "percent_statements_covered_display": "88"}, "missing_lines": [113], "excluded_lines": [], "start_line": 104}, "": {"executed_lines": [17, 19, 20, 21, 22, 23, 26, 31, 32, 36, 39, 47, 95, 98, 104], "summary": {"covered_lines": 15, "num_statements": 15, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1}}, "classes": {"AdapterUnavailable": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 0, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 26}, "Adapter": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 0, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 31}, "ClefFlashAdapter": {"executed_lines": [41, 42, 43, 44, 45, 49, 50, 51, 52, 55, 57, 58, 59, 60, 62, 63, 64, 65, 66, 70, 71, 72, 74, 75, 79, 80, 81, 85, 86, 91], "summary": {"covered_lines": 30, "num_statements": 32, "percent_covered": 93.75, "percent_covered_display": "94", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 93.75, "percent_statements_covered_display": "94"}, "missing_lines": [69, 82], "excluded_lines": [], "start_line": 36}, "StubAdapter": {"executed_lines": [100, 101, 102, 106, 108, 109, 110, 111, 112, 114], "summary": {"covered_lines": 10, "num_statements": 11, "percent_covered": 90.9090909090909, "percent_covered_display": "91", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 90.9090909090909, "percent_statements_covered_display": "91"}, "missing_lines": [113], "excluded_lines": [], "start_line": 95}, "": {"executed_lines": [17, 19, 20, 21, 22, 23, 26, 31, 32, 36, 39, 47, 95, 98, 104], "summary": {"covered_lines": 15, "num_statements": 15, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1}}}, "corvus/app.py": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 78, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 78, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [15, 17, 18, 19, 20, 21, 23, 25, 26, 27, 29, 30, 31, 34, 35, 36, 37, 38, 39, 42, 43, 44, 45, 46, 47, 48, 51, 52, 53, 54, 55, 58, 59, 60, 61, 62, 64, 67, 68, 70, 71, 72, 75, 76, 77, 78, 79, 80, 81, 82, 83, 85, 86, 88, 90, 91, 92, 93, 95, 96, 97, 98, 99, 101, 103, 105, 106, 107, 108, 109, 110, 112, 113, 114, 116, 117, 119, 121], "excluded_lines": [], "functions": {"_auth_key": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 4, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 4, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [52, 53, 54, 55], "excluded_lines": [], "start_line": 51}, "create_app": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 21, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 21, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [59, 60, 61, 62, 64, 67, 70, 71, 75, 76, 85, 86, 90, 91, 105, 106, 112, 113, 116, 117, 121], "excluded_lines": [], "start_line": 58}, "create_app.require_key": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 1, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [68], "excluded_lines": [], "start_line": 67}, "create_app.health": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 1, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [72], "excluded_lines": [], "start_line": 71}, "create_app.ingest": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 7, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 7, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [77, 78, 79, 80, 81, 82, 83], "excluded_lines": [], "start_line": 76}, "create_app.events": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 1, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [88], "excluded_lines": [], "start_line": 86}, "create_app.stream": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 4, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 4, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [92, 93, 95, 103], "excluded_lines": [], "start_line": 91}, "create_app.stream.gen": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 5, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 5, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [96, 97, 98, 99, 101], "excluded_lines": [], "start_line": 95}, "create_app.open_change": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 4, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 4, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [107, 108, 109, 110], "excluded_lines": [], "start_line": 106}, "create_app.active_changes": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 1, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [114], "excluded_lines": [], "start_line": 113}, "create_app.conflict_check": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 1, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [119], "excluded_lines": [], "start_line": 117}, "": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 28, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 28, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [15, 17, 18, 19, 20, 21, 23, 25, 26, 27, 29, 30, 31, 34, 35, 36, 37, 38, 39, 42, 43, 44, 45, 46, 47, 48, 51, 58], "excluded_lines": [], "start_line": 1}}, "classes": {"EventIn": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 0, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 34}, "ChangeIn": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 0, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 42}, "": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 78, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 78, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [15, 17, 18, 19, 20, 21, 23, 25, 26, 27, 29, 30, 31, 34, 35, 36, 37, 38, 39, 42, 43, 44, 45, 46, 47, 48, 51, 52, 53, 54, 55, 58, 59, 60, 61, 62, 64, 67, 68, 70, 71, 72, 75, 76, 77, 78, 79, 80, 81, 82, 83, 85, 86, 88, 90, 91, 92, 93, 95, 96, 97, 98, 99, 101, 103, 105, 106, 107, 108, 109, 110, 112, 113, 114, 116, 117, 119, 121], "excluded_lines": [], "start_line": 1}}}, "corvus/attested.py": {"executed_lines": [22, 24, 25, 26, 27, 28, 30, 32, 33, 36, 37, 38, 39, 40, 41, 50, 51, 53, 56, 58, 59, 61, 62, 63, 64, 67, 71, 72, 76, 77, 78, 84, 87, 91, 96, 97, 98, 99, 102, 103, 104, 107, 109, 110, 112, 113, 115, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 132, 133, 134, 135, 137, 138, 141], "summary": {"covered_lines": 64, "num_statements": 68, "percent_covered": 94.11764705882354, "percent_covered_display": "94", "missing_lines": 4, "excluded_lines": 0, "percent_statements_covered": 94.11764705882354, "percent_statements_covered_display": "94"}, "missing_lines": [79, 105, 129, 131], "excluded_lines": [], "functions": {"AttestedStore.__init__": {"executed_lines": [38, 39, 40, 41, 50, 51], "summary": {"covered_lines": 6, "num_statements": 6, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 37}, "AttestedStore.append": {"executed_lines": [56, 58, 59, 61, 62, 63, 64, 67, 71, 72], "summary": {"covered_lines": 10, "num_statements": 10, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 53}, "AttestedStore.chain": {"executed_lines": [77, 78, 84, 87], "summary": {"covered_lines": 4, "num_statements": 5, "percent_covered": 80.0, "percent_covered_display": "80", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 80.0, "percent_statements_covered_display": "80"}, "missing_lines": [79], "excluded_lines": [], "start_line": 76}, "AttestedStore.verify": {"executed_lines": [96, 97, 98, 99, 102, 103, 104, 107, 109, 110, 112, 113], "summary": {"covered_lines": 12, "num_statements": 13, "percent_covered": 92.3076923076923, "percent_covered_display": "92", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 92.3076923076923, "percent_statements_covered_display": "92"}, "missing_lines": [105], "excluded_lines": [], "start_line": 91}, "AttestedStore.lifecycle_walk": {"executed_lines": [119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 132, 133, 134, 135, 137, 138, 141], "summary": {"covered_lines": 17, "num_statements": 19, "percent_covered": 89.47368421052632, "percent_covered_display": "89", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 89.47368421052632, "percent_statements_covered_display": "89"}, "missing_lines": [129, 131], "excluded_lines": [], "start_line": 115}, "": {"executed_lines": [22, 24, 25, 26, 27, 28, 30, 32, 33, 36, 37, 53, 76, 91, 115], "summary": {"covered_lines": 15, "num_statements": 15, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1}}, "classes": {"AttestedStore": {"executed_lines": [38, 39, 40, 41, 50, 51, 56, 58, 59, 61, 62, 63, 64, 67, 71, 72, 77, 78, 84, 87, 96, 97, 98, 99, 102, 103, 104, 107, 109, 110, 112, 113, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 132, 133, 134, 135, 137, 138, 141], "summary": {"covered_lines": 49, "num_statements": 53, "percent_covered": 92.45283018867924, "percent_covered_display": "92", "missing_lines": 4, "excluded_lines": 0, "percent_statements_covered": 92.45283018867924, "percent_statements_covered_display": "92"}, "missing_lines": [79, 105, 129, 131], "excluded_lines": [], "start_line": 36}, "": {"executed_lines": [22, 24, 25, 26, 27, 28, 30, 32, 33, 36, 37, 53, 76, 91, 115], "summary": {"covered_lines": 15, "num_statements": 15, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1}}}, "corvus/canonical.py": {"executed_lines": [10, 12, 13, 14, 17, 19, 20, 21, 22, 23, 25, 28, 30, 31, 34, 35, 38, 42, 43], "summary": {"covered_lines": 19, "num_statements": 21, "percent_covered": 90.47619047619048, "percent_covered_display": "90", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 90.47619047619048, "percent_statements_covered_display": "90"}, "missing_lines": [24, 29], "excluded_lines": [], "functions": {"canonicalize": {"executed_lines": [19, 20, 21, 22, 23, 25, 28, 30, 31], "summary": {"covered_lines": 9, "num_statements": 11, "percent_covered": 81.81818181818181, "percent_covered_display": "82", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 81.81818181818181, "percent_statements_covered_display": "82"}, "missing_lines": [24, 29], "excluded_lines": [], "start_line": 17}, "canonical_json": {"executed_lines": [35], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 34}, "request_hash": {"executed_lines": [42, 43], "summary": {"covered_lines": 2, "num_statements": 2, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 38}, "": {"executed_lines": [10, 12, 13, 14, 17, 34, 38], "summary": {"covered_lines": 7, "num_statements": 7, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1}}, "classes": {"": {"executed_lines": [10, 12, 13, 14, 17, 19, 20, 21, 22, 23, 25, 28, 30, 31, 34, 35, 38, 42, 43], "summary": {"covered_lines": 19, "num_statements": 21, "percent_covered": 90.47619047619048, "percent_covered_display": "90", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 90.47619047619048, "percent_statements_covered_display": "90"}, "missing_lines": [24, 29], "excluded_lines": [], "start_line": 1}}}, "corvus/capture.py": {"executed_lines": [22, 24, 25, 26, 27, 30, 31, 32, 33, 34, 35, 36, 37, 38, 45, 48, 50, 54, 55, 56, 58, 59, 60, 63, 64, 69, 70, 72, 73, 74, 77, 79, 80, 81, 83, 85, 88, 89, 92, 94, 95, 96, 97], "summary": {"covered_lines": 43, "num_statements": 43, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "functions": {"CaptureStore.__init__": {"executed_lines": [32, 33, 34, 35, 36, 37, 38, 45, 48], "summary": {"covered_lines": 9, "num_statements": 9, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 31}, "CaptureStore.enqueue": {"executed_lines": [54, 55, 56, 58, 59, 60, 63, 64, 69, 70], "summary": {"covered_lines": 10, "num_statements": 10, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 50}, "CaptureStore.replay_put": {"executed_lines": [73, 74, 77], "summary": {"covered_lines": 3, "num_statements": 3, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 72}, "CaptureStore.replay_lookup": {"executed_lines": [80, 81, 83], "summary": {"covered_lines": 3, "num_statements": 3, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 79}, "CaptureStore.by_request_hash": {"executed_lines": [88, 89, 92], "summary": {"covered_lines": 3, "num_statements": 3, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 85}, "CaptureStore.stats": {"executed_lines": [95, 96, 97], "summary": {"covered_lines": 3, "num_statements": 3, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 94}, "": {"executed_lines": [22, 24, 25, 26, 27, 30, 31, 50, 72, 79, 85, 94], "summary": {"covered_lines": 12, "num_statements": 12, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1}}, "classes": {"CaptureStore": {"executed_lines": [32, 33, 34, 35, 36, 37, 38, 45, 48, 54, 55, 56, 58, 59, 60, 63, 64, 69, 70, 73, 74, 77, 80, 81, 83, 88, 89, 92, 95, 96, 97], "summary": {"covered_lines": 31, "num_statements": 31, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 30}, "": {"executed_lines": [22, 24, 25, 26, 27, 30, 31, 50, 72, 79, 85, 94], "summary": {"covered_lines": 12, "num_statements": 12, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1}}}, "corvus/cc_adapter.py": {"executed_lines": [26, 28, 29, 30, 31, 34, 35, 41, 42, 43, 44, 47, 49, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 68, 69, 70, 71, 76, 79, 80, 84, 89, 90, 93, 96, 97, 98, 101, 102, 109, 112, 113, 114, 116, 117, 119, 121, 123, 124, 128, 137], "summary": {"covered_lines": 51, "num_statements": 58, "percent_covered": 87.93103448275862, "percent_covered_display": "88", "missing_lines": 7, "excluded_lines": 0, "percent_statements_covered": 87.93103448275862, "percent_statements_covered_display": "88"}, "missing_lines": [105, 106, 122, 125, 133, 134, 138], "excluded_lines": [], "functions": {"CCAdapter.__init__": {"executed_lines": [41, 42, 43, 44, 47], "summary": {"covered_lines": 5, "num_statements": 5, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 35}, "CCAdapter.pre_tool_use": {"executed_lines": [52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 68, 69, 70, 71, 76, 79, 80, 84, 89, 90, 93, 96, 97, 98, 101, 102], "summary": {"covered_lines": 26, "num_statements": 28, "percent_covered": 92.85714285714286, "percent_covered_display": "93", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 92.85714285714286, "percent_statements_covered_display": "93"}, "missing_lines": [105, 106], "excluded_lines": [], "start_line": 49}, "CCAdapter.post_tool_use": {"executed_lines": [112, 113, 114, 116, 117], "summary": {"covered_lines": 5, "num_statements": 5, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 109}, "CCAdapter.handle": {"executed_lines": [121, 123, 124], "summary": {"covered_lines": 3, "num_statements": 5, "percent_covered": 60.0, "percent_covered_display": "60", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 60.0, "percent_statements_covered_display": "60"}, "missing_lines": [122, 125], "excluded_lines": [], "start_line": 119}, "main": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 2, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [133, 134], "excluded_lines": [], "start_line": 128}, "": {"executed_lines": [26, 28, 29, 30, 31, 34, 35, 49, 109, 119, 128, 137], "summary": {"covered_lines": 12, "num_statements": 13, "percent_covered": 92.3076923076923, "percent_covered_display": "92", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 92.3076923076923, "percent_statements_covered_display": "92"}, "missing_lines": [138], "excluded_lines": [], "start_line": 1}}, "classes": {"CCAdapter": {"executed_lines": [41, 42, 43, 44, 47, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 68, 69, 70, 71, 76, 79, 80, 84, 89, 90, 93, 96, 97, 98, 101, 102, 112, 113, 114, 116, 117, 121, 123, 124], "summary": {"covered_lines": 39, "num_statements": 43, "percent_covered": 90.69767441860465, "percent_covered_display": "91", "missing_lines": 4, "excluded_lines": 0, "percent_statements_covered": 90.69767441860465, "percent_statements_covered_display": "91"}, "missing_lines": [105, 106, 122, 125], "excluded_lines": [], "start_line": 34}, "": {"executed_lines": [26, 28, 29, 30, 31, 34, 35, 49, 109, 119, 128, 137], "summary": {"covered_lines": 12, "num_statements": 15, "percent_covered": 80.0, "percent_covered_display": "80", "missing_lines": 3, "excluded_lines": 0, "percent_statements_covered": 80.0, "percent_statements_covered_display": "80"}, "missing_lines": [133, 134, 138], "excluded_lines": [], "start_line": 1}}}, "corvus/compiler.py": {"executed_lines": [17, 19, 20, 21, 26, 29, 33, 43, 46, 47, 48, 49, 50, 52, 55, 62, 63, 64, 66, 69, 70, 71, 77, 78, 79, 80, 81, 83, 88, 89, 90, 94, 95, 96, 100, 101, 102, 103, 104, 106, 109, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 124, 125, 126, 127, 129, 130, 131, 132, 134, 135, 153, 156, 160, 161, 163, 164, 165, 167, 168, 169, 170, 173, 176, 177, 179, 185, 186, 187, 189, 190, 195, 198, 199, 201, 202, 203, 204, 206, 209, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 227, 228, 231], "summary": {"covered_lines": 104, "num_statements": 122, "percent_covered": 85.24590163934427, "percent_covered_display": "85", "missing_lines": 18, "excluded_lines": 0, "percent_statements_covered": 85.24590163934427, "percent_statements_covered_display": "85"}, "missing_lines": [36, 37, 38, 39, 40, 72, 171, 172, 174, 175, 181, 191, 192, 194, 200, 205, 229, 230], "excluded_lines": [], "functions": {"_fail_answer_index": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 5, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 5, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [36, 37, 38, 39, 40], "excluded_lines": [], "start_line": 33}, "validate_register": {"executed_lines": [46, 47, 48, 49, 50, 52, 55, 62, 63, 64, 66, 69, 70, 71, 77, 78, 79, 80, 81, 83, 88, 89, 90, 94, 95, 96, 100, 101, 102, 103, 104, 106], "summary": {"covered_lines": 32, "num_statements": 33, "percent_covered": 96.96969696969697, "percent_covered_display": "97", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 96.96969696969697, "percent_statements_covered_display": "97"}, "missing_lines": [72], "excluded_lines": [], "start_line": 43}, "_coverage": {"executed_lines": [112, 113, 114, 115, 116, 117, 118, 119, 120, 121], "summary": {"covered_lines": 10, "num_statements": 10, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 109}, "compile_catalog": {"executed_lines": [125, 126, 127, 129, 130, 131, 132, 134, 135, 153], "summary": {"covered_lines": 10, "num_statements": 10, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 124}, "diff_classify": {"executed_lines": [160, 161, 163, 164, 165, 167, 168, 169, 170, 173, 176, 177, 179, 185, 186, 187, 189, 190, 195, 198, 199, 201, 202, 203, 204, 206], "summary": {"covered_lines": 26, "num_statements": 36, "percent_covered": 72.22222222222223, "percent_covered_display": "72", "missing_lines": 10, "excluded_lines": 0, "percent_statements_covered": 72.22222222222223, "percent_statements_covered_display": "72"}, "missing_lines": [171, 172, 174, 175, 181, 191, 192, 194, 200, 205], "excluded_lines": [], "start_line": 156}, "build": {"executed_lines": [212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 227, 228, 231], "summary": {"covered_lines": 14, "num_statements": 16, "percent_covered": 87.5, "percent_covered_display": "88", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 87.5, "percent_statements_covered_display": "88"}, "missing_lines": [229, 230], "excluded_lines": [], "start_line": 209}, "": {"executed_lines": [17, 19, 20, 21, 26, 29, 33, 43, 109, 124, 156, 209], "summary": {"covered_lines": 12, "num_statements": 12, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1}}, "classes": {"CompilerError": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 0, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 29}, "": {"executed_lines": [17, 19, 20, 21, 26, 29, 33, 43, 46, 47, 48, 49, 50, 52, 55, 62, 63, 64, 66, 69, 70, 71, 77, 78, 79, 80, 81, 83, 88, 89, 90, 94, 95, 96, 100, 101, 102, 103, 104, 106, 109, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 124, 125, 126, 127, 129, 130, 131, 132, 134, 135, 153, 156, 160, 161, 163, 164, 165, 167, 168, 169, 170, 173, 176, 177, 179, 185, 186, 187, 189, 190, 195, 198, 199, 201, 202, 203, 204, 206, 209, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 227, 228, 231], "summary": {"covered_lines": 104, "num_statements": 122, "percent_covered": 85.24590163934427, "percent_covered_display": "85", "missing_lines": 18, "excluded_lines": 0, "percent_statements_covered": 85.24590163934427, "percent_statements_covered_display": "85"}, "missing_lines": [36, 37, 38, 39, 40, 72, 171, 172, 174, 175, 181, 191, 192, 194, 200, 205, 229, 230], "excluded_lines": [], "start_line": 1}}}, "corvus/config.py": {"executed_lines": [7, 9, 10, 11, 15, 36, 37, 38, 39, 40, 41, 43, 44, 45, 48], "summary": {"covered_lines": 15, "num_statements": 23, "percent_covered": 65.21739130434783, "percent_covered_display": "65", "missing_lines": 8, "excluded_lines": 0, "percent_statements_covered": 65.21739130434783, "percent_statements_covered_display": "65"}, "missing_lines": [55, 56, 57, 58, 66, 67, 68, 73], "excluded_lines": [], "functions": {"FleetConfig.event_types": {"executed_lines": [45], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 44}, "load_config": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 8, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 8, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [55, 56, 57, 58, 66, 67, 68, 73], "excluded_lines": [], "start_line": 48}, "": {"executed_lines": [7, 9, 10, 11, 15, 36, 37, 38, 39, 40, 41, 43, 44, 48], "summary": {"covered_lines": 14, "num_statements": 14, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1}}, "classes": {"FleetConfig": {"executed_lines": [45], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 37}, "": {"executed_lines": [7, 9, 10, 11, 15, 36, 37, 38, 39, 40, 41, 43, 44, 48], "summary": {"covered_lines": 14, "num_statements": 22, "percent_covered": 63.63636363636363, "percent_covered_display": "64", "missing_lines": 8, "excluded_lines": 0, "percent_statements_covered": 63.63636363636363, "percent_statements_covered_display": "64"}, "missing_lines": [55, 56, 57, 58, 66, 67, 68, 73], "excluded_lines": [], "start_line": 1}}}, "corvus/config_loader.py": {"executed_lines": [14, 16, 17, 18, 21, 22, 23, 25, 29, 30, 31, 32, 34, 38, 39, 41, 42], "summary": {"covered_lines": 17, "num_statements": 18, "percent_covered": 94.44444444444444, "percent_covered_display": "94", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 94.44444444444444, "percent_statements_covered_display": "94"}, "missing_lines": [40], "excluded_lines": [], "functions": {"ConfigLoader.__init__": {"executed_lines": [23], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 22}, "ConfigLoader.load_fleet_config": {"executed_lines": [29, 30, 31, 32], "summary": {"covered_lines": 4, "num_statements": 4, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 25}, "ConfigLoader.load_register": {"executed_lines": [38, 39, 41, 42], "summary": {"covered_lines": 4, "num_statements": 5, "percent_covered": 80.0, "percent_covered_display": "80", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 80.0, "percent_statements_covered_display": "80"}, "missing_lines": [40], "excluded_lines": [], "start_line": 34}, "": {"executed_lines": [14, 16, 17, 18, 21, 22, 25, 34], "summary": {"covered_lines": 8, "num_statements": 8, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1}}, "classes": {"ConfigLoader": {"executed_lines": [23, 29, 30, 31, 32, 38, 39, 41, 42], "summary": {"covered_lines": 9, "num_statements": 10, "percent_covered": 90.0, "percent_covered_display": "90", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 90.0, "percent_statements_covered_display": "90"}, "missing_lines": [40], "excluded_lines": [], "start_line": 21}, "": {"executed_lines": [14, 16, 17, 18, 21, 22, 25, 34], "summary": {"covered_lines": 8, "num_statements": 8, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1}}}, "corvus/conformance.py": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 66, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 66, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [31, 33, 34, 35, 36, 38, 39, 42, 66, 75, 77, 78, 79, 80, 81, 82, 85, 86, 87, 88, 92, 93, 94, 98, 99, 100, 104, 105, 106, 107, 108, 111, 116, 117, 118, 120, 121, 122, 123, 124, 125, 127, 128, 131, 132, 137, 141, 142, 143, 144, 146, 147, 148, 149, 150, 154, 155, 156, 157, 158, 159, 160, 162, 163, 164, 168], "excluded_lines": [], "functions": {"run_mutation_suite": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 17, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 17, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [75, 77, 78, 79, 80, 81, 82, 85, 86, 87, 88, 92, 93, 94, 98, 99, 100], "excluded_lines": [], "start_line": 66}, "_extract_red_test": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 4, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 4, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [105, 106, 107, 108], "excluded_lines": [], "start_line": 104}, "conformance_run": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 10, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 10, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [116, 117, 118, 120, 131, 146, 162, 163, 164, 168], "excluded_lines": [], "start_line": 111}, "conformance_run.check": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 7, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 7, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [121, 122, 123, 124, 125, 127, 128], "excluded_lines": [], "start_line": 120}, "conformance_run.happy_path": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 6, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 6, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [132, 137, 141, 142, 143, 144], "excluded_lines": [], "start_line": 131}, "conformance_run.existence_hiding": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 11, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 11, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [147, 148, 149, 150, 154, 155, 156, 157, 158, 159, 160], "excluded_lines": [], "start_line": 146}, "": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 11, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 11, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [31, 33, 34, 35, 36, 38, 39, 42, 66, 104, 111], "excluded_lines": [], "start_line": 1}}, "classes": {"": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 66, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 66, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [31, 33, 34, 35, 36, 38, 39, 42, 66, 75, 77, 78, 79, 80, 81, 82, 85, 86, 87, 88, 92, 93, 94, 98, 99, 100, 104, 105, 106, 107, 108, 111, 116, 117, 118, 120, 121, 122, 123, 124, 125, 127, 128, 131, 132, 137, 141, 142, 143, 144, 146, 147, 148, 149, 150, 154, 155, 156, 157, 158, 159, 160, 162, 163, 164, 168], "excluded_lines": [], "start_line": 1}}}, "corvus/contract_codes.py": {"executed_lines": [8], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "functions": {"": {"executed_lines": [8], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1}}, "classes": {"": {"executed_lines": [8], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1}}}, "corvus/core.py": {"executed_lines": [9, 11, 12, 13, 14, 15, 16, 18, 19, 20, 23, 24, 27, 30, 31, 34, 35, 36, 37, 38, 39, 43, 44, 45, 46, 47, 48, 49, 50, 51, 62, 63, 68, 71, 84, 85, 86, 87, 89, 90, 98, 99, 103, 107, 109, 110, 115, 119, 123, 124, 132, 136, 142, 143, 144, 145, 146, 147, 148, 150, 151, 152, 153, 193, 194, 195, 196, 197, 198, 199, 203, 204, 205, 206], "summary": {"covered_lines": 74, "num_statements": 98, "percent_covered": 75.51020408163265, "percent_covered_display": "76", "missing_lines": 24, "excluded_lines": 0, "percent_statements_covered": 75.51020408163265, "percent_statements_covered_display": "76"}, "missing_lines": [72, 73, 78, 80, 88, 154, 163, 169, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 186, 188, 189, 201, 202], "excluded_lines": [], "functions": {"_now_iso": {"executed_lines": [24], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 23}, "sign_event": {"executed_lines": [30, 31], "summary": {"covered_lines": 2, "num_statements": 2, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 27}, "CorvusCore.__init__": {"executed_lines": [36, 37, 38, 39], "summary": {"covered_lines": 4, "num_statements": 4, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 35}, "CorvusCore.ingest_event": {"executed_lines": [44, 45, 46, 47, 48, 49, 50, 51, 62, 63, 68], "summary": {"covered_lines": 11, "num_statements": 11, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 43}, "CorvusCore.query_events": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 4, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 4, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [72, 73, 78, 80], "excluded_lines": [], "start_line": 71}, "CorvusCore.open_change": {"executed_lines": [85, 86, 87, 89, 90, 98, 99, 103, 107], "summary": {"covered_lines": 9, "num_statements": 10, "percent_covered": 90.0, "percent_covered_display": "90", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 90.0, "percent_statements_covered_display": "90"}, "missing_lines": [88], "excluded_lines": [], "start_line": 84}, "CorvusCore.active_changes_for": {"executed_lines": [110, 115], "summary": {"covered_lines": 2, "num_statements": 2, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 109}, "CorvusCore.conflict_check": {"executed_lines": [123, 124, 132, 136, 142, 143, 144, 145, 146, 147, 148, 150, 151, 152, 153, 193, 194, 195, 196, 197, 198, 199, 203, 204, 205, 206], "summary": {"covered_lines": 26, "num_statements": 45, "percent_covered": 57.77777777777778, "percent_covered_display": "58", "missing_lines": 19, "excluded_lines": 0, "percent_statements_covered": 57.77777777777778, "percent_statements_covered_display": "58"}, "missing_lines": [154, 163, 169, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 186, 188, 189, 201, 202], "excluded_lines": [], "start_line": 119}, "": {"executed_lines": [9, 11, 12, 13, 14, 15, 16, 18, 19, 20, 23, 27, 34, 35, 43, 71, 84, 109, 119], "summary": {"covered_lines": 19, "num_statements": 19, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1}}, "classes": {"CorvusCore": {"executed_lines": [36, 37, 38, 39, 44, 45, 46, 47, 48, 49, 50, 51, 62, 63, 68, 85, 86, 87, 89, 90, 98, 99, 103, 107, 110, 115, 123, 124, 132, 136, 142, 143, 144, 145, 146, 147, 148, 150, 151, 152, 153, 193, 194, 195, 196, 197, 198, 199, 203, 204, 205, 206], "summary": {"covered_lines": 52, "num_statements": 76, "percent_covered": 68.42105263157895, "percent_covered_display": "68", "missing_lines": 24, "excluded_lines": 0, "percent_statements_covered": 68.42105263157895, "percent_statements_covered_display": "68"}, "missing_lines": [72, 73, 78, 80, 88, 154, 163, 169, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 186, 188, 189, 201, 202], "excluded_lines": [], "start_line": 34}, "": {"executed_lines": [9, 11, 12, 13, 14, 15, 16, 18, 19, 20, 23, 24, 27, 30, 31, 34, 35, 43, 71, 84, 109, 119], "summary": {"covered_lines": 22, "num_statements": 22, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1}}}, "corvus/decision_core.py": {"executed_lines": [20, 22, 23, 24, 27, 28, 31, 34, 37, 43, 44, 45, 48, 50, 51, 52, 53, 54, 55, 58, 59, 60, 64, 65, 66, 67, 68, 69, 71, 72, 74, 75, 77, 80, 82, 83, 84, 85, 87, 88, 91, 92, 93, 95, 97, 98, 99, 103, 104, 106, 107, 111, 112, 114, 127, 129, 130, 131, 133, 134, 135, 136, 138, 140, 142, 144, 145, 146, 149, 150, 152, 154, 155, 156, 158, 162, 163, 164, 167, 168, 169, 171, 172, 173, 174, 175, 176], "summary": {"covered_lines": 87, "num_statements": 100, "percent_covered": 87.0, "percent_covered_display": "87", "missing_lines": 13, "excluded_lines": 0, "percent_statements_covered": 87.0, "percent_statements_covered_display": "87"}, "missing_lines": [86, 89, 116, 117, 118, 119, 120, 122, 123, 124, 125, 141, 143], "excluded_lines": [], "functions": {"DecisionCore.__init__": {"executed_lines": [43, 44, 45], "summary": {"covered_lines": 3, "num_statements": 3, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 37}, "DecisionCore.solve": {"executed_lines": [50, 51, 52, 53, 54, 55, 58, 59, 60, 64, 65, 66, 67, 68, 69, 71, 72, 74, 75, 77], "summary": {"covered_lines": 20, "num_statements": 20, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 48}, "DecisionCore._dispatch": {"executed_lines": [82, 83, 84, 85, 87, 88], "summary": {"covered_lines": 6, "num_statements": 8, "percent_covered": 75.0, "percent_covered_display": "75", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 75.0, "percent_statements_covered_display": "75"}, "missing_lines": [86, 89], "excluded_lines": [], "start_line": 80}, "DecisionCore._check_deadline": {"executed_lines": [92, 93], "summary": {"covered_lines": 2, "num_statements": 2, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 91}, "DecisionCore._dispatch_rule": {"executed_lines": [97, 98, 99, 103, 104, 106, 107, 111, 112], "summary": {"covered_lines": 9, "num_statements": 9, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 95}, "DecisionCore._dispatch_lookup": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 9, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 9, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [116, 117, 118, 119, 120, 122, 123, 124, 125], "excluded_lines": [], "start_line": 114}, "DecisionCore._dispatch_model": {"executed_lines": [129, 130, 131, 133, 134, 135, 136, 138, 140, 142, 144, 145, 146], "summary": {"covered_lines": 13, "num_statements": 15, "percent_covered": 86.66666666666667, "percent_covered_display": "87", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 86.66666666666667, "percent_statements_covered_display": "87"}, "missing_lines": [141, 143], "excluded_lines": [], "start_line": 127}, "DecisionCore._full": {"executed_lines": [152, 154, 155, 156], "summary": {"covered_lines": 4, "num_statements": 4, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 150}, "DecisionCore._fail_cell": {"executed_lines": [162, 163, 164, 167, 168, 169], "summary": {"covered_lines": 6, "num_statements": 6, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 158}, "DecisionCore._failed_dependency": {"executed_lines": [173, 174, 175, 176], "summary": {"covered_lines": 4, "num_statements": 4, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 172}, "": {"executed_lines": [20, 22, 23, 24, 27, 28, 31, 34, 37, 48, 80, 91, 95, 114, 127, 149, 150, 158, 171, 172], "summary": {"covered_lines": 20, "num_statements": 20, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1}}, "classes": {"SliceExceeded": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 0, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 27}, "DecisionCore": {"executed_lines": [43, 44, 45, 50, 51, 52, 53, 54, 55, 58, 59, 60, 64, 65, 66, 67, 68, 69, 71, 72, 74, 75, 77, 82, 83, 84, 85, 87, 88, 92, 93, 97, 98, 99, 103, 104, 106, 107, 111, 112, 129, 130, 131, 133, 134, 135, 136, 138, 140, 142, 144, 145, 146, 152, 154, 155, 156, 162, 163, 164, 167, 168, 169, 173, 174, 175, 176], "summary": {"covered_lines": 67, "num_statements": 80, "percent_covered": 83.75, "percent_covered_display": "84", "missing_lines": 13, "excluded_lines": 0, "percent_statements_covered": 83.75, "percent_statements_covered_display": "84"}, "missing_lines": [86, 89, 116, 117, 118, 119, 120, 122, 123, 124, 125, 141, 143], "excluded_lines": [], "start_line": 34}, "": {"executed_lines": [20, 22, 23, 24, 27, 28, 31, 34, 37, 48, 80, 91, 95, 114, 127, 149, 150, 158, 171, 172], "summary": {"covered_lines": 20, "num_statements": 20, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1}}}, "corvus/decisions.py": {"executed_lines": [9, 11, 12, 13, 14, 17, 18, 19, 20, 21, 23, 33, 34, 36, 41, 42, 43, 48, 49, 57, 58, 60, 61, 62, 63, 64, 65, 72], "summary": {"covered_lines": 28, "num_statements": 28, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "functions": {"DecisionClient.__init__": {"executed_lines": [19, 20, 21], "summary": {"covered_lines": 3, "num_statements": 3, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 18}, "DecisionClient.decide": {"executed_lines": [33, 34, 36, 41, 42, 43, 48, 49, 57, 58, 60, 61, 62, 63, 64, 65, 72], "summary": {"covered_lines": 17, "num_statements": 17, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 23}, "": {"executed_lines": [9, 11, 12, 13, 14, 17, 18, 23], "summary": {"covered_lines": 8, "num_statements": 8, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1}}, "classes": {"DecisionClient": {"executed_lines": [19, 20, 21, 33, 34, 36, 41, 42, 43, 48, 49, 57, 58, 60, 61, 62, 63, 64, 65, 72], "summary": {"covered_lines": 20, "num_statements": 20, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 17}, "": {"executed_lines": [9, 11, 12, 13, 14, 17, 18, 23], "summary": {"covered_lines": 8, "num_statements": 8, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1}}}, "corvus/delivery.py": {"executed_lines": [13, 15, 18, 19, 25, 26, 27, 28, 29, 31, 35, 37, 38, 41, 43, 47, 48, 50, 51, 52, 53, 54, 55, 56, 60, 61, 63, 64, 66, 70, 71, 72, 73, 74, 75, 76, 77, 80, 81, 82, 83, 84, 89, 90, 92, 96, 97, 99, 103, 105, 106], "summary": {"covered_lines": 51, "num_statements": 55, "percent_covered": 92.72727272727273, "percent_covered_display": "93", "missing_lines": 4, "excluded_lines": 0, "percent_statements_covered": 92.72727272727273, "percent_statements_covered_display": "93"}, "missing_lines": [49, 78, 79, 104], "excluded_lines": [], "functions": {"DeliveryChain.__init__": {"executed_lines": [25, 26, 27, 28, 29], "summary": {"covered_lines": 5, "num_statements": 5, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 19}, "DeliveryChain.submit": {"executed_lines": [35, 37, 38, 41], "summary": {"covered_lines": 4, "num_statements": 4, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 31}, "DeliveryChain.deliver": {"executed_lines": [47, 48, 50, 51, 52, 53, 54, 55, 56, 60, 61, 63, 64], "summary": {"covered_lines": 13, "num_statements": 14, "percent_covered": 92.85714285714286, "percent_covered_display": "93", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 92.85714285714286, "percent_statements_covered_display": "93"}, "missing_lines": [49], "excluded_lines": [], "start_line": 43}, "DeliveryChain.deliver_on_recovery": {"executed_lines": [70, 71, 72, 73, 74, 75, 76, 77, 80, 81, 82, 83, 84, 89, 90, 92, 96, 97], "summary": {"covered_lines": 18, "num_statements": 20, "percent_covered": 90.0, "percent_covered_display": "90", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 90.0, "percent_statements_covered_display": "90"}, "missing_lines": [78, 79], "excluded_lines": [], "start_line": 66}, "DeliveryChain.route_invalid": {"executed_lines": [103, 105, 106], "summary": {"covered_lines": 3, "num_statements": 4, "percent_covered": 75.0, "percent_covered_display": "75", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 75.0, "percent_statements_covered_display": "75"}, "missing_lines": [104], "excluded_lines": [], "start_line": 99}, "": {"executed_lines": [13, 15, 18, 19, 31, 43, 66, 99], "summary": {"covered_lines": 8, "num_statements": 8, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1}}, "classes": {"DeliveryChain": {"executed_lines": [25, 26, 27, 28, 29, 35, 37, 38, 41, 47, 48, 50, 51, 52, 53, 54, 55, 56, 60, 61, 63, 64, 70, 71, 72, 73, 74, 75, 76, 77, 80, 81, 82, 83, 84, 89, 90, 92, 96, 97, 103, 105, 106], "summary": {"covered_lines": 43, "num_statements": 47, "percent_covered": 91.48936170212765, "percent_covered_display": "91", "missing_lines": 4, "excluded_lines": 0, "percent_statements_covered": 91.48936170212765, "percent_statements_covered_display": "91"}, "missing_lines": [49, 78, 79, 104], "excluded_lines": [], "start_line": 18}, "": {"executed_lines": [13, 15, 18, 19, 31, 43, 66, 99], "summary": {"covered_lines": 8, "num_statements": 8, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1}}}, "corvus/engine_shim.py": {"executed_lines": [15, 17, 18, 19, 20, 22, 24, 25, 27, 28, 29, 31, 33, 41, 43, 44, 53, 54, 57, 66, 67, 68, 69, 71, 72, 73, 75, 76, 77, 78, 79, 80, 83, 84, 92, 94, 97, 103, 104, 106, 107, 108, 111, 112, 113, 117, 118, 119, 125, 126, 127, 128, 129, 130, 131, 133, 134, 135, 139, 140, 141, 142, 143, 144, 146, 147, 149, 153, 157, 158, 159, 160, 161, 163, 164, 165, 166, 177, 178, 179, 180, 181, 182, 183, 184, 185, 189, 195, 196, 197, 198, 199, 200, 201, 204, 205, 207, 208, 209, 211, 212, 217, 218, 219, 220, 221, 222, 223, 224, 226, 227, 230, 234, 236, 237, 238, 239, 264, 274, 281, 282, 283, 284, 287, 288, 289, 292], "summary": {"covered_lines": 127, "num_statements": 147, "percent_covered": 86.39455782312925, "percent_covered_display": "86", "missing_lines": 20, "excluded_lines": 0, "percent_statements_covered": 86.39455782312925, "percent_statements_covered_display": "86"}, "missing_lines": [70, 105, 145, 162, 225, 229, 231, 245, 246, 247, 248, 249, 256, 257, 293, 294, 295, 296, 297, 298], "excluded_lines": [], "functions": {"err": {"executed_lines": [43, 44], "summary": {"covered_lines": 2, "num_statements": 2, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 41}, "_register_candidates": {"executed_lines": [67, 68, 69, 71, 72, 73], "summary": {"covered_lines": 6, "num_statements": 7, "percent_covered": 85.71428571428571, "percent_covered_display": "86", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 85.71428571428571, "percent_statements_covered_display": "86"}, "missing_lines": [70], "excluded_lines": [], "start_line": 66}, "_site_resolution": {"executed_lines": [84], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 83}, "_quantize": {"executed_lines": [103, 104, 106, 107, 108], "summary": {"covered_lines": 5, "num_statements": 6, "percent_covered": 83.33333333333333, "percent_covered_display": "83", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 83.33333333333333, "percent_statements_covered_display": "83"}, "missing_lines": [105], "excluded_lines": [], "start_line": 97}, "decide": {"executed_lines": [113, 117, 118, 119, 125, 126, 127, 128, 129, 130, 131, 133, 134, 135, 139, 140, 141, 142, 143, 144, 146, 147, 149, 153, 157, 158, 159, 160, 161, 163, 164, 165, 166, 177, 178, 179, 180, 181, 182, 183, 184, 185, 189, 195, 196, 197, 198, 199, 200, 201, 204, 205, 207, 208, 209, 211, 212, 217, 218, 219, 220, 221, 222, 223, 224, 226, 227, 230, 234, 236, 237, 238, 239, 264, 274, 281, 282, 283, 284], "summary": {"covered_lines": 79, "num_statements": 91, "percent_covered": 86.81318681318682, "percent_covered_display": "87", "missing_lines": 12, "excluded_lines": 0, "percent_statements_covered": 86.81318681318682, "percent_statements_covered_display": "87"}, "missing_lines": [145, 162, 225, 229, 231, 245, 246, 247, 248, 249, 256, 257], "excluded_lines": [], "start_line": 112}, "hashlib_sha": {"executed_lines": [288, 289], "summary": {"covered_lines": 2, "num_statements": 2, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 287}, "": {"executed_lines": [15, 17, 18, 19, 20, 22, 24, 25, 27, 28, 29, 31, 33, 41, 53, 54, 57, 66, 75, 76, 77, 78, 79, 80, 83, 92, 94, 97, 111, 112, 287, 292], "summary": {"covered_lines": 32, "num_statements": 38, "percent_covered": 84.21052631578948, "percent_covered_display": "84", "missing_lines": 6, "excluded_lines": 0, "percent_statements_covered": 84.21052631578948, "percent_statements_covered_display": "84"}, "missing_lines": [293, 294, 295, 296, 297, 298], "excluded_lines": [], "start_line": 1}}, "classes": {"": {"executed_lines": [15, 17, 18, 19, 20, 22, 24, 25, 27, 28, 29, 31, 33, 41, 43, 44, 53, 54, 57, 66, 67, 68, 69, 71, 72, 73, 75, 76, 77, 78, 79, 80, 83, 84, 92, 94, 97, 103, 104, 106, 107, 108, 111, 112, 113, 117, 118, 119, 125, 126, 127, 128, 129, 130, 131, 133, 134, 135, 139, 140, 141, 142, 143, 144, 146, 147, 149, 153, 157, 158, 159, 160, 161, 163, 164, 165, 166, 177, 178, 179, 180, 181, 182, 183, 184, 185, 189, 195, 196, 197, 198, 199, 200, 201, 204, 205, 207, 208, 209, 211, 212, 217, 218, 219, 220, 221, 222, 223, 224, 226, 227, 230, 234, 236, 237, 238, 239, 264, 274, 281, 282, 283, 284, 287, 288, 289, 292], "summary": {"covered_lines": 127, "num_statements": 147, "percent_covered": 86.39455782312925, "percent_covered_display": "86", "missing_lines": 20, "excluded_lines": 0, "percent_statements_covered": 86.39455782312925, "percent_statements_covered_display": "86"}, "missing_lines": [70, 105, 145, 162, 225, 229, 231, 245, 246, 247, 248, 249, 256, 257, 293, 294, 295, 296, 297, 298], "excluded_lines": [], "start_line": 1}}}, "corvus/facts.py": {"executed_lines": [27, 29, 30, 33, 38, 41, 42, 46, 47, 49, 52, 53, 54, 55, 56, 57, 59, 60, 61, 62, 63, 68, 69, 70, 71, 72, 73, 74, 75, 76, 79, 81, 85, 87, 88, 89, 90, 91, 93, 94, 101, 104, 105, 106, 109, 110, 111, 122], "summary": {"covered_lines": 48, "num_statements": 51, "percent_covered": 94.11764705882354, "percent_covered_display": "94", "missing_lines": 3, "excluded_lines": 0, "percent_statements_covered": 94.11764705882354, "percent_statements_covered_display": "94"}, "missing_lines": [114, 117, 118], "excluded_lines": [], "functions": {"FactComposer.__init__": {"executed_lines": [46, 47], "summary": {"covered_lines": 2, "num_statements": 2, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 42}, "FactComposer.compose": {"executed_lines": [52, 53, 54, 55, 56, 57, 59, 60, 61, 62, 63, 68, 69, 70, 71, 72, 73, 74, 75, 76, 79], "summary": {"covered_lines": 21, "num_statements": 21, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 49}, "FactComposer.compose_status_view": {"executed_lines": [85, 87, 88, 89, 90, 91, 93, 94], "summary": {"covered_lines": 8, "num_statements": 8, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 81}, "change_window_source": {"executed_lines": [104, 122], "summary": {"covered_lines": 2, "num_statements": 2, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 101}, "change_window_source.source": {"executed_lines": [105, 106, 109, 110, 111], "summary": {"covered_lines": 5, "num_statements": 8, "percent_covered": 62.5, "percent_covered_display": "62", "missing_lines": 3, "excluded_lines": 0, "percent_statements_covered": 62.5, "percent_statements_covered_display": "62"}, "missing_lines": [114, 117, 118], "excluded_lines": [], "start_line": 104}, "": {"executed_lines": [27, 29, 30, 33, 38, 41, 42, 49, 81, 101], "summary": {"covered_lines": 10, "num_statements": 10, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1}}, "classes": {"FactComposer": {"executed_lines": [46, 47, 52, 53, 54, 55, 56, 57, 59, 60, 61, 62, 63, 68, 69, 70, 71, 72, 73, 74, 75, 76, 79, 85, 87, 88, 89, 90, 91, 93, 94], "summary": {"covered_lines": 31, "num_statements": 31, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 41}, "": {"executed_lines": [27, 29, 30, 33, 38, 41, 42, 49, 81, 101, 104, 105, 106, 109, 110, 111, 122], "summary": {"covered_lines": 17, "num_statements": 20, "percent_covered": 85.0, "percent_covered_display": "85", "missing_lines": 3, "excluded_lines": 0, "percent_statements_covered": 85.0, "percent_statements_covered_display": "85"}, "missing_lines": [114, 117, 118], "excluded_lines": [], "start_line": 1}}}, "corvus/hlc.py": {"executed_lines": [8, 9, 10, 13, 14, 15, 16, 17, 19, 20, 21, 26, 27, 30, 31, 32, 33, 34, 35, 37, 38, 39, 40, 41, 42, 45, 47, 50, 51, 52, 53, 61], "summary": {"covered_lines": 32, "num_statements": 42, "percent_covered": 76.19047619047619, "percent_covered_display": "76", "missing_lines": 10, "excluded_lines": 0, "percent_statements_covered": 76.19047619047619, "percent_statements_covered_display": "76"}, "missing_lines": [22, 23, 24, 44, 54, 55, 56, 57, 59, 60], "excluded_lines": [], "functions": {"HLCTimestamp.__lt__": {"executed_lines": [20, 21], "summary": {"covered_lines": 2, "num_statements": 5, "percent_covered": 40.0, "percent_covered_display": "40", "missing_lines": 3, "excluded_lines": 0, "percent_statements_covered": 40.0, "percent_statements_covered_display": "40"}, "missing_lines": [22, 23, 24], "excluded_lines": [], "start_line": 19}, "HLCTimestamp.to_string": {"executed_lines": [27], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 26}, "HLC.__init__": {"executed_lines": [32, 33, 34, 35], "summary": {"covered_lines": 4, "num_statements": 4, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 31}, "HLC.now": {"executed_lines": [38, 39, 40, 41, 42, 45], "summary": {"covered_lines": 6, "num_statements": 7, "percent_covered": 85.71428571428571, "percent_covered_display": "86", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 85.71428571428571, "percent_statements_covered_display": "86"}, "missing_lines": [44], "excluded_lines": [], "start_line": 37}, "HLC.merge": {"executed_lines": [50, 51, 52, 53, 61], "summary": {"covered_lines": 5, "num_statements": 11, "percent_covered": 45.45454545454545, "percent_covered_display": "45", "missing_lines": 6, "excluded_lines": 0, "percent_statements_covered": 45.45454545454545, "percent_statements_covered_display": "45"}, "missing_lines": [54, 55, 56, 57, 59, 60], "excluded_lines": [], "start_line": 47}, "": {"executed_lines": [8, 9, 10, 13, 14, 15, 16, 17, 19, 26, 30, 31, 37, 47], "summary": {"covered_lines": 14, "num_statements": 14, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1}}, "classes": {"HLCTimestamp": {"executed_lines": [20, 21, 27], "summary": {"covered_lines": 3, "num_statements": 6, "percent_covered": 50.0, "percent_covered_display": "50", "missing_lines": 3, "excluded_lines": 0, "percent_statements_covered": 50.0, "percent_statements_covered_display": "50"}, "missing_lines": [22, 23, 24], "excluded_lines": [], "start_line": 14}, "HLC": {"executed_lines": [32, 33, 34, 35, 38, 39, 40, 41, 42, 45, 50, 51, 52, 53, 61], "summary": {"covered_lines": 15, "num_statements": 22, "percent_covered": 68.18181818181819, "percent_covered_display": "68", "missing_lines": 7, "excluded_lines": 0, "percent_statements_covered": 68.18181818181819, "percent_statements_covered_display": "68"}, "missing_lines": [44, 54, 55, 56, 57, 59, 60], "excluded_lines": [], "start_line": 30}, "": {"executed_lines": [8, 9, 10, 13, 14, 15, 16, 17, 19, 26, 30, 31, 37, 47], "summary": {"covered_lines": 14, "num_statements": 14, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1}}}, "corvus/observe.py": {"executed_lines": [21, 23, 26, 27, 31, 32, 33, 35, 41, 42, 46, 47, 49, 53, 54, 55, 58, 60, 63, 66, 70], "summary": {"covered_lines": 21, "num_statements": 21, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "functions": {"ObserveMode.__init__": {"executed_lines": [31, 32, 33], "summary": {"covered_lines": 3, "num_statements": 3, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 27}, "ObserveMode.record_attempt": {"executed_lines": [41, 42, 46, 47, 49, 53, 54, 55, 58], "summary": {"covered_lines": 9, "num_statements": 9, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 35}, "ObserveMode.coverage": {"executed_lines": [63], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 60}, "ObserveMode.token_issuance_allowed": {"executed_lines": [70], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 66}, "": {"executed_lines": [21, 23, 26, 27, 35, 60, 66], "summary": {"covered_lines": 7, "num_statements": 7, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1}}, "classes": {"ObserveMode": {"executed_lines": [31, 32, 33, 41, 42, 46, 47, 49, 53, 54, 55, 58, 63, 70], "summary": {"covered_lines": 14, "num_statements": 14, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 26}, "": {"executed_lines": [21, 23, 26, 27, 35, 60, 66], "summary": {"covered_lines": 7, "num_statements": 7, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1}}}, "corvus/ops.py": {"executed_lines": [13, 15, 18, 21, 26, 28, 32, 33, 34, 37, 41, 42, 43, 44, 46, 47, 48, 49, 51, 52, 53, 54, 56, 57, 58, 61, 70, 71, 72, 74, 75, 76, 79, 80, 81, 82, 83, 84, 85, 87], "summary": {"covered_lines": 40, "num_statements": 41, "percent_covered": 97.5609756097561, "percent_covered_display": "98", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 97.5609756097561, "percent_statements_covered_display": "98"}, "missing_lines": [77], "excluded_lines": [], "functions": {"FleetScopeResolver.__init__": {"executed_lines": [26], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 21}, "FleetScopeResolver.resolve": {"executed_lines": [32, 33, 34], "summary": {"covered_lines": 3, "num_statements": 3, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 28}, "Metrics.__init__": {"executed_lines": [42, 43, 44], "summary": {"covered_lines": 3, "num_statements": 3, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 41}, "Metrics.inc": {"executed_lines": [47, 48, 49], "summary": {"covered_lines": 3, "num_statements": 3, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 46}, "Metrics.set_gauge": {"executed_lines": [52, 53, 54], "summary": {"covered_lines": 3, "num_statements": 3, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 51}, "Metrics.snapshot": {"executed_lines": [57, 58], "summary": {"covered_lines": 2, "num_statements": 2, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 56}, "Health.__init__": {"executed_lines": [71, 72], "summary": {"covered_lines": 2, "num_statements": 2, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 70}, "Health.record_latency": {"executed_lines": [75, 76], "summary": {"covered_lines": 2, "num_statements": 3, "percent_covered": 66.66666666666667, "percent_covered_display": "67", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 66.66666666666667, "percent_statements_covered_display": "67"}, "missing_lines": [77], "excluded_lines": [], "start_line": 74}, "Health.state": {"executed_lines": [80, 81, 82, 83, 84, 85, 87], "summary": {"covered_lines": 7, "num_statements": 7, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 79}, "": {"executed_lines": [13, 15, 18, 21, 28, 37, 41, 46, 51, 56, 61, 70, 74, 79], "summary": {"covered_lines": 14, "num_statements": 14, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1}}, "classes": {"FleetScopeResolver": {"executed_lines": [26, 32, 33, 34], "summary": {"covered_lines": 4, "num_statements": 4, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 18}, "Metrics": {"executed_lines": [42, 43, 44, 47, 48, 49, 52, 53, 54, 57, 58], "summary": {"covered_lines": 11, "num_statements": 11, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 37}, "Health": {"executed_lines": [71, 72, 75, 76, 80, 81, 82, 83, 84, 85, 87], "summary": {"covered_lines": 11, "num_statements": 12, "percent_covered": 91.66666666666667, "percent_covered_display": "92", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 91.66666666666667, "percent_statements_covered_display": "92"}, "missing_lines": [77], "excluded_lines": [], "start_line": 61}, "": {"executed_lines": [13, 15, 18, 21, 28, 37, 41, 46, 51, 56, 61, 70, 74, 79], "summary": {"covered_lines": 14, "num_statements": 14, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1}}}, "corvus/state.py": {"executed_lines": [8, 10, 11, 12, 14, 59, 62, 63, 64, 65, 66, 67, 68, 70, 71, 72, 73, 74, 75], "summary": {"covered_lines": 19, "num_statements": 19, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "functions": {"State.__init__": {"executed_lines": [63, 64, 65, 66, 67, 68], "summary": {"covered_lines": 6, "num_statements": 6, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 62}, "State.execute": {"executed_lines": [71, 72, 73, 74, 75], "summary": {"covered_lines": 5, "num_statements": 5, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 70}, "": {"executed_lines": [8, 10, 11, 12, 14, 59, 62, 70], "summary": {"covered_lines": 8, "num_statements": 8, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1}}, "classes": {"State": {"executed_lines": [63, 64, 65, 66, 67, 68, 71, 72, 73, 74, 75], "summary": {"covered_lines": 11, "num_statements": 11, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 59}, "": {"executed_lines": [8, 10, 11, 12, 14, 59, 62, 70], "summary": {"covered_lines": 8, "num_statements": 8, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1}}}, "corvus/tokens.py": {"executed_lines": [31, 33, 34, 35, 38, 39, 44, 45, 48, 49, 53, 54, 55, 56, 57, 58, 60, 67, 68, 72, 80, 81, 83, 87, 91, 93, 94, 96, 100, 103, 108, 109, 114, 117, 140, 145], "summary": {"covered_lines": 36, "num_statements": 58, "percent_covered": 62.06896551724138, "percent_covered_display": "62", "missing_lines": 22, "excluded_lines": 0, "percent_statements_covered": 62.06896551724138, "percent_statements_covered_display": "62"}, "missing_lines": [40, 41, 69, 92, 95, 97, 98, 99, 101, 102, 104, 127, 128, 129, 130, 131, 132, 133, 134, 138, 141, 148], "excluded_lines": [], "functions": {"TokenRefused.__init__": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 2, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [40, 41], "excluded_lines": [], "start_line": 39}, "VerdictTokenIssuer.__init__": {"executed_lines": [53, 54, 55, 56, 57, 58], "summary": {"covered_lines": 6, "num_statements": 6, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 49}, "VerdictTokenIssuer.issue": {"executed_lines": [67, 68, 72, 80, 81], "summary": {"covered_lines": 5, "num_statements": 6, "percent_covered": 83.33333333333333, "percent_covered_display": "83", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 83.33333333333333, "percent_statements_covered_display": "83"}, "missing_lines": [69], "excluded_lines": [], "start_line": 60}, "VerdictTokenIssuer.consume": {"executed_lines": [87, 91, 93, 94, 96, 100, 103, 108, 109, 114], "summary": {"covered_lines": 10, "num_statements": 18, "percent_covered": 55.55555555555556, "percent_covered_display": "56", "missing_lines": 8, "excluded_lines": 0, "percent_statements_covered": 55.55555555555556, "percent_statements_covered_display": "56"}, "missing_lines": [92, 95, 97, 98, 99, 101, 102, 104], "excluded_lines": [], "start_line": 83}, "VerdictTokenIssuer.revoke": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 9, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 9, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [127, 128, 129, 130, 131, 132, 133, 134, 138], "excluded_lines": [], "start_line": 117}, "VerdictTokenIssuer.outstanding_for": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 1, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [141], "excluded_lines": [], "start_line": 140}, "action_fingerprint": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 1, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [148], "excluded_lines": [], "start_line": 145}, "": {"executed_lines": [31, 33, 34, 35, 38, 39, 44, 45, 48, 49, 60, 83, 117, 140, 145], "summary": {"covered_lines": 15, "num_statements": 15, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1}}, "classes": {"TokenRefused": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 2, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [40, 41], "excluded_lines": [], "start_line": 38}, "EvidenceNotDurable": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 0, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 44}, "VerdictTokenIssuer": {"executed_lines": [53, 54, 55, 56, 57, 58, 67, 68, 72, 80, 81, 87, 91, 93, 94, 96, 100, 103, 108, 109, 114], "summary": {"covered_lines": 21, "num_statements": 40, "percent_covered": 52.5, "percent_covered_display": "52", "missing_lines": 19, "excluded_lines": 0, "percent_statements_covered": 52.5, "percent_statements_covered_display": "52"}, "missing_lines": [69, 92, 95, 97, 98, 99, 101, 102, 104, 127, 128, 129, 130, 131, 132, 133, 134, 138, 141], "excluded_lines": [], "start_line": 48}, "": {"executed_lines": [31, 33, 34, 35, 38, 39, 44, 45, 48, 49, 60, 83, 117, 140, 145], "summary": {"covered_lines": 15, "num_statements": 16, "percent_covered": 93.75, "percent_covered_display": "94", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 93.75, "percent_statements_covered_display": "94"}, "missing_lines": [148], "excluded_lines": [], "start_line": 1}}}, "corvus/trust.py": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 61, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 61, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [36, 38, 41, 44, 52, 53, 56, 57, 58, 59, 60, 62, 66, 67, 68, 70, 77, 78, 79, 80, 83, 84, 85, 87, 94, 95, 96, 97, 98, 102, 108, 109, 110, 111, 112, 114, 115, 117, 118, 120, 122, 125, 126, 127, 128, 129, 130, 133, 134, 135, 138, 140, 141, 147, 154, 155, 161, 164, 166, 171, 172], "excluded_lines": [], "functions": {"TrustLedger.__init__": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 5, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 5, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [56, 57, 58, 59, 60], "excluded_lines": [], "start_line": 53}, "TrustLedger.tier": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 3, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 3, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [66, 67, 68], "excluded_lines": [], "start_line": 62}, "TrustLedger.record_outcome": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 7, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 7, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [77, 78, 79, 80, 83, 84, 85], "excluded_lines": [], "start_line": 70}, "TrustLedger.due_missing": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 5, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 5, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [94, 95, 96, 97, 98], "excluded_lines": [], "start_line": 87}, "TrustLedger.evaluate_promotion": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 20, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 20, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [108, 109, 110, 111, 112, 114, 115, 117, 118, 120, 122, 125, 126, 127, 128, 129, 130, 133, 134, 135], "excluded_lines": [], "start_line": 102}, "TrustLedger.promote": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 2, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [140, 141], "excluded_lines": [], "start_line": 138}, "TrustLedger.demote": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 2, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [154, 155], "excluded_lines": [], "start_line": 147}, "TrustLedger.invalidate_on_drift": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 1, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [164], "excluded_lines": [], "start_line": 161}, "TrustLedger.quarantine": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 2, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [171, 172], "excluded_lines": [], "start_line": 166}, "": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 14, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 14, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [36, 38, 41, 44, 52, 53, 62, 70, 87, 102, 138, 147, 161, 166], "excluded_lines": [], "start_line": 1}}, "classes": {"TrustLedger": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 47, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 47, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [56, 57, 58, 59, 60, 66, 67, 68, 77, 78, 79, 80, 83, 84, 85, 94, 95, 96, 97, 98, 108, 109, 110, 111, 112, 114, 115, 117, 118, 120, 122, 125, 126, 127, 128, 129, 130, 133, 134, 135, 140, 141, 154, 155, 164, 171, 172], "excluded_lines": [], "start_line": 52}, "": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 14, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 14, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [36, 38, 41, 44, 52, 53, 62, 70, 87, 102, 138, 147, 161, 166], "excluded_lines": [], "start_line": 1}}}}, "totals": {"covered_lines": 932, "num_statements": 1277, "percent_covered": 72.98355520751763, "percent_covered_display": "73", "missing_lines": 345, "excluded_lines": 0, "percent_statements_covered": 72.98355520751763, "percent_statements_covered_display": "73"}} \ No newline at end of file diff --git a/corvus-v2/junit.xml b/corvus-v2/junit.xml index a9ac60e..e88675c 100644 --- a/corvus-v2/junit.xml +++ b/corvus-v2/junit.xml @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/corvus-v2/requirements.txt b/corvus-v2/requirements.txt index d86765f..75b52d0 100644 --- a/corvus-v2/requirements.txt +++ b/corvus-v2/requirements.txt @@ -1,4 +1,7 @@ -fastapi>=0.115 -uvicorn>=0.30 -pyyaml>=6.0 -pydantic>=2.0 +# Floors are the versions the harness actually tested (python3.12), capped at the +# next MAJOR: a future breaking major must fail loudly at install time rather than +# be silently absorbed by a loose floor. Re-run `make cycle` before raising. +fastapi>=0.162,<1.0 +uvicorn>=0.54,<1.0 +pyyaml>=6.0.3,<7.0 +pydantic>=2.14,<3.0 diff --git a/corvus-v2/scripts/check_metrics.py b/corvus-v2/scripts/check_metrics.py index 9f6d9e1..4653466 100644 --- a/corvus-v2/scripts/check_metrics.py +++ b/corvus-v2/scripts/check_metrics.py @@ -1,47 +1,76 @@ #!/usr/bin/env python3 -"""The metrics drift guard: the committed dev-metrics.json must match a fresh -run. A stale file fails the gate — the mutation-provable control that keeps -the metrics honest (the mutation: stale the file → the gate must red).""" +"""The metrics drift guard: the committed dev-metrics.json must match a fresh run. + +A stale file fails the gate — the mutation-provable control that keeps the +metrics honest (the mutation: stale the file -> the gate must red). + +WHAT IS GATED AND WHY THE TOLERANCES ARE WHAT THEY ARE +The interpreter is PINNED to python3.12 in the Makefile and in CI, so the +interpreter-variance that forced a 7.0-point coverage tolerance is gone. The +measured history, kept because it explains the numbers: + 2026-10-19: the same suite on 3.15 = 79.1% vs 3.12 = 72.9% -> 6.2 points apart. + 2026-10-24: pinned 3.12.15 = 73.0%, 1277 statements, 90 tests. +The 108-tests / 79.1% / 1274-lines file committed on 2026-10-19 was therefore +stale, and the OLD guard passed it: it compared only coverage percent and +lines_total, so a test-count drift of 108-vs-90 was invisible. The test count +is now gated exactly. That is the whole point of a drift guard — it must be +able to fail on the drift that actually happened. +""" import argparse import json import sys from pathlib import Path +# The interpreter is pinned (python3.12) on both sides, so these are tight. +COVERAGE_TOLERANCE = 1.0 # percentage points — rounding only, not interpreter variance +LINES_TOLERANCE = 0 # statements are deterministic for a fixed interpreter + source + def main(): ap = argparse.ArgumentParser() - ap.add_argument("--expected", required=True) - ap.add_argument("--actual", required=True) - ap.add_argument("--tolerance", type=float, default=7.0, - help="the coverage percent tolerance — CALIBRATED TO THE MEASURED " - "interpreter variance (2026-10-19: the same suite on 3.15 = 79.1%% " - "vs 3.12 = 72.9%% → 6.2 points apart; the tolerance 7.0 covers it " - "while the stale file (the 227-era seed) still fails by 50+ points)") + ap.add_argument("--expected", required=True, help="the committed dev-metrics.json") + ap.add_argument("--actual", required=True, help="the metrics from a fresh run") + ap.add_argument("--coverage-tolerance", type=float, default=COVERAGE_TOLERANCE) + ap.add_argument("--lines-tolerance", type=int, default=LINES_TOLERANCE) args = ap.parse_args() expected = json.loads(Path(args.expected).read_text()) actual = json.loads(Path(args.actual).read_text()) - # The source_commit is INFORMATIONAL (every commit changes the HEAD sha, - # so gating on it is structurally unsatisfiable — caught live by this - # guard's own first CI run). The MEASURABLE facts gate. + # source_commit is INFORMATIONAL: every commit changes the HEAD sha, so gating + # on it is structurally unsatisfiable (caught live by this guard's first CI run). + # The MEASURABLE facts gate. drifts = [] + ec = expected.get("coverage", {}).get("percent") ac = actual.get("coverage", {}).get("percent") - if ec is None or ac is None or abs((ac or 0) - (ec or 0)) > args.tolerance: - drifts.append(f"coverage percent: {ec} != {ac}") + if ec is None or ac is None or abs((ac or 0) - (ec or 0)) > args.coverage_tolerance: + drifts.append(f"coverage percent: committed {ec} != fresh {ac} (tolerance {args.coverage_tolerance})") + et = expected.get("coverage", {}).get("lines_total") at = actual.get("coverage", {}).get("lines_total") - if et is not None and at is not None and abs(at - et) > 6: - drifts.append(f"lines_total: {et} != {at} (beyond the interpreter variance)") + if et is None or at is None or abs(at - et) > args.lines_tolerance: + drifts.append(f"lines_total: committed {et} != fresh {at} (tolerance {args.lines_tolerance})") + + # The test count is exact: it cannot vary with the interpreter, and its drift is + # exactly the failure the old guard could not see. + ett = expected.get("tests", {}).get("total") + att = actual.get("tests", {}).get("total") + if ett is None or att is None or ett != att: + drifts.append(f"tests total: committed {ett} != fresh {att} (exact — no tolerance)") + + af = actual.get("tests", {}).get("failed") + if af is not None and af > 0: + drifts.append(f"the fresh run has {af} failing test(s)") if drifts: print("METRICS DRIFT — the committed dev-metrics.json is stale:") for d in drifts: print(" ", d) - print("Run `make metrics` and commit the refreshed file.") + print("Run 'make test && make metrics' and commit the refreshed file.") sys.exit(1) - print("metrics: fresh (no drift)") + + print(f"metrics: fresh (no drift) — {att} tests, {ac}% coverage, {at} statements") if __name__ == "__main__": diff --git a/corvus-v2/scripts/dev_check.py b/corvus-v2/scripts/dev_check.py new file mode 100644 index 0000000..c9370a0 --- /dev/null +++ b/corvus-v2/scripts/dev_check.py @@ -0,0 +1,73 @@ +#!/usr/bin/env python3 +"""The corvus-v2 build proof: the engine actually serves. + +This is the harness's "build" step, and it proves three things a unit test +cannot: the app object constructs from a real config, it serves over a real +socket, and the auth boundary both admits a valid key and rejects an invalid +one. The 401 control matters — a check that only ever sees 200 would pass on +an app whose auth gate was deleted. + +Exit 0 on success, non-zero with the reason on failure. +""" +import json +import socket +import sys +import threading +import time +import urllib.error +import urllib.request + +sys.path.insert(0, ".") +from corvus.app import create_app # noqa: E402 +from corvus.config import FleetConfig # noqa: E402 + +API_KEY = "dev-local-key" + + +def free_port() -> int: + with socket.socket() as s: + s.bind(("127.0.0.1", 0)) + return s.getsockname()[1] + + +def main() -> int: + port = free_port() + cfg = FleetConfig(name="dev-fleet", node_id="dev-1", api_key=API_KEY) + app = create_app(config=cfg, db_path=":memory:") + import uvicorn + + t = threading.Thread( + target=lambda: uvicorn.run(app, host="127.0.0.1", port=port, log_level="error"), + daemon=True, + ) + t.start() + time.sleep(1.5) + + def get(path: str, key: str): + req = urllib.request.Request(f"http://127.0.0.1:{port}{path}", headers={"X-Corvus-Key": key}) + return urllib.request.urlopen(req, timeout=5) + + health = json.loads(get("/health", "unused").read()) + assert health["status"] == "ok", f"health not ok: {health}" + + authed = json.loads(get("/ops/events", API_KEY).read()) + assert authed is not None, "the authenticated read returned nothing" + + try: + get("/ops/events", "wrong-key") + except urllib.error.HTTPError as e: + assert e.code == 401, f"expected 401 for a bad key, got {e.code}" + else: + return fail("the auth gate did NOT reject a wrong key") + + print(f"build: ok — {health['fleet']} / health + authenticated read + 401 control") + return 0 + + +def fail(msg: str) -> int: + print(f"build: FAILED — {msg}", file=sys.stderr) + return 1 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/docs/DEV-READINESS-REVIEW.md b/docs/DEV-READINESS-REVIEW.md new file mode 100644 index 0000000..a74c526 --- /dev/null +++ b/docs/DEV-READINESS-REVIEW.md @@ -0,0 +1,213 @@ +# Dev Readiness Review — the plan against what the harness can prove + +**Baseline**: worktree `corvus-dev`, branch `harness/per-component`, HEAD `2191155` (= `origin/main`). +**Interpreter**: `python3 --version` → 3.15.0; `python3.12 --version` → 3.12.15. Every component +harness pins 3.12; CI uses 3.12. +**Method**: every current-state claim names its instrument — a `file:line`, a command with its real +output, or a live probe. Claims I could not verify are listed in §8, not softened into the prose. +Numbers below are from my own runs on this worktree unless a different instrument is named. The +repo's README and CLAUDE.md are not instruments: they describe v1 and are stale (§7.12). + +## 1. Component inventory + +| Component | What it is | Status | Current state — instrument | +|---|---|---|---| +| `corvus-v2` | The decision engine + the CCB spine (the single binary) | **LIVE** — deployed | 24 modules, 1,277 statements; 90 tests pass at 73.0% coverage (`make cycle`). No `pyproject.toml` (`ls corvus-v2/pyproject.toml` → absent; requirements.txt only), so `pip install -e .` is impossible. Three modules at 0% (`coverage.json` per-file list): `app.py` (78 stmts), `conformance.py` (66), `trust.py` (61). | +| `corvus-sdk` | Async Python client | **LIVE PACKAGE, v1 protocol** | 220 statements; 54 tests, 100% coverage, all against mocked HTTP (`respx`; `make cycle`). 30 `/ops` paths, **3** served by v2. | +| `corvus-cli` | typer CLI | **LIVE PACKAGE, v1 protocol** | 214 statements; 50 tests (added on this branch), 100% coverage, `MockTransport` (`make cycle`); 15 `/ops` paths, **3** served by v2; no evidence-export command. | +| `corvus-server` | v1 platform (FastAPI, CMDB, runbooks, Neo4j) | **LEGACY** — archived at `v1-archive`, not deployed | `src/` absent on this branch (`ls corvus-server/src` → No such file); `Dockerfile:35` still `COPY src/ src/`; two modules remain; 15 runbooks; 0 tests. | +| `corvus-hooks` | v1 governance hooks (CC PreToolUse/PostToolUse, 3 adapters, installer) | **LEGACY** — not deployed | stdlib scripts; default URL `http://localhost:9420` and v1 route `/ops/events/targets/{target}/status` (`corvus_core.py:28,80`); 0 tests; v1 copy archived at `~/.claude/hooks/_archive-corvus-decom-2026-05-28`. | +| `corvus-splunk` | Splunk app (4 dashboards, 11 searches, 3 lookups) | **LEGACY config** — not deployed | expects `index=corvus sourcetype="corvus:ocsf"` + `class_uid` (`default/macros.conf:4,13-29`); app version 0.1.0; 0 tests; no Splunk instance locally. | + +The `Status` column carries the distinction that matters: a component can be **live as a package** +(builds, lints, tests, CI-gated) while speaking a protocol nothing serves. `corvus-cli` and +`corvus-sdk` are exactly that (§3.1). + +## 2. What "live" actually is: the deployed surface + +- **One workload, one container.** `kubectl -n corvus get deploy,svc,pods -o wide` → `corvus-engine` + 1/1 ready, image `harbor.themillertribe-int.org/homelab/corvus-v2:2191155`, Service + `10.43.206.222:8933`, pod on `tmtdockp01` (1 restart 2d14h ago). `kubectl get deploy,sts,ds -A | + grep -i corvus` returns that single line — no v1 server, no second deployment. +- **The deployed artifact is the decision engine, not the CCB.** The container sets no + `command`/`args` (`kubectl … -o jsonpath` → `||8933`), so the image CMD runs: + `python -m corvus.engine_shim --port 8933` (`corvus-v2/Dockerfile:21`). The shim declares exactly + one route, `POST /v1/fleets/{fleet_id}/decide` (`corvus/engine_shim.py:111`); there is no GET + status route, and liveness/readiness are TCP probes on 8933. +- **The CCB spine is not deployed.** `corvus/app.py` defines the event ingest, change windows and + the conflict check (`app.py:70-119`, six paths) but no workload in this cluster serves them and + nothing exposes a port other than 8933. +- **The register is byte-identical to HEAD.** `shasum -a 256 decision-register.yaml` → + `7ede7637…6e368`; `kubectl -n corvus get cm corvus-register -o jsonpath='{.data.decision-register\.yaml}' + | shasum -a 256` → the same hash. The register is 19 sites + 10 facts + 3 composition policies + (`python3.12` + yaml: `len(sites)=19`, `len(fact_layer.facts)=10`), while its own header comment + (`decision-register.yaml:5`) says "18 sites + 9 fact citizens". +- **The live capture store is not durable.** The deployment sets `CORVUS_CAPTURE_DB=/data/capture.db` + on an `emptyDir` volume (`kubectl -n corvus get deploy corvus-engine -o yaml`), so the decision + records and the replay index die with the pod. The local default (`:memory:`, + `engine_shim.py:92`) is no better; only an explicitly configured file path persists. +- **Public reachability is real but the path is not visible from the cluster.** + `curl -sS -o /dev/null -w '%{http_code}' https://corvus.themillertribe-int.org/` → `404` + (the app answers); `dig +short corvus.themillertribe-int.org` → `192.168.20.230`; + `kubectl get ingress -A` → 0 corvus matches. The hop from that address to the ClusterIP is + outside the cluster's Ingress surface and I did not verify it. + +## 3. The two seams that are broken + +### 3.1 The clients speak v1; the engine serves v2 + +Exact string comparison of the clients' called paths against `app.py`'s route decorators +(`python3.12`, regex over the three files): + +``` +v2 routes: ['/health', '/ops/changes', '/ops/changes/active', '/ops/conflict-check', + '/ops/events', '/ops/events/stream'] +sdk: 30 distinct paths; exact v2 matches: 3 -> ['/ops/changes', '/ops/changes/active', '/ops/events'] +cli: 15 distinct paths; exact v2 matches: 3 -> ['/ops/changes', '/ops/changes/active', '/ops/events'] +``` + +So **27 of 30 SDK paths and 12 of 15 CLI paths are not served by v2** — `/ops/cmdb`, +`/ops/incidents`, `/ops/runbooks/*`, `/ops/graph/*`, `/ops/trust`, `/ops/gaps`, `/ops/metrics`, +`/ops/knowledge/*`, `/ops/discovery/*`, `/ops/problems`, `/ops/events/context`, +`/ops/events/targets/{t}/status`, `/ops/changes/{id}`. The same v1 routes are hard-coded in the +hooks (`corvus_core.py:80,107`) against `http://localhost:9420` (`:28`) — the v1 server's port. + +Their 100% coverage is real but scoped: the SDK tests mock with `respx`, and the CLI fixture states +"No test ever opens a socket" (`corvus-cli/tests/conftest.py:3`). **No test in the repo starts a v2 +server and runs a client against it.** Green here proves the client's own logic, not parity. + +### 3.2 The v2 binary exercises 4 of its 24 modules + +Static import reachability from the two entrypoints (`python3.12` + `ast` over `corvus/*.py`): + +``` +engine_shim reachable: ['canonical', 'capture', 'contract_codes', 'engine_shim'] +app reachable: ['app', 'config', 'core', 'hlc', 'state'] +NOT reachable from either entrypoint: __init__, adapter, attested, cc_adapter, compiler, + config_loader, conformance, decision_core, decisions, delivery, facts, observe, ops, tokens, trust +``` + +15 modules exist only for the tests or for the out-of-repo adapter. The load-bearing ones: + +- **The trust ledger is unwired.** `TrustLedger` (`trust.py:52`) has no importer; nothing writes the + `ops_trust` table (`state.py:49`) — `conflict_check` only reads it (`core.py:133`), so every live + answer carries the default `trust_tier: "ESCALATE"`. `test_spine.py:65-68` pins that default; no + test promotes a tier and observes it in a conflict answer. Capability 3 (graded autonomy) is not + on the deployed path. +- **The observe mode, delivery chain, verdict tokens, decision client and conformance runner are + not reachable from the deployed binary** — `observe.py`, `delivery.py`, `tokens.py`, + `decisions.py`, `conformance.py`. They are tested as units (`test_observe_delivery.py`, + `test_decision_contract.py`), never as the deployed surface. +- **`app.py` is 0% under pytest** even though it is the CCB's whole HTTP surface. The harness build + step exercises `/health` and the auth boundary over a socket (`scripts/dev_check.py`), which is + why the build target is meaningful — but no pytest test covers the app. +- **The P1 conformance gate is not gated.** At HEAD, `ci-v2.yaml` ran lint, tests, the metrics + guard and a smoke job — no mutation, no conformance run. The branch's CI matrix runs each + component's `make cycle`, which still does not include the `mutation`/`conformance` targets. + The P1 capability gate ("the conformance suite runs green in CI with the mutation evidence") is + therefore a manual target, not a gate. + +## 4. What the dev harness proves today + +Each component owns `/Makefile`; the root `Makefile` runs every component's `cycle`. + +| Component | Targets | Evidence from my run | What it cannot prove | +|---|---|---|---| +| `corvus-v2` | setup build lint test fix metrics metrics-check run check cycle mutation conformance clean | `make cycle`: "build: ok — dev-fleet / health + authenticated read + 401 control"; "All checks passed!"; "90 passed, 13 warnings in 15.94s"; "TOTAL 1277 345 73%"; "metrics: fresh (no drift) — 90 tests, 73.0% coverage, 1277 statements" | the deployed decision path; `app.py` under pytest; the mutation/conformance gates (manual, not in cycle/CI) | +| `corvus-sdk` | setup build lint test fix cycle clean | `make cycle`: "build: ok — 0.1.0"; "All checks passed!"; "54 passed in 0.33s"; "TOTAL 220 0 100%" | parity with v2 — every request is mocked | +| `corvus-cli` | setup build lint test fix cycle clean | `make cycle`: "import: ok"; "`corvus --help`" and "`corvus check-target --help`" exit 0; "All checks passed!"; "50 passed in 0.72s"; "TOTAL 214 0 100%" | parity with v2; any command that reads decisions/capture/audit evidence | +| `corvus-server` | setup lint import fix cycle clean | `make cycle`: "All checks passed!"; "import: ok on 3.12.15 — soc2 APIRouter(3 routes), typer app 'corvus' (11 commands)" | anything behavioral: no tests, no runnable app | +| `corvus-hooks` | setup lint import fix cycle clean | `make cycle`: "All checks passed!"; "import: byte-compiled 8 scripts"; "import: ok — corvus_core imported, public API present" | that the hooks work against any server (they target v1 routes) | +| `corvus-splunk` | setup validate cycle clean | `make cycle`: "validate: ok — 6 conf, 5 xml, 3 csv, 1 py" | that Splunk accepts the app, that the SPL is valid, that the dashboards render | + +Two contract deviations, stated plainly: `corvus-v2` has no `pyproject.toml`, so its `build` is a +live-socket proof instead of `pip install -e .`; and the three legacy components replace +`build`/`test` with `import`/`validate` because there is no installable package and no suite. + +Consequence for the umbrella: `make cycle` works for all six components, but the root's +`build`/`lint`/`test`/`fix` loops abort at the first component that lacks the target +(`make -C corvus-hooks test` → "No rule to make target 'test'"; `make -C corvus-splunk build` → +same for `build`, and splunk has no `lint` or `fix` either). Only the per-component `cycle` is a +uniform command today. + +## 5. Plan mapping — the phase that needs each component next + +| Component | Phase | What the plan needs | What the harness proves | The gap | +|---|---|---|---|---| +| `corvus-v2` | **P1** (then P2/P3) | C1 answers live traffic in observe mode; the capture store records full-schema decisions; the conformance suite runs green in CI with mutation evidence | the engine contract (15 wire tests), 90 unit tests, a live health/auth proof | trust ledger unwired; observe/delivery/tokens not on the deployed path; capture ephemeral live; conformance/mutation not in CI; `app.py` 0% under pytest | +| `corvus-sdk` | **P3** | "the SDK reduced to the documented HTTP contract (any language)" | 54 mocked tests at 100% | v1 protocol: 27/30 paths unserved; no real-server test | +| `corvus-cli` | **P5** | "the audit CLI's evidence export" | 50 mocked tests at 100%, entrypoint dispatch | v1 protocol; no decision/audit/evidence commands exist | +| `corvus-server` | **P2** (+P4) | the runbook schema + validation gate; the knowledge base; blind-spot detection "ported from the old implementation where the concept survives review" | lint + import of the two remaining modules | `src/` is in `v1-archive`; 15 runbooks with no schema gate; 78 archived test files / 746 test functions that cannot run on this branch | +| `corvus-hooks` | **P1** | ADR-004's adapter contract, its conformance suite, and the first two real adapters | lint + byte-compile + `corvus_core` import | v1 routes; no adapter-conformance fixture; the one real v2 adapter is outside the repo (§7.4) | +| `corvus-splunk` | **P3** | "The Splunk app validated against the rebuilt OCSF events" | config/XML/CSV parse + cross-reference validation | v2 emits no OCSF and forwards nothing to a SIEM (§7.6) | + +**THE acceptance gate is untestable today.** "A new harness reaches full governance parity by +shipping only an adapter" needs a fixture that runs an adapter against the engine and checks the +four capabilities. The repo has the engine's wire conformance (`conformance.py:111`) and unit tests +for the CC adapter with a stub client (`test_cc_adapter.py`), but no adapter-conformance harness. + +## 6. The metrics guard: the drift it could not see + +``` +committed at HEAD (git show HEAD:docs/canonical-path/dev-metrics.json): 108 tests, 79.1%, 1274 lines, source dabbda4 +my fresh run (make cycle): 90 tests, 73.0%, 1277 lines, source 2191155 +``` + +At HEAD the guard compared only coverage percent (tolerance 7.0) and `lines_total` (tolerance 6) +(`git diff corvus-v2/scripts/check_metrics.py` shows the removed code); 108-vs-90 tests was +invisible to it. On this branch the guard gates the test count exactly and coverage to 1.0 point +with 0-statement tolerance — my `make cycle` above passes the tightened gate. + +## 7. Blind spots — what a developer cannot verify locally + +1. **The deployed decision path has no test.** `app.py` is 0% under pytest; the deployed shim's only + route is `POST /decide`, so even a live smoke check writes to the capture store. +2. **The live capture store is ephemeral** (`emptyDir`): the audit trail does not survive a pod + restart, and no local run can prove otherwise for the deployment. +3. **Client↔engine parity is unproven**: no test starts a v2 server and drives a client at it. +4. **The only real adapter is out of repo.** `~/.claude/hooks/corvus-v2-observe.py` (wired at + `~/.claude/settings.json:119`) imports `corvus` from a different worktree + (`/Users/tmiller/worktrees/corvus-canonical/corvus-v2`) and defaults to the deployed URL. Its + chain DB `~/.corvus-v2/chain.db` has mtime 2026-10-19T15:17 (12,288 bytes) — the local evidence + store has not recorded since. Nothing in the repo exercises it. +5. **The acceptance gate has no fixture** (§5), so "parity by adapter alone" is a claim, not a check. +6. **OCSF/SIEM is absent from v2.** `grep -rniE 'splunk|\bsiem\b|ocsf' corvus-v2/corvus/ --include=*.py` + → one docstring line (`core.py:5`). PRODUCT capability 2's "OCSF 1.3.0" stream and the Splunk + app's consumer side cannot be validated locally. +7. **No lockfiles anywhere** (`find . -maxdepth 3 \( -name 'poetry.lock' -o -name 'uv.lock' -o -name + 'requirements*.lock' -o -name 'Pipfile.lock' -o -name 'pdm.lock' \) -not -path '*/.venv/*'` → none). + Dependency floors are `>=`; a fresh resolve today equals the current latest (Lead's PyPI query, + 2026-10-24T03:30Z, corroborated by `.venv` `pip list`: fastapi 0.162.0, uvicorn 0.54.0, + pydantic 2.14.1, pyyaml 6.0.3), but nothing pins that resolve — the only pin is the toolchain + (`ruff==0.17.1`, deliberate; latest is 0.17.2). Reproducibility rests on CI going red after a + break, not on a pinned set. The legacy server's floors are majors behind + (`corvus-server/requirements.txt`: `neo4j>=5.20.0`, `mcp>=1.0.0`; latest 6.4.1 and 2.3.0 per the + Lead's query), and it caps `pytest-asyncio>=0.25.0,<1.0.0`. +8. **The mutation runner rewrites the working tree.** `run_mutation_suite` writes the mutant and + restores it (`conformance.py:87,98`); a kill between the two leaves a mutated repo. It is not in + CI and is unsafe to run concurrently with anyone editing. +9. **The contract tests share a fixed port.** Each `shim` fixture starts uvicorn on 8934 and never + stops it; my run emits repeated `PytestUnhandledThreadExceptionWarning` (Thread-2…6, uvicorn + startup `SystemExit: 3`) and still passes because an earlier server is listening. Parallel runs + or a busy port collide. +10. **The deployed register load is inferred, not observed.** The mount is proven (hash match), and + `engine_shim.py:66-80` is the path ladder, but I could not read the running process's loaded + register: `kubectl exec` is blocked by the session's guardrails (a DDR is required for that + target), and I did not author one. +11. **The public route is unverified** (§2): DNS resolves to a LAN address; there is no Ingress. +12. **The repo's own docs are stale instruments.** `CLAUDE.md` documents `corvus-server/src/app.py`, + `routers/`, `middleware/` (absent: `ls corvus-server/src` fails), a 12-runbook count (15 on + disk: `ls corvus-server/runbooks/*.yaml | wc -l`), and a `docker run … ghcr.io/…/corvus:latest` + deployment (the live image is `harbor…/corvus-v2:2191155` on 8933). README describes the v1 box. + +## 8. Claims I could not verify + +- That the deployed engine actually **loaded** the mounted register (mount hash proven; load not). +- The live capture DB's contents, row count, or persistence across a restart (`kubectl exec` blocked). +- SDK/CLI behavior against a **real** v2 server (not attempted; static route comparison is the + instrument used instead). +- The v1 hooks' runtime behavior (no tests, not deployed, and their target routes do not exist in v2). +- The Splunk app in a real Splunk (no instance available): acceptance, SPL validity, rendering. +- The deployed engine's latency, availability, or behavior under load (no load instrument here). +- Whether the out-of-repo CC adapter currently works end-to-end (its chain DB is stale; running it + would POST a decision to the live engine, which I did not do). diff --git a/docs/canonical-path/dev-metrics.json b/docs/canonical-path/dev-metrics.json index 947d0cb..9797082 100644 --- a/docs/canonical-path/dev-metrics.json +++ b/docs/canonical-path/dev-metrics.json @@ -1,16 +1,16 @@ { "schema": 1, - "source_commit": "dabbda4", - "generated_at": "2026-10-19T21:30:43.414112+00:00", + "source_commit": "2191155", + "generated_at": "2026-10-24T03:24:33.605193+00:00", "tests": { - "total": 108, - "passed": 108, + "total": 90, + "passed": 90, "failed": 0 }, "coverage": { - "percent": 79.1, - "lines_covered": 1008, - "lines_total": 1274 + "percent": 73.0, + "lines_covered": 932, + "lines_total": 1277 }, - "duration_seconds": 0.0 + "duration_seconds": 16.38 } From 74963dcad174b37478eb5e16d53d4ba75946dd18 Mon Sep 17 00:00:00 2001 From: "tmt-homelab-agent[bot]" Date: Fri, 23 Oct 2026 20:37:08 -0700 Subject: [PATCH 2/3] =?UTF-8?q?docs(review):=20the=20umbrella=20abort=20is?= =?UTF-8?q?=20fixed=20=E2=80=94=20record=20the=20verified=20state,=20not?= =?UTF-8?q?=20the=20stale=20one?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/DEV-READINESS-REVIEW.md | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/docs/DEV-READINESS-REVIEW.md b/docs/DEV-READINESS-REVIEW.md index a74c526..76ed2f0 100644 --- a/docs/DEV-READINESS-REVIEW.md +++ b/docs/DEV-READINESS-REVIEW.md @@ -124,11 +124,14 @@ Two contract deviations, stated plainly: `corvus-v2` has no `pyproject.toml`, so live-socket proof instead of `pip install -e .`; and the three legacy components replace `build`/`test` with `import`/`validate` because there is no installable package and no suite. -Consequence for the umbrella: `make cycle` works for all six components, but the root's -`build`/`lint`/`test`/`fix` loops abort at the first component that lacks the target +Consequence for the umbrella, and its fix: the root's `build`/`lint`/`test`/`fix` first looped +over all six components and aborted at the first one lacking the target (`make -C corvus-hooks test` → "No rule to make target 'test'"; `make -C corvus-splunk build` → -same for `build`, and splunk has no `lint` or `fix` either). Only the per-component `cycle` is a -uniform command today. +same, and splunk has no `lint` or `fix` either). The root Makefile now declares per-target +component lists — `LIVE` (the three with build/test), `PY` (the five that lint and autofix), and +`ALL` (setup/cycle/clean) — so every root target resolves. Verified on this worktree: `make lint`, +`make build`, `make test` and `make fix` all exit 0, and `make fix` on the clean tree leaves +`git status` byte-identical (it is idempotent). `make check` is an alias for `make cycle`. ## 5. Plan mapping — the phase that needs each component next From 927e323f40ed399ae22c181c61e2b6e8fe8d3057 Mon Sep 17 00:00:00 2001 From: "tmt-homelab-agent[bot]" Date: Fri, 23 Oct 2026 20:38:39 -0700 Subject: [PATCH 3/3] fix(harness): the conformance target tested the wrong server and killed its own shell Two measured defects in the v2 conformance target, both found by running it in CI: 1. It cleaned up with pkill -f "engine_shim --port 8933". The recipe's own shell carries that string in its argv, so pkill matched the shell and killed it: the run passed 2/0 and make then reported "Terminated", exit 2 (CI 40058979560). It now kills the shim by PID. 2. It bound a fixed 8933. This host runs a launchd agent (com.themillertribe.corvus-v2-engine) already bound to 127.0.0.1:8933 from a different worktree, so a local "pass" was evidence about that process, not this code. The port is now ephemeral and a shim that fails to start fails loudly. Recorded both in docs/DEV-READINESS-REVIEW.md as blind spots. --- corvus-v2/Makefile | 16 +++++++++++++--- corvus-v2/coverage.json | 2 +- corvus-v2/junit.xml | 2 +- docs/DEV-READINESS-REVIEW.md | 12 +++++++++++- 4 files changed, 26 insertions(+), 6 deletions(-) diff --git a/corvus-v2/Makefile b/corvus-v2/Makefile index 54d8491..26cc406 100644 --- a/corvus-v2/Makefile +++ b/corvus-v2/Makefile @@ -60,9 +60,19 @@ mutation: ## The mutation evidence (the phase-gate target) $(PY) -c "import sys; sys.path.insert(0, '.'); from corvus.conformance import run_mutation_suite; import json; r = run_mutation_suite(); print(json.dumps(r, indent=1)); exit(0 if r['all_mutants_caught'] else 1)" conformance: ## The conformance run against the engine shim (the phase-gate target) - $(PY) -m corvus.engine_shim --port 8933 & sleep 2; \ - $(PY) -c "import sys; sys.path.insert(0, '.'); from corvus.conformance import conformance_run; import json; r = conformance_run('http://127.0.0.1:8933'); print(json.dumps(r, indent=1)); exit(0 if r['failed'] == 0 else 1)"; \ - pkill -f "engine_shim --port 8933" || true + @PORT=$$($(PY) -c 'import socket; s=socket.socket(); s.bind(("127.0.0.1", 0)); print(s.getsockname()[1]); s.close()'); \ + $(PY) -m corvus.engine_shim --port $$PORT & SHIM=$$!; sleep 2; \ + $(PY) -c "import sys, json; sys.path.insert(0, '.'); from corvus.conformance import conformance_run; r = conformance_run('http://127.0.0.1:' + sys.argv[1]); print(json.dumps(r, indent=1)); sys.exit(0 if r['failed'] == 0 else 1)" $$PORT; \ + STATUS=$$?; kill $$SHIM 2>/dev/null || true; exit $$STATUS +# Two measured defects this target used to have: +# 1. The shim is killed by PID, never by `pkill -f`: the recipe's own shell carries +# the pattern in its argv, so pkill matched and killed the shell — the run passed +# (2/0) while make reported "Terminated" and exited 2 (CI run 40058979560). +# 2. The port is EPHEMERAL. A fixed 8933 silently tested whatever already held it: +# this host runs a launchd agent (com.themillertribe.corvus-v2-engine) bound to +# 127.0.0.1:8933 from a different worktree, so a local conformance "pass" was +# evidence about that process, not this code. The ephemeral port removes the +# ambiguity; if the shim fails to start, conformance fails loudly. # PREFLIGHT:rollback-written — clean deletes only REGENERABLE state (the venv and the # pytest cache); `make setup` and `make test` recreate both. It deliberately does NOT diff --git a/corvus-v2/coverage.json b/corvus-v2/coverage.json index 969824e..9300f5d 100644 --- a/corvus-v2/coverage.json +++ b/corvus-v2/coverage.json @@ -1 +1 @@ -{"meta": {"format": 3, "version": "7.17.0", "timestamp": "2026-10-23T20:34:30.782572", "branch_coverage": false, "show_contexts": false}, "files": {"corvus/__init__.py": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 0, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "functions": {"": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 0, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1}}, "classes": {"": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 0, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1}}}, "corvus/adapter.py": {"executed_lines": [17, 19, 20, 21, 22, 23, 26, 31, 32, 36, 39, 41, 42, 43, 44, 45, 47, 49, 50, 51, 52, 55, 57, 58, 59, 60, 62, 63, 64, 65, 66, 70, 71, 72, 74, 75, 79, 80, 81, 85, 86, 91, 95, 98, 100, 101, 102, 104, 106, 108, 109, 110, 111, 112, 114], "summary": {"covered_lines": 55, "num_statements": 58, "percent_covered": 94.82758620689656, "percent_covered_display": "95", "missing_lines": 3, "excluded_lines": 0, "percent_statements_covered": 94.82758620689656, "percent_statements_covered_display": "95"}, "missing_lines": [69, 82, 113], "excluded_lines": [], "functions": {"Adapter.solve": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 0, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 32}, "ClefFlashAdapter.__init__": {"executed_lines": [41, 42, 43, 44, 45], "summary": {"covered_lines": 5, "num_statements": 5, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 39}, "ClefFlashAdapter.solve": {"executed_lines": [49, 50, 51, 52, 55, 57, 58, 59, 60, 62, 63, 64, 65, 66, 70, 71, 72, 74, 75, 79, 80, 81, 85, 86, 91], "summary": {"covered_lines": 25, "num_statements": 27, "percent_covered": 92.5925925925926, "percent_covered_display": "93", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 92.5925925925926, "percent_statements_covered_display": "93"}, "missing_lines": [69, 82], "excluded_lines": [], "start_line": 47}, "StubAdapter.__init__": {"executed_lines": [100, 101, 102], "summary": {"covered_lines": 3, "num_statements": 3, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 98}, "StubAdapter.solve": {"executed_lines": [106, 108, 109, 110, 111, 112, 114], "summary": {"covered_lines": 7, "num_statements": 8, "percent_covered": 87.5, "percent_covered_display": "88", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 87.5, "percent_statements_covered_display": "88"}, "missing_lines": [113], "excluded_lines": [], "start_line": 104}, "": {"executed_lines": [17, 19, 20, 21, 22, 23, 26, 31, 32, 36, 39, 47, 95, 98, 104], "summary": {"covered_lines": 15, "num_statements": 15, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1}}, "classes": {"AdapterUnavailable": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 0, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 26}, "Adapter": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 0, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 31}, "ClefFlashAdapter": {"executed_lines": [41, 42, 43, 44, 45, 49, 50, 51, 52, 55, 57, 58, 59, 60, 62, 63, 64, 65, 66, 70, 71, 72, 74, 75, 79, 80, 81, 85, 86, 91], "summary": {"covered_lines": 30, "num_statements": 32, "percent_covered": 93.75, "percent_covered_display": "94", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 93.75, "percent_statements_covered_display": "94"}, "missing_lines": [69, 82], "excluded_lines": [], "start_line": 36}, "StubAdapter": {"executed_lines": [100, 101, 102, 106, 108, 109, 110, 111, 112, 114], "summary": {"covered_lines": 10, "num_statements": 11, "percent_covered": 90.9090909090909, "percent_covered_display": "91", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 90.9090909090909, "percent_statements_covered_display": "91"}, "missing_lines": [113], "excluded_lines": [], "start_line": 95}, "": {"executed_lines": [17, 19, 20, 21, 22, 23, 26, 31, 32, 36, 39, 47, 95, 98, 104], "summary": {"covered_lines": 15, "num_statements": 15, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1}}}, "corvus/app.py": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 78, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 78, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [15, 17, 18, 19, 20, 21, 23, 25, 26, 27, 29, 30, 31, 34, 35, 36, 37, 38, 39, 42, 43, 44, 45, 46, 47, 48, 51, 52, 53, 54, 55, 58, 59, 60, 61, 62, 64, 67, 68, 70, 71, 72, 75, 76, 77, 78, 79, 80, 81, 82, 83, 85, 86, 88, 90, 91, 92, 93, 95, 96, 97, 98, 99, 101, 103, 105, 106, 107, 108, 109, 110, 112, 113, 114, 116, 117, 119, 121], "excluded_lines": [], "functions": {"_auth_key": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 4, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 4, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [52, 53, 54, 55], "excluded_lines": [], "start_line": 51}, "create_app": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 21, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 21, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [59, 60, 61, 62, 64, 67, 70, 71, 75, 76, 85, 86, 90, 91, 105, 106, 112, 113, 116, 117, 121], "excluded_lines": [], "start_line": 58}, "create_app.require_key": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 1, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [68], "excluded_lines": [], "start_line": 67}, "create_app.health": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 1, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [72], "excluded_lines": [], "start_line": 71}, "create_app.ingest": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 7, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 7, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [77, 78, 79, 80, 81, 82, 83], "excluded_lines": [], "start_line": 76}, "create_app.events": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 1, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [88], "excluded_lines": [], "start_line": 86}, "create_app.stream": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 4, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 4, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [92, 93, 95, 103], "excluded_lines": [], "start_line": 91}, "create_app.stream.gen": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 5, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 5, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [96, 97, 98, 99, 101], "excluded_lines": [], "start_line": 95}, "create_app.open_change": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 4, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 4, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [107, 108, 109, 110], "excluded_lines": [], "start_line": 106}, "create_app.active_changes": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 1, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [114], "excluded_lines": [], "start_line": 113}, "create_app.conflict_check": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 1, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [119], "excluded_lines": [], "start_line": 117}, "": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 28, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 28, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [15, 17, 18, 19, 20, 21, 23, 25, 26, 27, 29, 30, 31, 34, 35, 36, 37, 38, 39, 42, 43, 44, 45, 46, 47, 48, 51, 58], "excluded_lines": [], "start_line": 1}}, "classes": {"EventIn": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 0, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 34}, "ChangeIn": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 0, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 42}, "": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 78, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 78, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [15, 17, 18, 19, 20, 21, 23, 25, 26, 27, 29, 30, 31, 34, 35, 36, 37, 38, 39, 42, 43, 44, 45, 46, 47, 48, 51, 52, 53, 54, 55, 58, 59, 60, 61, 62, 64, 67, 68, 70, 71, 72, 75, 76, 77, 78, 79, 80, 81, 82, 83, 85, 86, 88, 90, 91, 92, 93, 95, 96, 97, 98, 99, 101, 103, 105, 106, 107, 108, 109, 110, 112, 113, 114, 116, 117, 119, 121], "excluded_lines": [], "start_line": 1}}}, "corvus/attested.py": {"executed_lines": [22, 24, 25, 26, 27, 28, 30, 32, 33, 36, 37, 38, 39, 40, 41, 50, 51, 53, 56, 58, 59, 61, 62, 63, 64, 67, 71, 72, 76, 77, 78, 84, 87, 91, 96, 97, 98, 99, 102, 103, 104, 107, 109, 110, 112, 113, 115, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 132, 133, 134, 135, 137, 138, 141], "summary": {"covered_lines": 64, "num_statements": 68, "percent_covered": 94.11764705882354, "percent_covered_display": "94", "missing_lines": 4, "excluded_lines": 0, "percent_statements_covered": 94.11764705882354, "percent_statements_covered_display": "94"}, "missing_lines": [79, 105, 129, 131], "excluded_lines": [], "functions": {"AttestedStore.__init__": {"executed_lines": [38, 39, 40, 41, 50, 51], "summary": {"covered_lines": 6, "num_statements": 6, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 37}, "AttestedStore.append": {"executed_lines": [56, 58, 59, 61, 62, 63, 64, 67, 71, 72], "summary": {"covered_lines": 10, "num_statements": 10, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 53}, "AttestedStore.chain": {"executed_lines": [77, 78, 84, 87], "summary": {"covered_lines": 4, "num_statements": 5, "percent_covered": 80.0, "percent_covered_display": "80", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 80.0, "percent_statements_covered_display": "80"}, "missing_lines": [79], "excluded_lines": [], "start_line": 76}, "AttestedStore.verify": {"executed_lines": [96, 97, 98, 99, 102, 103, 104, 107, 109, 110, 112, 113], "summary": {"covered_lines": 12, "num_statements": 13, "percent_covered": 92.3076923076923, "percent_covered_display": "92", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 92.3076923076923, "percent_statements_covered_display": "92"}, "missing_lines": [105], "excluded_lines": [], "start_line": 91}, "AttestedStore.lifecycle_walk": {"executed_lines": [119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 132, 133, 134, 135, 137, 138, 141], "summary": {"covered_lines": 17, "num_statements": 19, "percent_covered": 89.47368421052632, "percent_covered_display": "89", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 89.47368421052632, "percent_statements_covered_display": "89"}, "missing_lines": [129, 131], "excluded_lines": [], "start_line": 115}, "": {"executed_lines": [22, 24, 25, 26, 27, 28, 30, 32, 33, 36, 37, 53, 76, 91, 115], "summary": {"covered_lines": 15, "num_statements": 15, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1}}, "classes": {"AttestedStore": {"executed_lines": [38, 39, 40, 41, 50, 51, 56, 58, 59, 61, 62, 63, 64, 67, 71, 72, 77, 78, 84, 87, 96, 97, 98, 99, 102, 103, 104, 107, 109, 110, 112, 113, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 132, 133, 134, 135, 137, 138, 141], "summary": {"covered_lines": 49, "num_statements": 53, "percent_covered": 92.45283018867924, "percent_covered_display": "92", "missing_lines": 4, "excluded_lines": 0, "percent_statements_covered": 92.45283018867924, "percent_statements_covered_display": "92"}, "missing_lines": [79, 105, 129, 131], "excluded_lines": [], "start_line": 36}, "": {"executed_lines": [22, 24, 25, 26, 27, 28, 30, 32, 33, 36, 37, 53, 76, 91, 115], "summary": {"covered_lines": 15, "num_statements": 15, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1}}}, "corvus/canonical.py": {"executed_lines": [10, 12, 13, 14, 17, 19, 20, 21, 22, 23, 25, 28, 30, 31, 34, 35, 38, 42, 43], "summary": {"covered_lines": 19, "num_statements": 21, "percent_covered": 90.47619047619048, "percent_covered_display": "90", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 90.47619047619048, "percent_statements_covered_display": "90"}, "missing_lines": [24, 29], "excluded_lines": [], "functions": {"canonicalize": {"executed_lines": [19, 20, 21, 22, 23, 25, 28, 30, 31], "summary": {"covered_lines": 9, "num_statements": 11, "percent_covered": 81.81818181818181, "percent_covered_display": "82", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 81.81818181818181, "percent_statements_covered_display": "82"}, "missing_lines": [24, 29], "excluded_lines": [], "start_line": 17}, "canonical_json": {"executed_lines": [35], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 34}, "request_hash": {"executed_lines": [42, 43], "summary": {"covered_lines": 2, "num_statements": 2, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 38}, "": {"executed_lines": [10, 12, 13, 14, 17, 34, 38], "summary": {"covered_lines": 7, "num_statements": 7, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1}}, "classes": {"": {"executed_lines": [10, 12, 13, 14, 17, 19, 20, 21, 22, 23, 25, 28, 30, 31, 34, 35, 38, 42, 43], "summary": {"covered_lines": 19, "num_statements": 21, "percent_covered": 90.47619047619048, "percent_covered_display": "90", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 90.47619047619048, "percent_statements_covered_display": "90"}, "missing_lines": [24, 29], "excluded_lines": [], "start_line": 1}}}, "corvus/capture.py": {"executed_lines": [22, 24, 25, 26, 27, 30, 31, 32, 33, 34, 35, 36, 37, 38, 45, 48, 50, 54, 55, 56, 58, 59, 60, 63, 64, 69, 70, 72, 73, 74, 77, 79, 80, 81, 83, 85, 88, 89, 92, 94, 95, 96, 97], "summary": {"covered_lines": 43, "num_statements": 43, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "functions": {"CaptureStore.__init__": {"executed_lines": [32, 33, 34, 35, 36, 37, 38, 45, 48], "summary": {"covered_lines": 9, "num_statements": 9, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 31}, "CaptureStore.enqueue": {"executed_lines": [54, 55, 56, 58, 59, 60, 63, 64, 69, 70], "summary": {"covered_lines": 10, "num_statements": 10, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 50}, "CaptureStore.replay_put": {"executed_lines": [73, 74, 77], "summary": {"covered_lines": 3, "num_statements": 3, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 72}, "CaptureStore.replay_lookup": {"executed_lines": [80, 81, 83], "summary": {"covered_lines": 3, "num_statements": 3, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 79}, "CaptureStore.by_request_hash": {"executed_lines": [88, 89, 92], "summary": {"covered_lines": 3, "num_statements": 3, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 85}, "CaptureStore.stats": {"executed_lines": [95, 96, 97], "summary": {"covered_lines": 3, "num_statements": 3, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 94}, "": {"executed_lines": [22, 24, 25, 26, 27, 30, 31, 50, 72, 79, 85, 94], "summary": {"covered_lines": 12, "num_statements": 12, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1}}, "classes": {"CaptureStore": {"executed_lines": [32, 33, 34, 35, 36, 37, 38, 45, 48, 54, 55, 56, 58, 59, 60, 63, 64, 69, 70, 73, 74, 77, 80, 81, 83, 88, 89, 92, 95, 96, 97], "summary": {"covered_lines": 31, "num_statements": 31, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 30}, "": {"executed_lines": [22, 24, 25, 26, 27, 30, 31, 50, 72, 79, 85, 94], "summary": {"covered_lines": 12, "num_statements": 12, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1}}}, "corvus/cc_adapter.py": {"executed_lines": [26, 28, 29, 30, 31, 34, 35, 41, 42, 43, 44, 47, 49, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 68, 69, 70, 71, 76, 79, 80, 84, 89, 90, 93, 96, 97, 98, 101, 102, 109, 112, 113, 114, 116, 117, 119, 121, 123, 124, 128, 137], "summary": {"covered_lines": 51, "num_statements": 58, "percent_covered": 87.93103448275862, "percent_covered_display": "88", "missing_lines": 7, "excluded_lines": 0, "percent_statements_covered": 87.93103448275862, "percent_statements_covered_display": "88"}, "missing_lines": [105, 106, 122, 125, 133, 134, 138], "excluded_lines": [], "functions": {"CCAdapter.__init__": {"executed_lines": [41, 42, 43, 44, 47], "summary": {"covered_lines": 5, "num_statements": 5, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 35}, "CCAdapter.pre_tool_use": {"executed_lines": [52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 68, 69, 70, 71, 76, 79, 80, 84, 89, 90, 93, 96, 97, 98, 101, 102], "summary": {"covered_lines": 26, "num_statements": 28, "percent_covered": 92.85714285714286, "percent_covered_display": "93", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 92.85714285714286, "percent_statements_covered_display": "93"}, "missing_lines": [105, 106], "excluded_lines": [], "start_line": 49}, "CCAdapter.post_tool_use": {"executed_lines": [112, 113, 114, 116, 117], "summary": {"covered_lines": 5, "num_statements": 5, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 109}, "CCAdapter.handle": {"executed_lines": [121, 123, 124], "summary": {"covered_lines": 3, "num_statements": 5, "percent_covered": 60.0, "percent_covered_display": "60", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 60.0, "percent_statements_covered_display": "60"}, "missing_lines": [122, 125], "excluded_lines": [], "start_line": 119}, "main": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 2, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [133, 134], "excluded_lines": [], "start_line": 128}, "": {"executed_lines": [26, 28, 29, 30, 31, 34, 35, 49, 109, 119, 128, 137], "summary": {"covered_lines": 12, "num_statements": 13, "percent_covered": 92.3076923076923, "percent_covered_display": "92", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 92.3076923076923, "percent_statements_covered_display": "92"}, "missing_lines": [138], "excluded_lines": [], "start_line": 1}}, "classes": {"CCAdapter": {"executed_lines": [41, 42, 43, 44, 47, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 68, 69, 70, 71, 76, 79, 80, 84, 89, 90, 93, 96, 97, 98, 101, 102, 112, 113, 114, 116, 117, 121, 123, 124], "summary": {"covered_lines": 39, "num_statements": 43, "percent_covered": 90.69767441860465, "percent_covered_display": "91", "missing_lines": 4, "excluded_lines": 0, "percent_statements_covered": 90.69767441860465, "percent_statements_covered_display": "91"}, "missing_lines": [105, 106, 122, 125], "excluded_lines": [], "start_line": 34}, "": {"executed_lines": [26, 28, 29, 30, 31, 34, 35, 49, 109, 119, 128, 137], "summary": {"covered_lines": 12, "num_statements": 15, "percent_covered": 80.0, "percent_covered_display": "80", "missing_lines": 3, "excluded_lines": 0, "percent_statements_covered": 80.0, "percent_statements_covered_display": "80"}, "missing_lines": [133, 134, 138], "excluded_lines": [], "start_line": 1}}}, "corvus/compiler.py": {"executed_lines": [17, 19, 20, 21, 26, 29, 33, 43, 46, 47, 48, 49, 50, 52, 55, 62, 63, 64, 66, 69, 70, 71, 77, 78, 79, 80, 81, 83, 88, 89, 90, 94, 95, 96, 100, 101, 102, 103, 104, 106, 109, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 124, 125, 126, 127, 129, 130, 131, 132, 134, 135, 153, 156, 160, 161, 163, 164, 165, 167, 168, 169, 170, 173, 176, 177, 179, 185, 186, 187, 189, 190, 195, 198, 199, 201, 202, 203, 204, 206, 209, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 227, 228, 231], "summary": {"covered_lines": 104, "num_statements": 122, "percent_covered": 85.24590163934427, "percent_covered_display": "85", "missing_lines": 18, "excluded_lines": 0, "percent_statements_covered": 85.24590163934427, "percent_statements_covered_display": "85"}, "missing_lines": [36, 37, 38, 39, 40, 72, 171, 172, 174, 175, 181, 191, 192, 194, 200, 205, 229, 230], "excluded_lines": [], "functions": {"_fail_answer_index": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 5, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 5, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [36, 37, 38, 39, 40], "excluded_lines": [], "start_line": 33}, "validate_register": {"executed_lines": [46, 47, 48, 49, 50, 52, 55, 62, 63, 64, 66, 69, 70, 71, 77, 78, 79, 80, 81, 83, 88, 89, 90, 94, 95, 96, 100, 101, 102, 103, 104, 106], "summary": {"covered_lines": 32, "num_statements": 33, "percent_covered": 96.96969696969697, "percent_covered_display": "97", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 96.96969696969697, "percent_statements_covered_display": "97"}, "missing_lines": [72], "excluded_lines": [], "start_line": 43}, "_coverage": {"executed_lines": [112, 113, 114, 115, 116, 117, 118, 119, 120, 121], "summary": {"covered_lines": 10, "num_statements": 10, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 109}, "compile_catalog": {"executed_lines": [125, 126, 127, 129, 130, 131, 132, 134, 135, 153], "summary": {"covered_lines": 10, "num_statements": 10, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 124}, "diff_classify": {"executed_lines": [160, 161, 163, 164, 165, 167, 168, 169, 170, 173, 176, 177, 179, 185, 186, 187, 189, 190, 195, 198, 199, 201, 202, 203, 204, 206], "summary": {"covered_lines": 26, "num_statements": 36, "percent_covered": 72.22222222222223, "percent_covered_display": "72", "missing_lines": 10, "excluded_lines": 0, "percent_statements_covered": 72.22222222222223, "percent_statements_covered_display": "72"}, "missing_lines": [171, 172, 174, 175, 181, 191, 192, 194, 200, 205], "excluded_lines": [], "start_line": 156}, "build": {"executed_lines": [212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 227, 228, 231], "summary": {"covered_lines": 14, "num_statements": 16, "percent_covered": 87.5, "percent_covered_display": "88", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 87.5, "percent_statements_covered_display": "88"}, "missing_lines": [229, 230], "excluded_lines": [], "start_line": 209}, "": {"executed_lines": [17, 19, 20, 21, 26, 29, 33, 43, 109, 124, 156, 209], "summary": {"covered_lines": 12, "num_statements": 12, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1}}, "classes": {"CompilerError": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 0, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 29}, "": {"executed_lines": [17, 19, 20, 21, 26, 29, 33, 43, 46, 47, 48, 49, 50, 52, 55, 62, 63, 64, 66, 69, 70, 71, 77, 78, 79, 80, 81, 83, 88, 89, 90, 94, 95, 96, 100, 101, 102, 103, 104, 106, 109, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 124, 125, 126, 127, 129, 130, 131, 132, 134, 135, 153, 156, 160, 161, 163, 164, 165, 167, 168, 169, 170, 173, 176, 177, 179, 185, 186, 187, 189, 190, 195, 198, 199, 201, 202, 203, 204, 206, 209, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 227, 228, 231], "summary": {"covered_lines": 104, "num_statements": 122, "percent_covered": 85.24590163934427, "percent_covered_display": "85", "missing_lines": 18, "excluded_lines": 0, "percent_statements_covered": 85.24590163934427, "percent_statements_covered_display": "85"}, "missing_lines": [36, 37, 38, 39, 40, 72, 171, 172, 174, 175, 181, 191, 192, 194, 200, 205, 229, 230], "excluded_lines": [], "start_line": 1}}}, "corvus/config.py": {"executed_lines": [7, 9, 10, 11, 15, 36, 37, 38, 39, 40, 41, 43, 44, 45, 48], "summary": {"covered_lines": 15, "num_statements": 23, "percent_covered": 65.21739130434783, "percent_covered_display": "65", "missing_lines": 8, "excluded_lines": 0, "percent_statements_covered": 65.21739130434783, "percent_statements_covered_display": "65"}, "missing_lines": [55, 56, 57, 58, 66, 67, 68, 73], "excluded_lines": [], "functions": {"FleetConfig.event_types": {"executed_lines": [45], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 44}, "load_config": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 8, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 8, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [55, 56, 57, 58, 66, 67, 68, 73], "excluded_lines": [], "start_line": 48}, "": {"executed_lines": [7, 9, 10, 11, 15, 36, 37, 38, 39, 40, 41, 43, 44, 48], "summary": {"covered_lines": 14, "num_statements": 14, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1}}, "classes": {"FleetConfig": {"executed_lines": [45], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 37}, "": {"executed_lines": [7, 9, 10, 11, 15, 36, 37, 38, 39, 40, 41, 43, 44, 48], "summary": {"covered_lines": 14, "num_statements": 22, "percent_covered": 63.63636363636363, "percent_covered_display": "64", "missing_lines": 8, "excluded_lines": 0, "percent_statements_covered": 63.63636363636363, "percent_statements_covered_display": "64"}, "missing_lines": [55, 56, 57, 58, 66, 67, 68, 73], "excluded_lines": [], "start_line": 1}}}, "corvus/config_loader.py": {"executed_lines": [14, 16, 17, 18, 21, 22, 23, 25, 29, 30, 31, 32, 34, 38, 39, 41, 42], "summary": {"covered_lines": 17, "num_statements": 18, "percent_covered": 94.44444444444444, "percent_covered_display": "94", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 94.44444444444444, "percent_statements_covered_display": "94"}, "missing_lines": [40], "excluded_lines": [], "functions": {"ConfigLoader.__init__": {"executed_lines": [23], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 22}, "ConfigLoader.load_fleet_config": {"executed_lines": [29, 30, 31, 32], "summary": {"covered_lines": 4, "num_statements": 4, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 25}, "ConfigLoader.load_register": {"executed_lines": [38, 39, 41, 42], "summary": {"covered_lines": 4, "num_statements": 5, "percent_covered": 80.0, "percent_covered_display": "80", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 80.0, "percent_statements_covered_display": "80"}, "missing_lines": [40], "excluded_lines": [], "start_line": 34}, "": {"executed_lines": [14, 16, 17, 18, 21, 22, 25, 34], "summary": {"covered_lines": 8, "num_statements": 8, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1}}, "classes": {"ConfigLoader": {"executed_lines": [23, 29, 30, 31, 32, 38, 39, 41, 42], "summary": {"covered_lines": 9, "num_statements": 10, "percent_covered": 90.0, "percent_covered_display": "90", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 90.0, "percent_statements_covered_display": "90"}, "missing_lines": [40], "excluded_lines": [], "start_line": 21}, "": {"executed_lines": [14, 16, 17, 18, 21, 22, 25, 34], "summary": {"covered_lines": 8, "num_statements": 8, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1}}}, "corvus/conformance.py": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 66, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 66, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [31, 33, 34, 35, 36, 38, 39, 42, 66, 75, 77, 78, 79, 80, 81, 82, 85, 86, 87, 88, 92, 93, 94, 98, 99, 100, 104, 105, 106, 107, 108, 111, 116, 117, 118, 120, 121, 122, 123, 124, 125, 127, 128, 131, 132, 137, 141, 142, 143, 144, 146, 147, 148, 149, 150, 154, 155, 156, 157, 158, 159, 160, 162, 163, 164, 168], "excluded_lines": [], "functions": {"run_mutation_suite": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 17, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 17, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [75, 77, 78, 79, 80, 81, 82, 85, 86, 87, 88, 92, 93, 94, 98, 99, 100], "excluded_lines": [], "start_line": 66}, "_extract_red_test": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 4, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 4, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [105, 106, 107, 108], "excluded_lines": [], "start_line": 104}, "conformance_run": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 10, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 10, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [116, 117, 118, 120, 131, 146, 162, 163, 164, 168], "excluded_lines": [], "start_line": 111}, "conformance_run.check": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 7, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 7, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [121, 122, 123, 124, 125, 127, 128], "excluded_lines": [], "start_line": 120}, "conformance_run.happy_path": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 6, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 6, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [132, 137, 141, 142, 143, 144], "excluded_lines": [], "start_line": 131}, "conformance_run.existence_hiding": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 11, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 11, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [147, 148, 149, 150, 154, 155, 156, 157, 158, 159, 160], "excluded_lines": [], "start_line": 146}, "": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 11, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 11, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [31, 33, 34, 35, 36, 38, 39, 42, 66, 104, 111], "excluded_lines": [], "start_line": 1}}, "classes": {"": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 66, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 66, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [31, 33, 34, 35, 36, 38, 39, 42, 66, 75, 77, 78, 79, 80, 81, 82, 85, 86, 87, 88, 92, 93, 94, 98, 99, 100, 104, 105, 106, 107, 108, 111, 116, 117, 118, 120, 121, 122, 123, 124, 125, 127, 128, 131, 132, 137, 141, 142, 143, 144, 146, 147, 148, 149, 150, 154, 155, 156, 157, 158, 159, 160, 162, 163, 164, 168], "excluded_lines": [], "start_line": 1}}}, "corvus/contract_codes.py": {"executed_lines": [8], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "functions": {"": {"executed_lines": [8], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1}}, "classes": {"": {"executed_lines": [8], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1}}}, "corvus/core.py": {"executed_lines": [9, 11, 12, 13, 14, 15, 16, 18, 19, 20, 23, 24, 27, 30, 31, 34, 35, 36, 37, 38, 39, 43, 44, 45, 46, 47, 48, 49, 50, 51, 62, 63, 68, 71, 84, 85, 86, 87, 89, 90, 98, 99, 103, 107, 109, 110, 115, 119, 123, 124, 132, 136, 142, 143, 144, 145, 146, 147, 148, 150, 151, 152, 153, 193, 194, 195, 196, 197, 198, 199, 203, 204, 205, 206], "summary": {"covered_lines": 74, "num_statements": 98, "percent_covered": 75.51020408163265, "percent_covered_display": "76", "missing_lines": 24, "excluded_lines": 0, "percent_statements_covered": 75.51020408163265, "percent_statements_covered_display": "76"}, "missing_lines": [72, 73, 78, 80, 88, 154, 163, 169, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 186, 188, 189, 201, 202], "excluded_lines": [], "functions": {"_now_iso": {"executed_lines": [24], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 23}, "sign_event": {"executed_lines": [30, 31], "summary": {"covered_lines": 2, "num_statements": 2, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 27}, "CorvusCore.__init__": {"executed_lines": [36, 37, 38, 39], "summary": {"covered_lines": 4, "num_statements": 4, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 35}, "CorvusCore.ingest_event": {"executed_lines": [44, 45, 46, 47, 48, 49, 50, 51, 62, 63, 68], "summary": {"covered_lines": 11, "num_statements": 11, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 43}, "CorvusCore.query_events": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 4, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 4, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [72, 73, 78, 80], "excluded_lines": [], "start_line": 71}, "CorvusCore.open_change": {"executed_lines": [85, 86, 87, 89, 90, 98, 99, 103, 107], "summary": {"covered_lines": 9, "num_statements": 10, "percent_covered": 90.0, "percent_covered_display": "90", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 90.0, "percent_statements_covered_display": "90"}, "missing_lines": [88], "excluded_lines": [], "start_line": 84}, "CorvusCore.active_changes_for": {"executed_lines": [110, 115], "summary": {"covered_lines": 2, "num_statements": 2, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 109}, "CorvusCore.conflict_check": {"executed_lines": [123, 124, 132, 136, 142, 143, 144, 145, 146, 147, 148, 150, 151, 152, 153, 193, 194, 195, 196, 197, 198, 199, 203, 204, 205, 206], "summary": {"covered_lines": 26, "num_statements": 45, "percent_covered": 57.77777777777778, "percent_covered_display": "58", "missing_lines": 19, "excluded_lines": 0, "percent_statements_covered": 57.77777777777778, "percent_statements_covered_display": "58"}, "missing_lines": [154, 163, 169, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 186, 188, 189, 201, 202], "excluded_lines": [], "start_line": 119}, "": {"executed_lines": [9, 11, 12, 13, 14, 15, 16, 18, 19, 20, 23, 27, 34, 35, 43, 71, 84, 109, 119], "summary": {"covered_lines": 19, "num_statements": 19, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1}}, "classes": {"CorvusCore": {"executed_lines": [36, 37, 38, 39, 44, 45, 46, 47, 48, 49, 50, 51, 62, 63, 68, 85, 86, 87, 89, 90, 98, 99, 103, 107, 110, 115, 123, 124, 132, 136, 142, 143, 144, 145, 146, 147, 148, 150, 151, 152, 153, 193, 194, 195, 196, 197, 198, 199, 203, 204, 205, 206], "summary": {"covered_lines": 52, "num_statements": 76, "percent_covered": 68.42105263157895, "percent_covered_display": "68", "missing_lines": 24, "excluded_lines": 0, "percent_statements_covered": 68.42105263157895, "percent_statements_covered_display": "68"}, "missing_lines": [72, 73, 78, 80, 88, 154, 163, 169, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 186, 188, 189, 201, 202], "excluded_lines": [], "start_line": 34}, "": {"executed_lines": [9, 11, 12, 13, 14, 15, 16, 18, 19, 20, 23, 24, 27, 30, 31, 34, 35, 43, 71, 84, 109, 119], "summary": {"covered_lines": 22, "num_statements": 22, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1}}}, "corvus/decision_core.py": {"executed_lines": [20, 22, 23, 24, 27, 28, 31, 34, 37, 43, 44, 45, 48, 50, 51, 52, 53, 54, 55, 58, 59, 60, 64, 65, 66, 67, 68, 69, 71, 72, 74, 75, 77, 80, 82, 83, 84, 85, 87, 88, 91, 92, 93, 95, 97, 98, 99, 103, 104, 106, 107, 111, 112, 114, 127, 129, 130, 131, 133, 134, 135, 136, 138, 140, 142, 144, 145, 146, 149, 150, 152, 154, 155, 156, 158, 162, 163, 164, 167, 168, 169, 171, 172, 173, 174, 175, 176], "summary": {"covered_lines": 87, "num_statements": 100, "percent_covered": 87.0, "percent_covered_display": "87", "missing_lines": 13, "excluded_lines": 0, "percent_statements_covered": 87.0, "percent_statements_covered_display": "87"}, "missing_lines": [86, 89, 116, 117, 118, 119, 120, 122, 123, 124, 125, 141, 143], "excluded_lines": [], "functions": {"DecisionCore.__init__": {"executed_lines": [43, 44, 45], "summary": {"covered_lines": 3, "num_statements": 3, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 37}, "DecisionCore.solve": {"executed_lines": [50, 51, 52, 53, 54, 55, 58, 59, 60, 64, 65, 66, 67, 68, 69, 71, 72, 74, 75, 77], "summary": {"covered_lines": 20, "num_statements": 20, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 48}, "DecisionCore._dispatch": {"executed_lines": [82, 83, 84, 85, 87, 88], "summary": {"covered_lines": 6, "num_statements": 8, "percent_covered": 75.0, "percent_covered_display": "75", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 75.0, "percent_statements_covered_display": "75"}, "missing_lines": [86, 89], "excluded_lines": [], "start_line": 80}, "DecisionCore._check_deadline": {"executed_lines": [92, 93], "summary": {"covered_lines": 2, "num_statements": 2, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 91}, "DecisionCore._dispatch_rule": {"executed_lines": [97, 98, 99, 103, 104, 106, 107, 111, 112], "summary": {"covered_lines": 9, "num_statements": 9, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 95}, "DecisionCore._dispatch_lookup": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 9, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 9, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [116, 117, 118, 119, 120, 122, 123, 124, 125], "excluded_lines": [], "start_line": 114}, "DecisionCore._dispatch_model": {"executed_lines": [129, 130, 131, 133, 134, 135, 136, 138, 140, 142, 144, 145, 146], "summary": {"covered_lines": 13, "num_statements": 15, "percent_covered": 86.66666666666667, "percent_covered_display": "87", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 86.66666666666667, "percent_statements_covered_display": "87"}, "missing_lines": [141, 143], "excluded_lines": [], "start_line": 127}, "DecisionCore._full": {"executed_lines": [152, 154, 155, 156], "summary": {"covered_lines": 4, "num_statements": 4, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 150}, "DecisionCore._fail_cell": {"executed_lines": [162, 163, 164, 167, 168, 169], "summary": {"covered_lines": 6, "num_statements": 6, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 158}, "DecisionCore._failed_dependency": {"executed_lines": [173, 174, 175, 176], "summary": {"covered_lines": 4, "num_statements": 4, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 172}, "": {"executed_lines": [20, 22, 23, 24, 27, 28, 31, 34, 37, 48, 80, 91, 95, 114, 127, 149, 150, 158, 171, 172], "summary": {"covered_lines": 20, "num_statements": 20, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1}}, "classes": {"SliceExceeded": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 0, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 27}, "DecisionCore": {"executed_lines": [43, 44, 45, 50, 51, 52, 53, 54, 55, 58, 59, 60, 64, 65, 66, 67, 68, 69, 71, 72, 74, 75, 77, 82, 83, 84, 85, 87, 88, 92, 93, 97, 98, 99, 103, 104, 106, 107, 111, 112, 129, 130, 131, 133, 134, 135, 136, 138, 140, 142, 144, 145, 146, 152, 154, 155, 156, 162, 163, 164, 167, 168, 169, 173, 174, 175, 176], "summary": {"covered_lines": 67, "num_statements": 80, "percent_covered": 83.75, "percent_covered_display": "84", "missing_lines": 13, "excluded_lines": 0, "percent_statements_covered": 83.75, "percent_statements_covered_display": "84"}, "missing_lines": [86, 89, 116, 117, 118, 119, 120, 122, 123, 124, 125, 141, 143], "excluded_lines": [], "start_line": 34}, "": {"executed_lines": [20, 22, 23, 24, 27, 28, 31, 34, 37, 48, 80, 91, 95, 114, 127, 149, 150, 158, 171, 172], "summary": {"covered_lines": 20, "num_statements": 20, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1}}}, "corvus/decisions.py": {"executed_lines": [9, 11, 12, 13, 14, 17, 18, 19, 20, 21, 23, 33, 34, 36, 41, 42, 43, 48, 49, 57, 58, 60, 61, 62, 63, 64, 65, 72], "summary": {"covered_lines": 28, "num_statements": 28, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "functions": {"DecisionClient.__init__": {"executed_lines": [19, 20, 21], "summary": {"covered_lines": 3, "num_statements": 3, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 18}, "DecisionClient.decide": {"executed_lines": [33, 34, 36, 41, 42, 43, 48, 49, 57, 58, 60, 61, 62, 63, 64, 65, 72], "summary": {"covered_lines": 17, "num_statements": 17, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 23}, "": {"executed_lines": [9, 11, 12, 13, 14, 17, 18, 23], "summary": {"covered_lines": 8, "num_statements": 8, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1}}, "classes": {"DecisionClient": {"executed_lines": [19, 20, 21, 33, 34, 36, 41, 42, 43, 48, 49, 57, 58, 60, 61, 62, 63, 64, 65, 72], "summary": {"covered_lines": 20, "num_statements": 20, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 17}, "": {"executed_lines": [9, 11, 12, 13, 14, 17, 18, 23], "summary": {"covered_lines": 8, "num_statements": 8, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1}}}, "corvus/delivery.py": {"executed_lines": [13, 15, 18, 19, 25, 26, 27, 28, 29, 31, 35, 37, 38, 41, 43, 47, 48, 50, 51, 52, 53, 54, 55, 56, 60, 61, 63, 64, 66, 70, 71, 72, 73, 74, 75, 76, 77, 80, 81, 82, 83, 84, 89, 90, 92, 96, 97, 99, 103, 105, 106], "summary": {"covered_lines": 51, "num_statements": 55, "percent_covered": 92.72727272727273, "percent_covered_display": "93", "missing_lines": 4, "excluded_lines": 0, "percent_statements_covered": 92.72727272727273, "percent_statements_covered_display": "93"}, "missing_lines": [49, 78, 79, 104], "excluded_lines": [], "functions": {"DeliveryChain.__init__": {"executed_lines": [25, 26, 27, 28, 29], "summary": {"covered_lines": 5, "num_statements": 5, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 19}, "DeliveryChain.submit": {"executed_lines": [35, 37, 38, 41], "summary": {"covered_lines": 4, "num_statements": 4, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 31}, "DeliveryChain.deliver": {"executed_lines": [47, 48, 50, 51, 52, 53, 54, 55, 56, 60, 61, 63, 64], "summary": {"covered_lines": 13, "num_statements": 14, "percent_covered": 92.85714285714286, "percent_covered_display": "93", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 92.85714285714286, "percent_statements_covered_display": "93"}, "missing_lines": [49], "excluded_lines": [], "start_line": 43}, "DeliveryChain.deliver_on_recovery": {"executed_lines": [70, 71, 72, 73, 74, 75, 76, 77, 80, 81, 82, 83, 84, 89, 90, 92, 96, 97], "summary": {"covered_lines": 18, "num_statements": 20, "percent_covered": 90.0, "percent_covered_display": "90", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 90.0, "percent_statements_covered_display": "90"}, "missing_lines": [78, 79], "excluded_lines": [], "start_line": 66}, "DeliveryChain.route_invalid": {"executed_lines": [103, 105, 106], "summary": {"covered_lines": 3, "num_statements": 4, "percent_covered": 75.0, "percent_covered_display": "75", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 75.0, "percent_statements_covered_display": "75"}, "missing_lines": [104], "excluded_lines": [], "start_line": 99}, "": {"executed_lines": [13, 15, 18, 19, 31, 43, 66, 99], "summary": {"covered_lines": 8, "num_statements": 8, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1}}, "classes": {"DeliveryChain": {"executed_lines": [25, 26, 27, 28, 29, 35, 37, 38, 41, 47, 48, 50, 51, 52, 53, 54, 55, 56, 60, 61, 63, 64, 70, 71, 72, 73, 74, 75, 76, 77, 80, 81, 82, 83, 84, 89, 90, 92, 96, 97, 103, 105, 106], "summary": {"covered_lines": 43, "num_statements": 47, "percent_covered": 91.48936170212765, "percent_covered_display": "91", "missing_lines": 4, "excluded_lines": 0, "percent_statements_covered": 91.48936170212765, "percent_statements_covered_display": "91"}, "missing_lines": [49, 78, 79, 104], "excluded_lines": [], "start_line": 18}, "": {"executed_lines": [13, 15, 18, 19, 31, 43, 66, 99], "summary": {"covered_lines": 8, "num_statements": 8, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1}}}, "corvus/engine_shim.py": {"executed_lines": [15, 17, 18, 19, 20, 22, 24, 25, 27, 28, 29, 31, 33, 41, 43, 44, 53, 54, 57, 66, 67, 68, 69, 71, 72, 73, 75, 76, 77, 78, 79, 80, 83, 84, 92, 94, 97, 103, 104, 106, 107, 108, 111, 112, 113, 117, 118, 119, 125, 126, 127, 128, 129, 130, 131, 133, 134, 135, 139, 140, 141, 142, 143, 144, 146, 147, 149, 153, 157, 158, 159, 160, 161, 163, 164, 165, 166, 177, 178, 179, 180, 181, 182, 183, 184, 185, 189, 195, 196, 197, 198, 199, 200, 201, 204, 205, 207, 208, 209, 211, 212, 217, 218, 219, 220, 221, 222, 223, 224, 226, 227, 230, 234, 236, 237, 238, 239, 264, 274, 281, 282, 283, 284, 287, 288, 289, 292], "summary": {"covered_lines": 127, "num_statements": 147, "percent_covered": 86.39455782312925, "percent_covered_display": "86", "missing_lines": 20, "excluded_lines": 0, "percent_statements_covered": 86.39455782312925, "percent_statements_covered_display": "86"}, "missing_lines": [70, 105, 145, 162, 225, 229, 231, 245, 246, 247, 248, 249, 256, 257, 293, 294, 295, 296, 297, 298], "excluded_lines": [], "functions": {"err": {"executed_lines": [43, 44], "summary": {"covered_lines": 2, "num_statements": 2, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 41}, "_register_candidates": {"executed_lines": [67, 68, 69, 71, 72, 73], "summary": {"covered_lines": 6, "num_statements": 7, "percent_covered": 85.71428571428571, "percent_covered_display": "86", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 85.71428571428571, "percent_statements_covered_display": "86"}, "missing_lines": [70], "excluded_lines": [], "start_line": 66}, "_site_resolution": {"executed_lines": [84], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 83}, "_quantize": {"executed_lines": [103, 104, 106, 107, 108], "summary": {"covered_lines": 5, "num_statements": 6, "percent_covered": 83.33333333333333, "percent_covered_display": "83", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 83.33333333333333, "percent_statements_covered_display": "83"}, "missing_lines": [105], "excluded_lines": [], "start_line": 97}, "decide": {"executed_lines": [113, 117, 118, 119, 125, 126, 127, 128, 129, 130, 131, 133, 134, 135, 139, 140, 141, 142, 143, 144, 146, 147, 149, 153, 157, 158, 159, 160, 161, 163, 164, 165, 166, 177, 178, 179, 180, 181, 182, 183, 184, 185, 189, 195, 196, 197, 198, 199, 200, 201, 204, 205, 207, 208, 209, 211, 212, 217, 218, 219, 220, 221, 222, 223, 224, 226, 227, 230, 234, 236, 237, 238, 239, 264, 274, 281, 282, 283, 284], "summary": {"covered_lines": 79, "num_statements": 91, "percent_covered": 86.81318681318682, "percent_covered_display": "87", "missing_lines": 12, "excluded_lines": 0, "percent_statements_covered": 86.81318681318682, "percent_statements_covered_display": "87"}, "missing_lines": [145, 162, 225, 229, 231, 245, 246, 247, 248, 249, 256, 257], "excluded_lines": [], "start_line": 112}, "hashlib_sha": {"executed_lines": [288, 289], "summary": {"covered_lines": 2, "num_statements": 2, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 287}, "": {"executed_lines": [15, 17, 18, 19, 20, 22, 24, 25, 27, 28, 29, 31, 33, 41, 53, 54, 57, 66, 75, 76, 77, 78, 79, 80, 83, 92, 94, 97, 111, 112, 287, 292], "summary": {"covered_lines": 32, "num_statements": 38, "percent_covered": 84.21052631578948, "percent_covered_display": "84", "missing_lines": 6, "excluded_lines": 0, "percent_statements_covered": 84.21052631578948, "percent_statements_covered_display": "84"}, "missing_lines": [293, 294, 295, 296, 297, 298], "excluded_lines": [], "start_line": 1}}, "classes": {"": {"executed_lines": [15, 17, 18, 19, 20, 22, 24, 25, 27, 28, 29, 31, 33, 41, 43, 44, 53, 54, 57, 66, 67, 68, 69, 71, 72, 73, 75, 76, 77, 78, 79, 80, 83, 84, 92, 94, 97, 103, 104, 106, 107, 108, 111, 112, 113, 117, 118, 119, 125, 126, 127, 128, 129, 130, 131, 133, 134, 135, 139, 140, 141, 142, 143, 144, 146, 147, 149, 153, 157, 158, 159, 160, 161, 163, 164, 165, 166, 177, 178, 179, 180, 181, 182, 183, 184, 185, 189, 195, 196, 197, 198, 199, 200, 201, 204, 205, 207, 208, 209, 211, 212, 217, 218, 219, 220, 221, 222, 223, 224, 226, 227, 230, 234, 236, 237, 238, 239, 264, 274, 281, 282, 283, 284, 287, 288, 289, 292], "summary": {"covered_lines": 127, "num_statements": 147, "percent_covered": 86.39455782312925, "percent_covered_display": "86", "missing_lines": 20, "excluded_lines": 0, "percent_statements_covered": 86.39455782312925, "percent_statements_covered_display": "86"}, "missing_lines": [70, 105, 145, 162, 225, 229, 231, 245, 246, 247, 248, 249, 256, 257, 293, 294, 295, 296, 297, 298], "excluded_lines": [], "start_line": 1}}}, "corvus/facts.py": {"executed_lines": [27, 29, 30, 33, 38, 41, 42, 46, 47, 49, 52, 53, 54, 55, 56, 57, 59, 60, 61, 62, 63, 68, 69, 70, 71, 72, 73, 74, 75, 76, 79, 81, 85, 87, 88, 89, 90, 91, 93, 94, 101, 104, 105, 106, 109, 110, 111, 122], "summary": {"covered_lines": 48, "num_statements": 51, "percent_covered": 94.11764705882354, "percent_covered_display": "94", "missing_lines": 3, "excluded_lines": 0, "percent_statements_covered": 94.11764705882354, "percent_statements_covered_display": "94"}, "missing_lines": [114, 117, 118], "excluded_lines": [], "functions": {"FactComposer.__init__": {"executed_lines": [46, 47], "summary": {"covered_lines": 2, "num_statements": 2, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 42}, "FactComposer.compose": {"executed_lines": [52, 53, 54, 55, 56, 57, 59, 60, 61, 62, 63, 68, 69, 70, 71, 72, 73, 74, 75, 76, 79], "summary": {"covered_lines": 21, "num_statements": 21, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 49}, "FactComposer.compose_status_view": {"executed_lines": [85, 87, 88, 89, 90, 91, 93, 94], "summary": {"covered_lines": 8, "num_statements": 8, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 81}, "change_window_source": {"executed_lines": [104, 122], "summary": {"covered_lines": 2, "num_statements": 2, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 101}, "change_window_source.source": {"executed_lines": [105, 106, 109, 110, 111], "summary": {"covered_lines": 5, "num_statements": 8, "percent_covered": 62.5, "percent_covered_display": "62", "missing_lines": 3, "excluded_lines": 0, "percent_statements_covered": 62.5, "percent_statements_covered_display": "62"}, "missing_lines": [114, 117, 118], "excluded_lines": [], "start_line": 104}, "": {"executed_lines": [27, 29, 30, 33, 38, 41, 42, 49, 81, 101], "summary": {"covered_lines": 10, "num_statements": 10, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1}}, "classes": {"FactComposer": {"executed_lines": [46, 47, 52, 53, 54, 55, 56, 57, 59, 60, 61, 62, 63, 68, 69, 70, 71, 72, 73, 74, 75, 76, 79, 85, 87, 88, 89, 90, 91, 93, 94], "summary": {"covered_lines": 31, "num_statements": 31, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 41}, "": {"executed_lines": [27, 29, 30, 33, 38, 41, 42, 49, 81, 101, 104, 105, 106, 109, 110, 111, 122], "summary": {"covered_lines": 17, "num_statements": 20, "percent_covered": 85.0, "percent_covered_display": "85", "missing_lines": 3, "excluded_lines": 0, "percent_statements_covered": 85.0, "percent_statements_covered_display": "85"}, "missing_lines": [114, 117, 118], "excluded_lines": [], "start_line": 1}}}, "corvus/hlc.py": {"executed_lines": [8, 9, 10, 13, 14, 15, 16, 17, 19, 20, 21, 26, 27, 30, 31, 32, 33, 34, 35, 37, 38, 39, 40, 41, 42, 45, 47, 50, 51, 52, 53, 61], "summary": {"covered_lines": 32, "num_statements": 42, "percent_covered": 76.19047619047619, "percent_covered_display": "76", "missing_lines": 10, "excluded_lines": 0, "percent_statements_covered": 76.19047619047619, "percent_statements_covered_display": "76"}, "missing_lines": [22, 23, 24, 44, 54, 55, 56, 57, 59, 60], "excluded_lines": [], "functions": {"HLCTimestamp.__lt__": {"executed_lines": [20, 21], "summary": {"covered_lines": 2, "num_statements": 5, "percent_covered": 40.0, "percent_covered_display": "40", "missing_lines": 3, "excluded_lines": 0, "percent_statements_covered": 40.0, "percent_statements_covered_display": "40"}, "missing_lines": [22, 23, 24], "excluded_lines": [], "start_line": 19}, "HLCTimestamp.to_string": {"executed_lines": [27], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 26}, "HLC.__init__": {"executed_lines": [32, 33, 34, 35], "summary": {"covered_lines": 4, "num_statements": 4, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 31}, "HLC.now": {"executed_lines": [38, 39, 40, 41, 42, 45], "summary": {"covered_lines": 6, "num_statements": 7, "percent_covered": 85.71428571428571, "percent_covered_display": "86", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 85.71428571428571, "percent_statements_covered_display": "86"}, "missing_lines": [44], "excluded_lines": [], "start_line": 37}, "HLC.merge": {"executed_lines": [50, 51, 52, 53, 61], "summary": {"covered_lines": 5, "num_statements": 11, "percent_covered": 45.45454545454545, "percent_covered_display": "45", "missing_lines": 6, "excluded_lines": 0, "percent_statements_covered": 45.45454545454545, "percent_statements_covered_display": "45"}, "missing_lines": [54, 55, 56, 57, 59, 60], "excluded_lines": [], "start_line": 47}, "": {"executed_lines": [8, 9, 10, 13, 14, 15, 16, 17, 19, 26, 30, 31, 37, 47], "summary": {"covered_lines": 14, "num_statements": 14, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1}}, "classes": {"HLCTimestamp": {"executed_lines": [20, 21, 27], "summary": {"covered_lines": 3, "num_statements": 6, "percent_covered": 50.0, "percent_covered_display": "50", "missing_lines": 3, "excluded_lines": 0, "percent_statements_covered": 50.0, "percent_statements_covered_display": "50"}, "missing_lines": [22, 23, 24], "excluded_lines": [], "start_line": 14}, "HLC": {"executed_lines": [32, 33, 34, 35, 38, 39, 40, 41, 42, 45, 50, 51, 52, 53, 61], "summary": {"covered_lines": 15, "num_statements": 22, "percent_covered": 68.18181818181819, "percent_covered_display": "68", "missing_lines": 7, "excluded_lines": 0, "percent_statements_covered": 68.18181818181819, "percent_statements_covered_display": "68"}, "missing_lines": [44, 54, 55, 56, 57, 59, 60], "excluded_lines": [], "start_line": 30}, "": {"executed_lines": [8, 9, 10, 13, 14, 15, 16, 17, 19, 26, 30, 31, 37, 47], "summary": {"covered_lines": 14, "num_statements": 14, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1}}}, "corvus/observe.py": {"executed_lines": [21, 23, 26, 27, 31, 32, 33, 35, 41, 42, 46, 47, 49, 53, 54, 55, 58, 60, 63, 66, 70], "summary": {"covered_lines": 21, "num_statements": 21, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "functions": {"ObserveMode.__init__": {"executed_lines": [31, 32, 33], "summary": {"covered_lines": 3, "num_statements": 3, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 27}, "ObserveMode.record_attempt": {"executed_lines": [41, 42, 46, 47, 49, 53, 54, 55, 58], "summary": {"covered_lines": 9, "num_statements": 9, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 35}, "ObserveMode.coverage": {"executed_lines": [63], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 60}, "ObserveMode.token_issuance_allowed": {"executed_lines": [70], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 66}, "": {"executed_lines": [21, 23, 26, 27, 35, 60, 66], "summary": {"covered_lines": 7, "num_statements": 7, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1}}, "classes": {"ObserveMode": {"executed_lines": [31, 32, 33, 41, 42, 46, 47, 49, 53, 54, 55, 58, 63, 70], "summary": {"covered_lines": 14, "num_statements": 14, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 26}, "": {"executed_lines": [21, 23, 26, 27, 35, 60, 66], "summary": {"covered_lines": 7, "num_statements": 7, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1}}}, "corvus/ops.py": {"executed_lines": [13, 15, 18, 21, 26, 28, 32, 33, 34, 37, 41, 42, 43, 44, 46, 47, 48, 49, 51, 52, 53, 54, 56, 57, 58, 61, 70, 71, 72, 74, 75, 76, 79, 80, 81, 82, 83, 84, 85, 87], "summary": {"covered_lines": 40, "num_statements": 41, "percent_covered": 97.5609756097561, "percent_covered_display": "98", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 97.5609756097561, "percent_statements_covered_display": "98"}, "missing_lines": [77], "excluded_lines": [], "functions": {"FleetScopeResolver.__init__": {"executed_lines": [26], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 21}, "FleetScopeResolver.resolve": {"executed_lines": [32, 33, 34], "summary": {"covered_lines": 3, "num_statements": 3, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 28}, "Metrics.__init__": {"executed_lines": [42, 43, 44], "summary": {"covered_lines": 3, "num_statements": 3, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 41}, "Metrics.inc": {"executed_lines": [47, 48, 49], "summary": {"covered_lines": 3, "num_statements": 3, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 46}, "Metrics.set_gauge": {"executed_lines": [52, 53, 54], "summary": {"covered_lines": 3, "num_statements": 3, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 51}, "Metrics.snapshot": {"executed_lines": [57, 58], "summary": {"covered_lines": 2, "num_statements": 2, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 56}, "Health.__init__": {"executed_lines": [71, 72], "summary": {"covered_lines": 2, "num_statements": 2, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 70}, "Health.record_latency": {"executed_lines": [75, 76], "summary": {"covered_lines": 2, "num_statements": 3, "percent_covered": 66.66666666666667, "percent_covered_display": "67", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 66.66666666666667, "percent_statements_covered_display": "67"}, "missing_lines": [77], "excluded_lines": [], "start_line": 74}, "Health.state": {"executed_lines": [80, 81, 82, 83, 84, 85, 87], "summary": {"covered_lines": 7, "num_statements": 7, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 79}, "": {"executed_lines": [13, 15, 18, 21, 28, 37, 41, 46, 51, 56, 61, 70, 74, 79], "summary": {"covered_lines": 14, "num_statements": 14, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1}}, "classes": {"FleetScopeResolver": {"executed_lines": [26, 32, 33, 34], "summary": {"covered_lines": 4, "num_statements": 4, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 18}, "Metrics": {"executed_lines": [42, 43, 44, 47, 48, 49, 52, 53, 54, 57, 58], "summary": {"covered_lines": 11, "num_statements": 11, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 37}, "Health": {"executed_lines": [71, 72, 75, 76, 80, 81, 82, 83, 84, 85, 87], "summary": {"covered_lines": 11, "num_statements": 12, "percent_covered": 91.66666666666667, "percent_covered_display": "92", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 91.66666666666667, "percent_statements_covered_display": "92"}, "missing_lines": [77], "excluded_lines": [], "start_line": 61}, "": {"executed_lines": [13, 15, 18, 21, 28, 37, 41, 46, 51, 56, 61, 70, 74, 79], "summary": {"covered_lines": 14, "num_statements": 14, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1}}}, "corvus/state.py": {"executed_lines": [8, 10, 11, 12, 14, 59, 62, 63, 64, 65, 66, 67, 68, 70, 71, 72, 73, 74, 75], "summary": {"covered_lines": 19, "num_statements": 19, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "functions": {"State.__init__": {"executed_lines": [63, 64, 65, 66, 67, 68], "summary": {"covered_lines": 6, "num_statements": 6, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 62}, "State.execute": {"executed_lines": [71, 72, 73, 74, 75], "summary": {"covered_lines": 5, "num_statements": 5, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 70}, "": {"executed_lines": [8, 10, 11, 12, 14, 59, 62, 70], "summary": {"covered_lines": 8, "num_statements": 8, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1}}, "classes": {"State": {"executed_lines": [63, 64, 65, 66, 67, 68, 71, 72, 73, 74, 75], "summary": {"covered_lines": 11, "num_statements": 11, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 59}, "": {"executed_lines": [8, 10, 11, 12, 14, 59, 62, 70], "summary": {"covered_lines": 8, "num_statements": 8, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1}}}, "corvus/tokens.py": {"executed_lines": [31, 33, 34, 35, 38, 39, 44, 45, 48, 49, 53, 54, 55, 56, 57, 58, 60, 67, 68, 72, 80, 81, 83, 87, 91, 93, 94, 96, 100, 103, 108, 109, 114, 117, 140, 145], "summary": {"covered_lines": 36, "num_statements": 58, "percent_covered": 62.06896551724138, "percent_covered_display": "62", "missing_lines": 22, "excluded_lines": 0, "percent_statements_covered": 62.06896551724138, "percent_statements_covered_display": "62"}, "missing_lines": [40, 41, 69, 92, 95, 97, 98, 99, 101, 102, 104, 127, 128, 129, 130, 131, 132, 133, 134, 138, 141, 148], "excluded_lines": [], "functions": {"TokenRefused.__init__": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 2, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [40, 41], "excluded_lines": [], "start_line": 39}, "VerdictTokenIssuer.__init__": {"executed_lines": [53, 54, 55, 56, 57, 58], "summary": {"covered_lines": 6, "num_statements": 6, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 49}, "VerdictTokenIssuer.issue": {"executed_lines": [67, 68, 72, 80, 81], "summary": {"covered_lines": 5, "num_statements": 6, "percent_covered": 83.33333333333333, "percent_covered_display": "83", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 83.33333333333333, "percent_statements_covered_display": "83"}, "missing_lines": [69], "excluded_lines": [], "start_line": 60}, "VerdictTokenIssuer.consume": {"executed_lines": [87, 91, 93, 94, 96, 100, 103, 108, 109, 114], "summary": {"covered_lines": 10, "num_statements": 18, "percent_covered": 55.55555555555556, "percent_covered_display": "56", "missing_lines": 8, "excluded_lines": 0, "percent_statements_covered": 55.55555555555556, "percent_statements_covered_display": "56"}, "missing_lines": [92, 95, 97, 98, 99, 101, 102, 104], "excluded_lines": [], "start_line": 83}, "VerdictTokenIssuer.revoke": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 9, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 9, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [127, 128, 129, 130, 131, 132, 133, 134, 138], "excluded_lines": [], "start_line": 117}, "VerdictTokenIssuer.outstanding_for": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 1, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [141], "excluded_lines": [], "start_line": 140}, "action_fingerprint": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 1, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [148], "excluded_lines": [], "start_line": 145}, "": {"executed_lines": [31, 33, 34, 35, 38, 39, 44, 45, 48, 49, 60, 83, 117, 140, 145], "summary": {"covered_lines": 15, "num_statements": 15, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1}}, "classes": {"TokenRefused": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 2, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [40, 41], "excluded_lines": [], "start_line": 38}, "EvidenceNotDurable": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 0, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 44}, "VerdictTokenIssuer": {"executed_lines": [53, 54, 55, 56, 57, 58, 67, 68, 72, 80, 81, 87, 91, 93, 94, 96, 100, 103, 108, 109, 114], "summary": {"covered_lines": 21, "num_statements": 40, "percent_covered": 52.5, "percent_covered_display": "52", "missing_lines": 19, "excluded_lines": 0, "percent_statements_covered": 52.5, "percent_statements_covered_display": "52"}, "missing_lines": [69, 92, 95, 97, 98, 99, 101, 102, 104, 127, 128, 129, 130, 131, 132, 133, 134, 138, 141], "excluded_lines": [], "start_line": 48}, "": {"executed_lines": [31, 33, 34, 35, 38, 39, 44, 45, 48, 49, 60, 83, 117, 140, 145], "summary": {"covered_lines": 15, "num_statements": 16, "percent_covered": 93.75, "percent_covered_display": "94", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 93.75, "percent_statements_covered_display": "94"}, "missing_lines": [148], "excluded_lines": [], "start_line": 1}}}, "corvus/trust.py": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 61, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 61, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [36, 38, 41, 44, 52, 53, 56, 57, 58, 59, 60, 62, 66, 67, 68, 70, 77, 78, 79, 80, 83, 84, 85, 87, 94, 95, 96, 97, 98, 102, 108, 109, 110, 111, 112, 114, 115, 117, 118, 120, 122, 125, 126, 127, 128, 129, 130, 133, 134, 135, 138, 140, 141, 147, 154, 155, 161, 164, 166, 171, 172], "excluded_lines": [], "functions": {"TrustLedger.__init__": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 5, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 5, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [56, 57, 58, 59, 60], "excluded_lines": [], "start_line": 53}, "TrustLedger.tier": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 3, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 3, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [66, 67, 68], "excluded_lines": [], "start_line": 62}, "TrustLedger.record_outcome": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 7, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 7, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [77, 78, 79, 80, 83, 84, 85], "excluded_lines": [], "start_line": 70}, "TrustLedger.due_missing": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 5, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 5, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [94, 95, 96, 97, 98], "excluded_lines": [], "start_line": 87}, "TrustLedger.evaluate_promotion": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 20, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 20, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [108, 109, 110, 111, 112, 114, 115, 117, 118, 120, 122, 125, 126, 127, 128, 129, 130, 133, 134, 135], "excluded_lines": [], "start_line": 102}, "TrustLedger.promote": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 2, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [140, 141], "excluded_lines": [], "start_line": 138}, "TrustLedger.demote": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 2, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [154, 155], "excluded_lines": [], "start_line": 147}, "TrustLedger.invalidate_on_drift": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 1, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [164], "excluded_lines": [], "start_line": 161}, "TrustLedger.quarantine": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 2, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [171, 172], "excluded_lines": [], "start_line": 166}, "": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 14, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 14, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [36, 38, 41, 44, 52, 53, 62, 70, 87, 102, 138, 147, 161, 166], "excluded_lines": [], "start_line": 1}}, "classes": {"TrustLedger": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 47, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 47, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [56, 57, 58, 59, 60, 66, 67, 68, 77, 78, 79, 80, 83, 84, 85, 94, 95, 96, 97, 98, 108, 109, 110, 111, 112, 114, 115, 117, 118, 120, 122, 125, 126, 127, 128, 129, 130, 133, 134, 135, 140, 141, 154, 155, 164, 171, 172], "excluded_lines": [], "start_line": 52}, "": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 14, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 14, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [36, 38, 41, 44, 52, 53, 62, 70, 87, 102, 138, 147, 161, 166], "excluded_lines": [], "start_line": 1}}}}, "totals": {"covered_lines": 932, "num_statements": 1277, "percent_covered": 72.98355520751763, "percent_covered_display": "73", "missing_lines": 345, "excluded_lines": 0, "percent_statements_covered": 72.98355520751763, "percent_statements_covered_display": "73"}} \ No newline at end of file +{"meta": {"format": 3, "version": "7.17.0", "timestamp": "2026-10-23T20:37:05.987337", "branch_coverage": false, "show_contexts": false}, "files": {"corvus/__init__.py": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 0, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "functions": {"": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 0, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1}}, "classes": {"": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 0, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1}}}, "corvus/adapter.py": {"executed_lines": [17, 19, 20, 21, 22, 23, 26, 31, 32, 36, 39, 41, 42, 43, 44, 45, 47, 49, 50, 51, 52, 55, 57, 58, 59, 60, 62, 63, 64, 65, 66, 70, 71, 72, 74, 75, 79, 80, 81, 85, 86, 91, 95, 98, 100, 101, 102, 104, 106, 108, 109, 110, 111, 112, 114], "summary": {"covered_lines": 55, "num_statements": 58, "percent_covered": 94.82758620689656, "percent_covered_display": "95", "missing_lines": 3, "excluded_lines": 0, "percent_statements_covered": 94.82758620689656, "percent_statements_covered_display": "95"}, "missing_lines": [69, 82, 113], "excluded_lines": [], "functions": {"Adapter.solve": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 0, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 32}, "ClefFlashAdapter.__init__": {"executed_lines": [41, 42, 43, 44, 45], "summary": {"covered_lines": 5, "num_statements": 5, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 39}, "ClefFlashAdapter.solve": {"executed_lines": [49, 50, 51, 52, 55, 57, 58, 59, 60, 62, 63, 64, 65, 66, 70, 71, 72, 74, 75, 79, 80, 81, 85, 86, 91], "summary": {"covered_lines": 25, "num_statements": 27, "percent_covered": 92.5925925925926, "percent_covered_display": "93", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 92.5925925925926, "percent_statements_covered_display": "93"}, "missing_lines": [69, 82], "excluded_lines": [], "start_line": 47}, "StubAdapter.__init__": {"executed_lines": [100, 101, 102], "summary": {"covered_lines": 3, "num_statements": 3, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 98}, "StubAdapter.solve": {"executed_lines": [106, 108, 109, 110, 111, 112, 114], "summary": {"covered_lines": 7, "num_statements": 8, "percent_covered": 87.5, "percent_covered_display": "88", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 87.5, "percent_statements_covered_display": "88"}, "missing_lines": [113], "excluded_lines": [], "start_line": 104}, "": {"executed_lines": [17, 19, 20, 21, 22, 23, 26, 31, 32, 36, 39, 47, 95, 98, 104], "summary": {"covered_lines": 15, "num_statements": 15, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1}}, "classes": {"AdapterUnavailable": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 0, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 26}, "Adapter": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 0, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 31}, "ClefFlashAdapter": {"executed_lines": [41, 42, 43, 44, 45, 49, 50, 51, 52, 55, 57, 58, 59, 60, 62, 63, 64, 65, 66, 70, 71, 72, 74, 75, 79, 80, 81, 85, 86, 91], "summary": {"covered_lines": 30, "num_statements": 32, "percent_covered": 93.75, "percent_covered_display": "94", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 93.75, "percent_statements_covered_display": "94"}, "missing_lines": [69, 82], "excluded_lines": [], "start_line": 36}, "StubAdapter": {"executed_lines": [100, 101, 102, 106, 108, 109, 110, 111, 112, 114], "summary": {"covered_lines": 10, "num_statements": 11, "percent_covered": 90.9090909090909, "percent_covered_display": "91", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 90.9090909090909, "percent_statements_covered_display": "91"}, "missing_lines": [113], "excluded_lines": [], "start_line": 95}, "": {"executed_lines": [17, 19, 20, 21, 22, 23, 26, 31, 32, 36, 39, 47, 95, 98, 104], "summary": {"covered_lines": 15, "num_statements": 15, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1}}}, "corvus/app.py": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 78, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 78, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [15, 17, 18, 19, 20, 21, 23, 25, 26, 27, 29, 30, 31, 34, 35, 36, 37, 38, 39, 42, 43, 44, 45, 46, 47, 48, 51, 52, 53, 54, 55, 58, 59, 60, 61, 62, 64, 67, 68, 70, 71, 72, 75, 76, 77, 78, 79, 80, 81, 82, 83, 85, 86, 88, 90, 91, 92, 93, 95, 96, 97, 98, 99, 101, 103, 105, 106, 107, 108, 109, 110, 112, 113, 114, 116, 117, 119, 121], "excluded_lines": [], "functions": {"_auth_key": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 4, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 4, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [52, 53, 54, 55], "excluded_lines": [], "start_line": 51}, "create_app": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 21, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 21, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [59, 60, 61, 62, 64, 67, 70, 71, 75, 76, 85, 86, 90, 91, 105, 106, 112, 113, 116, 117, 121], "excluded_lines": [], "start_line": 58}, "create_app.require_key": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 1, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [68], "excluded_lines": [], "start_line": 67}, "create_app.health": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 1, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [72], "excluded_lines": [], "start_line": 71}, "create_app.ingest": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 7, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 7, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [77, 78, 79, 80, 81, 82, 83], "excluded_lines": [], "start_line": 76}, "create_app.events": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 1, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [88], "excluded_lines": [], "start_line": 86}, "create_app.stream": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 4, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 4, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [92, 93, 95, 103], "excluded_lines": [], "start_line": 91}, "create_app.stream.gen": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 5, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 5, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [96, 97, 98, 99, 101], "excluded_lines": [], "start_line": 95}, "create_app.open_change": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 4, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 4, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [107, 108, 109, 110], "excluded_lines": [], "start_line": 106}, "create_app.active_changes": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 1, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [114], "excluded_lines": [], "start_line": 113}, "create_app.conflict_check": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 1, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [119], "excluded_lines": [], "start_line": 117}, "": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 28, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 28, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [15, 17, 18, 19, 20, 21, 23, 25, 26, 27, 29, 30, 31, 34, 35, 36, 37, 38, 39, 42, 43, 44, 45, 46, 47, 48, 51, 58], "excluded_lines": [], "start_line": 1}}, "classes": {"EventIn": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 0, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 34}, "ChangeIn": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 0, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 42}, "": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 78, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 78, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [15, 17, 18, 19, 20, 21, 23, 25, 26, 27, 29, 30, 31, 34, 35, 36, 37, 38, 39, 42, 43, 44, 45, 46, 47, 48, 51, 52, 53, 54, 55, 58, 59, 60, 61, 62, 64, 67, 68, 70, 71, 72, 75, 76, 77, 78, 79, 80, 81, 82, 83, 85, 86, 88, 90, 91, 92, 93, 95, 96, 97, 98, 99, 101, 103, 105, 106, 107, 108, 109, 110, 112, 113, 114, 116, 117, 119, 121], "excluded_lines": [], "start_line": 1}}}, "corvus/attested.py": {"executed_lines": [22, 24, 25, 26, 27, 28, 30, 32, 33, 36, 37, 38, 39, 40, 41, 50, 51, 53, 56, 58, 59, 61, 62, 63, 64, 67, 71, 72, 76, 77, 78, 84, 87, 91, 96, 97, 98, 99, 102, 103, 104, 107, 109, 110, 112, 113, 115, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 132, 133, 134, 135, 137, 138, 141], "summary": {"covered_lines": 64, "num_statements": 68, "percent_covered": 94.11764705882354, "percent_covered_display": "94", "missing_lines": 4, "excluded_lines": 0, "percent_statements_covered": 94.11764705882354, "percent_statements_covered_display": "94"}, "missing_lines": [79, 105, 129, 131], "excluded_lines": [], "functions": {"AttestedStore.__init__": {"executed_lines": [38, 39, 40, 41, 50, 51], "summary": {"covered_lines": 6, "num_statements": 6, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 37}, "AttestedStore.append": {"executed_lines": [56, 58, 59, 61, 62, 63, 64, 67, 71, 72], "summary": {"covered_lines": 10, "num_statements": 10, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 53}, "AttestedStore.chain": {"executed_lines": [77, 78, 84, 87], "summary": {"covered_lines": 4, "num_statements": 5, "percent_covered": 80.0, "percent_covered_display": "80", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 80.0, "percent_statements_covered_display": "80"}, "missing_lines": [79], "excluded_lines": [], "start_line": 76}, "AttestedStore.verify": {"executed_lines": [96, 97, 98, 99, 102, 103, 104, 107, 109, 110, 112, 113], "summary": {"covered_lines": 12, "num_statements": 13, "percent_covered": 92.3076923076923, "percent_covered_display": "92", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 92.3076923076923, "percent_statements_covered_display": "92"}, "missing_lines": [105], "excluded_lines": [], "start_line": 91}, "AttestedStore.lifecycle_walk": {"executed_lines": [119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 132, 133, 134, 135, 137, 138, 141], "summary": {"covered_lines": 17, "num_statements": 19, "percent_covered": 89.47368421052632, "percent_covered_display": "89", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 89.47368421052632, "percent_statements_covered_display": "89"}, "missing_lines": [129, 131], "excluded_lines": [], "start_line": 115}, "": {"executed_lines": [22, 24, 25, 26, 27, 28, 30, 32, 33, 36, 37, 53, 76, 91, 115], "summary": {"covered_lines": 15, "num_statements": 15, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1}}, "classes": {"AttestedStore": {"executed_lines": [38, 39, 40, 41, 50, 51, 56, 58, 59, 61, 62, 63, 64, 67, 71, 72, 77, 78, 84, 87, 96, 97, 98, 99, 102, 103, 104, 107, 109, 110, 112, 113, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 132, 133, 134, 135, 137, 138, 141], "summary": {"covered_lines": 49, "num_statements": 53, "percent_covered": 92.45283018867924, "percent_covered_display": "92", "missing_lines": 4, "excluded_lines": 0, "percent_statements_covered": 92.45283018867924, "percent_statements_covered_display": "92"}, "missing_lines": [79, 105, 129, 131], "excluded_lines": [], "start_line": 36}, "": {"executed_lines": [22, 24, 25, 26, 27, 28, 30, 32, 33, 36, 37, 53, 76, 91, 115], "summary": {"covered_lines": 15, "num_statements": 15, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1}}}, "corvus/canonical.py": {"executed_lines": [10, 12, 13, 14, 17, 19, 20, 21, 22, 23, 25, 28, 30, 31, 34, 35, 38, 42, 43], "summary": {"covered_lines": 19, "num_statements": 21, "percent_covered": 90.47619047619048, "percent_covered_display": "90", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 90.47619047619048, "percent_statements_covered_display": "90"}, "missing_lines": [24, 29], "excluded_lines": [], "functions": {"canonicalize": {"executed_lines": [19, 20, 21, 22, 23, 25, 28, 30, 31], "summary": {"covered_lines": 9, "num_statements": 11, "percent_covered": 81.81818181818181, "percent_covered_display": "82", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 81.81818181818181, "percent_statements_covered_display": "82"}, "missing_lines": [24, 29], "excluded_lines": [], "start_line": 17}, "canonical_json": {"executed_lines": [35], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 34}, "request_hash": {"executed_lines": [42, 43], "summary": {"covered_lines": 2, "num_statements": 2, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 38}, "": {"executed_lines": [10, 12, 13, 14, 17, 34, 38], "summary": {"covered_lines": 7, "num_statements": 7, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1}}, "classes": {"": {"executed_lines": [10, 12, 13, 14, 17, 19, 20, 21, 22, 23, 25, 28, 30, 31, 34, 35, 38, 42, 43], "summary": {"covered_lines": 19, "num_statements": 21, "percent_covered": 90.47619047619048, "percent_covered_display": "90", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 90.47619047619048, "percent_statements_covered_display": "90"}, "missing_lines": [24, 29], "excluded_lines": [], "start_line": 1}}}, "corvus/capture.py": {"executed_lines": [22, 24, 25, 26, 27, 30, 31, 32, 33, 34, 35, 36, 37, 38, 45, 48, 50, 54, 55, 56, 58, 59, 60, 63, 64, 69, 70, 72, 73, 74, 77, 79, 80, 81, 83, 85, 88, 89, 92, 94, 95, 96, 97], "summary": {"covered_lines": 43, "num_statements": 43, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "functions": {"CaptureStore.__init__": {"executed_lines": [32, 33, 34, 35, 36, 37, 38, 45, 48], "summary": {"covered_lines": 9, "num_statements": 9, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 31}, "CaptureStore.enqueue": {"executed_lines": [54, 55, 56, 58, 59, 60, 63, 64, 69, 70], "summary": {"covered_lines": 10, "num_statements": 10, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 50}, "CaptureStore.replay_put": {"executed_lines": [73, 74, 77], "summary": {"covered_lines": 3, "num_statements": 3, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 72}, "CaptureStore.replay_lookup": {"executed_lines": [80, 81, 83], "summary": {"covered_lines": 3, "num_statements": 3, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 79}, "CaptureStore.by_request_hash": {"executed_lines": [88, 89, 92], "summary": {"covered_lines": 3, "num_statements": 3, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 85}, "CaptureStore.stats": {"executed_lines": [95, 96, 97], "summary": {"covered_lines": 3, "num_statements": 3, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 94}, "": {"executed_lines": [22, 24, 25, 26, 27, 30, 31, 50, 72, 79, 85, 94], "summary": {"covered_lines": 12, "num_statements": 12, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1}}, "classes": {"CaptureStore": {"executed_lines": [32, 33, 34, 35, 36, 37, 38, 45, 48, 54, 55, 56, 58, 59, 60, 63, 64, 69, 70, 73, 74, 77, 80, 81, 83, 88, 89, 92, 95, 96, 97], "summary": {"covered_lines": 31, "num_statements": 31, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 30}, "": {"executed_lines": [22, 24, 25, 26, 27, 30, 31, 50, 72, 79, 85, 94], "summary": {"covered_lines": 12, "num_statements": 12, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1}}}, "corvus/cc_adapter.py": {"executed_lines": [26, 28, 29, 30, 31, 34, 35, 41, 42, 43, 44, 47, 49, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 68, 69, 70, 71, 76, 79, 80, 84, 89, 90, 93, 96, 97, 98, 101, 102, 109, 112, 113, 114, 116, 117, 119, 121, 123, 124, 128, 137], "summary": {"covered_lines": 51, "num_statements": 58, "percent_covered": 87.93103448275862, "percent_covered_display": "88", "missing_lines": 7, "excluded_lines": 0, "percent_statements_covered": 87.93103448275862, "percent_statements_covered_display": "88"}, "missing_lines": [105, 106, 122, 125, 133, 134, 138], "excluded_lines": [], "functions": {"CCAdapter.__init__": {"executed_lines": [41, 42, 43, 44, 47], "summary": {"covered_lines": 5, "num_statements": 5, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 35}, "CCAdapter.pre_tool_use": {"executed_lines": [52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 68, 69, 70, 71, 76, 79, 80, 84, 89, 90, 93, 96, 97, 98, 101, 102], "summary": {"covered_lines": 26, "num_statements": 28, "percent_covered": 92.85714285714286, "percent_covered_display": "93", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 92.85714285714286, "percent_statements_covered_display": "93"}, "missing_lines": [105, 106], "excluded_lines": [], "start_line": 49}, "CCAdapter.post_tool_use": {"executed_lines": [112, 113, 114, 116, 117], "summary": {"covered_lines": 5, "num_statements": 5, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 109}, "CCAdapter.handle": {"executed_lines": [121, 123, 124], "summary": {"covered_lines": 3, "num_statements": 5, "percent_covered": 60.0, "percent_covered_display": "60", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 60.0, "percent_statements_covered_display": "60"}, "missing_lines": [122, 125], "excluded_lines": [], "start_line": 119}, "main": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 2, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [133, 134], "excluded_lines": [], "start_line": 128}, "": {"executed_lines": [26, 28, 29, 30, 31, 34, 35, 49, 109, 119, 128, 137], "summary": {"covered_lines": 12, "num_statements": 13, "percent_covered": 92.3076923076923, "percent_covered_display": "92", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 92.3076923076923, "percent_statements_covered_display": "92"}, "missing_lines": [138], "excluded_lines": [], "start_line": 1}}, "classes": {"CCAdapter": {"executed_lines": [41, 42, 43, 44, 47, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 68, 69, 70, 71, 76, 79, 80, 84, 89, 90, 93, 96, 97, 98, 101, 102, 112, 113, 114, 116, 117, 121, 123, 124], "summary": {"covered_lines": 39, "num_statements": 43, "percent_covered": 90.69767441860465, "percent_covered_display": "91", "missing_lines": 4, "excluded_lines": 0, "percent_statements_covered": 90.69767441860465, "percent_statements_covered_display": "91"}, "missing_lines": [105, 106, 122, 125], "excluded_lines": [], "start_line": 34}, "": {"executed_lines": [26, 28, 29, 30, 31, 34, 35, 49, 109, 119, 128, 137], "summary": {"covered_lines": 12, "num_statements": 15, "percent_covered": 80.0, "percent_covered_display": "80", "missing_lines": 3, "excluded_lines": 0, "percent_statements_covered": 80.0, "percent_statements_covered_display": "80"}, "missing_lines": [133, 134, 138], "excluded_lines": [], "start_line": 1}}}, "corvus/compiler.py": {"executed_lines": [17, 19, 20, 21, 26, 29, 33, 43, 46, 47, 48, 49, 50, 52, 55, 62, 63, 64, 66, 69, 70, 71, 77, 78, 79, 80, 81, 83, 88, 89, 90, 94, 95, 96, 100, 101, 102, 103, 104, 106, 109, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 124, 125, 126, 127, 129, 130, 131, 132, 134, 135, 153, 156, 160, 161, 163, 164, 165, 167, 168, 169, 170, 173, 176, 177, 179, 185, 186, 187, 189, 190, 195, 198, 199, 201, 202, 203, 204, 206, 209, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 227, 228, 231], "summary": {"covered_lines": 104, "num_statements": 122, "percent_covered": 85.24590163934427, "percent_covered_display": "85", "missing_lines": 18, "excluded_lines": 0, "percent_statements_covered": 85.24590163934427, "percent_statements_covered_display": "85"}, "missing_lines": [36, 37, 38, 39, 40, 72, 171, 172, 174, 175, 181, 191, 192, 194, 200, 205, 229, 230], "excluded_lines": [], "functions": {"_fail_answer_index": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 5, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 5, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [36, 37, 38, 39, 40], "excluded_lines": [], "start_line": 33}, "validate_register": {"executed_lines": [46, 47, 48, 49, 50, 52, 55, 62, 63, 64, 66, 69, 70, 71, 77, 78, 79, 80, 81, 83, 88, 89, 90, 94, 95, 96, 100, 101, 102, 103, 104, 106], "summary": {"covered_lines": 32, "num_statements": 33, "percent_covered": 96.96969696969697, "percent_covered_display": "97", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 96.96969696969697, "percent_statements_covered_display": "97"}, "missing_lines": [72], "excluded_lines": [], "start_line": 43}, "_coverage": {"executed_lines": [112, 113, 114, 115, 116, 117, 118, 119, 120, 121], "summary": {"covered_lines": 10, "num_statements": 10, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 109}, "compile_catalog": {"executed_lines": [125, 126, 127, 129, 130, 131, 132, 134, 135, 153], "summary": {"covered_lines": 10, "num_statements": 10, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 124}, "diff_classify": {"executed_lines": [160, 161, 163, 164, 165, 167, 168, 169, 170, 173, 176, 177, 179, 185, 186, 187, 189, 190, 195, 198, 199, 201, 202, 203, 204, 206], "summary": {"covered_lines": 26, "num_statements": 36, "percent_covered": 72.22222222222223, "percent_covered_display": "72", "missing_lines": 10, "excluded_lines": 0, "percent_statements_covered": 72.22222222222223, "percent_statements_covered_display": "72"}, "missing_lines": [171, 172, 174, 175, 181, 191, 192, 194, 200, 205], "excluded_lines": [], "start_line": 156}, "build": {"executed_lines": [212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 227, 228, 231], "summary": {"covered_lines": 14, "num_statements": 16, "percent_covered": 87.5, "percent_covered_display": "88", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 87.5, "percent_statements_covered_display": "88"}, "missing_lines": [229, 230], "excluded_lines": [], "start_line": 209}, "": {"executed_lines": [17, 19, 20, 21, 26, 29, 33, 43, 109, 124, 156, 209], "summary": {"covered_lines": 12, "num_statements": 12, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1}}, "classes": {"CompilerError": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 0, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 29}, "": {"executed_lines": [17, 19, 20, 21, 26, 29, 33, 43, 46, 47, 48, 49, 50, 52, 55, 62, 63, 64, 66, 69, 70, 71, 77, 78, 79, 80, 81, 83, 88, 89, 90, 94, 95, 96, 100, 101, 102, 103, 104, 106, 109, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 124, 125, 126, 127, 129, 130, 131, 132, 134, 135, 153, 156, 160, 161, 163, 164, 165, 167, 168, 169, 170, 173, 176, 177, 179, 185, 186, 187, 189, 190, 195, 198, 199, 201, 202, 203, 204, 206, 209, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 227, 228, 231], "summary": {"covered_lines": 104, "num_statements": 122, "percent_covered": 85.24590163934427, "percent_covered_display": "85", "missing_lines": 18, "excluded_lines": 0, "percent_statements_covered": 85.24590163934427, "percent_statements_covered_display": "85"}, "missing_lines": [36, 37, 38, 39, 40, 72, 171, 172, 174, 175, 181, 191, 192, 194, 200, 205, 229, 230], "excluded_lines": [], "start_line": 1}}}, "corvus/config.py": {"executed_lines": [7, 9, 10, 11, 15, 36, 37, 38, 39, 40, 41, 43, 44, 45, 48], "summary": {"covered_lines": 15, "num_statements": 23, "percent_covered": 65.21739130434783, "percent_covered_display": "65", "missing_lines": 8, "excluded_lines": 0, "percent_statements_covered": 65.21739130434783, "percent_statements_covered_display": "65"}, "missing_lines": [55, 56, 57, 58, 66, 67, 68, 73], "excluded_lines": [], "functions": {"FleetConfig.event_types": {"executed_lines": [45], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 44}, "load_config": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 8, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 8, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [55, 56, 57, 58, 66, 67, 68, 73], "excluded_lines": [], "start_line": 48}, "": {"executed_lines": [7, 9, 10, 11, 15, 36, 37, 38, 39, 40, 41, 43, 44, 48], "summary": {"covered_lines": 14, "num_statements": 14, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1}}, "classes": {"FleetConfig": {"executed_lines": [45], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 37}, "": {"executed_lines": [7, 9, 10, 11, 15, 36, 37, 38, 39, 40, 41, 43, 44, 48], "summary": {"covered_lines": 14, "num_statements": 22, "percent_covered": 63.63636363636363, "percent_covered_display": "64", "missing_lines": 8, "excluded_lines": 0, "percent_statements_covered": 63.63636363636363, "percent_statements_covered_display": "64"}, "missing_lines": [55, 56, 57, 58, 66, 67, 68, 73], "excluded_lines": [], "start_line": 1}}}, "corvus/config_loader.py": {"executed_lines": [14, 16, 17, 18, 21, 22, 23, 25, 29, 30, 31, 32, 34, 38, 39, 41, 42], "summary": {"covered_lines": 17, "num_statements": 18, "percent_covered": 94.44444444444444, "percent_covered_display": "94", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 94.44444444444444, "percent_statements_covered_display": "94"}, "missing_lines": [40], "excluded_lines": [], "functions": {"ConfigLoader.__init__": {"executed_lines": [23], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 22}, "ConfigLoader.load_fleet_config": {"executed_lines": [29, 30, 31, 32], "summary": {"covered_lines": 4, "num_statements": 4, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 25}, "ConfigLoader.load_register": {"executed_lines": [38, 39, 41, 42], "summary": {"covered_lines": 4, "num_statements": 5, "percent_covered": 80.0, "percent_covered_display": "80", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 80.0, "percent_statements_covered_display": "80"}, "missing_lines": [40], "excluded_lines": [], "start_line": 34}, "": {"executed_lines": [14, 16, 17, 18, 21, 22, 25, 34], "summary": {"covered_lines": 8, "num_statements": 8, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1}}, "classes": {"ConfigLoader": {"executed_lines": [23, 29, 30, 31, 32, 38, 39, 41, 42], "summary": {"covered_lines": 9, "num_statements": 10, "percent_covered": 90.0, "percent_covered_display": "90", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 90.0, "percent_statements_covered_display": "90"}, "missing_lines": [40], "excluded_lines": [], "start_line": 21}, "": {"executed_lines": [14, 16, 17, 18, 21, 22, 25, 34], "summary": {"covered_lines": 8, "num_statements": 8, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1}}}, "corvus/conformance.py": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 66, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 66, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [31, 33, 34, 35, 36, 38, 39, 42, 66, 75, 77, 78, 79, 80, 81, 82, 85, 86, 87, 88, 92, 93, 94, 98, 99, 100, 104, 105, 106, 107, 108, 111, 116, 117, 118, 120, 121, 122, 123, 124, 125, 127, 128, 131, 132, 137, 141, 142, 143, 144, 146, 147, 148, 149, 150, 154, 155, 156, 157, 158, 159, 160, 162, 163, 164, 168], "excluded_lines": [], "functions": {"run_mutation_suite": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 17, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 17, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [75, 77, 78, 79, 80, 81, 82, 85, 86, 87, 88, 92, 93, 94, 98, 99, 100], "excluded_lines": [], "start_line": 66}, "_extract_red_test": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 4, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 4, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [105, 106, 107, 108], "excluded_lines": [], "start_line": 104}, "conformance_run": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 10, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 10, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [116, 117, 118, 120, 131, 146, 162, 163, 164, 168], "excluded_lines": [], "start_line": 111}, "conformance_run.check": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 7, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 7, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [121, 122, 123, 124, 125, 127, 128], "excluded_lines": [], "start_line": 120}, "conformance_run.happy_path": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 6, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 6, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [132, 137, 141, 142, 143, 144], "excluded_lines": [], "start_line": 131}, "conformance_run.existence_hiding": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 11, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 11, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [147, 148, 149, 150, 154, 155, 156, 157, 158, 159, 160], "excluded_lines": [], "start_line": 146}, "": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 11, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 11, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [31, 33, 34, 35, 36, 38, 39, 42, 66, 104, 111], "excluded_lines": [], "start_line": 1}}, "classes": {"": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 66, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 66, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [31, 33, 34, 35, 36, 38, 39, 42, 66, 75, 77, 78, 79, 80, 81, 82, 85, 86, 87, 88, 92, 93, 94, 98, 99, 100, 104, 105, 106, 107, 108, 111, 116, 117, 118, 120, 121, 122, 123, 124, 125, 127, 128, 131, 132, 137, 141, 142, 143, 144, 146, 147, 148, 149, 150, 154, 155, 156, 157, 158, 159, 160, 162, 163, 164, 168], "excluded_lines": [], "start_line": 1}}}, "corvus/contract_codes.py": {"executed_lines": [8], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "functions": {"": {"executed_lines": [8], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1}}, "classes": {"": {"executed_lines": [8], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1}}}, "corvus/core.py": {"executed_lines": [9, 11, 12, 13, 14, 15, 16, 18, 19, 20, 23, 24, 27, 30, 31, 34, 35, 36, 37, 38, 39, 43, 44, 45, 46, 47, 48, 49, 50, 51, 62, 63, 68, 71, 84, 85, 86, 87, 89, 90, 98, 99, 103, 107, 109, 110, 115, 119, 123, 124, 132, 136, 142, 143, 144, 145, 146, 147, 148, 150, 151, 152, 153, 193, 194, 195, 196, 197, 198, 199, 203, 204, 205, 206], "summary": {"covered_lines": 74, "num_statements": 98, "percent_covered": 75.51020408163265, "percent_covered_display": "76", "missing_lines": 24, "excluded_lines": 0, "percent_statements_covered": 75.51020408163265, "percent_statements_covered_display": "76"}, "missing_lines": [72, 73, 78, 80, 88, 154, 163, 169, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 186, 188, 189, 201, 202], "excluded_lines": [], "functions": {"_now_iso": {"executed_lines": [24], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 23}, "sign_event": {"executed_lines": [30, 31], "summary": {"covered_lines": 2, "num_statements": 2, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 27}, "CorvusCore.__init__": {"executed_lines": [36, 37, 38, 39], "summary": {"covered_lines": 4, "num_statements": 4, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 35}, "CorvusCore.ingest_event": {"executed_lines": [44, 45, 46, 47, 48, 49, 50, 51, 62, 63, 68], "summary": {"covered_lines": 11, "num_statements": 11, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 43}, "CorvusCore.query_events": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 4, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 4, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [72, 73, 78, 80], "excluded_lines": [], "start_line": 71}, "CorvusCore.open_change": {"executed_lines": [85, 86, 87, 89, 90, 98, 99, 103, 107], "summary": {"covered_lines": 9, "num_statements": 10, "percent_covered": 90.0, "percent_covered_display": "90", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 90.0, "percent_statements_covered_display": "90"}, "missing_lines": [88], "excluded_lines": [], "start_line": 84}, "CorvusCore.active_changes_for": {"executed_lines": [110, 115], "summary": {"covered_lines": 2, "num_statements": 2, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 109}, "CorvusCore.conflict_check": {"executed_lines": [123, 124, 132, 136, 142, 143, 144, 145, 146, 147, 148, 150, 151, 152, 153, 193, 194, 195, 196, 197, 198, 199, 203, 204, 205, 206], "summary": {"covered_lines": 26, "num_statements": 45, "percent_covered": 57.77777777777778, "percent_covered_display": "58", "missing_lines": 19, "excluded_lines": 0, "percent_statements_covered": 57.77777777777778, "percent_statements_covered_display": "58"}, "missing_lines": [154, 163, 169, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 186, 188, 189, 201, 202], "excluded_lines": [], "start_line": 119}, "": {"executed_lines": [9, 11, 12, 13, 14, 15, 16, 18, 19, 20, 23, 27, 34, 35, 43, 71, 84, 109, 119], "summary": {"covered_lines": 19, "num_statements": 19, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1}}, "classes": {"CorvusCore": {"executed_lines": [36, 37, 38, 39, 44, 45, 46, 47, 48, 49, 50, 51, 62, 63, 68, 85, 86, 87, 89, 90, 98, 99, 103, 107, 110, 115, 123, 124, 132, 136, 142, 143, 144, 145, 146, 147, 148, 150, 151, 152, 153, 193, 194, 195, 196, 197, 198, 199, 203, 204, 205, 206], "summary": {"covered_lines": 52, "num_statements": 76, "percent_covered": 68.42105263157895, "percent_covered_display": "68", "missing_lines": 24, "excluded_lines": 0, "percent_statements_covered": 68.42105263157895, "percent_statements_covered_display": "68"}, "missing_lines": [72, 73, 78, 80, 88, 154, 163, 169, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 186, 188, 189, 201, 202], "excluded_lines": [], "start_line": 34}, "": {"executed_lines": [9, 11, 12, 13, 14, 15, 16, 18, 19, 20, 23, 24, 27, 30, 31, 34, 35, 43, 71, 84, 109, 119], "summary": {"covered_lines": 22, "num_statements": 22, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1}}}, "corvus/decision_core.py": {"executed_lines": [20, 22, 23, 24, 27, 28, 31, 34, 37, 43, 44, 45, 48, 50, 51, 52, 53, 54, 55, 58, 59, 60, 64, 65, 66, 67, 68, 69, 71, 72, 74, 75, 77, 80, 82, 83, 84, 85, 87, 88, 91, 92, 93, 95, 97, 98, 99, 103, 104, 106, 107, 111, 112, 114, 127, 129, 130, 131, 133, 134, 135, 136, 138, 140, 142, 144, 145, 146, 149, 150, 152, 154, 155, 156, 158, 162, 163, 164, 167, 168, 169, 171, 172, 173, 174, 175, 176], "summary": {"covered_lines": 87, "num_statements": 100, "percent_covered": 87.0, "percent_covered_display": "87", "missing_lines": 13, "excluded_lines": 0, "percent_statements_covered": 87.0, "percent_statements_covered_display": "87"}, "missing_lines": [86, 89, 116, 117, 118, 119, 120, 122, 123, 124, 125, 141, 143], "excluded_lines": [], "functions": {"DecisionCore.__init__": {"executed_lines": [43, 44, 45], "summary": {"covered_lines": 3, "num_statements": 3, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 37}, "DecisionCore.solve": {"executed_lines": [50, 51, 52, 53, 54, 55, 58, 59, 60, 64, 65, 66, 67, 68, 69, 71, 72, 74, 75, 77], "summary": {"covered_lines": 20, "num_statements": 20, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 48}, "DecisionCore._dispatch": {"executed_lines": [82, 83, 84, 85, 87, 88], "summary": {"covered_lines": 6, "num_statements": 8, "percent_covered": 75.0, "percent_covered_display": "75", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 75.0, "percent_statements_covered_display": "75"}, "missing_lines": [86, 89], "excluded_lines": [], "start_line": 80}, "DecisionCore._check_deadline": {"executed_lines": [92, 93], "summary": {"covered_lines": 2, "num_statements": 2, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 91}, "DecisionCore._dispatch_rule": {"executed_lines": [97, 98, 99, 103, 104, 106, 107, 111, 112], "summary": {"covered_lines": 9, "num_statements": 9, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 95}, "DecisionCore._dispatch_lookup": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 9, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 9, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [116, 117, 118, 119, 120, 122, 123, 124, 125], "excluded_lines": [], "start_line": 114}, "DecisionCore._dispatch_model": {"executed_lines": [129, 130, 131, 133, 134, 135, 136, 138, 140, 142, 144, 145, 146], "summary": {"covered_lines": 13, "num_statements": 15, "percent_covered": 86.66666666666667, "percent_covered_display": "87", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 86.66666666666667, "percent_statements_covered_display": "87"}, "missing_lines": [141, 143], "excluded_lines": [], "start_line": 127}, "DecisionCore._full": {"executed_lines": [152, 154, 155, 156], "summary": {"covered_lines": 4, "num_statements": 4, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 150}, "DecisionCore._fail_cell": {"executed_lines": [162, 163, 164, 167, 168, 169], "summary": {"covered_lines": 6, "num_statements": 6, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 158}, "DecisionCore._failed_dependency": {"executed_lines": [173, 174, 175, 176], "summary": {"covered_lines": 4, "num_statements": 4, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 172}, "": {"executed_lines": [20, 22, 23, 24, 27, 28, 31, 34, 37, 48, 80, 91, 95, 114, 127, 149, 150, 158, 171, 172], "summary": {"covered_lines": 20, "num_statements": 20, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1}}, "classes": {"SliceExceeded": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 0, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 27}, "DecisionCore": {"executed_lines": [43, 44, 45, 50, 51, 52, 53, 54, 55, 58, 59, 60, 64, 65, 66, 67, 68, 69, 71, 72, 74, 75, 77, 82, 83, 84, 85, 87, 88, 92, 93, 97, 98, 99, 103, 104, 106, 107, 111, 112, 129, 130, 131, 133, 134, 135, 136, 138, 140, 142, 144, 145, 146, 152, 154, 155, 156, 162, 163, 164, 167, 168, 169, 173, 174, 175, 176], "summary": {"covered_lines": 67, "num_statements": 80, "percent_covered": 83.75, "percent_covered_display": "84", "missing_lines": 13, "excluded_lines": 0, "percent_statements_covered": 83.75, "percent_statements_covered_display": "84"}, "missing_lines": [86, 89, 116, 117, 118, 119, 120, 122, 123, 124, 125, 141, 143], "excluded_lines": [], "start_line": 34}, "": {"executed_lines": [20, 22, 23, 24, 27, 28, 31, 34, 37, 48, 80, 91, 95, 114, 127, 149, 150, 158, 171, 172], "summary": {"covered_lines": 20, "num_statements": 20, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1}}}, "corvus/decisions.py": {"executed_lines": [9, 11, 12, 13, 14, 17, 18, 19, 20, 21, 23, 33, 34, 36, 41, 42, 43, 48, 49, 57, 58, 60, 61, 62, 63, 64, 65, 72], "summary": {"covered_lines": 28, "num_statements": 28, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "functions": {"DecisionClient.__init__": {"executed_lines": [19, 20, 21], "summary": {"covered_lines": 3, "num_statements": 3, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 18}, "DecisionClient.decide": {"executed_lines": [33, 34, 36, 41, 42, 43, 48, 49, 57, 58, 60, 61, 62, 63, 64, 65, 72], "summary": {"covered_lines": 17, "num_statements": 17, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 23}, "": {"executed_lines": [9, 11, 12, 13, 14, 17, 18, 23], "summary": {"covered_lines": 8, "num_statements": 8, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1}}, "classes": {"DecisionClient": {"executed_lines": [19, 20, 21, 33, 34, 36, 41, 42, 43, 48, 49, 57, 58, 60, 61, 62, 63, 64, 65, 72], "summary": {"covered_lines": 20, "num_statements": 20, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 17}, "": {"executed_lines": [9, 11, 12, 13, 14, 17, 18, 23], "summary": {"covered_lines": 8, "num_statements": 8, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1}}}, "corvus/delivery.py": {"executed_lines": [13, 15, 18, 19, 25, 26, 27, 28, 29, 31, 35, 37, 38, 41, 43, 47, 48, 50, 51, 52, 53, 54, 55, 56, 60, 61, 63, 64, 66, 70, 71, 72, 73, 74, 75, 76, 77, 80, 81, 82, 83, 84, 89, 90, 92, 96, 97, 99, 103, 105, 106], "summary": {"covered_lines": 51, "num_statements": 55, "percent_covered": 92.72727272727273, "percent_covered_display": "93", "missing_lines": 4, "excluded_lines": 0, "percent_statements_covered": 92.72727272727273, "percent_statements_covered_display": "93"}, "missing_lines": [49, 78, 79, 104], "excluded_lines": [], "functions": {"DeliveryChain.__init__": {"executed_lines": [25, 26, 27, 28, 29], "summary": {"covered_lines": 5, "num_statements": 5, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 19}, "DeliveryChain.submit": {"executed_lines": [35, 37, 38, 41], "summary": {"covered_lines": 4, "num_statements": 4, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 31}, "DeliveryChain.deliver": {"executed_lines": [47, 48, 50, 51, 52, 53, 54, 55, 56, 60, 61, 63, 64], "summary": {"covered_lines": 13, "num_statements": 14, "percent_covered": 92.85714285714286, "percent_covered_display": "93", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 92.85714285714286, "percent_statements_covered_display": "93"}, "missing_lines": [49], "excluded_lines": [], "start_line": 43}, "DeliveryChain.deliver_on_recovery": {"executed_lines": [70, 71, 72, 73, 74, 75, 76, 77, 80, 81, 82, 83, 84, 89, 90, 92, 96, 97], "summary": {"covered_lines": 18, "num_statements": 20, "percent_covered": 90.0, "percent_covered_display": "90", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 90.0, "percent_statements_covered_display": "90"}, "missing_lines": [78, 79], "excluded_lines": [], "start_line": 66}, "DeliveryChain.route_invalid": {"executed_lines": [103, 105, 106], "summary": {"covered_lines": 3, "num_statements": 4, "percent_covered": 75.0, "percent_covered_display": "75", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 75.0, "percent_statements_covered_display": "75"}, "missing_lines": [104], "excluded_lines": [], "start_line": 99}, "": {"executed_lines": [13, 15, 18, 19, 31, 43, 66, 99], "summary": {"covered_lines": 8, "num_statements": 8, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1}}, "classes": {"DeliveryChain": {"executed_lines": [25, 26, 27, 28, 29, 35, 37, 38, 41, 47, 48, 50, 51, 52, 53, 54, 55, 56, 60, 61, 63, 64, 70, 71, 72, 73, 74, 75, 76, 77, 80, 81, 82, 83, 84, 89, 90, 92, 96, 97, 103, 105, 106], "summary": {"covered_lines": 43, "num_statements": 47, "percent_covered": 91.48936170212765, "percent_covered_display": "91", "missing_lines": 4, "excluded_lines": 0, "percent_statements_covered": 91.48936170212765, "percent_statements_covered_display": "91"}, "missing_lines": [49, 78, 79, 104], "excluded_lines": [], "start_line": 18}, "": {"executed_lines": [13, 15, 18, 19, 31, 43, 66, 99], "summary": {"covered_lines": 8, "num_statements": 8, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1}}}, "corvus/engine_shim.py": {"executed_lines": [15, 17, 18, 19, 20, 22, 24, 25, 27, 28, 29, 31, 33, 41, 43, 44, 53, 54, 57, 66, 67, 68, 69, 71, 72, 73, 75, 76, 77, 78, 79, 80, 83, 84, 92, 94, 97, 103, 104, 106, 107, 108, 111, 112, 113, 117, 118, 119, 125, 126, 127, 128, 129, 130, 131, 133, 134, 135, 139, 140, 141, 142, 143, 144, 146, 147, 149, 153, 157, 158, 159, 160, 161, 163, 164, 165, 166, 177, 178, 179, 180, 181, 182, 183, 184, 185, 189, 195, 196, 197, 198, 199, 200, 201, 204, 205, 207, 208, 209, 211, 212, 217, 218, 219, 220, 221, 222, 223, 224, 226, 227, 230, 234, 236, 237, 238, 239, 264, 274, 281, 282, 283, 284, 287, 288, 289, 292], "summary": {"covered_lines": 127, "num_statements": 147, "percent_covered": 86.39455782312925, "percent_covered_display": "86", "missing_lines": 20, "excluded_lines": 0, "percent_statements_covered": 86.39455782312925, "percent_statements_covered_display": "86"}, "missing_lines": [70, 105, 145, 162, 225, 229, 231, 245, 246, 247, 248, 249, 256, 257, 293, 294, 295, 296, 297, 298], "excluded_lines": [], "functions": {"err": {"executed_lines": [43, 44], "summary": {"covered_lines": 2, "num_statements": 2, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 41}, "_register_candidates": {"executed_lines": [67, 68, 69, 71, 72, 73], "summary": {"covered_lines": 6, "num_statements": 7, "percent_covered": 85.71428571428571, "percent_covered_display": "86", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 85.71428571428571, "percent_statements_covered_display": "86"}, "missing_lines": [70], "excluded_lines": [], "start_line": 66}, "_site_resolution": {"executed_lines": [84], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 83}, "_quantize": {"executed_lines": [103, 104, 106, 107, 108], "summary": {"covered_lines": 5, "num_statements": 6, "percent_covered": 83.33333333333333, "percent_covered_display": "83", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 83.33333333333333, "percent_statements_covered_display": "83"}, "missing_lines": [105], "excluded_lines": [], "start_line": 97}, "decide": {"executed_lines": [113, 117, 118, 119, 125, 126, 127, 128, 129, 130, 131, 133, 134, 135, 139, 140, 141, 142, 143, 144, 146, 147, 149, 153, 157, 158, 159, 160, 161, 163, 164, 165, 166, 177, 178, 179, 180, 181, 182, 183, 184, 185, 189, 195, 196, 197, 198, 199, 200, 201, 204, 205, 207, 208, 209, 211, 212, 217, 218, 219, 220, 221, 222, 223, 224, 226, 227, 230, 234, 236, 237, 238, 239, 264, 274, 281, 282, 283, 284], "summary": {"covered_lines": 79, "num_statements": 91, "percent_covered": 86.81318681318682, "percent_covered_display": "87", "missing_lines": 12, "excluded_lines": 0, "percent_statements_covered": 86.81318681318682, "percent_statements_covered_display": "87"}, "missing_lines": [145, 162, 225, 229, 231, 245, 246, 247, 248, 249, 256, 257], "excluded_lines": [], "start_line": 112}, "hashlib_sha": {"executed_lines": [288, 289], "summary": {"covered_lines": 2, "num_statements": 2, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 287}, "": {"executed_lines": [15, 17, 18, 19, 20, 22, 24, 25, 27, 28, 29, 31, 33, 41, 53, 54, 57, 66, 75, 76, 77, 78, 79, 80, 83, 92, 94, 97, 111, 112, 287, 292], "summary": {"covered_lines": 32, "num_statements": 38, "percent_covered": 84.21052631578948, "percent_covered_display": "84", "missing_lines": 6, "excluded_lines": 0, "percent_statements_covered": 84.21052631578948, "percent_statements_covered_display": "84"}, "missing_lines": [293, 294, 295, 296, 297, 298], "excluded_lines": [], "start_line": 1}}, "classes": {"": {"executed_lines": [15, 17, 18, 19, 20, 22, 24, 25, 27, 28, 29, 31, 33, 41, 43, 44, 53, 54, 57, 66, 67, 68, 69, 71, 72, 73, 75, 76, 77, 78, 79, 80, 83, 84, 92, 94, 97, 103, 104, 106, 107, 108, 111, 112, 113, 117, 118, 119, 125, 126, 127, 128, 129, 130, 131, 133, 134, 135, 139, 140, 141, 142, 143, 144, 146, 147, 149, 153, 157, 158, 159, 160, 161, 163, 164, 165, 166, 177, 178, 179, 180, 181, 182, 183, 184, 185, 189, 195, 196, 197, 198, 199, 200, 201, 204, 205, 207, 208, 209, 211, 212, 217, 218, 219, 220, 221, 222, 223, 224, 226, 227, 230, 234, 236, 237, 238, 239, 264, 274, 281, 282, 283, 284, 287, 288, 289, 292], "summary": {"covered_lines": 127, "num_statements": 147, "percent_covered": 86.39455782312925, "percent_covered_display": "86", "missing_lines": 20, "excluded_lines": 0, "percent_statements_covered": 86.39455782312925, "percent_statements_covered_display": "86"}, "missing_lines": [70, 105, 145, 162, 225, 229, 231, 245, 246, 247, 248, 249, 256, 257, 293, 294, 295, 296, 297, 298], "excluded_lines": [], "start_line": 1}}}, "corvus/facts.py": {"executed_lines": [27, 29, 30, 33, 38, 41, 42, 46, 47, 49, 52, 53, 54, 55, 56, 57, 59, 60, 61, 62, 63, 68, 69, 70, 71, 72, 73, 74, 75, 76, 79, 81, 85, 87, 88, 89, 90, 91, 93, 94, 101, 104, 105, 106, 109, 110, 111, 122], "summary": {"covered_lines": 48, "num_statements": 51, "percent_covered": 94.11764705882354, "percent_covered_display": "94", "missing_lines": 3, "excluded_lines": 0, "percent_statements_covered": 94.11764705882354, "percent_statements_covered_display": "94"}, "missing_lines": [114, 117, 118], "excluded_lines": [], "functions": {"FactComposer.__init__": {"executed_lines": [46, 47], "summary": {"covered_lines": 2, "num_statements": 2, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 42}, "FactComposer.compose": {"executed_lines": [52, 53, 54, 55, 56, 57, 59, 60, 61, 62, 63, 68, 69, 70, 71, 72, 73, 74, 75, 76, 79], "summary": {"covered_lines": 21, "num_statements": 21, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 49}, "FactComposer.compose_status_view": {"executed_lines": [85, 87, 88, 89, 90, 91, 93, 94], "summary": {"covered_lines": 8, "num_statements": 8, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 81}, "change_window_source": {"executed_lines": [104, 122], "summary": {"covered_lines": 2, "num_statements": 2, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 101}, "change_window_source.source": {"executed_lines": [105, 106, 109, 110, 111], "summary": {"covered_lines": 5, "num_statements": 8, "percent_covered": 62.5, "percent_covered_display": "62", "missing_lines": 3, "excluded_lines": 0, "percent_statements_covered": 62.5, "percent_statements_covered_display": "62"}, "missing_lines": [114, 117, 118], "excluded_lines": [], "start_line": 104}, "": {"executed_lines": [27, 29, 30, 33, 38, 41, 42, 49, 81, 101], "summary": {"covered_lines": 10, "num_statements": 10, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1}}, "classes": {"FactComposer": {"executed_lines": [46, 47, 52, 53, 54, 55, 56, 57, 59, 60, 61, 62, 63, 68, 69, 70, 71, 72, 73, 74, 75, 76, 79, 85, 87, 88, 89, 90, 91, 93, 94], "summary": {"covered_lines": 31, "num_statements": 31, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 41}, "": {"executed_lines": [27, 29, 30, 33, 38, 41, 42, 49, 81, 101, 104, 105, 106, 109, 110, 111, 122], "summary": {"covered_lines": 17, "num_statements": 20, "percent_covered": 85.0, "percent_covered_display": "85", "missing_lines": 3, "excluded_lines": 0, "percent_statements_covered": 85.0, "percent_statements_covered_display": "85"}, "missing_lines": [114, 117, 118], "excluded_lines": [], "start_line": 1}}}, "corvus/hlc.py": {"executed_lines": [8, 9, 10, 13, 14, 15, 16, 17, 19, 20, 21, 26, 27, 30, 31, 32, 33, 34, 35, 37, 38, 39, 40, 41, 42, 45, 47, 50, 51, 52, 53, 61], "summary": {"covered_lines": 32, "num_statements": 42, "percent_covered": 76.19047619047619, "percent_covered_display": "76", "missing_lines": 10, "excluded_lines": 0, "percent_statements_covered": 76.19047619047619, "percent_statements_covered_display": "76"}, "missing_lines": [22, 23, 24, 44, 54, 55, 56, 57, 59, 60], "excluded_lines": [], "functions": {"HLCTimestamp.__lt__": {"executed_lines": [20, 21], "summary": {"covered_lines": 2, "num_statements": 5, "percent_covered": 40.0, "percent_covered_display": "40", "missing_lines": 3, "excluded_lines": 0, "percent_statements_covered": 40.0, "percent_statements_covered_display": "40"}, "missing_lines": [22, 23, 24], "excluded_lines": [], "start_line": 19}, "HLCTimestamp.to_string": {"executed_lines": [27], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 26}, "HLC.__init__": {"executed_lines": [32, 33, 34, 35], "summary": {"covered_lines": 4, "num_statements": 4, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 31}, "HLC.now": {"executed_lines": [38, 39, 40, 41, 42, 45], "summary": {"covered_lines": 6, "num_statements": 7, "percent_covered": 85.71428571428571, "percent_covered_display": "86", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 85.71428571428571, "percent_statements_covered_display": "86"}, "missing_lines": [44], "excluded_lines": [], "start_line": 37}, "HLC.merge": {"executed_lines": [50, 51, 52, 53, 61], "summary": {"covered_lines": 5, "num_statements": 11, "percent_covered": 45.45454545454545, "percent_covered_display": "45", "missing_lines": 6, "excluded_lines": 0, "percent_statements_covered": 45.45454545454545, "percent_statements_covered_display": "45"}, "missing_lines": [54, 55, 56, 57, 59, 60], "excluded_lines": [], "start_line": 47}, "": {"executed_lines": [8, 9, 10, 13, 14, 15, 16, 17, 19, 26, 30, 31, 37, 47], "summary": {"covered_lines": 14, "num_statements": 14, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1}}, "classes": {"HLCTimestamp": {"executed_lines": [20, 21, 27], "summary": {"covered_lines": 3, "num_statements": 6, "percent_covered": 50.0, "percent_covered_display": "50", "missing_lines": 3, "excluded_lines": 0, "percent_statements_covered": 50.0, "percent_statements_covered_display": "50"}, "missing_lines": [22, 23, 24], "excluded_lines": [], "start_line": 14}, "HLC": {"executed_lines": [32, 33, 34, 35, 38, 39, 40, 41, 42, 45, 50, 51, 52, 53, 61], "summary": {"covered_lines": 15, "num_statements": 22, "percent_covered": 68.18181818181819, "percent_covered_display": "68", "missing_lines": 7, "excluded_lines": 0, "percent_statements_covered": 68.18181818181819, "percent_statements_covered_display": "68"}, "missing_lines": [44, 54, 55, 56, 57, 59, 60], "excluded_lines": [], "start_line": 30}, "": {"executed_lines": [8, 9, 10, 13, 14, 15, 16, 17, 19, 26, 30, 31, 37, 47], "summary": {"covered_lines": 14, "num_statements": 14, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1}}}, "corvus/observe.py": {"executed_lines": [21, 23, 26, 27, 31, 32, 33, 35, 41, 42, 46, 47, 49, 53, 54, 55, 58, 60, 63, 66, 70], "summary": {"covered_lines": 21, "num_statements": 21, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "functions": {"ObserveMode.__init__": {"executed_lines": [31, 32, 33], "summary": {"covered_lines": 3, "num_statements": 3, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 27}, "ObserveMode.record_attempt": {"executed_lines": [41, 42, 46, 47, 49, 53, 54, 55, 58], "summary": {"covered_lines": 9, "num_statements": 9, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 35}, "ObserveMode.coverage": {"executed_lines": [63], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 60}, "ObserveMode.token_issuance_allowed": {"executed_lines": [70], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 66}, "": {"executed_lines": [21, 23, 26, 27, 35, 60, 66], "summary": {"covered_lines": 7, "num_statements": 7, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1}}, "classes": {"ObserveMode": {"executed_lines": [31, 32, 33, 41, 42, 46, 47, 49, 53, 54, 55, 58, 63, 70], "summary": {"covered_lines": 14, "num_statements": 14, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 26}, "": {"executed_lines": [21, 23, 26, 27, 35, 60, 66], "summary": {"covered_lines": 7, "num_statements": 7, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1}}}, "corvus/ops.py": {"executed_lines": [13, 15, 18, 21, 26, 28, 32, 33, 34, 37, 41, 42, 43, 44, 46, 47, 48, 49, 51, 52, 53, 54, 56, 57, 58, 61, 70, 71, 72, 74, 75, 76, 79, 80, 81, 82, 83, 84, 85, 87], "summary": {"covered_lines": 40, "num_statements": 41, "percent_covered": 97.5609756097561, "percent_covered_display": "98", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 97.5609756097561, "percent_statements_covered_display": "98"}, "missing_lines": [77], "excluded_lines": [], "functions": {"FleetScopeResolver.__init__": {"executed_lines": [26], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 21}, "FleetScopeResolver.resolve": {"executed_lines": [32, 33, 34], "summary": {"covered_lines": 3, "num_statements": 3, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 28}, "Metrics.__init__": {"executed_lines": [42, 43, 44], "summary": {"covered_lines": 3, "num_statements": 3, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 41}, "Metrics.inc": {"executed_lines": [47, 48, 49], "summary": {"covered_lines": 3, "num_statements": 3, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 46}, "Metrics.set_gauge": {"executed_lines": [52, 53, 54], "summary": {"covered_lines": 3, "num_statements": 3, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 51}, "Metrics.snapshot": {"executed_lines": [57, 58], "summary": {"covered_lines": 2, "num_statements": 2, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 56}, "Health.__init__": {"executed_lines": [71, 72], "summary": {"covered_lines": 2, "num_statements": 2, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 70}, "Health.record_latency": {"executed_lines": [75, 76], "summary": {"covered_lines": 2, "num_statements": 3, "percent_covered": 66.66666666666667, "percent_covered_display": "67", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 66.66666666666667, "percent_statements_covered_display": "67"}, "missing_lines": [77], "excluded_lines": [], "start_line": 74}, "Health.state": {"executed_lines": [80, 81, 82, 83, 84, 85, 87], "summary": {"covered_lines": 7, "num_statements": 7, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 79}, "": {"executed_lines": [13, 15, 18, 21, 28, 37, 41, 46, 51, 56, 61, 70, 74, 79], "summary": {"covered_lines": 14, "num_statements": 14, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1}}, "classes": {"FleetScopeResolver": {"executed_lines": [26, 32, 33, 34], "summary": {"covered_lines": 4, "num_statements": 4, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 18}, "Metrics": {"executed_lines": [42, 43, 44, 47, 48, 49, 52, 53, 54, 57, 58], "summary": {"covered_lines": 11, "num_statements": 11, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 37}, "Health": {"executed_lines": [71, 72, 75, 76, 80, 81, 82, 83, 84, 85, 87], "summary": {"covered_lines": 11, "num_statements": 12, "percent_covered": 91.66666666666667, "percent_covered_display": "92", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 91.66666666666667, "percent_statements_covered_display": "92"}, "missing_lines": [77], "excluded_lines": [], "start_line": 61}, "": {"executed_lines": [13, 15, 18, 21, 28, 37, 41, 46, 51, 56, 61, 70, 74, 79], "summary": {"covered_lines": 14, "num_statements": 14, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1}}}, "corvus/state.py": {"executed_lines": [8, 10, 11, 12, 14, 59, 62, 63, 64, 65, 66, 67, 68, 70, 71, 72, 73, 74, 75], "summary": {"covered_lines": 19, "num_statements": 19, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "functions": {"State.__init__": {"executed_lines": [63, 64, 65, 66, 67, 68], "summary": {"covered_lines": 6, "num_statements": 6, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 62}, "State.execute": {"executed_lines": [71, 72, 73, 74, 75], "summary": {"covered_lines": 5, "num_statements": 5, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 70}, "": {"executed_lines": [8, 10, 11, 12, 14, 59, 62, 70], "summary": {"covered_lines": 8, "num_statements": 8, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1}}, "classes": {"State": {"executed_lines": [63, 64, 65, 66, 67, 68, 71, 72, 73, 74, 75], "summary": {"covered_lines": 11, "num_statements": 11, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 59}, "": {"executed_lines": [8, 10, 11, 12, 14, 59, 62, 70], "summary": {"covered_lines": 8, "num_statements": 8, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1}}}, "corvus/tokens.py": {"executed_lines": [31, 33, 34, 35, 38, 39, 44, 45, 48, 49, 53, 54, 55, 56, 57, 58, 60, 67, 68, 72, 80, 81, 83, 87, 91, 93, 94, 96, 100, 103, 108, 109, 114, 117, 140, 145], "summary": {"covered_lines": 36, "num_statements": 58, "percent_covered": 62.06896551724138, "percent_covered_display": "62", "missing_lines": 22, "excluded_lines": 0, "percent_statements_covered": 62.06896551724138, "percent_statements_covered_display": "62"}, "missing_lines": [40, 41, 69, 92, 95, 97, 98, 99, 101, 102, 104, 127, 128, 129, 130, 131, 132, 133, 134, 138, 141, 148], "excluded_lines": [], "functions": {"TokenRefused.__init__": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 2, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [40, 41], "excluded_lines": [], "start_line": 39}, "VerdictTokenIssuer.__init__": {"executed_lines": [53, 54, 55, 56, 57, 58], "summary": {"covered_lines": 6, "num_statements": 6, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 49}, "VerdictTokenIssuer.issue": {"executed_lines": [67, 68, 72, 80, 81], "summary": {"covered_lines": 5, "num_statements": 6, "percent_covered": 83.33333333333333, "percent_covered_display": "83", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 83.33333333333333, "percent_statements_covered_display": "83"}, "missing_lines": [69], "excluded_lines": [], "start_line": 60}, "VerdictTokenIssuer.consume": {"executed_lines": [87, 91, 93, 94, 96, 100, 103, 108, 109, 114], "summary": {"covered_lines": 10, "num_statements": 18, "percent_covered": 55.55555555555556, "percent_covered_display": "56", "missing_lines": 8, "excluded_lines": 0, "percent_statements_covered": 55.55555555555556, "percent_statements_covered_display": "56"}, "missing_lines": [92, 95, 97, 98, 99, 101, 102, 104], "excluded_lines": [], "start_line": 83}, "VerdictTokenIssuer.revoke": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 9, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 9, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [127, 128, 129, 130, 131, 132, 133, 134, 138], "excluded_lines": [], "start_line": 117}, "VerdictTokenIssuer.outstanding_for": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 1, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [141], "excluded_lines": [], "start_line": 140}, "action_fingerprint": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 1, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [148], "excluded_lines": [], "start_line": 145}, "": {"executed_lines": [31, 33, 34, 35, 38, 39, 44, 45, 48, 49, 60, 83, 117, 140, 145], "summary": {"covered_lines": 15, "num_statements": 15, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1}}, "classes": {"TokenRefused": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 2, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [40, 41], "excluded_lines": [], "start_line": 38}, "EvidenceNotDurable": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 0, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 44}, "VerdictTokenIssuer": {"executed_lines": [53, 54, 55, 56, 57, 58, 67, 68, 72, 80, 81, 87, 91, 93, 94, 96, 100, 103, 108, 109, 114], "summary": {"covered_lines": 21, "num_statements": 40, "percent_covered": 52.5, "percent_covered_display": "52", "missing_lines": 19, "excluded_lines": 0, "percent_statements_covered": 52.5, "percent_statements_covered_display": "52"}, "missing_lines": [69, 92, 95, 97, 98, 99, 101, 102, 104, 127, 128, 129, 130, 131, 132, 133, 134, 138, 141], "excluded_lines": [], "start_line": 48}, "": {"executed_lines": [31, 33, 34, 35, 38, 39, 44, 45, 48, 49, 60, 83, 117, 140, 145], "summary": {"covered_lines": 15, "num_statements": 16, "percent_covered": 93.75, "percent_covered_display": "94", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 93.75, "percent_statements_covered_display": "94"}, "missing_lines": [148], "excluded_lines": [], "start_line": 1}}}, "corvus/trust.py": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 61, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 61, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [36, 38, 41, 44, 52, 53, 56, 57, 58, 59, 60, 62, 66, 67, 68, 70, 77, 78, 79, 80, 83, 84, 85, 87, 94, 95, 96, 97, 98, 102, 108, 109, 110, 111, 112, 114, 115, 117, 118, 120, 122, 125, 126, 127, 128, 129, 130, 133, 134, 135, 138, 140, 141, 147, 154, 155, 161, 164, 166, 171, 172], "excluded_lines": [], "functions": {"TrustLedger.__init__": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 5, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 5, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [56, 57, 58, 59, 60], "excluded_lines": [], "start_line": 53}, "TrustLedger.tier": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 3, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 3, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [66, 67, 68], "excluded_lines": [], "start_line": 62}, "TrustLedger.record_outcome": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 7, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 7, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [77, 78, 79, 80, 83, 84, 85], "excluded_lines": [], "start_line": 70}, "TrustLedger.due_missing": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 5, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 5, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [94, 95, 96, 97, 98], "excluded_lines": [], "start_line": 87}, "TrustLedger.evaluate_promotion": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 20, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 20, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [108, 109, 110, 111, 112, 114, 115, 117, 118, 120, 122, 125, 126, 127, 128, 129, 130, 133, 134, 135], "excluded_lines": [], "start_line": 102}, "TrustLedger.promote": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 2, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [140, 141], "excluded_lines": [], "start_line": 138}, "TrustLedger.demote": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 2, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [154, 155], "excluded_lines": [], "start_line": 147}, "TrustLedger.invalidate_on_drift": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 1, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [164], "excluded_lines": [], "start_line": 161}, "TrustLedger.quarantine": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 2, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [171, 172], "excluded_lines": [], "start_line": 166}, "": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 14, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 14, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [36, 38, 41, 44, 52, 53, 62, 70, 87, 102, 138, 147, 161, 166], "excluded_lines": [], "start_line": 1}}, "classes": {"TrustLedger": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 47, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 47, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [56, 57, 58, 59, 60, 66, 67, 68, 77, 78, 79, 80, 83, 84, 85, 94, 95, 96, 97, 98, 108, 109, 110, 111, 112, 114, 115, 117, 118, 120, 122, 125, 126, 127, 128, 129, 130, 133, 134, 135, 140, 141, 154, 155, 164, 171, 172], "excluded_lines": [], "start_line": 52}, "": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 14, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 14, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0"}, "missing_lines": [36, 38, 41, 44, 52, 53, 62, 70, 87, 102, 138, 147, 161, 166], "excluded_lines": [], "start_line": 1}}}}, "totals": {"covered_lines": 932, "num_statements": 1277, "percent_covered": 72.98355520751763, "percent_covered_display": "73", "missing_lines": 345, "excluded_lines": 0, "percent_statements_covered": 72.98355520751763, "percent_statements_covered_display": "73"}} \ No newline at end of file diff --git a/corvus-v2/junit.xml b/corvus-v2/junit.xml index e88675c..c12f6d3 100644 --- a/corvus-v2/junit.xml +++ b/corvus-v2/junit.xml @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/docs/DEV-READINESS-REVIEW.md b/docs/DEV-READINESS-REVIEW.md index 76ed2f0..cf574cc 100644 --- a/docs/DEV-READINESS-REVIEW.md +++ b/docs/DEV-READINESS-REVIEW.md @@ -192,7 +192,17 @@ with 0-statement tolerance — my `make cycle` above passes the tightened gate. 9. **The contract tests share a fixed port.** Each `shim` fixture starts uvicorn on 8934 and never stops it; my run emits repeated `PytestUnhandledThreadExceptionWarning` (Thread-2…6, uvicorn startup `SystemExit: 3`) and still passes because an earlier server is listening. Parallel runs - or a busy port collide. + or a busy port collide. The `conformance` make target had the same class of defect and it bit + CI: it bound a fixed 8933 and cleaned up with `pkill -f "engine_shim --port 8933"`, which also + matched the recipe's own shell, so the run passed 2/0 while make reported "Terminated" and + exited 2 (CI run 40058979560). It now binds an ephemeral port and kills the shim by PID. +10. **This host runs a launchd-managed engine on the conformance port.** `launchctl list` shows + `com.themillertribe.corvus-v2-engine` (PID 66272, `-m corvus.engine_shim --port 8933 --host + 127.0.0.1`, cwd `/Users/tmiller/worktrees/corvus-canonical/corvus-v2`, python 3.15) holding + 127.0.0.1:8933. It restarts when killed (parent PID 1). A local `make conformance` against a + fixed 8933 was therefore testing THAT process, not this worktree's code — a green local result + that proved nothing. The ephemeral port fixes the harness; the agent itself is outside this + repo and was not touched. 10. **The deployed register load is inferred, not observed.** The mount is proven (hash match), and `engine_shim.py:66-80` is the path ladder, but I could not read the running process's loaded register: `kubectl exec` is blocked by the session's guardrails (a DDR is required for that