Skip to content
On this page

The Code Plugin

The code plugin maps one code repo to one board. It runs inside Claude Code, Codex, or Cursor, analyzes the repo locally, and pushes a graph of services, APIs, databases, and their connections. It also brings the board's build context back to the repo. For a guided first run, start with Getting Started — Hands-On.

Note

Everything the plugin does runs inside your own AI coding session and needs no model provider connected. You connect a model only for the portal's in-app Chat.

Binding makes the repo the board's governing Code Plugin source and the board an app board. /ground also links a board to a repo's documents, including a repo that holds only documents (Grounding a board in documents). To edit boards across a workspace, use the workspace plugin.

One binding, both directions: the plugin pushes the map and pulls the build context back.

Install and connect

The install id is pmap-code. Add the marketplace and install the plugin.

BASH
/plugin marketplace add provenmap/pmap-claude
/plugin install pmap-code@provenmap
# Restart Claude Code so the commands load.

Then connect the repo and push its first board update:

BASH
/login      # browser sign-in — pick a workspace, then this repo's board
/analyze    # map the codebase, locally
/sync       # push it to the board

Any member of the organization can sign in to an app board that already exists, viewers included; pushing needs no seat. Making a system an app from the sign-in page, which creates the board and its binding, is an editor's step, and a viewer isn't offered it. A credential stops working when the member who created it is suspended or leaves the organization.

To change boards later, run /login switch. Local analysis belongs to the board it was built for, so after you connect a different board, /analyze and /sync stop and name both. Run /login switch to go back, or /analyze --clean to delete the local analysis and build one for the new board. Nothing is copied between boards.

Two situations get their own sections below: restoring local state after the plugin's folder is deleted, and switching to a board in another workspace.

Other account commands:

  • /status — what is configured, what changed since the last analysis, the change periods recorded from this checkout, and the last five scheduled runs
  • /configure — hand-managed credentials and CI; see Signing In & Credentials
  • /logout and /update — disconnect, or upgrade to the latest build

When a newer version is published, the message at the start of each session names it and says in one sentence what it brings: run /update, then restart the session. If ProvenMap stops supporting your installed version, its commands stop, say why, and ask you to update.

The lifecycle

The commands fall into five stages:

#StagePurposeCommands
1AccountBind this repo to a board/login · /configure · /status · /logout · /update · /help
2MapMap the codebase onto a board/analyze-archetypes · /analyze · /aspects · /inspect · /sync · /ground · /restyle
3UnderstandRun intelligence on the mapped board/discover · /insights · /changes
4BuildUse the platform's build context in the code/skills · /build · /work-items
5OperateCompare production signals with the board/monitor

/start reads the repo's state, ranks the next steps, and offers to run the first. When a playbook run is live on the bound board, the run's next command step comes first. When work items are waiting on the bound board, /start says how many, names the top three, and offers /work-items. /start --for <slug> starts a playbook on the bound board; to carry out a run's steps, use the workspace plugin's /run-playbook.

Map

/analyze-archetypes settles node types before analysis. It proposes missing workspace archetypes. It's optional unless analysis.archetypeGate is "strict"; then /analyze stops until the check passes, and prompts again when the catalogue or commit changes. Admins review proposals in Archetypes. Flags: --dry-run, --skip-submit, --replace, --force.

/analyze maps the system locally. It pushes nothing and never touches your source files.

BASH
/analyze                                           # incremental pass over what changed
/analyze --clean                                   # full re-analysis from scratch
/analyze --drill <parent-board-slug>/<node-slug>   # map one node into its own child board
/analyze --deeper <folder>                         # give one folder its own board, past the depth cap too
/analyze --all                                     # progressive pass across all layers
/analyze --all --auto                              # the same, unattended — no mid-run prompts
/analyze --scheduled                               # unattended upkeep for a schedule: refresh changed boards, sync, then record change periods

By default, /analyze reads only the git diff since the last analyzed commit. When a board's only changes are edits to files its nodes already cover, a script refreshes it and none of your coding agent's usage is spent. /status lists that board as script refresh (no model). Run /analyze --clean when a result looks stale.

--clean deletes the local analysis and everything derived from it: the board files, the plan, the coverage record, and the local copies and push record of the /discover results. It keeps your connection, settings, role map and anything captured by hand. Ask for the list first and the plugin reports what would go without deleting anything.

