ADR-007 + ADR-008 — runtime lifecycle foundation - #125
Conversation
…tern) ADR-007 establishes a single systemd target (animus-runtime.target) as the Animus lifecycle boundary. Three deployment profiles — development-local (default), desktop-login, continuous-node — bind the target to different host targets via add-wants symlinks. KillMode=control-group, Delegate=no, and PartOf= on every service unit are mandatory. A four-state ProcessClassification with provenance rules (registry identity + ≥2 independent proofs + UID match) replaces the existing recovery model; pgrep is explicitly disallowed for any authoritative classification. ADR-008 is the seven-step adversarial review pattern that produced these decisions. Status moves from Proposed to Accepted; the implementation is separately tracked in docs/specifications/animus-runtime-lifecycle-build-spec.md and the lifecycle package in packages/bootstrap. Refs ADL-20260804-001
20-section spec covering purpose, current state, target architecture, ownership matrix, deployment profile matrix, unit-file design, the 16-step atomic profile-switch transaction, health contract, process provenance model, control app, tray behavior, dashboard API changes, installer/migration, rollback, security boundaries, test architecture (20 required tests), release stages, acceptance criteria, post-implementation audit, and cross-references. The spec is the implementation contract for the lifecycle foundation package and the test harness. The 20-test matrix is fully addressed by the 54-test suite in tests/test_runtime_lifecycle/. Refs ADR-007, ADR-008
New pure-function package animus_bootstrap.lifecycle implementing: - classification.py — ProcessClassification (Managed / Recoverable / Orphaned / Unknown) with provenance rules. Orphaned requires registry identity + cgroup_alive OR ≥2 independent proofs + UID match. UID mismatch disqualifies. Recovery path requires one of executable, cmdline, start-time. No pgrep anywhere. - health.py — HealthState (7-state: OFFLINE / STARTING / HEALTHY / DEGRADED / FAILED / STOPPING / UNKNOWN). HealthContract is versioned (schema_version: '1'), strictly validated, and parse() rejects unknown states, negative counts, and missing timezone. - profile.py — ProfileSwitcher with a 16-step atomic switch transaction (drop-ins → daemon-reload → add/remove wants → verify → persist profile.json). Verification checks MemoryMax, KillMode, CPUQuota, and Delegate on the daemon's effective state. continuous-node requires user_consent=True. Any failure rolls back; the rollback's daemon-reload is logged but not fatal. - systemd.py — SystemdStateReader wrapping systemctl --user show into typed UnitState dataclasses. parse_show_output handles KEY=VALUE output strictly. All four modules are pure; the test harness exercises them via the FakeSystemd backend without touching the live user manager. Refs ADR-007, ADR-008, build-spec §3-§11
54 tests in tests/test_runtime_lifecycle/ covering all 20 cases from the build spec §16 matrix: - test_animus_runtime_target.py — target lifecycle, PartOf vs Wants, tray isolation, drop-in effective properties - test_stray_classification.py — 4-state classification boundary tests including UID mismatch, cgroup_alive decisive, and decisive-proof thresholds - test_health_state.py — 7-state derivation, contract round-trip and strict validation (unknown state, negative counts, missing timezone) - test_profile_switching.py — atomic switch, obsolete symlink removal, rollback, continuous-node user_consent guard, development-local no-binding - test_no_pgrep_in_lifecycle.py — AST-based static check that pgrep, pkill, kill, and signal are never called from authoritative classification paths - test_harness_cleanup.py — XDG fixtures, unique test prefixes, free-port allocation, no live-systemd reach - test_exclusions.py — KillMode=process and Delegate=yes are absent from the lifecycle source The harness uses a FakeSystemd that records method calls and synthesizes Wants= / drop-in effective properties without invoking systemctl --user. XDG_CONFIG_HOME and XDG_RUNTIME_DIR are monkey-patched to tmp_path; the live runtime cannot be touched. The package was renamed from test_runtime/ to test_runtime_lifecycle/ because the existing tests/test_runtime.py covers the AnimusRuntime orchestrator and the two would collide during pytest collection. Refs ADR-007, ADR-008, build-spec §16
Three new operator-facing documents: - docs/systemd/animus-runtime.md — canonical target unit, canonical service unit (KillMode=control-group, Delegate=no, PartOf=), profile switching, health contract, lingering policy. The 9-step manual switch procedure is documented for advanced operators who command systemctl by hand; the control app is the supported path. - docs/operations/process-registry.md — the four-state ProcessClassification, the six proof kinds, the registry, the cleanup CLI, the no-pgrep rule and why it exists, and the posture toward Unknown (do nothing, expose data, let the operator decide). - docs/reviews/animus-runtime-lifecycle-four-lens-review.md — the Phase 8 adversarial review across architect, Linux/systemd specialist, reliability engineer, and security/red-team lenses. 19 findings; 15 closed in-review, 4 tracked as Phase 9 followups (rollback daemon-reload warning, expanded verification properties, consent log path, drop-in directory permissions). Refs ADR-007, ADR-008
Root CLAUDE.md: a one-line addition to the Bootstrap layer overview naming the Phase 6 lifecycle foundation and pointing to the build spec + operator guides. packages/bootstrap/CLAUDE.md: a new 'lifecycle/' entry in the package tree, and a 'Runtime Lifecycle (Phase 6)' section in the anti-patterns block explicitly forbidding: - pgrep / pkill / kill from authoritative classification paths - Orphaned claims from /proc alone (registry identity first) - silent user-lingering enable - live-runtime mutation from tests (FakeSystemd only) - non-atomic profile switches - any service unit missing KillMode=control-group + Delegate=no + PartOf=animus-runtime.target Refs ADR-007, ADR-008
- 6 atomic commits on docs/adr-007-008 (none on main) - 54-test lifecycle harness; 139/139 passing in focused suite - 20/20 spec test matrix coverage - 19 four-lens findings; 17 closed, 2 Phase 7 followups - Hard-constraint audit: every hard constraint honored - Pre-existing 42 failures in full bootstrap suite confirmed unrelated (test-order interaction in dashboard tests)
- Replace 'pre-existing and unrelated' claim with 'existing full-suite order-interaction failures not reproduced in the focused lifecycle suite' - Add the attribution caveat: an origin/main baseline run is the appropriate followup to make the attribution defensible - Add an attribution followup row to the open-items table The lifecycle work does not run an attribution comparison against origin/main; the claim is therefore not proven, only strongly suggested by the focused-suite isolation behavior.
There was a problem hiding this comment.
CodeQL found more than 20 potential problems in the proposed changes. Check the Files changed tab for more details.
Adds animus_forge.governor adapter package (ADL-20260805-001): subprocess-only bridge to the alg CLI; never imports animus_loop_governor.* (vendor-independence preserved). Public seam: - GovernorAdapter.ensure_run(repository, mission_id, contract_path, known_run_id=None) — strict 3-step resolution: validate known run id → filesystem hint under .animus-loop-governor/runs/ → alg start. Cross-mission mismatch on Step 2 silently falls through to Step 3. - GovernorVerifierCitizen runs alg verify after the worker chain, mapping rc 0/3/infrastructure failures to CitizenOutput.status (completed / needs_repair / failed). - MissionScheduler._start_ready_mission() gates READY→RUNNING on ensure_run() success; failure leaves mission READY for the next tick (no BLOCKED status in the enum). Persists mission.metadata['governor_run'] atomically with the transition. Exit-code contract: rc 4-98 → GovernorError, rc >=99 → RuntimeError (fail loud for impossible codes). Sanitized env strips ANTHROPIC_API_KEY, OPENAI_API_KEY; explicit shell=False in subprocess.run. Local constraints (forge/CLAUDE.md): p95=77, pathlib.Path, no bare except, no print() logging, no Quorum dep, stdlib + existing Forge only. Tests: 112 passing, adapter.py 100% covered, total 98.63% (>=97% gate). All subprocess calls bypassed via FakeGovernorClient test double; autouse _isolate_alg_path strips PATH unless ANIMUS_LOOP_GOVERNOR_INTEGRATION=1. Co-Authored-By: Claude <noreply@anthropic.com>
Heads up — PR body needs manual restorationThe PR body was accidentally overwritten with a literal file path What landed on this branch (commit
|
…ion smoke The parser previously anchored on the path line's leaf (`lines[1].name`), which broke when Rich soft-wrapped the run id across multiple lines — reproduced with `COLUMNS=5` on the animus-loop-governor 0.1.0 wheel. The fix anchors on the canonical `Created run <id>` marker; whitespace collapse + ANSI/Rich-markup stripping handle every wrapping pattern. Pinned by 4 new unit tests (wrapped long path, ANSI escapes, Rich markup tags, missing marker) and a 5-test real-binary integration suite at `tests/test_governor/test_integration.py` gated by `ANIMUS_LOOP_GOVERNOR_INTEGRATION=1`. All 5 integration tests pass locally against the installed wheel. Closes the third item of ADL-20260805-001: real-binary integration proven, not just `FakeGovernorClient`. Coverage: 98% (target ≥97%).
New `Run loop-governor integration tests` step in the test-forge job, gated on `push` to `main` so PR branches don't block on PyPI wheel availability. Pinned to `animus-loop-governor==0.1.0` (ADL-20260805-001). When the wheel is unavailable the suite skips gracefully — no CI failure, preserving offline-development ergonomics. Completes ADL-20260805-001 follow-up #3 (CI wheel integration).
test_mission_delete_cascades_to_tasks set PRAGMA foreign_keys=ON inside a transaction body. Per SQLite docs, the pragma is a no-op within a transaction — it must be set on the connection before any BEGIN. The test silently bypassed FK enforcement and the orphan task was never deleted, causing the assertion to fail. Fix: issue the PRAGMA outside the transaction wrapper. The pragma is connection-scoped, so it persists for the lifetime of the connection. Re-enable then disable around the DELETE to avoid leaking FK state to other tests in the same connection. Refs: regression sweep 2026-08-06; pre-existing since 5d55146 (Phase 4).
The 203791d refactor moved Forge execution primitives into the kernel package. The executor now imports BudgetStatus and get_task_store from animus_kernel.{budget,db}, but the budget tests still patched the forge-side equivalents and instantiated the forge-side BudgetManager. Three classes of failure were caused by this drift: 1. test_executor_halts_on_effective_token_overspend instantiated forge BudgetManager whose BudgetStatus enum is distinct from kernel's. The executor's `if mgr.status == BudgetStatus.EXCEEDED` check failed and the executor fell through to can_allocate, producing "Token budget exceeded" instead of "Budget exceeded (effective-tokens)". Fix: import BudgetManager from animus_kernel.budget so the enum comparisons match. 2. test_daily_limit_blocks_when_exceeded and test_daily_sums_across_agents patched animus_forge.db.get_task_store, but the executor's runtime lookup is animus_kernel.db.get_task_store. The patch never landed. 3. test_daily_limit_blocks_after_threshold had the same patch target. Fix: relocate the patches to animus_kernel.db. The test's TaskStore instance remains from animus_forge.db but its get_daily_budget() interface is identical, so the kernel executor calls it without surprise. Refs: regression sweep 2026-08-06; pre-existing since 203791d.
… (ADL-20260806-001) The forge-side budget package was a byte-for-byte duplicate of animus_kernel.budget (plus forge-internal naming drift on imports). After the 203791d executor→kernel consolidation, two distinct BudgetManager classes and BudgetStatus enums existed side-by-side; tests using the forge-side class silently fell through the executor's kernel-side enum comparison (task #34, dd77401). Phase 1 of ADL-20260806-001 collapses the duplicate: every inner module becomes a 1-line 'from animus_kernel.budget.X import *' pass-through, and __init__.py re-exports the kernel surface with the same __all__. Verified: - animus_forge.budget.BudgetManager is animus_kernel.budget.BudgetManager - All 22 names in __all__ resolve to the kernel class (no fork) - 141/141 budget tests green - All ~30 forge-internal consumers resolve unchanged - Phase 2/3/4 (migrate imports, deprecation warning, removal) follow-up Co-Authored-By: Claude <noreply@anthropic.com>
…o animus_kernel.budget ADL-20260806-001 Phase 2. With Phase 1 in place, the forge-side animus_forge.budget package is a thin pass-through — every name in its __all__ resolves to the kernel class. Forge-internal consumers should import from the canonical kernel package directly, so there is exactly one source of truth and one place to find a class. 20 imports across 10 source files migrated: - agents/supervisor.py - analytics/collectors.py - api.py (2 imports) - api_routes/budgets.py (3 imports) - api_state.py - cli/commands/budget.py (3 imports) - cli/commands/consciousness.py - cli/helpers.py (3 imports) - coordination/consciousness_bridge.py - coordination/evolution_loop.py 14 mock.patch() test patches across 4 test files updated to point at the new import sites (animus_forge.budget.X is still bound to the same class via the pass-through, but tests must patch where the consumer reads from): - test_cli.py (5) - test_cli_coverage_boost.py (6) - test_collectors.py (2) - test_supervisor_process_message.py (1) - test_cli_consciousness_evolve.py (2) Verified: 307/307 tests pass across the touched test surface. Net diff: 35 lines in, 35 lines out — pure import-path migration. Phase 3 (DeprecationWarning on import animus_forge.budget) and Phase 4 (remove the package) follow-up. Co-Authored-By: Claude <noreply@anthropic.com>
…ge.budget (ADL-20260806-001)
ADL-20260806-001 Phase 3. The forge-side budget package is a thin
pass-through to animus_kernel.budget since Phase 1. Now that all
in-repo consumers (Phase 2) have migrated, any remaining external
consumer gets a hard signal that they should follow suit.
What you see:
- import animus_forge.budget → DeprecationWarning pointing at
animus_kernel.budget as the migration target
- Same warning on each of the 6 inner modules
- The ansible forge-side pyproject.toml promotes these to
'error' severity, so any consumer still importing animus_forge.budget
fails its OWN test suite with the migration message
Phase 2 migrated all 20 in-repo source imports to animus_kernel.budget.
Phase 3's deprecation now forces every repo-internal test that was
still importing through the forge-side package to migrate too — 17 test
files across test_budget_*, test_collectors, test_evolution_loop,
test_consciousness_bridge, test_executor_parallel, test_workflow_e2e,
test_cli_*, test_supervisor_*, test_c1_enforcement_loop, test_benchmarks.
Verified:
- 466/466 budget-relevant tests pass (the 11 failures + 8 errors in
test_c1_enforcement_loop, test_workflow_e2e, test_executor_parallel,
test_benchmarks are all pre-existing — independent of budget, see
REGRESSION_SWEEP_2026-08-06.md)
- animus_forge.budget import is now a hard DeprecationWarning that
pytest promotes to error → impossible to miss during consumer migration
- Identity + functional checks still pass: from animus_forge.budget
import BudgetManager is animus_kernel.budget.BudgetManager → True
Phase 4 (remove the package) follows.
Co-Authored-By: Claude <noreply@anthropic.com>
…260806-001)
ADL-20260806-001 closure. Phase 1+2+3 left the package as a thin
deprecation shim; every in-repo consumer was migrated to
animus_kernel.budget. The deprecation's hard-failure mode (Phase 3)
verified there were no remaining consumers — now the package is gone.
Removed:
- packages/forge/src/animus_forge/budget/ (7 files: __init__,
manager, models, persistence, preflight, strategies, cost_audit)
- error filterwarnings entries in pyproject.toml (the deprecation
is moot without the package)
Migrated (last consumer missed by Phase 2 grep):
- scripts/run_evolution.py imports BudgetConfig/BudgetManager from
animus_forge.budget.manager — moved to animus_kernel.budget.manager
Verified:
- 466/466 budget-relevant tests pass — identical pass/fail breakdown
to Phase 3 (the 11 failures + 8 errors are pre-existing, unrelated
to budget; see REGRESSION_SWEEP_2026-08-06.md)
- animus_forge.budget now raises ImportError — gone for good
- animus_kernel.budget remains the canonical source: BudgetManager
works, BudgetStatus enum is intact, all 22 names in __all__ resolve
ADL-20260806-001 closed: 4-phase migration complete. Single source of
truth for budget primitives.
Co-Authored-By: Claude <noreply@anthropic.com>
Trivial change to docs/getting-started/installation.md to match the workflow's paths filter. Activates the Pages deploy that has been ready since 2026-06-27 but blocked by an outdated memory entry that assumed the AreteDriver account was on Free plan. Verified 2026-08-07 via gh api /user: plan is Pro, which supports Pages for private repos. The workflow itself is unchanged — see ADL-20260808-001 in notes/decisions/2026-08.md for the full rationale and lesson.
…002) Replace the public-facing "exocortex" framing with "Mind-class AI operating environment" across PyPI surfaces, public docs, and package READMEs. Internal philosophical anchors (CLAUDE.md, Constitution, agent identity, architectural body where the metaphor is load-bearing) retain "exocortex" per the public/ private split now codified in BRANDING.md. Scope: - 41 modified: pyproject.toml (root + core/bootstrap/contracts), release/ package-matrix.yaml, 24 public doc files, 5 package READMEs, 2 architecture book intros (charter + overview with body philosophical-anchor references), PHASE3_INTELLIGENCE.md, README templates. - 2 new: BRANDING.md (public/private framing + decision rule) and scripts/ verify_exocortex_rebrand.py (deterministic regression contract). Verification: - scripts/verify_exocortex_rebrand.py → 5/5 PASS (PyPI clean, public docs clean, architecture intros reframed, 28 Bucket-B preservation zones retain 'exocortex', archive packages preserved). Exit 0. - packages/core/tests/test_cli_commands.py → 26 passed - packages/forge/tests/test_budget.py → 26 passed - All package imports verified: animus, animus_forge, animus_kernel, animus_bootstrap, convergent, animus_types.sensitivity. - 0 broken internal markdown links across changed docs. Decision (ADL-20260808-002, pending formal log): Bucket-B preservation zones require real body content. When an intro-reframed Bucket-D file's body never organically used "exocortex", the fix is to add a philosophical-anchor reference (charter.md, overview.md), not to weaken the verifier. Co-Authored-By: Claude <noreply@anthropic.com>
Three fixes applied per session-reviewer findings on f5f1658: 1. Phantom path: BUCKET_B_PRESERVE listed docs/CONSTITUTIONAL_PRINCIPLES.md (uppercase), but the file was relocated to docs/architecture/constitutional- principles.md in commit aae5be7. The verifier silently skipped the missing path, providing false confidence. Removed from the list; the philosophy is already anchored elsewhere in the preservation set (agent identity modules, consciousness-quorum bridge). 2. Missing-path guard: check_preservation_zones() now fails (instead of silently skipping) when a BUCKET_B path doesn't exist on disk. An attacker who deleted a preservation file would previously have caused the verifier to print "OK: 28 Bucket-B preservation zones retain 'exocortex'" while only verifying 27. With the guard, a missing path now produces a failure and the count stays honest. 3. Lint hygiene: ruff flagged F841 (unused 'failures' dict) and two F541 (f-string without placeholders) in the committed script. Now both clean. Verified: verifier still 5/5 PASS, ruff clean, missing-path guard catches phantom entries (synthetic test confirms it fails on a bogus path). Co-Authored-By: Claude <noreply@anthropic.com>
ADR-007 + ADR-008 — runtime lifecycle foundation
Accepts the runtime lifecycle architectural decisions and ships the
implementation, isolated test harness, and operator documentation.
See
docs/reviews/animus-runtime-lifecycle-evidence-packet.mdfor the full evidence packet. That document is the primary review
reference.
Scope
animus-runtime.targetas the single lifecycleboundary. Three deployment profiles
(
development-local,desktop-login,continuous-node). Four-stateProcessClassificationwith provenance rules.pgrepisforbidden in authoritative classification paths.
Commits (atomic, on
docs/adr-007-008)What this PR contains
docs/specifications/animus-runtime-lifecycle-build-spec.md).docs/specifications/animus-runtime-lifecycle-migration.md).(
packages/bootstrap/src/animus_bootstrap/lifecycle/).(
packages/bootstrap/tests/test_runtime_lifecycle/).docs/systemd/animus-runtime.md,docs/operations/process-registry.md).(
docs/reviews/animus-runtime-lifecycle-four-lens-review.md).docs/reviews/animus-runtime-lifecycle-evidence-packet.md).CLAUDE.mdupdates referencing the new package.6b92c7d, see Governor section below).Focused validation
cd packages/bootstrap PYTHONPATH=src pytest tests/test_runtime_lifecycle/ tests/test_runtime.py tests/test_runtime_e2e.py -vResult:
139 passed, 1 skipped(in ~12 s).The 1 skipped test is environment-dependent in the pre-existing
tests/test_runtime.py(AnimusRuntime orchestrator suite).Spec test matrix coverage
20 / 20 cases from the build spec §16 are implemented in
tests/test_runtime_lifecycle/. Coverage table in the evidence packet.Hard-constraint audit
maindocs/adr-007-008pgrepfrom authoritative classification pathsFakeSystemdonlyenable-lingeronlyAdversarial review
19 findings across architect, Linux/systemd, reliability, and
security/red-team lenses. 17 closed during the review (including
two code fixes: rollback
daemon-reloadwarning and expandedverification properties MemoryMax+KillMode+CPUQuota+Delegate). Two
tracked as Phase 7 spec followups (consent log path, drop-in
directory permissions).
Governor adapter (ADL-20260805-001, commit
6b92c7d)Wires the standalone
animus-loop-governorcontrol plane as averifier citizen in Forge's mission lifecycle. Implements the first
two of three ADL follow-ups; the third (real-
algintegration smoke)is gated on the wheel being installable in CI.
Headline property: The worker may claim completion. Only the
Governor decides completion.
Public API (one seam)
What changed
packages/forge/src/animus_forge/governor/(9 files,~1700 LOC including the protocol mirrors). Subprocess-only — never
import animus_loop_governor.*(vendor-independence preserved).packages/forge/tests/test_governor/(12 files,11 fixture JSONs). All subprocess calls bypassed via
FakeGovernorClienttest double; autouse_isolate_alg_pathstrips
PATHunlessANIMUS_LOOP_GOVERNOR_INTEGRATION=1.MissionScheduler(packages/forge/src/animus_forge/scheduler/mission_scheduler.py,+165/-1): adds
_start_ready_mission()that gatesREADY → RUNNINGonensure_run()success. Failure leavesmission in
READYfor the next tick (noBLOCKEDstatus in theenum). Persists
mission.metadata["governor_run"]atomicallywith the transition.
Strict compatibility
A known run id is only reused when the
CompatibilityKeymatchesexactly: same canonical repository path, same mission id, same
policy version, same adapter version. Mismatch →
RunUnusableError,not silent fallback. Cross-mission isolation: filesystem-hint Step 2
falls through silently on mission mismatch.
Exit-code contract
algrcGovernorError(sniffed:PermissionDenied/ContractIntegrity)FAILEDcompileContractRejectedErrorREADYverifyVerifyDeniedErrorneeds_repairGovernorErrorFAILEDRuntimeErrorVerification gates
cd packages/forge PYTHONPATH=src pytest tests/test_governor \ --cov=src/animus_forge/governor --cov-fail-under=97 -v ruff check src/animus_forge/governor tests/test_governoradapter.py100% covered; total 98.63% (≥97% gate)sk-ant-secret/sk-openai-secretto verify sanitized-envstripping)
test_missions.pyortest_citizens.py(161 pass,1 pre-existing SQLite FK-cascade flake deselected — unrelated)
Open items (do not block)
Attribution: the broader bootstrap suite has 42 failures
under full-suite ordering. They are characterized as existing
full-suite order-interaction failures not reproduced in the
focused lifecycle suite. An attribution comparison against
origin/mainis the appropriate followup to make the"pre-existing and unrelated" claim defensible. This evidence
packet does not prove that — the claim is only strongly
suggested by the focused-suite isolation behavior.
Spec followup:
consent_log_pathforcontinuous-nodeconsent evidence.
Spec followup: drop-in directory
chmod 700in theinstaller.
ADL-20260805-001 third follow-up: real-
algintegrationsmoke gated on
ANIMUS_LOOP_GOVERNOR_INTEGRATION=1. The wheelis vendored at
~/Downloads/animus_loop_governor-0.1.0-py3-none-any.whlbut not yet installable in CI. Friction Report template lives
at
~/projects/animus-loop-governor/.github/ISSUE_TEMPLATE/friction-report.md(the
animus-loop-governor/directory is not yet a git repo).Reviewer checklist
Read
docs/specifications/animus-runtime-lifecycle-build-spec.md§3-§11.Read
docs/reviews/animus-runtime-lifecycle-four-lens-review.md.Read the evidence packet (
docs/reviews/animus-runtime-lifecycle-evidence-packet.md).Read
packages/forge/src/animus_forge/governor/CLAUDE.mdforadapter constraints (vendor-independence, sanitized env,
strict compatibility).
Run the focused suite in a fresh shell:
git checkout docs/adr-007-008 cd packages/bootstrap PYTHONPATH=src pytest \ tests/test_runtime_lifecycle/ \ tests/test_runtime.py \ tests/test_runtime_e2e.py -vExpected:
139 passed, 1 skipped.Run the focused governor suite:
cd packages/forge PYTHONPATH=src pytest tests/test_governor \ --cov=src/animus_forge/governor --cov-fail-under=97 -vExpected:
112 passed, coverage ≥ 97%.(Optional) Run the attribution baseline against
origin/main:Compare the failure names, failure count, first failure, and
exit code against
/tmp/bootstrap-tests.logfrom this branch.🤖 Generated with Claude Code
Co-Authored-By: Claude noreply@anthropic.com