Slice 79 - Setup and Uninstall Instruction Foundation
Date: 2026-07-01
Scope#
Restore the first setup/uninstall layer in the Python product:
- add
codealmanac setup - add
codealmanac uninstall - install setup-owned Codex and Claude global agent instructions
- remove only setup-owned instruction artifacts on uninstall
- keep both commands idempotent and non-interactive with
--yes - expose JSON and text output through the existing admin CLI edge
This slice does not add raw-mode selection, provider auth/model selection, local automation choices, auto-update scheduling, Cursor/Windsurf/OpenCode instruction targets, or hosted setup wording.
Why Now#
The live agreement says setup and uninstall were not intentionally dropped. The archived behavior made setup feel like a real product surface, while the current Python CLI still lacks the command. The highest-value first slice is the durable instruction contract because it is small, testable, and reverses cleanly through uninstall.
Shape#
result = app.setup.run(RunSetupRequest(targets=(SetupTarget.CODEX,)))
result = app.setup.uninstall(RunUninstallRequest(targets=(SetupTarget.CODEX,)))The service owns the product command and result model. The filesystem adapter owns agent-specific files:
services/setup/
models.py
ports.py
requests.py
service.py
integrations/setup/
instructions.pyapp.py wires the adapter into SetupService; CLI dispatch builds Pydantic
requests and renders returned models.
Decisions#
- Public setup target values are
codex,claude, andall. allinstalls Codex and Claude instructions. Future targets can extend the enum and adapter contract when they become concrete.- Codex receives an inline managed block in
~/.codex/AGENTS.mdor~/.codex/AGENTS.override.mdwhen the override file exists and is non-empty. - Claude receives
~/.claude/codealmanac.mdplus an import line in~/.claude/CLAUDE.md. - Managed markers use
<!-- codealmanac:start -->and<!-- codealmanac:end -->. - Uninstall removes only current
codealmanacinstruction artifacts. Oldalmanacartifacts may belong to a separate product install and are not Python v1 compatibility scope. --skip-instructionsmakes setup an honest no-op for this slice.--keep-instructionsmakes uninstall leave the instruction layer alone.- Scheduler removal will be added when setup owns local automation choices.
Cosmic Python Transfer#
Chapter 4 says the service layer captures the use case. Setup/uninstall are
use cases, so they belong behind SetupService, not inside argparse handlers.
Chapter 10 says commands capture intent and fail loudly. RunSetupRequest and
RunUninstallRequest are command-shaped request models.
Chapter 13 recommends a composition root for explicit dependencies. app.py
wires the real filesystem installer, while tests can inject a fake installer.
Files#
src/codealmanac/services/setup/src/codealmanac/integrations/setup/src/codealmanac/app.pysrc/codealmanac/cli/parser/admin.pysrc/codealmanac/cli/dispatch/admin.pysrc/codealmanac/cli/render/admin.pytests/test_setup_service.pytests/test_cli.pytests/test_architecture.py
Verification#
Focused:
uv run pytest tests/test_setup_service.py tests/test_cli.py tests/test_architecture.py tests/test_public_contract.py
uv run ruff check src/codealmanac/services/setup src/codealmanac/integrations/setup src/codealmanac/app.py src/codealmanac/cli tests/test_setup_service.py tests/test_cli.py tests/test_architecture.pyBroad:
uv run pytest
uv run ruff check .
git diff --checkDogfood:
HOME="$(mktemp -d)" uv run codealmanac setup --yes --target codex
HOME="$HOME" uv run codealmanac setup --yes --target codex
HOME="$HOME" uv run codealmanac uninstall --yes --target codex