Skip to content

Latest commit

 

History

History
525 lines (396 loc) · 32.4 KB

File metadata and controls

525 lines (396 loc) · 32.4 KB

autonomous-fleet

You describe the work. A team of AI agents is designed to ship the PRs.
Drop-in skills for Claude Code, Grok, Codex, and Orca.

MIT License agentskills.io format Stars Version 0.3.0 Last commit

autonomous-fleet — multi-agent engineering framework

↑ Generated by Nano Banana Pro via OpenRouter. Prompt: scripts/banner/banner-prompt.txt


What it is

A library of skills you install into your coding agent (Claude Code, Grok, Codex, or Orca). You describe a chunk of work in plain English; a small team of worker agents — a builder, a fresh build-blind reviewer, and an integrator, usually different model families — splits it up, works in parallel on isolated git branches, and opens one pull request per piece, with the disciplines a senior engineer would apply: small commits, conflict-aware merges, a frozen scope per run, end-to-end verification before "done". Underneath the fleet sits the part that makes it trustworthy: a verification substrate — reviewer findings re-quoted against source, anti-anchoring blind-fix ordering, sha256-manifested run archives, a stop-verify gate — so no agent-written PR reaches you on vibes alone.

You stay the reviewer of last resort. The agents do the typing — and their work is mechanically verified before you ever see the PR.

Why a team of agents at all? The single-agent-first critique is right where sub-agents must share evolving context: hand-offs lose information. Fleet missions are scoped to dodge that failure mode — each unit of work (one doc area, one file under test, one finding) is independent by construction, so workers never depend on each other's context. Parallelism buys wall-clock time; cross-vendor review buys blind-spot diversity; and the seams the critique warns about are exactly where the substrate's mechanical gates sit.


How it ships work — the role topology

Inside a run, the workers aren't a homogeneous swarm. Each task moves through three distinct roles, and the framework is designed to use different sessions — often different model families — for each, so review isn't self-marking:

Role What it does Default staffing
🛠️ Builder Writes the code on a fresh worktree, opens the PR @codex (OpenAI Codex / GPT-5)
🔍 Reviewer Reads only the PR diff and EVIDnever the builder's session @claude (Anthropic, fresh terminal)
🚦 Integrator Closes findings, merges, cleans the worktree @claude

This topology came out of the Aula run — the framework's defining Stage-9 finding (prompts.md L3013 in the source corpus). A previous run had committed "DONE — all 15 features ready for main" while the end-to-end demo aborted at step 5, with two untested cross-tenant security leaks and the entire front half of the product missing. Root cause: the same model that built the work was marking its own homework. The fix became a structural rule, not a stylistic preference.

Build-blindness is structural in the cross-vendor case; instructed otherwise. When builder and reviewer run as separate processes — different vendors, or Orca's process-per-role topology — the reviewer is spawned with no access to the builder's session, scratchpads, or prior context, so the isolation is a mechanical property: it can only judge the artifact (the diff + EVID), not the intent. The shipped headless path, however, runs one agent process per mission; there's no second terminal there, so build-blindness on single-session adapters is fresh-context isolation the run instructs (the reviewer pass is told to read only the diff + EVID), not a guarantee the runtime enforces. If you can read your own commit message while reviewing your own diff, that's not review — and the cross-vendor topology is the only one that makes that mechanically impossible.

Design missions stay on @grok. For design-integration (and the archived landing-page-convergence draft), the corpus showed @grok with the frontend-design specialization produces materially better visual fidelity than @codex. The Stage-9 builder retirement applies to general-purpose builds only; design missions explicitly carry the exception in their SKILL.md.

Single-vendor hosts are honest about the trade-off. If you only have one model family available (e.g. running everything on Claude Code), the framework still instructs terminal separation — the reviewer gets a fresh session with no context inheritance — but it loses the cross-vendor blind-spot diversity, and on the single-process headless path the separation is an instructed discipline rather than a separate-process guarantee. Which mode a run took is recorded as reviewer_mode in its fleet-outcome — an enum the validator now enforces (invalid values fail validation; absence draws a warning), so the disclosure is machine-checkable, not an honor-system note.

