Set Up Persistent Memory and Metrics
Your agents finish a session, and their findings disappear. The next
session starts from scratch, with no continuity and no accumulated
evidence, so you cannot tell whether yesterday's change made
anything better. gemba-wiki and
gemba-xmr work together to solve this. The wiki gives
agents durable shared memory, and XmR charts turn that memory into a
signal the team can trust.
This guide covers the full path. You bootstrap the wiki, record metrics and chart them, then embed live charts in a storyboard that updates itself.
Prerequisites
- Node.js 22+
-
The
gemba-*commands. Every example below runs them withnpx, which downloads each command on demand. To install the whole family once, runnpm install -g @forwardimpact/gemba. - A GitHub repository with a wiki enabled (Settings > Features > Wikis)
-
GITHUB_TOKENorGH_TOKENset in the environment (for wiki clone/sync) -
Agent profiles defined under
.claude/agents/(one.mdfile per agent) -
Skills defined under
.claude/skills/(one directory per skill)
Step 1: Bootstrap the wiki
Initialize the wiki working tree from your repository root:
npx gemba-wiki init
init: wiki ready at /home/you/repo/wiki
This clones the repository's GitHub wiki into
wiki/. The command derives the wiki URL from the
repository's origin remote.
init also pre-creates one
wiki/metrics/<skill>/ directory per skill whose
directory name starts with kata-. That prefix is a
shipped default that refers to Kata, the platform's reference
tenant. You can read about its practice at
kata.team. A skill with any
other name loses nothing, because
gemba-xmr record creates the directory on the first
write.
The command is idempotent, so a second run on an initialized wiki changes nothing. The command authenticates with ambient GitHub credentials.
After initialization, the directory structure looks like this:
wiki/
Home.md
MEMORY.md
metrics/
kata-documentation/
kata-security-audit/
kata-spec/
...
Each metrics/<skill>/ directory is where that
skill's observations collect over time.
Step 2: Set up agent summary files
Each agent needs a summary file in wiki/ with a message
inbox marker so that teammates can send memos. Name the file after
the agent profile, and create one per agent:
<!-- wiki/platform-engineer.md -->
# Platform Engineer
## Message Inbox
<!-- memo:inbox -->
## Summary
Last run: (none)
The <!-- memo:inbox --> marker is invisible in
rendered markdown, but gemba-wiki memo requires it.
Without it, the memo command exits with code 2 and a diagnostic.
Place the marker once and do not remove it.
Step 3: Record observations to CSV
As agents run, they record measured observations to the CSV file for
their skill. The gemba-xmr record command handles the
file lifecycle. It creates the directory and the CSV header if they
do not exist:
npx gemba-xmr record --skill code-review --metric findings_count --value 3 --unit count --event-type kata-shift
--event-type gives the workflow that records the row
(its filename without .yml). Inside GitHub Actions you
can omit it, because the value falls back to
$GITHUB_WORKFLOW_REF. Local runs must pass it
explicitly.
The read commands filter on event_type, and they
default to the kata-shift
slice. That default is the reference tenant's shift workflow.
Record with
kata-shift to follow this guide end to end. If you use
your own workflow name, pass
--event-type <name> to every read command, and
expect gemba-wiki refresh to skip those rows, because
refresh reads the default slice only.
metric=findings_count n=1 status=insufficient_data latest=3
The one-line summary confirms that the command appended the row. It
also shows the current sample size and the classification. With only
one data point, the status is insufficient_data. XmR
limits require at least 15 observations.
The year in the path comes from the recorded date. The CSV is
written to wiki/metrics/code-review/2026.csv with the
standard header:
date,metric,value,unit,run,note,event_type,host_run
2026-05-04,findings_count,3,count,,,kata-shift,local
Record with full context
Add a run identifier and a contextual note:
npx gemba-xmr record \
--skill security-audit \
--metric findings_count \
--value 5 \
--unit count \
--event-type kata-shift \
--run "https://github.com/org/repo/actions/runs/12345" \
--note "new dependency audit rule"
The run field links back to the CI run or the session
that produced the observation. The note field captures
what you learned. It records context that the numbers alone cannot
show.
CSV schema
| Field | Required | Description |
|---|---|---|
date |
yes | ISO 8601 (YYYY-MM-DD). Sort key. |
metric |
yes | Metric name. One CSV can carry many metrics. They are grouped. |
value |
yes |
Numeric. validate rejects a non-numeric value.
|
unit |
yes |
Free text (count, days,
pct, ...). validate rejects an empty
unit.
|
run |
no | URL or identifier of the run that produced this observation. |
note |
no | Free text. Record what you discovered when a signal appears. |
event_type |
yes |
The workflow that recorded the row (its filename without
.yml).
|
host_run |
no |
The CI run that produced the row. record writes
local when no run id is available.
|
Validate the file at any time:
npx gemba-xmr validate wiki/metrics/code-review/2026.csv
A zero exit code means the file matches the schema.
Step 4: Analyze the metrics
Once a metric has at least 15 observations,
gemba-xmr computes natural process limits and applies
Wheeler's three detection rules. The limits only mean something
when each metric tracks a single process. See
One process per chart. Run the analysis:
npx gemba-xmr analyze wiki/metrics/code-review/2026.csv --metric findings_count
The output includes the 14-line XmR chart, the computed limits, and a classification. For structured output that scripts and agents can parse:
npx gemba-xmr analyze wiki/metrics/code-review/2026.csv --metric findings_count --format json
{
"source": "wiki/metrics/code-review/2026.csv",
"generated": "2026-05-04",
"event_type": "kata-shift",
"metrics": [
{
"metric": "findings_count",
"unit": "count",
"n": 18,
"from": "2026-04-02",
"to": "2026-05-04",
"status": "predictable",
"classification": "stable",
"latest": { "date": "2026-05-04", "value": 3, "mr": 1 },
"stats": { "mu": 6.4, "R": 2.3, "sigmaHat": 2.03, "UPL": 12.5, "LPL": 0.3, "URL": 7.5, "zoneUpper": 9.4, "zoneLower": 3.3 },
"signals": { "xRule1": [], "xRule2": [], "xRule3": [], "mrRule1": [] }
}
]
}
Read classification first:
| Classification | Meaning | What to do |
|---|---|---|
stable |
No rules activated. Predictable. | Leave it alone. Intervention makes the process worse. |
signals |
At least one X-chart rule activated. | Investigate what changed. |
chaos |
mR Rule 1 activated. Variation is unstable. | Investigate the outsized moves before you trust any limits. |
insufficient |
Fewer than 15 points. | Record more observations. |
The limits come from the data itself, so you need no external targets. Do not set goals based on these limits. They describe what the process does, and not what it should do.
For a deeper look at signal rules, chart anatomy, and how to respond to each classification, see XmR Analysis.
Step 5: Embed live charts in the storyboard
A storyboard is a monthly markdown file in wiki/ that
tracks the team's metrics.
gemba-wiki refresh writes a skeleton for the current
month when no file exists yet. Add one marker pair per metric you
want charted:
<!-- wiki/storyboard-2026-M05.md -->
# Storyboard -- 2026-M05
## Metrics
### findings_count (code-review)
<!-- xmr:findings_count:wiki/metrics/code-review/2026.csv -->
<!-- /xmr -->
### cycle_time (delivery)
<!-- xmr:cycle_time:wiki/metrics/delivery/2026.csv -->
<!-- /xmr -->
Each XmR block is a marker pair. The opening comment gives the
metric and the CSV path. The closing comment marks the end of the
region that refresh replaces.
The skeleton also has obstacle and experiment sections, and
refresh fills those from your issue tracker. The
runtime renders those sections but does not define their meaning. An
obstacle and an experiment take their meaning from the improvement
method your team runs. One worked method is
the agent-team practice.
Regenerate all charts in the storyboard:
npx gemba-wiki refresh
Without a path argument, this targets the current month's
storyboard at wiki/storyboard-YYYY-MNN.md. To refresh a
specific file:
npx gemba-wiki refresh wiki/storyboard-2026-M05.md
After refresh, each block contains the fenced chart and a signal summary that lists any fired rules:
<!-- xmr:findings_count:wiki/metrics/code-review/2026.csv -->
```
UPL 12.5 ┬
│ ·
+1.5σ 9.4 │ · · · · · · · · · ·
μ 6.4 ┼
-1.5σ 3.3 │ · · · ·
│ · · ·
LPL 0.3 ┴
URL 7.5 ┬
│ · · · · · ·
R 2.3 ┼
│ · · · · · · · · · ·
0.0 ┴ ·
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
```
**Signals:** —
<!-- /xmr -->
When the metric has fewer than 15 points, the block shows an
"Insufficient data" line instead of the chart. The block
lists fired rules by name (xRule1, xRule2,
xRule3, mrRule1). A dash means none fired.
The operation is idempotent, so two runs produce the same output. The command leaves files without markers unchanged.
Step 6: Sync the wiki
The wiki is a separate git repository. Two commands keep it in sync with the remote:
npx gemba-wiki pull
pull: up to date
npx gemba-wiki push
push: committed and pushed
push does nothing when no local changes exist. On
conflicts, local state wins, so the most recent session's
observations take precedence. pull exits non-zero with
a diagnostic when it detects a conflict.
Both commands work well as hooks in your agent workflow. Run
pull at session start to pick up changes from other
agents, and run push at session end to save your own.
Step 7: Send memos between agents
When one agent discovers something that another agent should see on its next run, a memo delivers the message:
npx gemba-wiki memo --from qa-engineer --to platform-engineer --message "findings_count shifted after the new review rubric landed"
wrote /home/you/repo/wiki/platform-engineer.md
The message appears in the target agent's
## Message Inbox section:
- 2026-05-04 from **qa-engineer**: findings_count shifted after the new review rubric landed
Newest memos appear first. To reach every agent except yourself:
npx gemba-wiki memo --from qa-engineer --to all --message "storyboard refreshed with new baseline"
Verify
Work through this checklist to confirm that the full memory system works:
-
Wiki exists. The
wiki/directory contains a.gitsubdirectory.git -C wiki rev-parse --git-dirExpected:
.git -
Metrics directories exist. One per skill that
initpre-creates, plus one per skill you have recorded against.ls wiki/metrics/Expected: one directory per skill (for example
code-review/,kata-spec/). -
CSV validates. At least one CSV passes schema validation.
npx gemba-xmr validate wiki/metrics/code-review/2026.csvExpected: exit code 0.
-
Analysis runs. If 15+ observations exist, the classification is not
insufficient.npx gemba-xmr analyze wiki/metrics/code-review/2026.csv --format jsonExpected:
"classification"is"stable","signals", or"chaos". -
Storyboard refreshes. Charts regenerate without errors.
npx gemba-wiki refreshExpected: no stderr output.
-
Sync round-trips. You can push and pull changes.
npx gemba-wiki push && npx gemba-wiki pullExpected:
push: committed and pushed(ornothing to push) andpull: up to date. -
Memos arrive. A test memo appears in the target's inbox.
npx gemba-wiki memo --from test --to platform-engineer --message "verify memo delivery"Expected: a
wrote <project-root>/wiki/platform-engineer.mdline.
What's next
Send a Memo or Update a Storyboard
Communicate across your agent team and keep storyboards current. You do not manage the wiki infrastructure yourself.
Audit and Auto-Fix the Wiki
Keep the wiki valid against a declarative rule catalogue. Auto-fix what is safe to fix. Report the rest to a human, so that stale memory does not corrupt coordination.
Allocate Collision-Ledger Entries for Parallel Work
Assign stable ids to parallel work without merge collisions. An append-only issue thread anchors every id. The ledger page gets a projection only when you rebuild.
Chart a Metric and Check Variation
Know whether a metric changed or only varied. Natural process limits and Wheeler's detection rules separate signal from noise.
Coordinate an Agent Team
Run a lead and N participant agents in one asynchronous session. Choose supervise, facilitate, or discuss. Pass messages with Ask, Answer, and Announce. One NDJSON trace records everything that happened.
Prove Agent Changes
Reproducible evidence that agent changes improved outcomes, from the eval session through the trace analysis.