Nothing in the app is deleted. The next /sync updates the pushed boards from the fresh analysis. The next /discover adds its results beside the old insights and context boards; delete those in the app if you no longer want them.

Each run reports analysis coverage, how many planned boards are built, stale, incomplete, or unbuilt, also shown on the hub's analysis coverage card (App Boards).

A proposal is a board the plan suggests but never builds unasked. It's one of three kinds:

  • a cluster of at least analysis.plan.unitFloor significant files that no board holds yet
  • a drill-down the analysis suggested
  • removing a board whose files are all gone

/analyze lists each one with its key: --plan-accept <key> accepts it, and --plan-dismiss <key> dismisses it. The Next area question in /analyze offers both. A dismissed proposal stays off the list until it grows by unitFloor more significant files.

Important

Changed 4 October 2026: Nothing is proposed past analysis.plan.maxDepth. /analyze names the boards that could split further at the cap once, under At the depth cap, with nothing to accept.

/analyze --deeper <folder> gives one folder its own board, past analysis.plan.maxDepth too. The new board sits under the board that holds most of the folder's files. Files the plan put on other boards stay there, and the run names them. /analyze refuses, and says what to name instead, when the folder:

  • is one file, which is a node on its board
  • holds fewer significant files than a board at its layer needs: 10 at layer 1, 5 deeper
  • is already a board, or adds nothing beyond boards that exist
  • has no single board holding more than half of its files

Each selected drill-down builds in parallel in its own subagent, on the model in analysis.subagentModel. --auto reports oversized nodes and file waivers instead of resolving them; branch, credential, and strict-archetype checks still stop it.

/analyze --scheduled keeps the boards current on a schedule you create, such as a local routine in Claude Code or a scheduled task in Codex. Each run refreshes only the boards whose files changed in commits since their last analysis, then syncs them. It then records the change periods git has since the last run, with the same sentences /changes writes. When no board changed, the run reads no code and pushes no board. It never builds a new board or accepts a proposal; run /analyze --auto for that.

A run refreshes at most analysis.plan.maxScheduledRefreshes boards, and the next run continues with the rest, longest-waiting first. Scheduled Runs explains the limit.

/monitor and /ground take --scheduled too. Every scheduled run is recorded, with the reason when it stops, and shows in /status and on the hub.

Imports that leave a drill-down board's scope appear as boundary ports, ghost nodes rebuilt on every run; see Nodes & Edges.

/sync pushes the diff, not the whole board. It also adds the ✓ Confirmed mark to Completed work items whose structural changes match the code. After each board it lists the work items it confirmed, and the Open and In progress ones it completed because their changes were in code. It also names any work item you completed in this repo whose structural changes it didn't find.

BASH
/sync                  # one board (prompts if you have several)
/sync --board <slug>   # a specific board
/sync --all            # the whole layered tree

/sync describes each push in one sentence. The agent writes what the push changes in the architecture, such as "Now snapshots baskets to a new table before checkout". Each push session shows it beside who pushed, and so does the root hub's Recent activity card, under Add widget. The agent writes it only from what it knows changed since the last sync, and leaves it out otherwise. The hub then shows the push's type and counts.

/sync records no change period. Who did what in the repo, week by week, is /changes's job (Understand). When closed periods are missing, /sync ends with one line that says how many and names /changes.

Warning

By default, synced nodes and edges include a source reference: the relative file path. The board links each path to the file in your repository, on the branch the binding is pinned to. /login records the repository on the binding; so does the first /sync from a repo with an origin remote. If paths are sensitive, set "includeSourceReferences": false in .provenmap/config.json. Local analysis under .provenmap/boards/ keeps paths, so you can re-enable them without re-analyzing.

The security page lists everything each command sends to ProvenMap, and the privacy policy says how it is kept. /help links both.

/sync tags each business area with its domain. The agent looks once at every board it hasn't seen, including any /analyze has rewritten. It reads an outline of the whole tree and gives each business-area node one domain tag, such as domain:billing, reusing your organization's domain tags. The nodes inside it, the boards it drills into, and the tables, endpoints and channels they use all take that domain. A tag you add to a node yourself wins over the one the plugin pushed. /sync then names how many nodes it tagged.

