Build or rebuild an avva Decision Model in avva Studio — the procedure, the list of records you approve and the script that prints it. Use whenever the user mentions avva, a decision model, avva Studio, extracting their decisions, or runs /avva-build-model.
Installs into .claude/skills of the current project.
Are you the author of Avva Studio?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/kdobrinov-avva-studio)
---
name: avva-studio
description: Build or rebuild an avva Decision Model in avva Studio — the procedure, the list of records you approve and the script that prints it. Use whenever the user mentions avva, a decision model, avva Studio, extracting their decisions, or runs /avva-build-model.
---
# avva Studio: the procedure
1. Call `begin_extraction` on the `avva-studio` MCP server and follow the brief it returns, step by step — with `rebuild: true` when the user is updating a model they already published from its saved file, which reviews that set instead of sweeping again. The brief is written in the user's voice and it is the whole method; this skill adds tooling, not a second brief. Its first step is its ONE QUESTION BEFORE YOU READ ANYTHING: ask it, as the brief words it, and wait for the answer before any search.
2. Sweep as the brief's routes say — on a rebuild, only the material the user names. Its IF YOU CAN RUN PARALLEL WORKERS rule runs one sweep per source and a merge that loses no candidate, and its NEVER A SOURCE rule says what this run must not read as material; follow both as the brief words them.
3. Review the set, report the sweep, ask its one question and wait; then merge duplicates — the brief's REVIEW YOUR OWN SET, REPORT THE SWEEP and DUPLICATES, in that order.
4. Write the json first — before any avva tool call. Save the exact array you would submit as `avva-decisions-<domain>.json` — the exact file name the brief gives you, never one you derive from the domain yourself — OUTSIDE any git working tree: by default in `~/avva/` (create the folder), or where the user says. It is their raw approved set and its only copy, and a project directory is usually a repository one `git add -A` from a remote. If the user wants it inside a repository, first add its path to that repository's `.git/info/exclude` and tell them you did. If a file of that name already exists and this is not a rebuild, rename it to `avva-decisions-<domain>.previous.json` first and tell them. On a rebuild, or for any change to records the user already approved, leave the saved file as it is and write the changes into a working copy beside it; it replaces the saved file only after their yes. The script below warns when the file is tracked or not ignored; act on the warning before anything else. Every record carries an `origin` placeholder label for where it came from.
5. Render the records with the bundled script, never by hand:
```
node "${CLAUDE_PLUGIN_ROOT}/scripts/render-sheet.mjs" avva-decisions-<domain>.json [--range "<the range the user set>"] [--exceptions 3,7,12] [--against 2,5,9] [--instructions 4,11] [--statements 8,14] [--thin 3,9] [--authorship 5] [--client 2,6] [--off-domain 6] [--records 11-20] [--before <the saved file> [--rebuild]] [--lang ru|en]
```
It validates the records against the wire shape — a field it does not know is named and shown in full, never refused — writes every record in full to `avva-decisions-<domain>.md` beside the json, the readable sheet the user reads before approving, and prints to stdout what the chat shows: the header, the first record, the group table, what needs the user's eye, the least-sure records, the flags and the one question. It flags residual emails, phones, URLs, ticket ids, key-looking strings and records that name avva itself. `--exceptions` takes the numbers of the records you are least sure are clean after redaction; that judgment is yours, the script only renders it. `--against` takes the numbers of the records the brief's AGAINST THE DEFAULT rule marks — also your reading — and the script prints the count; the request for more such records belongs to the sweep report's one question, never to the sheet. `--instructions` takes the numbers the brief's review pass put in its "instructions, not calls" group — no alternative and no reason on record — and the script lists them as their own group the user keeps or strikes in one word; never drop one yourself. `--statements` takes the numbers the review put in "statements, not decisions" — a declaration with no fork and no reason, product copy, an answer to a hypothetical, someone else's text, anything an AI assistant wrote — and the script lists them as a group that is OUT unless the user keeps one with their reason; the question's count leaves them out. `--thin` takes the numbers the review put in "thin: says nothing a stranger could use" — no particular in the situation, no reason or only the circumstance, and the call anyone in the field would make — the other OUT-by-default group, kept by number. `--authorship` takes the records whose author you cannot tell, and `--client` the records from a client's or an employer's material (a client's origin placeholder is read without it); both are listed under what needs the user's eye. `--off-domain` does the same for the records the review marked outside the domain. A record listed outside its origin's group shows its origin, and the table counts every record an origin's strike removes. BEFORE THE SHEET, run it once with `--ask` (and the same `--statements`, `--thin` and `--against`): it prints only what only the user can add — the records that go whose reason or other side is still empty after you looked in their sources, at most ten (a missing reason first, then a call against the default, then the newest), each with its date, situation and call, how far the reasons are from the next label, and two questions — and writes no file. Put that in the chat as its own message, as it came out. Write each answer into that record's driver or otherSide in their words with the sheet's redactions, then render the sheet, which shows them in their records; their one yes covers them. "I don't remember" is a full answer; a reply that passes over the list is not one, so ask it once more on its own. Never offer a reason for them to confirm. Where more remain, offer the next ten once, never forced. Pass `--range` whenever the user set one, so records outside it land in their own group. Run the working copy with `--before` and the saved file on a rebuild or after any change to approved records: the script then prints each changed field before → after and each new record in full, in place of the full list. On a rebuild add `--rebuild`: the sheet's one question then also asks whether any call in the saved set is one the user would no longer make — a call they name is removed from the working copy (the explicit remove; striking a changed record only reverts it), and the next render lists it as removed.
6. Put that output in the chat as it came out, with the brief's COVERAGE lines and its DUPLICATES merge lines right after the output's four numbered facts (the brief's HEADER, which comes first), and ask the brief's one question with the count; tell the user where `avva-decisions-<domain>.md` is — every record is in full there, and they read it before they answer. Never paste every record into the chat. If the user asks to read some here, run it again with `--records 11-20` or any number they name — that prints only those records, so nothing is asked twice. Everything the user reads is rendered from the json by this script — never retyped, summarized or tidied by you, which is the whole reason the script exists. After removals, edit the json, run it again (the file is rewritten), and show the group table only.
7. Only after explicit approval — after the user read the file, or after the brief's TRUSTED CHECK when they said they trust your selection — call `submit_decisions` with the array in the json exactly as it stands, and `reasons_asked: true` once they have answered the `--ask` list (it stores nothing before), and follow what it returns.