agentsclimarketplace

Cartographer

Skill calumjs/ARMADA/skills/cartographer

The ARMADA cartographer. Owns *per-repo* knowledge: it mines completed fleet runs for reusable, actionable heuristics and maintains a reviewable knowledge base under `.armada/cartography/`, so the fleet specialises to a repo over time without anyone hand-writing AGENTS.md guidance. It analyses one completed run from the evidence already on the issue/PR — the original issue, the PR diff, commit/retry history, muster + human review comments, build/test failures, and the resolution path — and emits `heuristic / evidence / confidence` entries, paying special attention to human corrections, repeated failures, and repeated successes. It dedupes, updates, and prunes against existing cartography, then commits the changes into the active ARMADA PR so they ride the muster review + autoMerge gate. shipwright reads cartography before building; crows-nest auto-runs it (best-effort, side-channel) at its reconcile points when the `cartography` config key is on. Trigger when the user says "learn from this run", "update the cartography", "map this repo", "extract heuristics", "what has the fleet learned", or invokes /cartographer. Accepts a PR number, an issue number, or nothing (defaults to the current branch's PR). Distinct from the fleet-defect self-improvement loop — cartographer is about the *host* repo, fleet-defect is about *ARMADA*.From its SKILL.md

Install
npx -y skills add calumjs/ARMADA --skill cartographer

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 4 stars4 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

SKILL.md

29.8 KB, as published. Nobody here has run it

cartographer — learn per-repo heuristics and specialise the fleet over time

Every ARMADA run discovers repo-specific knowledge — a pre-build step that has to run first, a companion file that always moves with another, a convention a human keeps correcting — and today it evaporates between runs. cartographer is the ship that owns per-repo knowledge: it mines a completed run for reusable, actionable heuristics and maintains a knowledge base under .armada/cartography/, so the fleet specialises to a repo over time without anyone hand-writing guidance. The next shipwright run consults that map during its Research step and plans with the grain of the repo.

Consult-before-acting. The pattern cartographer establishes — read the accumulated map before you act, write back what you learned after — is the shape future ships should adopt. shipwright is the first consumer (its Research step, §2); muster is the second — it reads the same cartography before reviewing (muster §0c) so a diff that reintroduces a known pitfall gets flagged, closing the consult-before-acting loop on the review side too.

0. The boundary — cartographer vs the fleet-defect loop (read this first)

ARMADA already has one self-improvement loop: the fleet-defect loop (charter §9, shipwright §10, crows-nest §7). cartographer is a second, orthogonal learning loop, and the two must never be confused:

fleet-defect loopcartographer
Learns aboutARMADA itself — a skill step was wrong/missing, a guard didn't fire, the fleet had to guessthe host repo — its build quirks, conventions, pitfalls, workflows
Files againstthe armadaRepo (e.g. calumjs/ARMADA) — never the host projectthe host repo's own .armada/cartography/
Outputa fleet-defect GitHub issuereviewable Markdown heuristics committed to the active PR
Triggera defect in the fleet's own guidancea completed run that revealed repo knowledge

The fleet-defect loop is left entirely unchanged by cartographer. If a reflection is about ARMADA's own guidance, it still routes through charter §9 as a fleet-defect — cartographer does not touch it, re-implement it, or file against armadaRepo. A broken test or wrong requirement in the target project is neither a fleet-defect nor cartography unless it yields a reusable repo heuristic. When in doubt: Is this about how ARMADA works (→ fleet-defect) or about how this repo works (→ cartographer)?

1. Inputs and modes

cartographer runs in two modes, both analysing one completed run:

  • Manual (/cartographer / /armada:cartographer). A human invokes it on demand against:
    • a PR number — analyse that PR's run;
    • an issue number — find its linked PR and analyse that run;
    • nothing — default to the current branch's PR (gh pr view --json number on the branch).
  • Auto (dispatched by crows-nest). A best-effort background subagent fired at crows-nest's three terminal reconcile points (§7). It's handed the issue/PR it should analyse and runs non-interactively.

If the repo isn't commissioned (no .armada/config.json), run commission first — cartography is gated by a config key it writes (§8).

2. The cartography store — .armada/cartography/

Repo knowledge lives under .armada/cartography/ as reviewable Markdown, committed to the repo like the rest of .armada/ (it's project knowledge, not secrets). It's plain Markdown on purpose: a human reviews it in the PR diff, edits it by hand, or deletes an entry they disagree with.

Layout — a topic split (create files lazily; a brand-new repo may start as a single cartography.md and split out as it grows — the SKILL documents both and either is valid):

FileHolds
architecture.mdHow the system is put together — module boundaries, where things live, what depends on what.
conventions.mdHouse style the repo enforces — naming, structure, the service/helper a human keeps steering toward.
pitfalls.mdTraps that bite — generated files you mustn't edit, ordering gotchas, flaky areas, footguns.
workflows.mdRepo-specific procedures — pre-build steps, codegen, the order operations must run in.
testing.mdHow tests really work here — the runner, fixtures, what a green/red baseline looks like, slow suites.
glossary.mdRepo-local vocabulary — domain terms, internal names, acronyms a newcomer would miss.

Add an index.md only if helpful. Keep each file a flat list of heuristic entries (§3) under topic headings; don't let it sprawl into prose essays — the point is a scannable, actionable map a subagent reads in seconds.

3. The heuristic format — actionable and structured

Every entry is a heuristic / evidence / confidence triple — an instruction the fleet can act on, not a passive fact. The litmus test: could a shipwright run do something differently because of this line? If not, it's a fact, not a heuristic — drop it.

### Run `npm run generate` before the main build
- **heuristic:** Before `npm run build`, run `npm run generate` — the build depends on generated
  types that aren't checked in.
- **evidence:** 3 failed builds in PR #123 ("Cannot find module './generated'") cleared the moment
  `npm run generate` was run first.
- **confidence:** High
- **source:** PR #123 · 2026-06-06

Confidence is one of High | Medium | Low, earned by evidence:

  • High — a human correction, or a pattern seen across multiple runs (repeated failure then success, or repeated success). Acted on by default.
  • Medium — observed once with clear cause-and-effect in this run. Applied with a light touch; promoted to High when a later run confirms it.
  • Low — a plausible inference from a single ambiguous signal. Proposal-only — surfaced for a human, not auto-applied, and the first to be pruned if never confirmed (§5).

Good vs bad

Good (actionable)Bad (passive fact)
"Before the main build, run npm run generate.""The project uses code generation."
"Put new API handlers in src/api/, not src/routes/ — reviewers move them every time.""There is an src/api/ directory."
"Don't edit *.gen.ts — they're regenerated and your change is lost.""The repo uses React."
"Tests need DATABASE_URL set or the suite errors at import.""There are tests."

A line a reviewer would answer "so what?" to is a fact; cut it. Keep every entry specific, imperative, and tied to evidence.

4. Analyse one completed run

Gather the evidence already on the issue/PR — no re-running the build. Pull in parallel:

  • The original issue — gh issue view <n> (title, body, acceptance criteria, comments).
  • The PR diff — gh pr diff <pr> and gh pr view <pr> --json files,title,body.
  • Commit + retry history — git log on the PR branch; how many attempts before green (repeated build/test failures then a pass is the strongest signal).
  • muster + human review comments — gh pr view <pr> --json reviews and gh api repos/{owner}/{repo}/pulls/<pr>/comments. Human corrections are the highest-value evidence (§4a).
  • Build / test failures — failure messages in CI logs or the PR/issue comment trail, and what finally cleared them.
  • The resolution path — what the working change actually did differently from the failed attempts.
  • Existing cartography — read .armada/cartography/ first so you update rather than duplicate (§5).

From that evidence, emit heuristics (§3), paying particular attention to:

  • Human corrections → §4a (highest value).
  • Repeated failures — the same error class hit N times before a fix landed → a High-confidence pitfall or workflow ("do X first", "don't touch Y"). The worked example: 3 failed builds before learning npm run generate is required → Workflow heuristic, Confidence High.
  • Repeated successes — a pattern that worked across runs (the same file always edited alongside another, a test command that's reliably green) → a convention or workflow worth codifying.

Be conservative: a one-off with no clear cause is not yet a heuristic. Prefer few High-value entries over many speculative ones — the map is read on every future build, so noise has a cost.

4a. Human corrections become heuristics (highest value)

A human review comment that corrects the fleet is the single most valuable evidence there is — someone spent attention to steer the repo. Convert every correction into a reusable heuristic:

Human review commentCartography heuristic
"use FooService instead of calling the client directly"conventions: "Call FooService for X; don't use the raw client." Confidence High.
"don't touch generated files"pitfalls: "Never edit generated files (*.gen.*); regenerate instead." Confidence High.
"run npm run generate first"workflows: "Run npm run generate before the build." Confidence High.

A correction lands at High confidence immediately — it doesn't need to be seen twice. Record the review-comment URL / PR as evidence so the heuristic is auditable back to the human who set it.

5. Reconcile — no duplicate or stale knowledge

Before writing, reconcile against existing cartography. Read .armada/cartography/ and, for each candidate heuristic:

  • Update, don't duplicate. If a near-twin already exists, update it in place — strengthen its confidence, append the new evidence (e.g. "+ PR #145"), or sharpen the wording. Never append a second entry that says almost the same thing. Two entries on the same topic is a bug in the map.
  • Promote on repetition. A Medium heuristic confirmed by a second run becomes High; note both pieces of evidence.
  • Prune stale / low-value. Remove an entry when it's contradicted by newer evidence (a human reversed the guidance), superseded (the workflow changed — the codegen step was removed), or a Low-confidence guess that was never confirmed across several subsequent runs. Pruning is part of the job: a map full of dead entries is worse than a small accurate one.
  • Demote on contradiction. If new evidence weakens but doesn't kill an entry, lower its confidence and record why, rather than deleting outright.

The store is append-rarely, edit-often: most runs adjust existing entries; only genuinely new knowledge adds a line.

6. shipwright reads cartography before building

cartographer is only useful if the fleet consults it. shipwright's Research step (§2) — where it already reads README / CLAUDE.md / docs/ — is extended to also read .armada/cartography/ and apply relevant heuristics during planning (§3 of shipwright):

  • A workflow heuristic ("run npm run generate first") becomes a planned step.
  • A pitfall ("don't edit *.gen.ts") fences the change.
  • A convention ("use FooService") shapes the implementation to match the grain of the repo.

High-confidence heuristics are applied by default; Low-confidence ones are surfaced as considerations, not hard constraints. This is the payoff: each run the repo gets easier to build because the last run wrote down what it learned.

7. Auto-run once per fleet-run, batched (ship's-bell discipline)

When the cartography config key is on (§8), crows-nest does not fire cartographer once per reconcile — that would emit one cartography update per issue/PR on a busy backlog, all racing on the same .armada/cartography/ files and flooding the review lane. Instead the lookout accumulates the completed runs at its three terminal reconcile points — the same points the ship's bell rings — and dispatches cartographer once per fleet-run, over the whole batch (crows-nest §8d):

  • build-completion (crows-nest §2d) — a background build returned opened; record the new PR's run.
  • PR-pipeline outcome (crows-nest §3e) — a review→merge pipeline reconciled; record the addressed PR (its muster + human review comments are the richest correction evidence).
  • issue-shipped (crows-nest §5) — an issue closed armada:shipped; record the full resolution path.

Each reconcile enqueues a run; the actual cartographer dispatch happens once, at the run's idle point (frontier clear, accumulator non-empty — crows-nest §8d.ii), handed the entire accumulated batch to analyse together. So on the auto path cartographer is invoked with a set of runs, not one — it analyses them all (§4), reconciles once against existing cartography (§5), and emits a single knowledge update (§9a). It runs under the ship's-bell discipline (crows-nest §8c) — a side-channel courtesy, never part of the tick's outcome:

  • Best-effort & side-channel. cartographer runs after the consequential actions (the label swaps, the merges, the issue closes have already happened). It is the last, optional step — never re-ordered ahead of an outcome.
  • Batched & bounded — one pass per fleet-run. At most one cartographer in flight, in the background, in its own context, over the whole batch. It never fans out a swarm, never holds a tick open, and emits one cartography PR per fleet-run, not one per reconcile.
  • Single-writer — no race. Because every pass writes the same .armada/cartography/ files, crows-nest serialises cartographer: it never dispatches a second pass while one is in flight (§8d.ii), so two cartography updates never collide on those files.
  • Never blocks, derails, or fails the tick. If cartographer errors, finds nothing, or the tool isn't available, the tick is unaffected — swallow the failure (log it at most once) and carry on. A failed map update must never turn a green tick red, exactly as a failed bell ring never does.
  • De-duped. A run recorded at two reconcile points (its PR merged and its issue shipped) is analysed once — crows-nest de-dups the accumulator by number (§8d.i), and the batch itself is reconciled as one set, so no run is mapped twice.

With the key off (the default), crows-nest does not accumulate or auto-dispatch cartographer at all — learning is opt-in, and manual /cartographer always works regardless.

8. Config gating — the cartography key

Auto-run is gated by a cartography key in .armada/config.json, mirroring how autoMerge / notify / autoArmSelfFixes gate other autonomous behaviour. commission writes it with a safe default:

// How cartographer learns per-repo heuristics. Default "off": never auto-runs.
//   "off"      → cartographer never auto-runs; only manual /cartographer works (default)
//   "proposal" → batches per fleet-run, then only *proposes* one diff for human approval
//   "on"       → batches per fleet-run, then commits one update into the active PR (rides muster + autoMerge)
"cartography": "off",
  • "off" (default). Cartographer never auto-runs. The fleet behaves exactly as before; a human who wants the map runs /cartographer by hand. This is the conservative default — learning is an explicit opt-in, like autoMerge and autoArmSelfFixes.
  • "proposal". Accumulates runs and, at the fleet-run's idle point (§7, crows-nest §8d.ii), dispatches one batched pass that never commits silently — it presents the proposed cartography diff (as a PR comment or for human approval) rather than pushing. The middle ground: learning is on, but a human signs the update.
  • "on". Accumulates runs and, at the idle point, dispatches one batched pass that commits a single knowledge update into the active PR (§9/§9a) so it rides the existing review + merge gate — one cartography update per fleet-run, not one per reconcile.

commission always writes "off" on a fresh repo — turning cartographer's autonomy on is a deliberate hand edit, never something commissioning enables (same posture as autoMerge: false).

8a. The cartography key interacts with .gitignore — "on" needs a tracked store

Because "on" commits into the active PR by staging .armada/cartography/ (§9), that path must be tracked for the learning to land. If the repo gitignores .armada/cartography/, the git add is a silent no-op and "on" writes into a void — the same silent-gitignore collision class as the drop-in .claude/ issue (#95/#96). This gives a clear rule:

cartographyCommits to the PR?Effect if .armada/cartography/ is gitignored
"off"No (never auto-runs)No effect — nothing is written.
"proposal"No (presents a diff for approval)No effect — a gitignored store doesn't strand it.
"on"Yes (stages + commits)Learning silently dropped — git add no-ops. Warned by commission §1c and cartographer §9.0.

"Gitignored" here means the files won't stage, not merely that the directory is named in an ignore rule: a content-level ignore (.armada/cartography/*, .armada/cartography/**, or a scoped *.md) drops the learned files while leaving the directory reported "tracked". The §9.0 / §1c preflight therefore probes the actual files (a dry-run git add), not just the dir, and the un-ignore hint covers parent-dir (!.armada/) and recursive (!.armada/cartography/**) cases, not only !.armada/cartography/.

So: a repo that wants "on" must keep .armada/cartography/ tracked (not gitignored); a repo that does gitignore it — treating its learned map as local scratch, which is exactly what ARMADA itself does to keep its own cartography out of the shipped plugin — should stay at "proposal" rather than "on". The two guards make the collision impossible to hit silently: commission §1c warns at setup time, and cartographer §9.0 warns again at commit time and skips the commit rather than reporting a success that never landed.

9. Reviewable updates — never a silent default-branch mutation

Cartography is repo knowledge that future builds trust, so an update must be reviewed, never a silent commit to the base branch. cartographer rides the existing review machinery:

9.0 Preflight — refuse to stage a gitignored store (don't silently no-op)

Before staging anything, check that .armada/cartography/ is actually tracked — because if the repo gitignores it, git add .armada/cartography/ is a silent no-op (git refuses ignored paths), the commit carries nothing, and the learning is silently dropped. This is the same silent-gitignore collision class as the drop-in .claude/ issue (#95/#96) and is exactly the failure this guard exists to catch: "on" mode looks like it committed, but nothing landed. commission warns about it at setup (commission §1c); cartographer is the commit-time backstop — never assume the store is committable, verify it:

Test the actual files you're about to commit, not just the directory path. A bare git check-ignore -q .armada/cartography tests only the directory, so a content-level ignore — .armada/cartography/*, .armada/cartography/**, or a scoped *.md under it — can leave the directory reported "tracked" while the real learned files are unstageable; git add then silently no-ops them and the drop class isn't closed. Probe the concrete files with a dry-run add (the same thing the real git add would do), and treat "nothing added / paths are ignored" as GITIGNORED:

# Robust preflight: dry-run the exact add and see if git would actually stage anything.
# --ignore-missing avoids erroring on an empty/new store; the guard fires when the files are ignored.
staged=$(git add --dry-run --ignore-missing -- .armada/cartography/ 2>&1)
if [ -z "$staged" ] || printf '%s' "$staged" | grep -qiE 'ignored by .*gitignore|paths are ignored'; then
  echo "GITIGNORED"      # dir may look tracked, but the learned files won't stage → treat as ignored
else
  echo "tracked"
fi
# Belt-and-braces alternative — check-ignore each concrete file under the store (catches *, **, *.md):
#   git ls-files --others --exclude-standard --ignored -- .armada/cartography/   # lists ignored files, if any
#   for f in .armada/cartography/*.md; do git check-ignore -q "$f" && echo "GITIGNORED: $f"; done

If .armada/cartography/ (or .armada/, or a content-level */**/*.md rule under it) is ignored, do not attempt the silent git add — it would no-op and you'd report success while nothing landed. Instead surface a clear warning and skip the commit, then carry on without failing (on the auto path cartographer is best-effort and side-channel, §7 — it must never turn a green tick red; on the manual path, tell the user directly):

⚠ cartography: .armada/cartography/ is gitignored, so the learned heuristics cannot be committed —
  `git add` would be a silent no-op and the update would be lost. Nothing was committed. To land
  cartography, un-ignore the store yourself so the files can stage — the right un-ignore depends on
  which rule is catching them:
    • a direct dir ignore (.armada/cartography/)        → add `!.armada/cartography/`
    • a recursive/content ignore (.armada/cartography/**, .../*, *.md) → add `!.armada/cartography/**`
    • a parent-dir ignore (.armada/ ignores everything)  → re-include the parents too:
        `!.armada/` then `!.armada/cartography/` then `!.armada/cartography/**`
      (a child negation can't un-ignore a file whose parent dir is still ignored)
  …then re-run; or switch cartography to "proposal" mode (which presents the diff for approval instead
  of committing). I will not modify your .gitignore.

Report this in the §10 summary as Path: BLOCKED (.armada/cartography/ gitignored — nothing committed) so the drop is visible, never silent. Never work around the ignore by force-adding (git add -f) — that smuggles the update past the very .gitignore the repo set on purpose, and past the review intent; the correct resolution is the human un-ignoring the path or choosing "proposal". ("proposal" mode never reaches this preflight in a blocking way — it presents a diff rather than committing, so a gitignored store doesn't strand it; the guard bites only the committing paths below.)

Only once the store is confirmed tracked do you proceed to commit:

  • When there's an active ARMADA PR (the common case — the run that produced the learning is on an open PR): commit the .armada/cartography/ changes into that PR's branch. The update then rides the same muster review + autoMerge gate as the code — a reviewer sees the heuristic change in the same diff as the work that motivated it, and approves or edits it there. Commit message: cartography: <one-line of what was learned>.
  • When there's no active PR (e.g. a blocked issue with no open PR, or a manual run against an already-merged PR): cartographer opens a dedicated cartography PR (cartography: learn from PR #<n>, armed with the triggerLabel so the ready-PR watch reviews it) — or, in "proposal" mode, presents the proposed diff for approval instead of pushing.

Either way the rule holds: a cartography change is always reviewable and never a silent mutation of the default branch. The active-PR path is preferred because it keeps the learning attached to the run that produced it; the dedicated-PR path is the fallback when no such PR exists.

9a. The batched auto path — one knowledge update for the whole fleet-run

On the auto path cartographer is handed a batch of runs (§7, crows-nest §8d.ii), not a single one. It analyses the whole set together and emits exactly one knowledge update for the fleet-run, not one per run — that is the whole point of batching, and what stops the review lane from flooding:

  • Analyse the whole batch, reconcile once. Run the §4 analysis across all the batched runs, then do the §5 reconcile once over the combined set of candidate heuristics. Batching is what makes the dedupe better, not just cheaper: a heuristic that shows up in three of the run's PRs is seen three times in one pass and lands at High confidence (repeated-success / repeated-failure, §3) instead of being written three separate times by three separate per-reconcile passes. De-dup, promote-on-repetition, and prune exactly as §5 — just over the batch.
  • One update, one review object. Emit a single set of .armada/cartography/ edits for the whole batch and land it on one review object via §9:
    • Active PR present (the run still has an open ARMADA PR — e.g. the last PR of the run, or the cartography pass runs before the final merge) → commit the one batched update into that PR's branch. Commit message: cartography: batch learnings from fleet-run (<N> runs: #a, #b, …).
    • No active PR (the common end-of-run case — every PR of the run already merged) → open one dedicated cartography PR for the batch (cartography: learn from fleet-run (#a, #b, …), armed with the triggerLabel), never one per run. In "proposal" mode, present the one combined diff for approval instead of pushing.
  • Single-writer — never two passes on the same files. crows-nest already serialises dispatch so only one cartographer runs at a time (crows-nest §8d.ii). Hold up your end of that contract: a batched pass reads .armada/cartography/ fresh, edits, and lands its one update atomically — it does not assume another pass is interleaving, and it never splits the batch across multiple concurrent PRs. One writer, one batched update, no race on the cartography files.

The manual path (§1) is unchanged: a human invoking /cartographer against a single PR/issue still produces a single-run update via §9 — §9a is only the shape the auto, batched path takes.

10. Report

Summarise what was learned, in one short block:

## Cartography update — <repo> · run #<pr/issue>   (or: fleet-run batch #a, #b, …)
- **Runs:**    <N> analysed in this batch — #a, #b, #c   (auto/batched path; "1" on the manual path)
- **Added:**   <N> heuristic(s)   — e.g. workflows: "run npm run generate before build" (High)
- **Updated:** <N> — e.g. conventions: "use FooService" confidence Medium → High (+ PR #145)
- **Pruned:**  <N> — e.g. removed stale "edit config.yml" (superseded)
- **Path:**    committed to PR #<n>  |  opened cartography PR #<m>  |  proposed for approval  |  BLOCKED (.armada/cartography/ gitignored — nothing committed, §9.0)

The BLOCKED path is the §9.0 preflight outcome — printed when .armada/cartography/ is gitignored so the commit can't land; it makes the silent drop visible (nothing was committed, here's why, here's how to fix it) instead of reporting a phantom success.

On the auto path, this summary is a log line in the tick output (side-channel, §7) — never a ship's-bell notification of its own and never anything that gates the tick.

Inputs

  • Manual: a PR number, an issue number, or nothing (defaults to the current branch's PR).
  • Auto: the issue/PR crows-nest hands it at a reconcile point (§7), plus the cartography config mode (§8).

Output

  • Reviewable .armada/cartography/*.md changes (added / updated / pruned heuristics in the heuristic / evidence / confidence format), committed into the active ARMADA PR (or a dedicated cartography PR / a proposed diff when there's no active PR) so every update rides the muster review
    • autoMerge gate and is never a silent default-branch mutation.
  • A commit-time gitignore preflight (§9.0): if .armada/cartography/ is gitignored, the commit paths skip staging and surface a clear warning (Path: BLOCKED) instead of silently no-op'ing a git add — so "on"-mode learning is never silently dropped. Never force-added past the ignore; the fix is un-ignoring the store or using "proposal" mode. commission §1c warns about the same collision at setup time.
  • A one-block summary of what was added / updated / pruned and which review path it took (§10).
  • The fleet-defect self-improvement loop is untouched — cartographer is about the host repo, not ARMADA (§0).

Keep looking

Skills are one crate of 628,853. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.