/sync styles the boards it pushes from the styling plan /analyze saves for size, color, and layout. If styling fails, the structure is still pushed; run /restyle.

BASH
/restyle              # pick from your least-styled boards
/restyle <board-slug> # restyle a specific board

/restyle creates a new plan for your approval, with no /sync needed after. The latest styling decision wins, whether it came from the plugin or an architect's /style-board.

/sync checks the board's boundary rules against this checkout on each successful sync, with nothing to configure. The report adds a totals line and one line per rule violated or not evaluated:

TEXT
Boundary rules: 3 hold, 1 violated, 1 not evaluated.

The plugin never changes code to fix a violation. On a branch other than the binding's pinned branch, the check is skipped.

/ground links the board's nodes to the documents that back them. After /sync, it writes an evidence link, an anchor and quoted excerpt, wherever a document states a node's claim. It refreshes links whose document changed, drops links whose document is gone, and pushes the result without asking you to approve each link. The report counts the links stored, removed and drifted, names each document that changed since it was cited (drift), and lists the nodes left unlinked, with the reason. For a repo that holds only documents, see Grounding a board in documents.

BASH
/ground                  # the bound board
/ground --board <slug>   # a specific board
/ground --scheduled      # unattended, for a schedule: no prompts, and the run is recorded

When nothing has drifted, gone missing or been left unlinked, /ground ends without changing or pushing any link, so a scheduled run is cheap.

/aspects, in full

/aspects extracts aspects, the typed details attached to a board's graph, from code and reconciles them onto the board. It never overwrites rows authored in the portal.

Important

Changed 10 October 2026: the command is /aspects, with the same flags and workflow. /adopt only prints that it is now /aspects.

BASH
/aspects --aspect <kind> [--mode replace|merge] [--comparisons all|none] [--dry-run]
--aspect <kind>What it extracts
database.schemaTables, columns, keys, indexes
api.surfaceEndpoints, parameters, auth
ui.pagesThe app's front-end route surface — see Pages
event.catalogPublished and consumed events, and their brokers
authz.registryThe policy definitions that decide who can do what
api.clientsThe other services the code calls, over what, and the calls it names — see Aspects Across Systems
ai.surfaceThe agents the code runs, the tools it serves to agents and the places it calls a model — see Aspects

/aspects doesn't extract boundary rules: an architect declares them on the board, and /sync checks them.

/aspects describes itself in one sentence, as /sync does, naming the tables, endpoints or channels it changed; the push shows it on the hub. The Schema and API contract change rules are answered on the change period its push lands in, from the rows it added, changed and removed.

Run bare /aspects to pick several kinds at once. --db and --api are back-compat shorthand for database.schema and api.surface. Extraction reads definitions only: it never runs your app, connects to a live database, or evaluates a policy against real inputs. Run /analyze and /sync first.

Every row /aspects pushes carries the file and line it was read from, and the Aspects screen shows it. A field the agent cannot cite, such as a column's nullability or whether a parameter is required, stays empty rather than guessed. A row whose file is unchanged since that aspect's last push keeps that push's reading of its contract, so a re-extraction cannot drift a contract nobody touched. The nodes that use a row are always read afresh. The result names the commit it compared against; --no-copy-through reads every row afresh.

Each table, endpoint and channel takes the domain of the node it is used by. After a push, /aspects says how many rows have no domain yet; run /sync, which tags the board's business areas, then /aspects again. --dry-run builds the rows exactly as a push would, without sending them.

A push is refused when it reads the shape of fewer than half the contracts the board's last push read. The refusal gives the counts: "Landing it would wipe shapes a previous run read." Extract the shapes and push again, or push with --force when the loss is real.

When the board sits on an open comparison, /aspects reads it first. On the new side of a rewrite it looks for the contracts the old side served before anything else. The summary says how many it found, how many it did not, and what else the repo serves.

When a comparison tracks a branch of this app, /aspects asks whether to push that branch's contracts too. --comparisons all or --comparisons none answers without asking, for a scheduled run. It pushes the board first, then reads each tracked branch through a scratch checkout under .provenmap/, so your own checkout never changes. Those contracts land in the comparison's set and the board stays as the pinned branch pushed it; the result says where each push landed. A checkout of a tracked branch stops every command and names the comparison.

