SuperAPI AI Directory

generate-revision-ux

General & other

View repository

Updated 10-16 00:30

About this 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.

Files and paths

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.


Workflow

Step 1 - Confirm there is state worth rendering

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:

  • Inspect the ledger's section shapes, entry counts, IDs, axis ranges, and optional fields such as derisking and past-vision notes. Do not assume a fixed assumption count or require every spike to have evidence.
  • Inventory spike directories and artifact names, extensions, and byte sizes, including 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.
  • Do not invent evidence, convert the ledger, or alter classifier categories.
  • If sections, scales, or required field types are incompatible, stop and name the 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.

Step 2 - Build

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.

Step 3 - Validate and serve it

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.

Step 4 - Hand back the dashboard

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.


Guardrails

  • Render, never author. This skill does not set risk or confidence, does not write to the ledger, and does not edit vision.md. If the picture is wrong, the fix is upstream in whichever skill owns that axis.
  • The generated directory is disposable. Treat ux/ as build output. Never store anything there that is not reproducible from .amplifier/revisioner/.