A note on the prompts.md citations. Throughout this repo you'll see provenance markers like <!-- Corpus: prompts.md L… --> and references to prompts.md / directives.md "in the source corpus." That corpus — the raw multi-stage run logs and directives this framework was distilled from — is private upstream and not shipped here; the distilled, public record is this repo. The citations trace provenance (which run a rule came from), not files you can open in the tree. See CONTRIBUTING.md's Distillation Discipline.


What you can ask it to do

Say this in your coding agent's chat, after installation:

You say What it ships
"The docs are out of date, fix them" One PR per stale doc file. A summary doc listing what was out of sync.
"Raise test coverage on the payments module" One PR per file being tested (typically 3–8 PRs). Coverage report in each PR description.
"Red-team this API and patch what you find" A review report opened as a GitHub issue, then one PR per finding it patches.
"Get this ready to ship" A multi-step campaign: review the surface → raise test coverage → sync the docs → check end-to-end works. Stops if any step fails.

Each run takes minutes to hours depending on scope. You get GitHub notifications when PRs are ready to review.

More missions in docs/exploratory/missions/ (exploratory — documented but not yet shipped end-to-end on an external repo with a run-archive).


Try it

Install takes about a minute. In evidenced runs the first PR has shown up within minutes.

Evidence status (2026-07-03). The first external run with autonomously-landed PRs exists: doc-sync on ravidsrk/gemoji — 3 PRs opened, build-blind reviewed (one genuine FAIL→fix→PASS round), and merged by agents, with a validated run-archive (.fleet/runs/20260703T054520Z-doc-sync-3e8173/). Topology: interactive claude coordinator + sandboxed codex builders + fresh codex reviewers (single-vendor caveat recorded). Still open: a single-process fully headless external run (the sandbox-bypass launch needs explicit operator opt-in) and adversarial-bench A/B numbers — see docs/external-dogfood/.

Before you start