After its pushes, /aspects redraws the two boards of each open comparison the app is on whose table changed. It draws both sides together, each app with the contracts that differ, checks them against the comparison's contracts and lands both at once. A comparison whose boards already match its table is left as it is.

/inspect

/inspect captures your running app into the board. It opens the app in a browser on a throwaway profile, where Pick selects a component and Annotate boxes a region and attaches a note.

BASH
/inspect                          # open the running app and record a session
/inspect --url http://localhost:3000
/inspect --env local              # open a URL saved under inspect.urls
/inspect --capture <url>          # headless: screenshot + element map, no human
/inspect --list | --show <id>     # review recorded sessions

Capturing needs no credentials; only pushing does. A pushed session becomes a work item's visual context and stores each page's page capture on its ui.page aspect for Pages.

Understand

/discover runs after the repo is mapped and synced, and ranks the findings worth showing. It reads the code behind the strongest candidates and leads with What stands out: the finding for each pick, with the file and line it rests on. Test and example code stays out of the suggestions, which come in two kinds:

  • Insights describe one element and trace the relevant path, such as a chokepoint, an outage cascade, or the route from an entry point to a leaf.
  • Context boards draw a small C4 board of relationships to explain a blast radius, a neighborhood, or where data lives.
Watch: /discover finds the insights and context boards worth showing

Take the suggested set, pick from the ranked menus, or refocus the ranking. --auto takes the suggested set without asking, a [count] sizes it, --lens reliability,onboarding,ownership weights the ranking up front, and --board <slug> scopes one board.

Insights appear under the Architecture Highlights skill, and context boards in the hub's Context boards card. A new run replaces the previous results. A context board the new run draws again keeps its address, so a link you shared still opens it.

/insights runs the workspace's insight skills locally over the board and source, then pushes the insights. Each is tied to an element and can become a work item.

/changes reads the repo's git history into change periods: one record per calendar week or month, in UTC, for the branch the binding is pinned to. Each holds the period's commits and how many name a coding agent, each person with the agent named in their commits, the services the changed files belong to, and the work item numbers the commits cite. It answers the Schema, API contract and Infrastructure change rules from the files the commits changed, with up to five names and paths behind a yes. The server answers Structure itself, from the syncs that landed in the period.

It also groups the period's commits into pieces of work, each one diary entry. A commit joins the piece named by its conventional-commit scope (feat(hub): … joins hub), else the node most of its files belong to, else other changes. A repo keeps at most eight a period, the largest first. Each lists the nodes its files belong to, who did it with which agent, the rules its files hit and the work item numbers its commits cite. It also records when its first and last commits landed.

BASH
/changes                    # record every period not yet recorded, back to the workspace's Read history back setting
/changes --since <date>     # read further back, once
/changes --recompute        # rewrite closed periods already recorded
/changes --facts-only       # record the facts and write no sentences

The agent writes the words, newest period first. For each piece of work it writes a headline, what the work did, and one word per rule it hit, its impact: breaking, additive or internal. It also writes what changed for each rule answered Changed.

Each sentence names an area of work with no counts and no judgement, and never ranks or compares people. Anything the commits don't settle, an impact included, is left out rather than guessed. A scheduled run writes the same sentences for every period it records. Commit messages and file lists stay on your machine; only the record is pushed.

The open period is rewritten on every run; a closed one is written once unless you pass --recompute. A shallow clone that doesn't reach a period's start marks it truncated. /analyze --scheduled runs /changes after its sync. /changes ends by saying how many periods it recorded, how many were already recorded, and why any was dropped.

/sync and /analyze end with a line when closed periods are missing, and /start offers it once boards are analysed and no period is recorded. /status has a Changes section with the last run and the newest period. Changes shows the record on the board and how a flagged rule is reviewed.

Build

These commands bring board context back and write application or compiled-skill files into the repo, where the other commands write local plugin state.

/skills compiles this app's skills, with related skills grouped into a recipe, into IDE-native files (.claude/skills/ on Claude Code). It preserves local edits and records what it wrote in pmap-skills.lock.json; commit both so the team shares them.

