The halos toolchain: 8 CLI modules for personal AI infrastructure
The problem
Running personal AI infrastructure requires operational tooling. Not dashboards - dashboards are for teams with dedicated ops engineers. CLI tools that a single operator can run from a terminal, producing auditable output that feeds into the next step.
halos is 8 Python modules, each with its own CLI, each solving a specific operational problem.
memctl: structured memory
AI assistants forget everything between sessions. The context window is finite and ephemeral. Anything worth remembering needs durable storage with structure.
memctl new --title "Ben's preferred email format" --type preference --tags communication,ben
memctl search --tags ben --text email
memctl link --from note-42 --to note-17
memctl enrich # Propose new backlinks based on content similarity
memctl prune --execute # Archive low-value notes (score < threshold)
memctl graph --format html # Render backlink graph
Each note is a markdown file with YAML frontmatter. The index is a JSON file that tracks metadata, backlinks, and decay scores.
The key abstraction: one claim per note. “Ben prefers plain text emails” is a note. “Ben’s communication preferences” with 12 bullet points is not - that’s 12 notes with backlinks.
Backlinks create a knowledge graph. Time-decay pruning prevents bloat. The index is the source of truth.
nightctl: work tracking
Tasks, jobs, and agent-jobs flow through a 13-state machine:
open -> planning -> plan_review -> in_progress -> review -> testing -> done
|
blocked -> cancelled
|
running -> failed -> retry
nightctl add "Fix deployment script" --kind task
nightctl plan T-042 # Generate execution plan
nightctl start T-042 # Transition to in_progress
nightctl block T-042 --reason "Waiting on API credentials"
nightctl unblock T-042
nightctl done T-042
Three kinds of items:
- task - State tracking only. Human executes.
- job - Executable script. Runs in overnight window.
- agent-job - Structured plan with XML validation. Agent executes.
Agent-jobs require a plan before execution. The plan is validated against schema. If the plan fails review, the job returns to planning state - it cannot proceed without valid plan.
halctl: fleet management
Covered in part 1. The summary:
halctl create --name X --personality Y # Provision new instance
halctl list # Audit table
halctl push --all # Propagate governance updates
halctl smoke X # 15 infrastructure checks
halctl assess X # 8 behavioural scenarios
halctl status X # Instance health
halctl freeze | fold | fry | reset X # Lifecycle management
agentctl: session telemetry
Tracks LLM usage across sessions. The key feature: spin detection.
agentctl sessions # List recent sessions
agentctl usage --period 7d # Token usage summary
agentctl spin-check # Detect spinning-to-infinity
Spinning-to-infinity is when an agent enters a loop of self-reflection without making progress. It looks like work. It produces tokens. It accomplishes nothing.
The detector watches for:
- High token count with low file changes
- Repeated similar prompts within a session
- Planning cycles that never transition to execution
When detected, the session is flagged. The operator reviews whether intervention is needed.
cronctl: scheduled jobs
cronctl list # Show defined cron jobs
cronctl enable daily-briefing # Enable job
cronctl disable daily-briefing # Disable job
cronctl generate # Output crontab for installation
Jobs are defined in YAML. The generate command outputs crontab syntax for installation. Separation of definition from installation keeps the config portable.
briefings: daily digests
hal-briefing generate # Generate today's briefing
hal-briefing send # Send to configured channel
Briefings aggregate:
- Active tasks from nightctl
- Recent memory notes from memctl
- Fleet status from halctl
- Any alerts or anomalies
Delivered daily via Telegram at 07:00. The operator wakes up to a status summary without needing to run multiple queries.
logctl: structured log reader
logctl search --level error --since 1h
logctl tail --instance dad --lines 50
logctl export --period 24h --format json
Agents produce structured logs (JSON with level, timestamp, instance, message). logctl queries them. The abstraction layer means log format can change without breaking queries.
reportctl: periodic digests
reportctl daily # Generate daily ecosystem report
reportctl weekly # Generate weekly summary
reportctl export --period 30d # Export data for analysis
Aggregates across all modules:
- Fleet health trend
- Memory growth rate
- Task completion rate
- Token usage trend
- Anomaly frequency
The output is markdown, suitable for archiving or review.
The integration pattern
The modules compose:
# Morning routine
hal-briefing send # Digest arrives on Telegram
halctl list # Quick fleet health check
nightctl list --status open # Today's tasks
# After making changes
halctl smoke ben # Verify instance health
halctl assess ben # Verify behaviour
# Evening
reportctl daily # What happened today
memctl prune --dry-run # What's stale
Each command is idempotent. Each produces structured output. Each can be scripted.
Why CLI, not dashboard
Dashboards require:
- A web server to run
- Authentication to secure
- A UI framework to maintain
- Browser context switching to use
CLIs require:
- A terminal
- Python with uv
For a single operator managing personal infrastructure, the CLI is lower overhead. The output is text that can be piped, grepped, and versioned. The commands can be scripted into larger workflows.
If fleet size grows to where a dashboard makes sense, the structured output from these tools becomes the data layer for that dashboard. The primitives stay the same.
Source
- All modules:
halos/ - Config schemas:
*ctl.yamlin repo root - Python environment:
pyproject.tomlwith uv
This is part 3 of the halos series. Previous: the assessment system. Previous: fleet provisioning.