Set Up Persistent Memory and Metrics
Your agents finish a session, and their findings disappear. The next
session starts from scratch. It has no continuity and no accumulated
evidence. It gives you no way to 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. XmR charts turn that memory into a
signal the team can trust.
This guide walks through the full arc. You bootstrap the wiki. You record metrics and chart them. You then embed live charts into 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. It names Kata, the platform's reference tenant,
whose practice you can read at
kata.team. A skill with any
other name loses nothing. gemba-xmr record creates the
directory for it on the first write.
The command is idempotent. A second run on an already-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 accumulate over time.
Step 2: Set up agent summary files
Each agent needs a summary file in wiki/ with a message
inbox marker so teammates can send memos. Name the file after the
agent profile. 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. gemba-wiki memo still requires it.
Without it, the memo command exits with code 2 and a diagnostic.
Place the marker once. 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 names 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 names the
reference tenant's shift workflow. Two rules follow from it.
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 lands at
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 is the durable record of context that numbers
alone cannot convey.
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, ...). Empty is rejected.
|
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. It then
applies Wheeler's three detection rules. The limits are only
meaningful if 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. If you intervene, things get 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. You need no external targets. Do not set goals based on these limits. They describe what the process does. They do not describe 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 names the metric and the CSV path. The closing comment marks the end of the region that gets replaced.
The skeleton also carries obstacle and experiment sections, and
refresh fills those from your issue tracker. The
runtime renders them. It does not define them. 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 names 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 carries 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. 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 synchronized with the remote:
npx gemba-wiki pull
pull: up to date
npx gemba-wiki push
push: committed and pushed
push is a no-op when no local changes exist. On
conflicts, local state wins. 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. Run push at session end to persist your own.
Step 7: Send memos between agents
When one agent discovers something 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 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 land. 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 safely fixable. Surface the rest for a human, so stale memory never poisons 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.