BASH
/skills            # compile the bundle into the repo
/skills --status   # read-only: up to date? changed upstream? edited locally?

/build implements the build context (compiled skills, open work items, unbuilt board design, and aspect contracts), including in an empty repo. It changes nothing until you approve the plan, and a re-run builds only what changed.

BASH
/build           # assemble the build context, plan, then implement after approval
/build --plan    # present the plan only — no files touched

/work-items works handed-off work items in five steps: claim, plan, implement from Instructions and anchors, verify with project checks, then resolve with a note.

Before planning, /work-items reads the code the work item changes, what depends on it and the tests near it. It also reads your rules files and compiled skills, then runs your checks for a baseline. Nothing is edited until you approve the plan.

You pick the work item in the terminal, or choose Pick on the board to pick it in the browser. It never resolves without verification evidence, and blocks stale work items. A structural work item can skip the resolve: the next /sync completes it once its changes are in code, unless it has a Remove answer.

You author, hand off, and assign work items in the portal; see Work items.

Operate

/monitor matches production signals (stack frames, resource names, routes, and tags) to board elements and shows the matches as insights. It asks you once about each uncertain match.

BASH
/monitor                          # pull signals from connected monitoring tools
/monitor --input <signals-file>   # or feed an exported, normalized signals file
/monitor setup                    # configure sources and a recurring run
/monitor --scheduled              # unattended, for a schedule: no prompts, and the run is recorded

/monitor setup scaffolds config and, where supported, offers to create a recurring /monitor --scheduled run. Unattended runs read PMAP_* credentials, so secrets never pass through chat.

Configuration reference

Settings live in .provenmap/config.json and credentials in .provenmap/credentials.json. Add a setting to override its default; delete it to restore the default. config.schema.json, beside the config, lists every setting and its default for editor completion.

What /login writes

A fresh sign-in on Claude Code writes this file:

JSON
{
  "$schema": "./config.schema.json",
  "baseUrl": "https://platform.provenmap.com/api",
  "branch": "main",
  "boardSlug": "payments",
  "excludePaths": ["node_modules", "dist", ".git", "coverage"],
  "includeTests": false,
  "includeSourceReferences": true,
  "analysis": { "subagentModel": "sonnet" }
}

On Codex, subagentModel is gpt-5-codex; Cursor omits it.

SettingDefaultEffect
baseUrlhttps://platform.provenmap.com/apiThe API endpoint /login used. Change it only for a self-hosted instance.
branchset by /loginThe git branch pinned to the binding. Commands refuse to push from any other branch.
boardSlugset by /loginThe board this repo is bound to, the root of its board tree.
excludePathsnode_modules, dist, .git, coverageRepo-relative directories the analysis skips, with everything beneath them.
includeTestsfalseSet true to analyze test files and test directories.
includeSourceReferencestrueSet false to omit file paths from synced nodes and edges.
analysis.subagentModelset by /loginThe model for every parallel layer subagent. "" uses per-layer defaults: domain layers inherit the session model, deeper layers a faster one.

Tuning settings

Analysis coverage

SettingDefaultEffect
coverage.ignore[]Glob patterns left out of the planned board tree and its counts.
coverage.extensions[]Extra file extensions to count, by filename only and with no dependency edges.
coverage.infratrueCounts infrastructure and schema files (Docker, Terraform, CI workflows, Kubernetes, SQL migrations, serverless templates) once a board covers them. Set false to exclude them.

Board content

SettingDefaultEffect
analysis.edgeBudgetPerNode2Board-wide edge budget: this value times the node count, drawn highest import count first. 1 gives a leaner board; 0 draws every resolved relation, subject to analysis.hubDrawnPerHub.
analysis.hubDrawnPerHub3On boards of ten or more nodes, caps the consumer edges drawn from a module that over 40% of the board imports; the node lists the rest. 0 lists every consumer.
analysis.archetypeGateoffSet "strict" to require a settled archetype vocabulary before /analyze. Run /analyze-archetypes to pass the check.
analysis.minorFilesallHow small helper files appear on drill-down boards: all folds eligible files into the node that uses them, one-host folds only single-importer files, off gives each file its own node. Eligible means at most analysis.minorMaxLines lines, imported by another file, and no exported class.
analysis.minorMaxLines100Line cap for the minor-file fold. Files above it are always their own candidates.
analysis.roots[]Extra source directories, relative to the repo root, for a layout your build files don't declare. Python, Go, Ruby, Rust, and Swift imports resolve against each one.

