Skip to main content

ripwire-quality-bar

Code QUALITY of what YOU just wrote, before you commit or say 'done', or verifying a cleanup: --quality-delta lists what got WORSE in 10 kinds and exits 2 only when pre-existing code got materially worse; which restructuring a measured shape (humps/deep, a tangle) calls for. Merge safety → change-check. Even a single-line leaf fix runs it.

Ir para a instalação

Informações da origem

Repositório
redhat-et/ripwire
Última atividade na origem
20 de setembro de 2026 às 20:45
Idioma detectado do SKILL.md
inglês
Estrelas
2.312
Forks
149

Opções de instalação

Por padrão, está selecionado o prompt que primeiro revisa a origem. Você pode mudar para um comando direto ou baixar uma cópia local.

Revise os arquivos de origem

Leia o SKILL.md e os arquivos complementares exibidos pelo SkillsMP antes de decidir se vai instalar.

Explorador de arquivos
2 arquivos

Exibindo SKILL.md

SKILL.md
Instruções da origem · Visualização somente leitura
name
ripwire-quality-bar
description
Code QUALITY of what YOU just wrote, before you commit or say 'done', or verifying a cleanup: --quality-delta lists what got WORSE in 10 kinds and exits 2 only when pre-existing code got materially worse; which restructuring a measured shape (humps/deep, a tangle) calls for. Merge safety → change-check. Even a single-line leaf fix runs it.
allowed-tools
Bash, Read
# The quality-bar convergence loop > Routing: > • PR-submission readiness — tests to run, blast radius, "safe to merge?" → **ripwire-change-check** — run > `--quality-delta` FIRST, then its `--test-gate`: clean code that runs the wrong tests still regresses. > • Reusing before you write the code in the first place → **ripwire-reuse-first**. > • Wide-angle "where does this still look rotten" read across a whole file/subsystem (not a before/after > delta) → the panel below, or **ripwire-fresh-eyes** for the full six-family breakdown. > • **You have the measurement and need the FIX** — for your own diff or for a subsystem **ripwire-fresh-eyes** > just measured → the shape → refactor playbook and the closed fix loop are both on this page, below. > • **The regression is a MEMORY-layout hypothesis, not one of the 10 quality kinds** — `--lint`'s built-in > cache-\* pack (8 static data-layout checks) is a normal part of a lint pass; `--field-affinity[=STRUCT]` > is the deeper struct-level lens once a profile implicates a specific aggregate → **ripwire-perf-target**. > • Not sure which skill? → **ripwire-router**. Don't eyeball quality — **measure the delta your change introduced**, with a deterministic oracle, in a bounded loop. A file that was already complex is not your regression. Apply the "non-trivial work" trigger to the LOOP, not the check. `--quality-delta` warm-runs in well under a second — cheaper than deciding by eye whether a fix "counts" as trivial, and that eyeball judgment is precisely where a leaf-looking edit that quietly changed a signature or added a branch slips through unmeasured. Run it. What a single-line leaf fix that preserves the signature and adds no branch, symbol, dependency, or abstraction gets to skip is everything AFTER a clean run: the drill-down table, `--dmm`, acking, a second round. This skill (and this file) earns its cost when the one-shot delta actually reports something — a clean `gating="0"` run on a leaf fix is confirmation, not ceremony you were right to skip. ## Before you converge: the wide-angle read — `--quality-panel` `ripwire <dir> --quality-panel[=strict|default|lenient] --legend=compact` is THE SINGLE COMMAND for "does what I just touched still look rotten" — one ranked report over **six** evidence families (the four `--ensemble` joins — `structural`, `lexical`, `confusion`, `historical` — plus `colocation` and `state`; the full per-family breakdown lives in **ripwire-fresh-eyes**). Point it at the file or symbol you just edited for a multi-angle second opinion the single `--quality-delta` number can't give you on its own. **Read it correctly: it is a lens, never a gate.** `--help` says so in the flag's own text and the contract is enforced in code — `--quality-panel` exits 0 unconditionally, on every preset, on every repo. It does not compare against a baseline and it cannot fail a commit. The gate for "did MY change make this WORSE" is Step 3 below (`--quality-delta`) — that is the only pass in this skill (or in ripwire) with an exit code that means something. Run `--quality-panel` for the wide-angle read, converge with `--quality-delta`, never the other way round. Pick the preset by what "rotten" needs to mean right now: `lenient` (all six families, 1 must agree) is a reading order, roughly a third of any tree; `default` (all six, 2 must agree) is a review list; `strict` (only the four families measured stable enough to stand behind repeatedly — `historical` and `colocation` are fixed-size worst-40 cuts over a ranking whose population moves, so both re-shuffle release to release on code that never changed) is the rung closest to something CI-shaped, but it is still a lens — nothing here plugs into an exit code the way `--quality-delta` does. ### Read the structural row as a PROFILE — `nest=` alone is a max, and misleads solo `nest=` reports the single deepest line in a function. One line at depth 9 and a thousand lines at depth 9 report the same number, so `nest=9` cannot tell a **tangled** body from a long **blocked-sequential** one whose max was set by one inner loop nobody has to hold in their head. Acting on `nest=` alone is how an agent guard-clauses a dispatch table. `--metrics` (and the structural family's `why=` string in `--quality-panel` / `--ensemble`) now carry the profile beside the max: ``` <e f="structural" counted="1" why="ccx=724 loc=1244 nest=9 humps=30 deep=308 rrank=1"/> ``` **Every concrete number on this page is ILLUSTRATIVE OF A SHAPE, never a value to expect.** The counters themselves are under active calibration — an else-clause over-count fix in flight moves `humps=` down by a large fraction, and `ccx=`/`nest=` with it, on else-heavy functions. What is durable is what you *do* with the row: `humps=1` vs many, the two ratios below, and the semantics (regions vs lines, absence below the bar, `deep < humps` legal). Read the row in front of you; never carry a remembered number to it. - **`humps=`** — how many *maximal control-nesting regions* reach the nesting bar (`bar_nest=` on the panel root; CodeScene's "bumpy road": a rise above the threshold then a fall). One deep tangle is `1`; repeated missing abstractions are many. EXACT, not a floor. - **`deep=`** — how many **LINES** lie inside those regions, read against the `loc=` already on the row. A disclosed FLOOR (`deep_floor="1"`). - Both are **absent exactly when `nest <` the bar** — not-deep, never a hidden `0`. - **`deep` below `humps` is legal output, not a defect.** `deep` counts lines and `humps` counts regions, and two regions can share a line: a one-line `if(c){x;}else{y;}` at the bar is 2 regions on 1 line. Three reviewers have read that shape as a bug; it isn't. Two ratios do the actual discriminating, and you compute them yourself from the row: | Ratio | High says | Low says | |---|---|---| | **`deep/loc`** | **tangled** — the body *sustains* depth, so most of what you read is nested | **blocked-sequential** — a long run of shallow steps (a dispatch table, a switch, a setup block); the max is one inner loop | | **`deep/humps`** | **few giant tangles** — one region holds depth for a long stretch; the expensive fix | **many tiny touches** — repeated missing abstractions, each hump its own cheap extraction | Three shapes off this repo's own source — read the *pattern*, not the digits, which move with calibration: a ~1000-line function at a **low** `deep/loc` (`main`, roughly a tenth) sits beside one at **~2.5×** that fraction (`buildGraph`) once `loc`/`nest` have declared them equivalent; and a function far too small for any size bar to fire can carry the **highest** `deep/loc` in the table (`ur_walkTree`, `loc=87`, near half its body deep in a single hump). The first is blocked-sequential, the second tangled, the third dense — three different fixes, one indistinguishable `nest=`. **`locals=`** rides the same row: the count of local-variable declarations, a FLOOR (`locals_floor="1"`), **C/C++ only** and **absent — never a bare `0`** — for every other language. It measures the working set a reader must hold at once, which is the thing extraction is actually supposed to shrink; a "split" that leaves `locals` where it was mostly moved braces. **`join="deep+untested"`** on a `--quality-panel` row is a **conjunction of two facts the report already holds** — this row carries `deep=` *and* no indexed test reaches it — annotated, not a seventh family. It changes nothing: not `fam=`, not `of=`, not the ordering, not which rows appear. It is the pair where a refactor is most wanted and least safe, so it routes straight to **test first, refactor second** in the playbook below. It is **suppressed on every row when `tested_scope="0"`**, because on a corpus whose tests were never crawled "untested" would be a fact about the crawl, not about the code — read `tested_scope=` on the root before you read the absence of the annotation as good news. `deep_untested=` on the root counts them across the WHOLE row set, which the `limit=` window does not change. **The per-file churn caveat.** The `historical` family's `churn=` and `hrank=` are **FILE facts, inherited verbatim by every symbol in the file** — a symbol in a churny file collects that family without any property of its own. Discount it accordingly: on a row whose other evidence is thin, `historical` may be saying only "this file is busy", not "this function is." (`hrank=` is also a *relative* decile cut over this corpus, so something always fires.) ## The loop 1. **Zero-setup path:** just make your change, then run `ripwire <dir> --quality-delta --legend=compact` before you call it done — add `--legend=compact` every time you run this in a loop: on a CLEAN report the legend is nearly the whole payload (2,776 B to 454 B measured on a small fixture, 15,601 B to 8,775 B on a mid-change repo), the rows are byte-identical either way, and you have already read the dictionary — in a git repo it auto-compares the working tree vs `git HEAD` (`<quality-delta baseline="git-HEAD">` confirms it), no start-of-task action needed. **Tighter loop on a long change:** run `ripwire <dir> --quality-baseline` FIRST — **on a clean tree** — to pin an explicit floor (takes precedence over HEAD) so each edit deltas against the original start, not the last commit. On a tree that already differs from HEAD the pin **refuses**, naming the gating findings it would have swallowed into the floor: commit first, or pass `--allow-dirty` to pin anyway, which stamps the absorbed count so every later report carries `baseline_absorbed="N"` and a green exit beside it reads "clean *since the pin*". 2. **Make your change.** 3. **Measure the delta** — `ripwire <dir> --quality-delta --legend=compact` → only the regressions you introduced, across the 10 kinds in the table below. Each emits `<r kind="…" sym=… was=… now=…>` (`members=` for duplication). Test-fixture dirs are exempt from `dead-code`; `short-horizon-churn` ignores your own current edit and exempts brand-new symbols/markdown/fixtures. Two exemptions are DISCLOSED on the report rather than silent, and both change how you read a zero: a symbol defined by a self-registering test/benchmark macro (doctest `TEST_CASE`, gtest `TEST`/`TEST_F`/`TEST_P`, Catch2, Google Benchmark, plus anything in `.ripwire_config`'s `register_macros`) is never `dead-code` — a static initializer is invisible to a name-based call graph — and the header's `register-macro-excluded="N"` counts how many were dropped that way, printed even at 0. A `duplication` row whose members share only a recognized *idiom* — a scalar threshold ladder, an enum-to-string switch table, a builder chain — and share no domain identifiers across different scopes is demoted to `sev="minor"` with `idiom="…"` and stops gating. **The idiom name is there so you can overrule it by reading**: a demotion is a judgement the tool is showing its work on, not a row it hid. **Watch `verbosity` hardest** — LOC growth is the single most-measured agent failure mode, the one most likely to hide in an otherwise-clean diff. **Read the exit code correctly — it is narrower than it looks.** Findings are sorted on three independent axes, and only one combination gates: - **acked** — suppressed entirely (counted honestly in `acked="N"`). - **ORIGIN** — a symbol that EXISTED at the baseline and got worse is *preexisting-worse* (**no** `origin=` attribute on the row); one that exists only because the code is NEW carries `origin="new-symbol"`. - **MATERIALITY** — a small numeric delta is additionally `sev="minor"`. **`--quality-delta` exits 2 ONLY on preexisting-worse AND major AND unacked** — exactly the `gating="N"` count in the header. Read `gating=`, not `regressions=`. A real header looks like: ``` <quality-delta baseline="git-HEAD" regressions="0" minor="0" acked="0" preexisting-worse="0" new-symbol="0" gating="0" at="f0a45e43d"> ``` **`origin="new-symbol"` rows are PRINTED but NEVER gate.** They are the debt you are adding — read them; nothing else will make you. And `--help` is explicit that **exit 0 means "nothing that already existed got worse", NOT "clean"**: a change that is entirely new code can add unbounded new-symbol debt and still exit 0. Never report "quality-delta passed" as "no new debt" — open the rows. Two more contract details worth knowing: clone kinds classify by member set (a group is new-symbol only if EVERY member is new), and `short-horizon-churn` is preexisting by construction. **LIMIT:** origin is canonId (`path::scope::name`) identity, so a **RENAMED or MOVED symbol reads as new** — a genuine regression carried in with a move classifies `new-symbol` and will not gate. If your diff moves code, the exit code is especially weak evidence; read the rows. 4. **Fix the REAL ones, re-run, converge.** Which fix a row calls for is the **shape → refactor playbook** below; proving the fix landed is the **closed fix loop** below that. Repeat until clean or the remainder are conscious trade-offs. **Record a trade-off instead of re-reading it forever:** `ripwire <dir> --quality-ack="why it's accepted"` writes the currently-visible findings into `.ripwire_quality_acks` (committable) — later runs suppress them honestly (`acked="N"`) and a finding REAPPEARS the moment it worsens past its acked size. **Ack a SUBSET, never the screen.** Bare `--quality-ack` accepts *every* finding currently visible, so using it to accept one deliberate change silently accepts the rest too — that is how a ratchet turns into a rubber stamp. Narrow it with `--ack-only=SUBSTR[,SUBSTR]`, which matches a finding's kind, its canonical id, or its **facet**: ```bash ripwire <dir> --quality-delta --ack-only=contract-change --quality-ack="arity change required by <fix>" ``` Prefer the facet over the kind when one exists: `api-surface` also covers the never-gating `new-symbol` rows, so acking by kind can sweep in dozens of findings to accept a handful. `--ack-only=gating` selects exactly what would exit 2. A pattern matching nothing refuses (exit 1) rather than acking everything. Whatever you leave unacked stays visible — that is the point; an exit 2 you have explained in a commit message is worth more than an exit 0 you bought with a blanket ack. **Sharing the working tree with other sessions? Then `--ack-only` is not enough — add `--scope=`.** `--quality-delta` compares the *working tree* against HEAD, so in a checkout several agents are editing at once, every sibling's uncommitted rows land in **your** report. Bare `--quality-ack` there accepts the whole screen, which writes another session's debt into a committed ledger under *your* reason string: that is how the ratchet becomes a rubber stamp, and no amount of care reading the report prevents it. `--scope=GLOB[,GLOB...]` files each finding by its `p=` path: ```bash ripwire <dir> --quality-delta --legend=compact --scope=src/render,src/render_gl.h # gate on MY subtree only ripwire <dir> --quality-delta --scope=src/render --quality-ack="deliberate" # …and ack only my rows ``` Rows outside the scope are **still printed**, under an `<out-of-scope>` element with a do-not-ack banner, and never gate; the header's `scoped-out-gating=` says how many of them *would* have gated, so a scoped exit 0 means "nothing of mine is broken", never "the tree is clean". The ack cannot write an out-of-scope row at all, and an `--ack-only=` that names one refuses (exit 1). Each row you write records `by=<scope>`, so a later run can flag an ack that suppressed a path its author never owned (`foreign-acks=`). A pattern with no wildcard is a root-anchored path prefix; `*`/`?` match the whole path, with `*` spanning `/`. A scope that names nothing indexed refuses rather than reporting you clean. One reserved word: `--scope=diff` is whatever the working tree changed vs the baseline, expanded to one path per changed indexed file. It is sugar for the **single-writer** case — in the shared tree this flag exists for, a sibling's edits are "changed" too, so name your own paths there. 5. **Want ONE number instead of a list — `ripwire <dir> --dmm --legend=compact`.** `--quality-delta` says *which* kinds got worse; it has no scale, so "is this change better than my last one?" has no answer. `--dmm` is that scale: the Delta Maintainability Model (di Biase, Rastogi, Bruntink & van Deursen, TechDebt 2019; thresholds and arithmetic from PyDriller's reference implementation) scores the share of the volume your change moved that landed in — or freed from — risky units. ``` <dmm base="2edbb46c…" target="working-tree" available="1" combine="pooled" size_metric="physical-loc" dmm="0.436" good="462" bad="597" base_units="4759" target_units="4780"> <p k="size" dmm="0.184" good="65" bad="288" d_low="65" d_high="288"/>… ``` A unit (a function/method definition with a body) is **low risk** iff `loc<=15` (size), `cyclomatic<=5` (complexity), `params<=2` (interfacing). `good` = low-risk volume **added** plus high-risk volume **removed**; `bad` = the reverse; `dmm = good/(good+bad)`. **Deleting a god function scores 1.000; growing one scores 0.000.** The three sub-scores are separately actionable — a low `size` with a healthy `interfacing` says *split the function*, not *change the signature*. Three things to carry. **It is a DELTA, never a level:** editing bad code without changing its size, complexity or parameter count contributes *nothing* — you are not punished for touching a mess, which is deliberate. **`dmm="UNAVAILABLE"` is not a score of 1.0 or 0.0** — it means `good+bad` was 0 (a rename, a
Ver no GitHub
Este SKILL.md e muito grande, entao o SkillsMP mostra aqui apenas a primeira secao. Ver no GitHub