>- which risky assumptions need the user's attention right now (amend the vision, or unblock a spike), and a drill-down into the evidence behind every verdict. Reads .amplifier/revisioner/ (risky-assumptions.yaml plus each data/<id>/ spike directory), emits a single revision-state.json, and instantiates a bundled React template the user runs with pnpm or npm. Use this whenever someone wants to SEE the state of the "visualize the assumptions", "build a dashboard for this", "is there a UI for the revisioner", "I want to click into the evidence", or after a de-risking pass when a text report is too dense to reason about. Also use it when the user wants to share the current state with someone who will not run the tool themselves.
npx skills add https://github.com/microsoft/amplifier-skill-revisioner --skill generate-revision-ux
Set up the bundled dashboard from state already on disk, validate it, and serve it
for the user. The template owns the UI; this skill does not design or customize it.
You are not producing findings here, and you are not moving risk or confidence.
This skill reads state and renders it.
Bundled scripts/, references/, and assets/ paths are relative to the actual
installed directory containing this skill's SKILL.md, not the working directory.
Locate that observed directory with the host's skill-discovery or filesystem tools
and verify required files. If multiple copies exist, use the observed host-selected
copy or ask; do not guess. Replace <absolute path to this skill> in command examples
with that directory, keeping paths quoted; placeholders are not runnable as written.
Run helpers from the target project root; .amplifier/revisioner/ remains project-relative.
| What | Path |
|---|---|
| Source state (read) | ./.amplifier/revisioner/ |
| Classifier reused for bucketing | Installed vision-check-in helper, resolved in Step 2 |
| Builder | scripts/build_ux.py |
| Bundled app template | assets/template/ |
| Generated app (write) | ./.amplifier/revisioner/ux/ |
| Emitted data contract | references/state-contract.md |
The generated app is disposable. It is rebuilt from .amplifier/revisioner/ every time,
so nothing a user edits inside ux/ survives, and nothing of value lives only there.
Check that ./.amplifier/revisioner/risky-assumptions.yaml exists. If it does not,
stop and point the user at find-risky-assumptions: an empty ledger renders an empty
page, which wastes their time and teaches them nothing.
A ledger with entries but no data/ directories is fine. The classifier still uses
recorded confidence and approaches; missing spike files do not imply an open verdict.
Before building, compare the actual state with references/state-contract.md:
fields such as derisking and past-vision notes. Do not assume a fixed assumption
count or require every spike to have evidence.
nested paths. Summarize totals and at most 30 file entries; do not read raw artifacts
wholesale. Sample up to three spike directories with different available fields.
Read at most 80 lines per sampled plan/findings file and inspect status/verdict
objects under 16 KiB for their keys and types; otherwise inspect size only and let
the builder validate them. Missing files and empty files are different states.
file, field, expected shape/range, and owning skill that must resolve it. Do not guess
a conversion. Review builder warnings for optional unreadable documents; malformed
status is a build error, while a malformed verdict retains a raw artifact link.
Stop on permission errors rather than treating inaccessible files as absent.
Resolve the classifier without running another workflow: use the host's skill-discovery
or filesystem tools to locate the installed vision-check-in/SKILL.md. Resolve that
file's parent directory, append scripts/classify.py, and verify the resulting absolute
path is a file. Do not assume the skills are siblings. If multiple copies exist, use the
observed host-selected copy or ask; do not guess. If the skill or helper is missing,
stop before any output write and report that vision-check-in is required. Do not skip
classification or install the dependency automatically.
Replace the classifier placeholder below with that observed absolute path and resolve
this skill's builder as described above, keeping both paths quoted. Do not run the
placeholders or invent shell variables for them:
python3 '<absolute path to this skill>/scripts/build_ux.py' \
--classifier '<resolved absolute path to classify.py>'
The builder's default expects physically sibling skill directories. Passing the resolved
--classifier also supports skills installed in different locations.
This reads the ledger and the vision, shells out to the check-in classifier so the
buckets and recommended mode match exactly what vision-check-in reports, pulls in each
spike's spike-plan.md, findings.md, and verdict.json, indexes the remaining raw
artifacts, and writes everything to ./.amplifier/revisioner/ux/public/revision-state.json.
The bundled template is copied alongside it.
Review builder warnings and compare the generated data with the source ledger and
classifier output: entries, axes, buckets, and recommended mode must agree. Use bounded
reads when investigating discrepancies; do not repair source state in this skill.
Useful flags (--help lists all of them):
--out <dir> # target directory, default ./.amplifier/revisioner/ux
--data-only # refresh revision-state.json without re-copying the template
--file <path> # a ledger somewhere other than the default
--classifier <path> # check-in classifier; relative overrides use the project cwd
Reach for --data-only when spikes have finished since the last build and the user
already has the dev server running. The page picks up the new state on reload.
Finish the job. A user who asked to see the state should not have to install
dependencies and start a dev server to get there, so run it for them and hand back a URL.
The app is a Vite + React project with no backend. Install with pnpm when it is on
PATH, otherwise npm. Run the generated app's tests and production build after install
(use the equivalent pnpm commands when selected):
cd .amplifier/revisioner/ux && npm install && npm test && npm run build
If any check fails, stop and report it. After checks pass, start the server from the
generated app directory in the background so it outlives the turn:
setsid nohup npm run dev > /tmp/revision-ux.log 2>&1 < /dev/null & disown
setsid matters. A plain background job stays in the shell's process group and dies
with it, so the server disappears the moment the command that launched it returns, and
the URL you hand over is already dead.
Let Vite automatically select an available port starting at 5183, falling back to
the next free port when it is taken. Do not ask the user to choose a port, stop unrelated
listeners, or enable strictPort.
Poll /tmp/revision-ux.log until Vite prints its Local: line, then read the actual URL
from there rather than assuming a port.
Confirm it actually serves before claiming it works:
curl -sf -o /dev/null -w '%{http_code}\n' <url> && \
curl -sf -o /dev/null -w '%{http_code}\n' <url>/revision-state.json
Two 200s means the page and its data are reachable, not that the UI renders correctly.
If browser automation is available, verify rendering and evidence navigation against
the actual generated data. Otherwise disclose that browser validation was not performed.
Do not open a browser for the user, and do not assume the host has one.
For a version that can be handed to someone who will not run a dev server, npm run build
emits a static bundle under dist/ that any static file host can serve.
Lead with the actual URL and briefly report the checks performed, warnings, and any
validation not completed. Leave the server running; give a stop command scoped to that
server and its log path, /tmp/revision-ux.log.
risk or confidence, does notwrite to the ledger, and does not edit vision.md. If the picture is wrong, the fix is
upstream in whichever skill owns that axis.
ux/ as build output. Never storeanything there that is not reproducible from .amplifier/revisioner/.
Take microsoft/generate-revision-ux from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.
The instructions reference npm.
Without those the skill loads but fails at the first command.