Sync and /inspect

SettingDefaultEffect
validation.skipBoardStructureCheckfalseSet true to opt out of the board-structure guardrail described in When a run fails.
inspect.urls{}Named app URLs for /inspect, such as {"local": "http://localhost:3000"}. Run /inspect --env local to open one. /inspect offers to save a URL you give it here.
inspect.defaultEnvnullThe environment /inspect opens when you pass neither --url nor --env. The first environment you save becomes the default.

Board-tree plan

SettingDefaultEffect
analysis.plan.maxDepth4The deepest layer the plan creates or proposes boards for; the bound board is layer 0. /analyze --deeper <folder> goes past it for one folder. null removes the cap. See When plan settings take effect.
analysis.plan.unitFloor12The minimum significant files a cluster needs to become a board or a proposal. A child must also leave that many in its parent.
analysis.plan.maxParallel4Boards /analyze --auto builds at once.
analysis.plan.maxBoardsPerRun25Boards one /analyze --auto run builds before it stops and asks.
analysis.plan.maxScheduledRefreshes15Changed boards one /analyze --scheduled run refreshes. The next scheduled run continues with the rest, longest-waiting first; /analyze --auto refreshes them all now.
Tip

To plan without limits, set maxDepth to null for depth and lower unitFloor for breadth, so smaller clusters become boards too. Raise maxBoardsPerRun to build the whole tree in one /analyze --all --auto run. Every extra board adds model tokens, analysis time, and rows against your graph allowance.

When plan settings take effect

The first /analyze computes the board-tree plan and stores it; maxDepth and unitFloor apply to that computation. maxParallel, maxBoardsPerRun and maxScheduledRefreshes apply on every run.

Warning

Changing maxDepth or unitFloor after the plan exists doesn't resize it: planned boards stay, and deeper layers appear only as proposals. To re-plan, run /analyze --clean, then rebuild and /sync. /sync doesn't delete boards the new plan drops.

Files and allowance

Edges take the largest share of your organization's graph allowance. A repo of about 3,000 files across 29 boards uses about 2,300 rows at the default analysis.edgeBudgetPerNode, 1,500 at 1, and 4,200 at 0.

Credential fields and PMAP_* variables are covered in Signing In & Credentials. Everything else the plugin writes lives under gitignored .provenmap/. Commit what /skills writes and the application changes from /build and /work-items.

Nothing syncs in the background: analysis, sync, and monitoring run only when you, or a schedule you created, run the commands.

Grounding a board in documents

/ground works in two kinds of repo.

A code repo. The board came from /analyze and /sync. /ground cites the ADRs, RFCs, READMEs and design docs in the tree against the nodes they describe, and never overwrites the analysed board with a mirror.

A documents-only repo. The architect authors the board in the app; the repo holds the PRDs, RFCs and ADRs. Bind the repo to that board with /login, using the same binding credential as a code repo, then run /ground. It mirrors the board locally so /insights and /discover can read it, and links the documents to its nodes.

There is no /analyze phase. /start routes such a repo straight to /ground, and /status shows the board as mirrored, with its evidence links and drift in place of sync state. After /login switch moves the binding to a different board, the next /ground starts from the previous board's links.

In both cases, each push replaces the binding's evidence set on the server.

Supported document formats:

FormatExtensions
Markdown / MDX.md, .mdx, .markdown
reStructuredText.rst
AsciiDoc.adoc, .asciidoc
Plain text.txt
Wiki exports (Confluence, Notion).md, .html
PDF.pdf (extractable text)

/ground reads the whole repo, skipping dot-directories, node_modules, and any configured excludePaths.

Important

Changed 24 September 2026: grounding moved here from the connect plugin, which is retired. /ground picks up the .provenmap/ state the old plugin left, as is.

Restore local state from ProvenMap

When the .provenmap/ folder is gone, because you removed it to start over or a teammate cloned the repo fresh, /login reconnects the repo to the same board. The next board command then restores the bound board and its child boards from ProvenMap, and reports which boards it restored.