autonomous-fleet drives your coding agent — it doesn't ship one. You'll need:

  • A supported agent, installed and authenticatedClaude Code, Codex, Grok, or Orca.
  • Node.js ≥ 18 — for npx skills (the agentskills.io installer).
  • Python ≥ 3.12 — used by the headless campaign and validate-* tooling (scripts/*.py); not needed for the interactive Step 3 path.
  • git and an authenticated gh — run gh auth status to confirm; every task ships as a GitHub PR.
  • CLI auth for your chosen runtime only if you use the headless campaign scripts (grok login, etc.). The interactive path in Step 3 needs just the agent itself.

Recommended for build-blind review: Orca with autonomous-fleet-adapter-orca gives structural cross-vendor isolation — separate terminals per role (@codex builds, fresh @claude reviews). Single-session hosts (Claude, Grok, Codex) instruct terminal separation; headless runs one process per mission (see role topology above).

Step 1 — Install the skills into your repo

In a terminal, in your project's root directory:

npx skills@1.5.12 add https://github.com/ravidsrk/autonomous-fleet \
  --skill setup-autonomous-fleet \
  --skill autonomous-fleet \
  --skill autonomous-fleet-core \
  --skill fleet-program \
  --skill autonomous-fleet-adapter-orca \
  --skill doc-sync \
  -y

This creates a .agents/skills/ folder (gitignored — your git status stays clean). The folder is the universal agentskills.io format, which Claude Code, Grok, Codex, and Orca all read.

Orca is the reference runtime — structural build-blind review and native multi-terminal orchestration. On Grok, Claude Code, or Codex, swap -orca for -grok, -claude-code, or -codex. Want every skill? Use --skill '*'.

On Orca: fleet missions use only the skills above. For full-handoff routing (one-shot ownership transfer without supervision), also load Orca's companion skills orchestration and orca-cli — they ship with the Orca app, not this repo. See autonomous-fleet-adapter-orcareferences/orca-platform.md.

Step 2 — Configure the repo once

In your coding agent's chat (Claude Code's chat panel, Codex's chat, etc.), invoke the skill:

/setup-autonomous-fleet

In Claude Code and Codex, /setup-autonomous-fleet is a slash command. In Grok and Orca, paste the skill's name as a natural-language instruction (the runtimes that don't have slash UIs route by skill name). Either way, the skill picks up your repo's config.

It asks which agent you're on, which branch prefix to use, and writes the config to your repo.

Step 3 — Ask it to do work

In the same chat, plain English:

The docs are out of date, fix them

What you'll see, in order:

  1. A plan written to a file you can read and abort if you don't like it.
  2. Worker agents kicked off (you'll see them spawn).
  3. PRs appear in GitHub as each one finishes (within minutes in interactive dogfood runs; the fully-autonomous external path is still being evidenced — see the evidence status above).

Each PR has a readiness doc explaining what was done, why, and how it was verified — and the run's reviewer role has signed off before you see it. You're the final reviewer. On Orca (cross-vendor, separate terminals) that first reviewer is mechanically build-blind — a different process that never saw the builder's session. On single-session hosts (Claude Code, Codex, Grok) it is a fresh same-vendor pass with instructed isolation, not a mechanical guarantee (see the role topology above).

To stop a run mid-flight, close the chat (workers check in with the ledger and exit). The file ledger survives, so you can pick up where you left off in a new chat.

That's it. The rest of this README is for going deeper.

📖 Going deeper? The Guide walks through every concept, mission, and reference, from your first PR to writing a custom adapter; a Starlight docs-site build (docs-site/dist) adds search and nav.


The full menu

Three shipped missions today (doc-sync, test-coverage, adversarial-review-and-fix) plus the fleet-program shell for chaining them. 12 exploratory missions are documented but not yet shipped — see docs/exploratory/missions/ (six more are parked in its archive/). Install the ones you need with --skill <name>, or grab everything with --skill '*'.

Daily housekeeping

Skill Ask it to…
doc-sync Sync README, CI files, and build scripts to match the code
test-coverage Raise coverage on a specific module or file

💡 Why start with doc-sync? Documentation sits among the higher-merging AI-agent PR categories — the cross-agent aggregate is ~84% in the AIDev dataset (~33k agent-authored PRs across major repos): arXiv:2601.15195, Ehsani et al., MSR 2026. (Per-task merge rates vary widely by agent; treat the tier ordering as qualitative, not a per-skill guarantee.)

Audit-and-fix

Skill Ask it to…
adversarial-review-and-fix Red-team a surface, write a review, then patch the findings

Exploratory (not yet shipped end-to-end)

agents-layer, browser-qa-fix, bug-batch, cleanup, contract-first-build, dependency-update, design-integration, incident-investigate, inference-cost, scaffold-align, take-product-to-completion, and targeted-migration — 12 exploratory missions in all — live under docs/exploratory/missions/. They're documented in full but lack the progress + readiness + external-archive triple required to ship — see the promotion criteria in the exploratory README. Six overlap-or-unproven drafts (release-document, devex-audit, landing-page-convergence, product-framing, security-cso-audit, legacy-rebuild) are parked in archive/ — each needs the evidence triple plus a written differentiation case to return.

Run a campaign (chain skills together)

./scripts/run-campaign.sh claude --preset repo-health      # doc-sync → test-coverage
./scripts/run-campaign.sh claude --preset ship-with-proof  # review-fix → test-coverage → doc-sync
./scripts/run-campaign.sh claude --preset quality-gate     # review-fix → test-coverage

The secure-ship, align-then-ship, handoff-to-product, and gstack-quality presets are archived in scripts/campaigns/ pending promotion of the missions they reference (dependency-update, take-product-to-completion, the three early-exploratory scaffolders, and demoted gstack-derived mission nodes respectively).

⚠️ Headless note. The campaign scripts drive each runtime's CLI in headless mode, which needs that CLI authenticated on the host (e.g. grok login) and isn't yet fully validated end-to-end. If a run can't authenticate, drive the same missions interactively from your agent's chat / /goal instead.

Each step waits for the previous one to pass a verification gate. If a gate fails, the campaign stops and tells you why. Add --dry-run to see the plan without running it.

Plumbing skills you don't call directly

These get pulled in automatically by the skills above:

Skill Role
autonomous-fleet The entry point — routes vague requests to the right mission
autonomous-fleet-core The engine — every run goes through it
fleet-program The campaign runner — chains missions with conditional gates
setup-autonomous-fleet First-run repo configuration

And one adapter per supported runtime:

Skill Runtime
adapter-claude-code Claude Code
adapter-grok Grok Build
adapter-codex OpenAI Codex
adapter-orca Orca
adapter-template Template — copy this to add a new runtime

Verify any agent's run — fleet-verify

The verification substrate stands alone. Point one command at a run directory — produced by this framework, or assembled from any agent's artifacts — and it replays every layer: reviewer findings re-quoted against source (Layer 1), blind-fix anti-anchoring order (Layer 3), archive manifest + sha256 (Layer 4), fleet-outcome gates, and the trace schema. Truly-absent artifacts are SKIPPED by name — but a missing manifest.json, or a manifest that names evidence a layer then can't verify, is a hard failure: you can't call a run verified when its own manifest points at evidence that isn't there. An empty or manifest-less run dir exits 2 — empty verification is not success.

python scripts/fleet_verify.py .fleet/runs/<run_id> --repo .    # layer table + exit code
python scripts/fleet_verify.py .fleet/runs/<run_id> --json      # machine-readable

Or as a CI step via the bundled action.yml:

- uses: ravidsrk/autonomous-fleet@main
  with:
    run-dir: .fleet/runs/${{ env.RUN_ID }}

Or install it standalone — no clone, isolated env — via uvx:

uvx --from git+https://github.com/ravidsrk/autonomous-fleet fleet-verify <run-dir> --repo .

What every run is built to do

These are the disciplines the engine builds into every run — you don't have to remember to ask. Most are prompt-level disciplines the run follows; the evidence-based ones can additionally be enforced at runtime by opting into strict mode (Claude Code today — see skills/autonomous-fleet-core/references/strict-mode.md).

🔒 The work won't go sideways

  • One PR per unit — never one giant blob
  • Original commits preserved, never squashed; agent authorship attributed by default (Co-Authored-By trailers)
  • Merges are conflict-aware; worktrees cleaned up after every merge
  • Testnet / staging only — merge ≠ deploy
  • The file ledger survives session restarts and context compaction

🧪 The work is verified, not just attempted

  • External facts get verified against real sources (logged to docs/research-notes.md)
  • Runs don't complete with unverified_assumptions > 0 (strict mode can enforce this on disk)
  • Every run reports a declared cost_estimate (USD) in its outcome — an aggregated estimate, not a metered spend
  • Shell commands go through a sandboxed wrapper that scrubs env vars
  • Optional container-use placement gives each worker an isolated container

🎯 "Done" means actually done

  • A green test suite is not "done"
  • Shipping missions only complete when end-to-end is verified (not just exit codes)
  • Every run has a frozen scope boundary — no surprise expansions
  • Editorial / credential decisions route through explicit lanes (fix / draft-and-gate / refuse) — never fabricated

Under the hood — the architecture

The framework has four component layers (distinct from the verification substrate's numbered layers below). You only interact with the top layer; the rest happens automatically.

┌──────────────────────────────────────────────────────────────┐
│  autonomous-fleet (umbrella)         ← routes vague requests │
│  fleet-program (campaigns)           ← chains + conditional  │
│  setup-autonomous-fleet              ← per-repo config       │
├──────────────────────────────────────────────────────────────┤
│  autonomous-fleet-core               ← engine (THE method)   │
├──────────────────────────────────────────────────────────────┤
│  adapter-{claude-code, grok, codex, orca, template}          │
│  ↑ maps the engine to one runtime's real commands            │
├──────────────────────────────────────────────────────────────┤
│  missions × 3 (doc-sync, test-coverage,                      │
│                adversarial-review-and-fix)                   │
│  + 12 exploratory under docs/exploratory/missions/           │
│  Tier 1 (recurring) → Tier 2 (campaign) → Tier 3 (ship)      │
└──────────────────────────────────────────────────────────────┘
  • Core + mission + adapter = a single-mission run
  • Core + fleet-program + adapter = a campaign (linear or conditional, one mission at a time per repo)
Infrastructure Adapters Missions
🟦 Infrastructure
engine · entry · program · setup
🟪 Adapters
one engine · many runtimes
🟧 Missions
discrete jobs · safe to chain
Under the hood — the run outcome (fleet-outcome)

Every run emits a readiness document with this YAML block at the top. Campaign edges, the file ledger, and the dashboard all read it to decide what's next.

fleet-outcome:
  mission: test-coverage
  status: done                   # done | partial | blocked
  repo: /path/to/your/repo       # absolute path
  base_branch: main
  prs_merged: 2
  unverified_assumptions: 0      # research-discipline gate; must be 0 to progress
  archive_enabled: true          # run left a validated .fleet/runs/<run_id>/ trail
  run_id: 20260623T141522Z-test-coverage-3a9c2f
  cost_estimate: 1.84            # declared estimate (USD), aggregated — not a metered spend
  reviewer_mode: cross-vendor-structural   # review topology; enum enforced by the validator
  metrics:                       # mission-specific (under fleet-outcome.metrics)
    e2e_verified: true           # real end-to-end state, not exit codes
    gaps_open: 0
    coverage_regressed: false

Full spec: skills/autonomous-fleet-core/references/fleet-outcome.md

Validate it locally

If you're hacking on the framework itself:

./scripts/bootstrap.sh                             # first-time contributor setup: venv + deps + validate-all
./scripts/validate-all.sh                          # everything: skills + fleet-outcome + goals + run-archive + blind-fix + trace + pytest (100% line coverage of scripts/*.py)
./scripts/run-campaign.sh grok --preset repo-health --dry-run
./scripts/run-mission-headless.sh grok doc-sync --max-turns 50

Individual validators:

./scripts/validate-skills.sh                       # SKILL.md packages (agentskills.io)
./scripts/validate-fleet-outcome.sh                # readiness doc fleet-outcome YAML
./scripts/validate-goal-condition.sh --scan-docs   # /goal binding
python scripts/validate_run_archive.py             # Layers 3 & 4: manifest + sha256 + mtime ordering (the blind-fix anti-anchoring ordering IS Layer 3)
pytest tests/                                      # full suite (73 files, 1586 tests; 100% line coverage of the Python tooling, scripts/*.py — shell is validated by behavioral + mutation tests, not line coverage)

# Operator gates (run on a specific run-id)
python scripts/verify_findings.py \
  .fleet/runs/<run_id>/p0-review-findings.json \
  --repo .                                         # Layer 1: re-quote every reviewer-cited line
echo '{"cwd":"."}' | python scripts/stop_verify.py --explain  # Layer 2: stop-verify CC hook (reads hook JSON on stdin)
python scripts/verify_blind_fix.py .fleet/runs/<run_id>/  # Layer 3: blind-fix anti-anchoring guard
python scripts/fleet_verify.py .fleet/runs/<run_id> --repo .  # All layers + outcome + trace in one shot (CI: action.yml)
python scripts/emit_trace.py validate \
       .fleet/runs/<run_id>/trace.jsonl              # Telemetry: structured trace stream (vibe-kanban / Agent View contract)
python scripts/analyze_seat.py per-run             # Telemetry: seat analysis across all archives
python scripts/analyze_cost.py per-run             # Telemetry: per-run + aggregate inference cost

# CI-only gate (mirrors .github/workflows/ci.yml)
./scripts/mutation-check.sh                        # assert every manifest mutation is caught by guard tests

./scripts/eval-campaign-edge.sh \
  --readiness docs/doc-sync-readiness.md \
  --campaign docs/composition-e2e-campaign.yaml \
  --current-node docs

Skill validation uses skill-creator's quick_validate.py. CI runs validate-all.sh on every push and PR to main.

⚠️ Headless execution still requires runtime CLI auth and isn't fully end-to-end validated yet. When CLI auth isn't available, drive the run from the interactive agent's /goal instead.

Author your own skill or adapter

Install Anthropic's skill-creator once — not bundled here because it's only needed if you're authoring, not running:

npx skills add https://github.com/anthropics/skills --skill skill-creator -y -p

Then:

npx skills init my-new-mission              # scaffold
./scripts/validate-skills.sh                # validate

Follow the skill-creator workflow at .agents/skills/skill-creator/SKILL.md between those two steps.

For a new runtime adapter, copy skills/autonomous-fleet-adapter-template/ and fill the six primitives: PLACE, SPAWN_WORKER, DISPATCH, WAIT, INSPECT, SYNC_TASK_STATE.

Repository layout
autonomous-fleet/
├── skills/                              # publishable skills (npx skills discovers these)
│   ├── autonomous-fleet/                # umbrella entry-point
│   ├── fleet-program/                   # sequential + conditional campaign DAGs
│   ├── setup-autonomous-fleet/          # per-repo config
│   ├── autonomous-fleet-core/
│   │   ├── SKILL.md
│   │   ├── references/
│   │   │   ├── engine.md                # full engine spec
│   │   │   ├── composition.md           # skill loading rules
│   │   │   ├── community-skills.md      # gstack / agent-skills / mattpocock hooks
│   │   │   ├── fleet-outcome.md         # readiness YAML spec
│   │   │   ├── runtime-goals.md         # /goal + ledger binding
│   │   │   ├── review-findings.md       # Layers 1 & 3: findings schema + verifier (L1) and blind-fix/anti-anchoring protocol (L3)
│   │   │   ├── strict-mode.md           # Layer 2: stop-verify Claude Code hook (opt-in)
│   │   │   └── run-archive.md           # Layer 4: .fleet/runs/<run_id>/ manifest scheme
│   │   └── assets/
│   │       ├── substrate/                          # bundled Python validators + lib (travels with npx skills; issue #80)
│   │       ├── fleet-review-findings.schema.json   # Layer 1 schema
│   │       ├── fleet-review-findings.example.json
│   │       ├── fleet-run-manifest.schema.json      # Layer 4 manifest schema
│   │       └── fleet-trace.schema.json             # Telemetry: structured trace stream contract
│   ├── autonomous-fleet-adapter-{orca,claude-code,grok,codex,template}/
│   │       └── (claude-code) assets/hooks/         # Layer 2 stop-verify hook + hooks.json (opt-in)
│   └── doc-sync/, test-coverage/, adversarial-review-and-fix/  # 3 shipped missions (Commit D, 2026-06-23)
├── docs/
│   ├── README.md                        # docs/ index — load-bearing files warning
│   ├── exploratory/missions/            # 12 exploratory + archive/ (six parked)
│   ├── external-dogfood/                # gemoji repo-health + ship-with-proof evidence
│   ├── research-community-skills.md
│   └── doc-sync-audit.md                # latest drift index
├── scripts/
│   ├── validate-all.sh                  # umbrella: skills + fleet-outcome + goals + run-archive + blind-fix + trace + pytest
│   ├── validate-{skills,fleet-outcome,goal-condition}.sh
│   ├── validate_run_archive.py          # Layer 4 manifest + on-disk integrity validator
│   ├── verify_findings.py               # Layer 1 reviewer-findings source verifier
│   ├── stop_verify.py                   # Layer 2 stop-verify hook entrypoint
│   ├── verify_blind_fix.py              # Layer 3 anti-anchoring (blind-fix) verifier
│   ├── fleet_verify.py                  # one-shot: Layers 1–4 + outcome + trace on a run dir
│   ├── emit_trace.py                    # Telemetry: structured trace stream (vibe-kanban / Agent View contract)
│   ├── analyze_seat.py                  # Telemetry: seat analysis ("earns its seat") across archives
│   ├── analyze_cost.py                  # Telemetry: per-run + aggregate inference cost
│   ├── mutation-check.sh                # standing mutation gate (CI: assert tests catch known bugs)
│   ├── eval-campaign-edge.{sh,py}
│   ├── coupling-graph.py                # import/symbol graph for coupling-aware decomposition
│   ├── render-dashboard.py              # ledger → attention-zone HTML dashboard
│   ├── run-{campaign,mission-headless,sandboxed}.sh
│   ├── campaigns/                       # repo-health, ship-with-proof, align-then-ship, quality-gate, secure-ship, handoff-to-product
│   ├── lib/                             # fleet_outcome, fleet_run, verify_findings, verify_blind_fix, emit_trace, analyze_seat, analyze_cost, locks, substrate_disable, stop_verify, mission_registry, venv-bootstrap
│   └── install-skills.sh
├── action.yml                           # GitHub Action: fleet-verify as a PR-side gate
├── tests/                               # 73 test files, 1586 tests; validators + engine doctrine + 4-layer substrate
├── .agents/skills/                      # installed skill copies (gitignored)
└── skills-lock.json                     # lockfile for npx skills

Acknowledgments

Parts of the orchestration substrate adapt mechanism designs from Agent Orchestrator (Copyright 2026 Untrivial, Apache License 2.0). We port selected ideas as portable validators and engine doctrine — not the AO daemon, UI, or upstream source tree.

Full credits, source mapping, and license notes: ATTRIBUTIONS.md · NOTICE


Sibling repo: agent-skills — 5 production-grade capability skills (Cloudflare DNS, Fly → AWS migration, deep research, terminal posters, AI image generation).
Install one or both. Same author, different scope.