Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
68ba265
docs(adr): accept ADR-007 (runtime lifecycle) and ADR-008 (review pat…
AreteDriver Aug 4, 2026
ad2d7fd
docs(spec): runtime lifecycle build specification
AreteDriver Aug 4, 2026
f34e5a1
feat(bootstrap): runtime lifecycle foundation (ADR-007, ADR-008)
AreteDriver Aug 4, 2026
b2110b0
test(bootstrap): isolated runtime lifecycle test harness
AreteDriver Aug 4, 2026
c84fcc4
docs(animus): operator guides and four-lens review
AreteDriver Aug 4, 2026
05d64fd
docs(claude): reference the new lifecycle package
AreteDriver Aug 4, 2026
552587e
docs: Phase 9 evidence packet
AreteDriver Aug 4, 2026
e0715ed
docs(evidence): tighten full-suite failure attribution language
AreteDriver Aug 4, 2026
6b92c7d
feat(governor): wire animus-loop-governor as Forge verifier citizen
AreteDriver Aug 6, 2026
53ac7d4
fix(governor): anchor _parse_run_id on canonical marker; add integrat…
AreteDriver Aug 6, 2026
e075742
ci(forge): run loop-governor integration tests on main
AreteDriver Aug 6, 2026
ad2e8c7
fix(test): enable FK enforcement outside transaction in cascade test
AreteDriver Aug 6, 2026
dd77401
fix(test): align budget tests with kernel/forge split
AreteDriver Aug 6, 2026
9a8465a
refactor(forge/budget): Phase 1 — re-export from animus_kernel.budget…
AreteDriver Aug 6, 2026
15ef659
refactor(forge): Phase 2 — migrate 20 forge-internal budget imports t…
AreteDriver Aug 7, 2026
cf06940
feat(forge/budget): Phase 3 — DeprecationWarning on import animus_for…
AreteDriver Aug 7, 2026
3ff70a8
refactor(forge): Phase 4 — remove animus_forge.budget package (ADL-20…
AreteDriver Aug 7, 2026
2c660d3
docs: trigger docs-deploy.yml (ADL-20260808-001 MkDocs Pages activation)
AreteDriver Aug 8, 2026
f5f1658
docs: complete exocortex→operating-environment rebrand (ADL-20260808-…
AreteDriver Aug 8, 2026
9b3d802
fix(verifier): remove phantom BUCKET_B path; add missing-path guard
AreteDriver Aug 8, 2026
09ce9a3
fix(ci): restore truthful gates and repair runner setup
AreteDriver Aug 18, 2026
5056478
fix(ci): repair merge-sensitive and PWA gates
AreteDriver Aug 18, 2026
a703f79
Merge commit '4d49c630cc8b4c1c27e905c7a1bb2ee14a14c53d' into docs/adr…
AreteDriver Aug 18, 2026
044668e
style: align merged security changes with hooks
AreteDriver Aug 18, 2026
c2bd6f7
fix(ci): make package gates reproducible
AreteDriver Aug 18, 2026
a7ac19b
fix(ci): repair remaining reproducibility gates
AreteDriver Aug 18, 2026
c7cba25
fix(ci): align runtime contracts with executable gates
AreteDriver Aug 18, 2026
1cf2fb7
fix(ci): isolate kernel test environment
AreteDriver Aug 18, 2026
e588689
fix(review): address CodeQL lifecycle findings
AreteDriver Aug 18, 2026
fd3eb76
fix(ci): isolate model tests and ratchet coverage
AreteDriver Aug 18, 2026
b577976
fix(ci): remove suite-wide GC tax and isolate optional tests
AreteDriver Aug 18, 2026
c4b2868
fix(ci): parallelize forge suite by test file
AreteDriver Aug 18, 2026
140993d
fix(ci): rebalance forge workers dynamically
AreteDriver Aug 18, 2026
7e5cf1b
fix(forge): close container boundaries and stop scheduler hangs
AreteDriver Aug 18, 2026
5194990
fix(ci): bound Forge baseline debt and preserve coverage
AreteDriver Aug 18, 2026
953f942
fix(tests): restore Anthropic module after missing-SDK simulation
AreteDriver Aug 18, 2026
e28e409
fix(tests): isolate Anthropic optional-dependency seams
AreteDriver Aug 18, 2026
5965a6f
fix(review): align container test-double signatures
AreteDriver Aug 18, 2026
3b01eee
fix(ci): ledger dashboard persistence flakes
AreteDriver Aug 18, 2026
4169c00
docs: refine runtime lifecycle evidence packet
AreteDriver Sep 4, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
136 changes: 77 additions & 59 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ jobs:
with:
python-version: "3.12"

- name: Install version-check dependencies
run: python -m pip install packaging==25.0

- name: Check version alignment
run: python3 scripts/check_version_alignment.py

Expand Down Expand Up @@ -77,16 +80,15 @@ jobs:
run: pip install ruff

- name: Lint all packages
run: ruff check packages/ --exclude packages/_archive/

- name: Format check
run: ruff format --check packages/ --exclude packages/_archive/
run: python scripts/ruff-ratchet.py

pre-commit:
name: Pre-commit Hooks
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
fetch-depth: 0

- name: Set up Python
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v6
Expand All @@ -104,7 +106,13 @@ jobs:
run: pip install pre-commit

- name: Run pre-commit
run: pre-commit run --all-files --show-diff-on-failure
env:
PRE_COMMIT_FROM_REF: ${{ github.event.pull_request.base.sha || github.event.before }}
run: |
if [ -z "$PRE_COMMIT_FROM_REF" ] || [ "$PRE_COMMIT_FROM_REF" = "0000000000000000000000000000000000000000" ]; then
PRE_COMMIT_FROM_REF="$(git rev-parse HEAD^)"
fi
pre-commit run --from-ref "$PRE_COMMIT_FROM_REF" --to-ref HEAD --show-diff-on-failure

schema-validate:
name: Schema Validation Gate
Expand Down Expand Up @@ -150,6 +158,7 @@ jobs:
type-check:
name: Type Check (mypy)
runs-on: ubuntu-latest
timeout-minutes: 20
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0

Expand All @@ -173,39 +182,7 @@ jobs:
pip install -e "packages/core/[dev]"
pip install -e "packages/forge/[dev]"
pip install -e "packages/bootstrap/[dev]"
pip install mypy

- name: Run mypy on core
run: |
mypy packages/core/animus/ \
--ignore-missing-imports \
--warn-return-any \
--warn-unused-configs \
--pretty

- name: Run mypy on kernel
run: |
mypy packages/kernel/src/animus_kernel/ \
--ignore-missing-imports \
--warn-return-any \
--warn-unused-configs \
--pretty

- name: Run mypy on forge
run: |
mypy packages/forge/src/animus_forge/ \
--ignore-missing-imports \
--warn-return-any \
--warn-unused-configs \
--pretty

- name: Run mypy on bootstrap
run: |
mypy packages/bootstrap/src/animus_bootstrap/ \
--ignore-missing-imports \
--warn-return-any \
--warn-unused-configs \
--pretty
pip install mypy==1.18.2

- name: Mypy ratchet
run: python3 scripts/mypy-ratchet.py core kernel forge bootstrap
Expand All @@ -225,6 +202,7 @@ jobs:
test-kernel:
name: Test Kernel (Python ${{ matrix.python-version }})
runs-on: ubuntu-latest
timeout-minutes: 20
strategy:
fail-fast: false
matrix:
Expand All @@ -245,13 +223,16 @@ jobs:
restore-keys: ${{ runner.os }}-pip-kernel-${{ matrix.python-version }}-

- name: Install dependencies
run: pip install -e packages/types/ -e "packages/kernel/[dev]"
run: |
pip install -e packages/types/ -e "packages/kernel/[dev]"
pip install --no-deps -e packages/core/
pip install fastapi cryptography

- name: Test with coverage
run: pytest packages/kernel/tests/ -v --tb=short --cov=animus_kernel --cov-report=term-missing --cov-report=xml

- name: Upload coverage to Codecov
uses: codecov/codecov-action@ad3126e4f63f4c42e9f548cce398fb82e6d4c260 # v5.5.1
uses: codecov/codecov-action@5a1091511ad55cbe89839c7260b706298ca349f7 # v5.5.1
with:
files: ./coverage.xml
fail_ci_if_error: false
Expand All @@ -263,6 +244,7 @@ jobs:
test-core:
name: Test Core (Python ${{ matrix.python-version }})
runs-on: ubuntu-latest
timeout-minutes: 20
strategy:
fail-fast: false
matrix:
Expand All @@ -286,10 +268,13 @@ jobs:
# animus-types is a sibling pip-installable package and is not
# published to PyPI — pip resolves it from the local path when
# both -e targets are part of the same install transaction.
run: pip install -e packages/types/ -e "packages/core/[dev,api]"
run: |
pip install -e packages/types/ -e "packages/kernel/[dev]"
pip install -e "packages/core/[dev,api,postgres,mcp]"

- name: Test with coverage
run: pytest packages/core/tests/ -v --tb=short --cov=animus --cov-report=term-missing
working-directory: packages/core
run: pytest tests/ --cov=animus --cov-report=term-missing
env:
ANIMUS_SKIP_INTEGRATION_TESTS: "1"

Expand Down Expand Up @@ -321,10 +306,12 @@ jobs:
run: python -c "from animus_quorum._core import IntentGraph; from animus_quorum.rust_backend import HAS_RUST; assert HAS_RUST"

- name: Native backend tests
run: pytest packages/quorum/tests/test_rust_backend.py -q --tb=short
working-directory: packages/quorum
run: pytest tests/test_rust_backend.py -q --tb=short

- name: Test with coverage
run: PYTHONPATH=packages/quorum/python pytest packages/quorum/tests/ -v --tb=short
working-directory: packages/quorum
run: PYTHONPATH=python pytest tests/ -v --tb=short

test-types:
name: Test Types
Expand Down Expand Up @@ -365,18 +352,19 @@ jobs:
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v5
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip-contracts-${{ hashFiles('packages/contracts/pyproject.toml') }}
key: ${{ runner.os }}-pip-contracts-${{ hashFiles('packages/types/pyproject.toml', 'packages/contracts/pyproject.toml') }}
restore-keys: ${{ runner.os }}-pip-contracts-

- name: Install dependencies
run: pip install -e "packages/contracts/[dev]"
run: pip install -e "packages/types/[dev]" -e packages/contracts/

- name: Test with coverage
run: pytest packages/contracts/tests/ -v --tb=short --cov=animus_contracts --cov-report=term-missing

test-forge:
name: Test Forge
runs-on: ubuntu-latest
timeout-minutes: 45
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0

Expand Down Expand Up @@ -408,11 +396,33 @@ jobs:
# real network calls.
OPENAI_API_KEY: "sk-dummy-ci-no-network-calls"
ANTHROPIC_API_KEY: "sk-dummy-ci-no-network-calls"
run: pytest tests/ -v --tb=short --cov=animus_forge --cov-report=term-missing
ANIMUS_FORGE_BASELINE_QUARANTINE: "1"
# Internal coverage-push ratchets are development artifacts rather than
# the production regression suite (see the repository test breakdown).
# Keep each file on one worker: several legacy modules share test-local
# compatibility state and are not safe to split with work stealing.
run: pytest tests/ --ignore=tests/_internal_ratchets -n 2 --dist loadfile -v --tb=short --cov=animus_forge --cov-report=term-missing

- name: Run loop-governor integration tests
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
working-directory: packages/forge
env:
ANIMUS_LOOP_GOVERNOR_INTEGRATION: "1"
run: |
# The integration suite shells out to a real ``alg`` binary.
# Install the wheel from the Artifacts / a pinned release URL.
# Pin to 0.1.0 (ADL-20260805-001) to avoid drift.
pip install \
"animus-loop-governor==0.1.0" \
--index-url https://pypi.org/simple/ \
|| echo "::warning::animus-loop-governor 0.1.0 not on PyPI; integration suite skipped"
which alg || echo "alg not installed; integration tests will skip"
pytest tests/test_governor/test_integration.py -v --tb=short

test-bootstrap:
name: Test Bootstrap (Python ${{ matrix.python-version }})
runs-on: ubuntu-latest
timeout-minutes: 20
strategy:
fail-fast: false
matrix:
Expand All @@ -433,23 +443,24 @@ jobs:
restore-keys: ${{ runner.os }}-pip-bootstrap-${{ matrix.python-version }}-

- name: Install dependencies
run: pip install -e "packages/bootstrap/[dev]"
run: pip install -e "packages/bootstrap/[dev,push]"

- name: Test with coverage
run: pytest packages/bootstrap/tests/ -v --tb=short --cov=animus_bootstrap --cov-report=term-missing
working-directory: packages/bootstrap
run: pytest tests/ -v --tb=short --cov=animus_bootstrap --cov-report=term-missing
env:
PYTHONPATH: packages/bootstrap/src

test-database:
name: Test Database (PostgreSQL ${ matrix.postgres-version })
name: Test Database (PostgreSQL ${{ matrix.postgres-version }})
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
postgres-version: ["14", "15", "16"]
services:
postgres:
image: postgres:${ matrix.postgres-version }
image: postgres:${{ matrix.postgres-version }}
env:
POSTGRES_PASSWORD: testpass
POSTGRES_DB: animus_test
Expand Down Expand Up @@ -489,7 +500,7 @@ jobs:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0

- name: Set up Node.js
uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673c0b81f2ad1477f6a8 # v4
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with:
node-version: "20"

Expand Down Expand Up @@ -522,29 +533,36 @@ jobs:
- name: Install dependencies
run: |
pip install -e packages/types/
pip install -e "packages/quorum/[dev]"
pip install -e "packages/kernel/[dev]"
pip install -e "packages/core/[dev,api,postgres,mcp]"
pip install -e "packages/contracts/[dev]"
pip install -e "packages/forge/[dev]"
pip install -e "packages/bootstrap/[dev]"

- name: Run integration tests
run: pytest tests/integration/ -v --tb=short

docker:
name: Docker Build (Kernel)
runs-on: ubuntu-latest
timeout-minutes: 20
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0

- name: Set up QEMU
uses: docker/setup-qemu-action@8b30df9d033bf30582b8504e1f5c1275d3b41d61 # v3.3.0
uses: docker/setup-qemu-action@53851d14592bedcffcf25ea515637cff71ef929a # v3.3.0

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@988b5a0280414a5210132054a6c801aca2759e3d # v3.6.1
uses: docker/setup-buildx-action@988b5a0280414f521da01fcc63a27aeeb4b104db # v3.6.1

- name: Build multi-arch kernel image
uses: docker/build-push-action@4f58f7924f5cfc5316c7fba6f4e67c4d484fbc37 # v6.9.0
- name: Build kernel image
uses: docker/build-push-action@4f58ea79222b3b9dc2c8bbdd6debcef730109a75 # v6.9.0
with:
context: packages/kernel
platforms: linux/amd64,linux/arm64
context: .
file: packages/kernel/Dockerfile
platforms: linux/amd64
load: true
push: false
tags: animus-kernel:ci
cache-from: type=gha
Expand All @@ -554,7 +572,7 @@ jobs:
run: docker run --rm --platform linux/amd64 animus-kernel:ci python -c "import animus_kernel; print('OK amd64')"

- name: Test CLI inside container (amd64)
run: docker run --rm --platform linux/amd64 animus-kernel:ci python -m animus_kernel --help
run: docker run --rm --platform linux/amd64 animus-kernel:ci animus-kernel --help

sbom:
name: Generate SBOMs
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ coverage.json
*.py,cover
.hypothesis/
.pytest_cache/
mypy-report.txt

# Virtual environments
venv/
Expand Down Expand Up @@ -103,6 +104,7 @@ packages/forge/src/animus_forge/workflows/no-op-*.json
# Node
node_modules/
package-lock.json
!packages/pwa/package-lock.json
packages/forge/forge/forge_audit.jsonl
.claude/

Expand Down
65 changes: 65 additions & 0 deletions BRANDING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# Animus Branding

> The public face and the internal anchor, named together.

---

## Public-facing framing

Animus is positioned externally as a **Mind-class AI operating environment** — a persistent, sovereign personal intelligence layer you own. The phrase "operating environment" grounds the project in conventional engineering language (an execution substrate, not a personhood claim) and avoids the cognitive-symmetry metaphor that "exocortex" carries.

Public surfaces — PyPI descriptions, README, docs site, marketing copy — use "operating environment" and related engineering terms (memory, orchestration, governance, evidence). This is the canonical external surface.

## Internal philosophical anchor

Internally, the agent's self-model and constitutional principles are anchored in the philosophical framing of an **exocortex** — an external cognitive system that augments biological intelligence via persistent memory, task tracking, and preference learning across sessions and devices.

This philosophical anchor informs:
- Agent identity files (e.g., `packages/core/animus/identity.py`)
- Internal code self-references (e.g., `BRANDING.md`, `CLAUDE.md`, constitutional principles)
- Architectural body text where the philosophical metaphor is load-bearing
- The Constitution (`docs/CONSTITUTIONAL_PRINCIPLES.md`)

The split is intentional. The public surface optimizes for credibility and adoptability; the internal anchor preserves the philosophical content that shaped the project's design choices.

## Why both terms exist

| Surface | Term | Rationale |
|---|---|---|
| PyPI / marketing | AI operating environment | Engineering clarity, no personhood claim |
| User-facing docs | operating environment | Consistent with positioning |
| README, docs site | Mind-class AI operating environment | Trademark-class positioning |
| Agent identity | exocortex | Philosophical anchor for self-model |
| Constitutional principles | exocortex | Philosophical anchor for design rationale |
| Internal architecture body | exocortex | Where the metaphor carries the argument |

## Decision rule

When adding or changing content, ask:

1. **Is this user-facing?** Use "operating environment" or related engineering language.
2. **Is this an internal philosophical / constitutional / identity anchor?** Use "exocortex" and preserve the metaphor.
3. **Is this a stable technical identifier** (package name, import path, ADL/ADR title)? Do not rename — it is owner-specific and out of scope for branding changes.

When in doubt, default to the public surface. The internal anchor is preserved deliberately in the files where the philosophy is load-bearing.

## Verification

The rebrand contract is enforced by `scripts/verify_exocortex_rebrand.py`:

- **PyPI surfaces** must not contain "exocortex"
- **Public docs** must not contain "exocortex"
- **Architecture book intros** (first 5 lines) must use engineering framing
- **Internal philosophical-anchor files** (CLAUDE.md, Constitution, agent identity, etc.) MUST retain "exocortex"
- **Archive packages** keep their own branding

Run the verifier after any branding change:

```bash
python3 scripts/verify_exocortex_rebrand.py
```

## History

- 2026-08-08: BRANDING.md created during exocortex-sweep rebrand (ADL pending).
- Pre-2026-08-08: "exocortex" was used in both public and internal surfaces without explicit public/private split.
2 changes: 2 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,8 @@ python scripts/mypy-ratchet.py --init

**Bootstrap** (`packages/bootstrap/src/animus_bootstrap/`) — Install daemon, onboarding wizard, local dashboard, message gateway, intelligence layer, and persona system. Phase 1: one-command install, Rich-based setup wizard (8 steps), HTMX dashboard at localhost:7700, systemd/launchd service management, auto-updater. Phase 2: message gateway with 8 channel adapters (Telegram, Discord, Slack, Matrix, WhatsApp, Signal, Email, WebChat), cross-channel sessions, cognitive backends (Anthropic/Ollama/Forge), middleware (auth/ratelimit/logging). Phase 3: intelligence layer with memory integration (SQLite FTS5 + ChromaDB/Animus stubs), tool executor (8 built-in tools + MCP bridge + permission system), proactive engine (scheduler, quiet hours, 3 built-in checks), automation pipeline (triggers/conditions/actions with SQLite persistence), IntelligentRouter (memory-enriched + tool loop), intelligence dashboard (/tools, /automations, /activity). Phase 4: persona & voice layer with PersonaEngine (registry + channel routing), VoiceConfig (6 presets + time shifts), KnowledgeDomainRouter (9 domains), ContextAdapter (time/channel/mood), SQLite persona persistence, persona dashboard (/personas, /routing). Runtime wiring (AnimusRuntime orchestrator, lifespan, health endpoint). Native Anthropic tool_use (CognitiveResponse, ToolCall, multi-turn cognitive loop). Phase 5: self-improvement loop with self-heal proactive check (auto-detects tool failures/slow/errors every 6h), ImprovementSandbox (safe YAML config + identity changes with backup/rollback), impact measurement (baseline/post metrics, -100 to +100 score), 37 built-in tools, 6 proactive checks.

**Bootstrap lifecycle** (`packages/bootstrap/src/animus_bootstrap/lifecycle/`) — Phase 6 runtime-lifecycle foundation (ADR-007, ADR-008). Pure functions: `HealthState` (7-state health contract), `ProcessClassification` (4-state provenance rules — `Managed`/`Recoverable`/`Orphaned`/`Unknown`, never `pgrep`), `ProfileSwitcher` (atomic 16-step profile switch with rollback), `SystemdStateReader` (typed wrapper around `systemctl --user show`). See `docs/specifications/animus-runtime-lifecycle-build-spec.md` for the canonical contract and `docs/systemd/animus-runtime.md` + `docs/operations/process-registry.md` for operator guidance.

## Key Files

### Core
Expand Down
Loading
Loading