finalize
Skill18 starsChanged 5 months agoMITView on GitHub
Finish a chunk of work so it is actually ready to push. Runs Principle VII gates 3 and 4 in cost order and fixes what they surface — instrumentation suite on a device → combined coverage against thresholds → Figma parity for any screens named with --screens → /verify code review — then reconverges whatever the fixes invalidated. Ends in READY_TO_PUSH or BLOCKED, never a partial claim.
22 other projects use a version of this.
Adopted by
Most recently taken up by
- DnsQueen/orcinus-skillstheir own version, first seen Nov 8, 2026
- MagicJosh/rastheir own version, first seen Nov 2, 2026
- SDSLeon/lightcodetheir own version, first seen Nov 1, 2026
- griffinhilly/claude-code-synthesistheir own version, first seen Nov 1, 2026
- Porabuild/Poracodetheir own version, first seen Nov 1, 2026
- nrflo/nrflotheir own version, first seen Oct 29, 2026
Used with
Projects with it also use simplify, debug and 1 more.
Other files people use alongside this one.
Files found in the same public projects as a version of this one, more often than they turn up anywhere else. Each project counts once, large collections count for less, and this file's own repository is left out.
Hugging FaceSkillsimplify
Refactor code after tests pass. The "Refactor" phase of Red-Green-Refactor.
Also in 3 projects that use this
AnthropicSkilldebug
Structured debugging session — reproduce, isolate, diagnose, and fix. Trigger with an error message or stack trace, "this works in staging but not prod", "something broke after the deploy", or when behavior diverges from expected and the cause isn't obvious.
Also in 3 projects that use this
SentrySkillcommit
Create commit messages following Sentry conventions. Use when committing code changes, writing commit messages, or formatting git history. Follows conventional commits with Sentry-specific issue references.
Also in 3 projects that use this
Other versions22 projects use a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 22
- morethanwords/tweb★ 2.7ksame name
- educlopez/ui-craft★ 441same name
- zifeo/lade★ 135same name
- Porabuild/Poracode★ 121same name
- SDSLeon/lightcode★ 121same name
- redis/docs★ 86same name
- skillberry-ai/cap-evolve★ 69same name
- griffinhilly/claude-code-synthesis★ 67same name
- alexiolan/craft-skills★ 17same name
- grimoire-rs/grimoire★ 15same name
12 more not listed
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository67 other files it gives its agents.
- agent-onboardingSkill
- android-backgroundSkill
- android-cliSkill
- android-compose-architectureSkill
- android-compose-componentsSkill
- android-data-layerSkill
- android-di-koinSkill
- android-error-handlingSkill
- android-integration-testingSkill
- android-jacoco-setupSkill
- android-jvm-test-coverageSkill
- android-module-structureSkill
- android-navigationSkill
- android-presentation-mviSkill
- android-preview-figma-verifySkill
- android-ui-screenshot-verifySkill
- android-ui-testingSkill
- android-ui-verifySkill
- android-unit-testingSkill
- android-version-catalogSkill
- architecture-decision-recordSkill
- careful-planningSkill
- compose-adaptive-layoutsSkill
- figma-to-android-vectorSkill
- git-commitSkill
- handoffSkill
- kmp-compose-architectureSkill
- kmp-compose-componentsSkill
- kmp-data-layerSkill
- kmp-di-koinSkill
- kmp-error-handlingSkill
- kmp-integration-testingSkill
- kmp-migration-analyzerSkill
- kmp-module-structureSkill
- kmp-navigationSkill
- kmp-presentation-mviSkill
- kmp-ui-testingSkill
- kmp-unit-testingSkill
- kotlin-coroutinesSkill
- kotlin-flowsSkill
- kotlin-mutation-testingSkill
- openspec-artifact-review-lightSkill
- openspec-artifact-reviewSkill
- project-breakdownSkill
- react-data-layerSkill
- react-error-handlingSkill
- react-integration-testingSkill
- react-presentation-mviSkill
- react-project-structureSkill
- react-routingSkill
- react-screen-architectureSkill
- react-securitySkill
- react-server-stateSkill
- react-ui-componentsSkill
- react-unit-testingSkill
- speckit-parallelize-agent-teamsSkill
- speckit-parallelize-subagentsSkill
- spring-api-layerSkill
- spring-di-configurationSkill
- spring-integration-testingSkill
- The first 60 shown.
The file
We split this skill into the rules it gives an agent
11 rules. 0 are common, 1 is distinctive, and 10 are very specific to this project.
0
Common
Most of the 22 edited versions we read keep these.
1
Distinctive
This author's own choices. Worth a look.
10
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 59
Every fixing stage (3, 4, 5, 6) and the reconverge (7) gets at most 3 fix-and-recheck cycles.
- Very specific: line 70
Never silently reduce scope to make a stage pass.
- Very specific: line 87
Never set FOLDIO_DRY_RUN, FOLDIO_STOP_FORCE_MODULES, FOLDIO_PUSH_FORCE_MODULES or FOLDIO_SKIP_*.
- Very specific: line 170
Get a device: If adb devices shows no online emulator:
- Very specific: line 231
Do not chase the percentage.
- Very specific: line 246
Runs only when
--screens=was passed: No flag → skip the stage entirely and record why in the report. - Very specific: line 313
Every fix made in Stages 3–6 invalidated something earlier.
- Distinctive: line 377
Never report a stage as passed that you did not run.
- Very specific: line 378
Never narrow scope to reach READY_TO_PUSH.
- Very specific: line 379
Never weaken a test, add @Ignore, or lower a threshold to clear a gate.
- Very specific: line 382
If a gate is stuck, BLOCKED with an accurate Remaining is the correct and useful outcome.
“Common” is measured: kept by at least 6 in 10 of the 22 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
/finalize — make a chunk of work push-ready
You are the main agent. Sub-agents under .claude/agents/ cannot dispatch
further sub-agents, so every fan-out happens from your context.
What this is, and what it is not
.claude/hooks/foldio-verify/push-gate.sh decides; it deliberately never
performs. It reads artifacts Gradle already produced, denies in
milliseconds, and prints the exact commands that would clear the denial —
because a long-running hook that times out does not block, so the gate would
be weakest on exactly the biggest changes.
/finalize is the performer on the other side of that split. It runs the
long, visible, resumable work the gate names, fixes what fails, and stops
when the gate would allow the push.
Two rules follow from that, and they are not negotiable:
- Never restate a number, threshold, module kind, module list or refresh
command that
scope.shandstatus.shalready report. Ask them. A finalize that prints different commands than the gate does is worse than no finalize, because it sends the user to run something that will not clear the denial. - Never invent scope. Modules come from
scope.sh, the screens to check against Figma come from--screens, findings come from/verify.
Gates 1 and 2 (compiles, JVM unit tests) are already covered by the Stop and
SubagentStop hooks, so /finalize does not run them as a step of their own.
They reappear only inside Stage 7, where a fix may have broken them.
Arguments
The user invoked: /finalize $ARGUMENTS
$ARGUMENTS is optional. Recognized flags, any order, both optional:
--base=<ref>— git ref the chunk of work is measured against. Default:master. It is exported asFOLDIO_BASE_BRANCHfor every hook helper and passed to/verifyas--base=<ref>, so both halves look at the same diff.--screens=<Screen>[,<Screen>...]— the screens to check against Figma. Comma-separated, no spaces. Each entry is a composable name (VerifyWaitingScreen) or a path to its file. Omit the flag and Stage 5 does not run at all.
Any other token, or a malformed flag, → emit INVALID_INVOCATION (Stage 8
format) with the offending token in Notes and stop.
The attempt budget
Every fixing stage (3, 4, 5, 6) and the reconverge (7) gets at most 3
fix-and-recheck cycles. This mirrors FOLDIO_MAX_BLOCKS=3 in
stop-gate.sh, and for the same reason: a gate the agent cannot satisfy must
end loudly rather than grind.
On the 4th failure of a stage, stop that stage, record it under Remaining
with the verbatim command that reproduces it, and carry on to the next
stage anyway — a coverage gap that needs a large test suite should not
prevent the review from running. A stage that exhausted its budget forces the
final verdict to BLOCKED.
Never silently reduce scope to make a stage pass. If you skip something,
Remaining says so.
The scripts this skill drives
Two read-only reporting scripts under .claude/hooks/foldio-verify/. Both
take plain arguments, print a stable format, and always exit 0 — call them
directly, and never source lib/*.sh yourself:
sh .claude/hooks/foldio-verify/scope.sh [--base=<ref>]— printsMODULES(what changed) andSCOPE(what the change reaches).sh .claude/hooks/foldio-verify/status.sh <module> ...— prints the coverage table the push gate decides from.
Neither is a gate and no hook calls either of them; that separation is what stops a reporting script from being able to change a verdict.
Never set FOLDIO_DRY_RUN, FOLDIO_STOP_FORCE_MODULES,
FOLDIO_PUSH_FORCE_MODULES or FOLDIO_SKIP_*. Those are test seams. Setting
one during a finalize produces a run that verified nothing and says it did.
Stage 0 — Parse arguments
- Tokenize
$ARGUMENTS. Empty → default (base=master). - Match each token against
--base=<ref>or--screens=<list>. Anything else →INVALID_INVOCATION(Stage 8 format) and stop. - Confirm the ref resolves:
git rev-parse --verify --quiet <ref>ororigin/<ref>. Neither →INVALID_INVOCATIONwith "base ref does not exist". --screens=with an empty value →INVALID_INVOCATION. Absent is how you say "no Figma check"; empty is a typo.
Stage 1 — Scope
sh .claude/hooks/foldio-verify/scope.sh --base=<ref>Output:
MODULES :core:sync :feature:auth:data
SCOPE :app :core:sync :feature:auth:data :feature:auth:presentationMODULES and SCOPE are different lists used for different things, and
mixing them up is a real failure:
MODULESis what changed. Coverage is measured over this, because a module's coverage is a property of its own code.SCOPEis what the change reaches. Gradle builds a module's dependencies, never its dependents, so Stage 7 compiles and unit-tests this wider list — a signature change in:core:domainbreaks consumers whose own tasks the narrow list never runs.
scope.sh already folds in the cases worth knowing about: it covers
committed, uncommitted and untracked work (the right scope for a chunk that
is about to be pushed but may not be committed), and it widens to every module
when a version-catalog, convention-plugin or root build file changed.
An ERROR line instead of SCOPE → report it and stop; do not fall back to
a narrower scope. Empty MODULES → emit NOTHING_TO_FINALIZE (Stage 8
format) and stop.
Record both lists; every later stage refers back to them.
Stage 2 — Baseline read (free, no Gradle)
sh .claude/hooks/foldio-verify/status.sh <module> <module> ...Pass Stage 1's MODULES list literally — shell state does not survive between
Bash tool calls, so there is no variable to carry.
This is read-only by construction and takes milliseconds. Its table is the authoritative to-do list for Stages 3 and 4 — do not derive your own.
Handle the structural rows before spending anything on a device:
no-jacoco→ run theandroid-jacoco-setupskill for that module. Nothing downstream can measure it until this is done.no tests(production code, nosrc/testand nosrc/androidTest) → the module needs a suite written from scratch. Treat it as a Stage 4 coverage gap, and expect it to consume the whole budget.no sources→ nothing to do, ignore.
Stage 3 — Instrumentation suite on a device
This runs before coverage, not after it, and the ordering is load-bearing:
foldioCombinedCoverage dependsOn testDebugUnitTest only. It merges
whatever .ec files happen to be on disk. Produce the report first and you
get a unit-test-only number wearing a combined report's name.
Scope: every module in MODULES whose kind (the Stage 2 table's KIND column)
is combined or instrumentation and whose row is not already ok.
Nothing to run → skip to Stage 4.
- Get a device. If
adb devicesshows no online emulator:
Pollpython3 .claude/skills/android-instrumentation-coverage/scripts/select_emulator.py --min-sdk 26 android emulator start <avd>adb devicesfor up to 3 minutes. Follow theandroid-cliskill if it will not boot. Run the suites strictly one at a time, each through the device lock:
ANDROID_SERIAL=<serial> python3 \ .claude/skills/android-combined-test-coverage/scripts/device_lock.py \ -- ./gradlew <module>:connectedDebugAndroidTestDo not parallelize this stage. Worktree fan-out is the right instinct for CPU-bound per-module work and the wrong one here: two connected runs for the same test package on one emulator destroy each other's execution data, and the loser dies with "Process crashed" having produced test results but no
.ec. That is precisely thedevice-run-no-datastate the push gate reports, and it is invisible until the gate reports the module as never having run.- Fix failures here, not later. Use
superpowers:systematic-debuggingfor anything that is not obvious, andandroid-integration-testing/android-ui-testingfor the conventions the fixed test must follow. A failing instrumentation test is a fact; do not weaken an assertion or add@Ignoreto get past this stage.
Re-run only the module that failed. Budget 3.
Stage 4 — Coverage report and thresholds
Produce the reports.
status.shalready prints the exact refresh command for every module without a current result, under "To refresh the modules with no current result". Run those, verbatim. They come from the same rendererpush-gate.shdenies with, which is the only reason the commands here cannot drift from the ones that clear the denial.For
combined/instrumentationmodules this is<module>:foldioCombinedCoverage, and it must be its own Gradle invocation, separate from Stage 3's connected run. Asking for both in one call lets Gradle write the report before the connected tests have deposited their.ecfiles.The renderer prints a literal
ANDROID_SERIAL=<serial>placeholder in the connected-run line. Substitute the real serial fromadb devices; Stage 3 has already run that half, so here you normally need only the second (coverage) line it prints.- Re-read
sh .claude/hooks/foldio-verify/status.sh <module> .... Every row must beok. For each
lowrow,render_coverage.py(already invoked by the gate, and printable directly) names the weakest classes. Write real tests for them:- pure logic, ViewModels, mappers, validators →
android-unit-testing - anything crossing a database / network / clock / WorkManager boundary →
android-integration-testing - Compose UI and E2E flows →
android-ui-testing
Do not chase the percentage. Tests written to move a number and assert nothing will come back as
/verifyfindings in Stage 6, and they make the module harder to change.:core:cryptois at 100% inthresholds.json— for security-critical algorithmic code the number is a floor on behaviour, not on lines executed.- pure logic, ViewModels, mappers, validators →
- New tests invalidate the report that was just produced (
coverage.pyrecords the content it measured, not just an mtime). Re-run only that module's refresh commands — and its device pass too, but only if the new tests live undersrc/androidTest.
Budget 3.
Stage 5 — Figma parity for the screens you named
Runs only when --screens= was passed. No flag → skip the stage entirely
and record why in the report. Never go looking for screens yourself: an
unasked-for Figma pass burns emulator-free but expensive render cycles on
screens the user did not change, and a screen the user cares about is one they
will name.
For each entry in --screens=:
- Resolve it to a file. A path is used as-is. A bare composable name is
resolved by searching the modules from Stage 1:
Zero matches, or more than one → stop and ask which file. Do not pick.grep -rln "fun <Screen>(" --include='*.kt' <module-dir>/src/main - Read the file and collect its screen-state
@Previewfunctions, and for each one the Figma frame URL in the inline comment directly above the@Previewannotation (one blank line between them is fine — that is the house style). - A named screen whose previews carry no Figma URL is a hard stop for that
screen, not a guess and not a search. Report it as
NO FRAME — <Screen>and move to the next one.android-preview-figma-verifyrefuses to guess a pairing, and you must not guess one for it. - Make sure Android Studio has synced.
render-compose-previewrenders from Studio's VFS, not from disk. Stages 3 and 4 just edited files from the CLI, so without a reload you get a byte-identical render of the pre-fix source and a match that means nothing. If you cannot confirm a sync, report Stage 5 as NOT RUN — Studio out of sync and ask the user to reload. A false match here is worse than no check. - Invoke
android-preview-figma-verifyonce per (preview, frame) pair, passing both sides explicitly: the file plus the preview composable name, and the Figma URL. It reports only; it never edits. - Fix the deviations it grades as significant, following
android-compose-components/android-presentation-mvi. Figma is the source of truth. A deviation you keep on purpose gets written down in the report with its reason — an undocumented deviation is a failure of this stage.
Budget 3.
Stage 6 — Code review
Invoke /verify --base=<ref> with the same ref Stage 0 resolved.
Act on its verdict:
FIXES_REQUIRED→ fix every surviving finding./verifyhas already filtered to HIGH-confidenceBLOCKER/MAJORat its validator stage and then audited them, so everything that reaches you is in scope. The one way to close a finding without changing code is to quote the discovered rule that contradicts it — record that quote in the report.TESTS_FAILED→ fix the tests. This is a fact, immune to audit filtering.- Findings prefixed
[UNVERIFIED]→ report, do not auto-fix. The audit could not confirm them cheaply, so a meaningful share are false positives and chasing them churns code for nothing. They go in the report for the user to judge. PASS/SKIPPED→ done.
Re-run /verify with the same args after fixing, per its own re-invocation
contract. Budget 3 invocations total.
Stage 7 — Targeted reconverge
Every fix made in Stages 3–6 invalidated something earlier. Without this
stage /finalize finishes green and the push gate still denies with "no
coverage report matching the code on disk".
Reconverge only what was actually invalidated. Diff the working tree against
the state at Stage 1 to get fixed_files, then:
| what changed | what to re-run |
any .kt / .kts | <module>:assembleDebug + <module>:testDebugUnitTest for every module in SCOPE (:build + :test for JVM-only modules). Usually warm from the Stop hook. |
| production code in a measured module | that module's refresh command, as printed by status.sh |
| …and that module needs a device | its connectedDebugAndroidTest through device_lock.py first |
| a UI source in a screen Stage 5 verified | re-verify only that screen's previews |
| anything at all | one more /verify --base=<ref> |
Exit condition, both parts required:
sh .claude/hooks/foldio-verify/status.sh <module> ...shows every rowok, and- the last
/verifyreturnedPASSorSKIPPEDagainst the current tree — not against the tree as it was before the Stage 6 fixes.
Budget 3 passes over the table. A fix in the reconverge that invalidates the reconverge is the signal to stop and hand back, not to keep going.
Stage 8 — Verdict
## Verdict
READY_TO_PUSH | BLOCKED | NOTHING_TO_FINALIZE | INVALID_INVOCATION
## Coverage
<the final status.sh table, verbatim>
## Instrumentation
<one line per module: PASS <module> or FAIL <module> + failing test FQNs; or "not run — no module needs a device">
## Figma
<one line per verified preview: MATCH, or the deviation and how it was resolved;
documented deviations with their reason;
NO FRAME lines for named screens whose previews carry no Figma URL;
or "not run — <--screens not passed / Studio out of sync>">
## Review
<surviving /verify findings and how each was resolved, plus every [UNVERIFIED] finding>
## Remaining
<every stage that exhausted its budget, with the verbatim command that reproduces it>READY_TO_PUSH requires all of: Coverage fully ok, Instrumentation
with no FAIL, Figma with no unresolved significant deviation, Review clear
of BLOCKER/MAJOR, and Remaining empty. Anything else is BLOCKED. There is
no partial pass and no "green apart from".
/finalize does not commit and does not push. On READY_TO_PUSH with
a dirty tree, say so and suggest /git-commit — the push gate is the
authority on whether the work may leave the machine, and this skill should not
be the thing that decides the work is committable.
Honesty contract
The whole point of this skill is that its verdict can be trusted. So:
- Never report a stage as passed that you did not run.
- Never narrow scope to reach
READY_TO_PUSH. - Never weaken a test, add
@Ignore, or lower a threshold to clear a gate.thresholds.jsonexists only to raise a module above 80, never to lower one — a module below 80 gains tests. - If a gate is stuck,
BLOCKEDwith an accurateRemainingis the correct and useful outcome.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