A restored board is a copy of what the app holds, not an analysis of your code. The plugin has no record of which commit each board was built from. The first /analyze after a restore therefore reads every board in full, not the diff since the last run. It rebuilds each board under the slug it already has in the app, so the boards, their work items and their insights stay where they are. /sync then pushes only what changed.

The new plan may cut the code differently from the tree already in the app. /analyze lists each board in the app that the plan does not cover. Run /analyze --deeper <folder> to keep one as a board. Otherwise /sync names it as orphaned once its parent board is rebuilt, and you delete it in the app if it is no longer wanted.

/sync refuses a push that would create a second board at a node that already drills into one in the app. Nothing is pushed; run /analyze so the board carries the plan's slugs, then /sync again.

Settings and credentials come back through /login. The role map is not stored in ProvenMap and does not come back; /analyze writes a new one.

Switch to a board in another workspace

/login switch connects the repo to a board you pick in the browser, in any workspace you belong to. A common case: you mapped the Volleyland repo into a Volleyland app board in your own trial workspace, Kai's sandbox, while evaluating. The team has since set up the company workspace, Volleyland Studio, where the architect created a Volleyland app board of its own, with the same slug. You run /login switch to move the repo there.

Local analysis belongs to the board it was built for. The plugin notices at connect time that your analysis was built for the board in Kai's sandbox, and says so. Every board command then stops on the same message until you choose a way forward. Nothing is pushed and nothing local is changed.

The message names both boards and both workspaces and offers two choices:

  • Go back to Kai's sandbox. Run /login switch again and pick the board there. Your local analysis keeps working as it is.
  • Continue with Volleyland Studio. Run /analyze --clean. It deletes the local analysis and everything derived from it, then builds a fresh one for the Volleyland Studio board. The board in Kai's sandbox is untouched. If the architect's board already has child boards, the plugin restores them first and rebuilds them in place, as in Restore local state from ProvenMap.

Nothing is copied between boards. Both workspaces hold a board with the slug volleyland, and pushing the sandbox analysis at the studio board would overwrite what the architect drew. If the sandbox board no longer exists, or you have left that workspace, /analyze --clean is the only way forward.

When a run fails

What you seeWhat's happening, and the fix
/sync rejected by the board-structure checkA board with more than 8 nodes has no domain_group containers. Re-run /analyze, which populates them. If the board really is that simple, set validation.skipBoardStructureCheck; every /sync then says so on stderr.
/sync refuses on a branch mismatchThe branch in your config is not the branch the binding is tied to. Set the config to match the binding.
Browser says This board isn't in your workspaces.The project remembers a board in a workspace you didn't sign in to, and plain /login only reconnects to that board. Cancel it and run /login switch to pick a workspace and board; your local analysis is kept, and the plugin tells you whether it belongs to the board you picked.
Credentials rejectedThe credential was revoked, a fresh /login on this machine replaced it, or the member who created it has left the organization (the message says so). Run /login to reconnect. For a reference binding, use Generate new secret under Binding actions → Copy credentials and update credentials.json or your CI environment variables.
Push rejected with a repo mismatchThe board is bound to a different repo. The binding refuses pushes from any repo but the first one that pushed. Bind this repo to its own board instead.
/sync stops saying a drill-down would duplicate a boardA node on the board points at a child slug other than the board the app already has at that node, so the push would create a twin and orphan the existing board's subtree. Nothing was pushed. Run /analyze, which gives the board the plan's slugs, then /sync.
/analyze or /sync stops saying the board was renamedSomeone renamed the bound board in the app, so your local boards can't be pushed. Run /analyze --clean; /login switch can't help, since the connection is the same.
/aspects stops before extractingThe board structure is not synced yet. Run /analyze → /sync first, then /aspects. If strict archetype checking is enabled, run /analyze-archetypes before /analyze.
/ground stops saying the board was never pushedThe analysed board isn't on the server yet. Run /sync, then /ground.
Claude says a .provenmap/ file is written only by the ProvenMap scriptsOn Claude Code, the plugin blocks hand edits to the files its scripts own: the element and evidence stores, boards/manifest.json, tree-plan.json and plan-run.json. Change the board files and run /sync, or run /analyze to rebuild the plan (/analyze --clean starts over).

What's next