diff --git a/docs/upstream/cursor-pstack.md b/docs/upstream/cursor-pstack.md index 229916e249..388826cf41 100644 --- a/docs/upstream/cursor-pstack.md +++ b/docs/upstream/cursor-pstack.md @@ -37,6 +37,7 @@ directory Cursor exposes"), and Cursor transcript paths under `~/.cursor/`. | `technical-writing` | [`docs-hygiene:write-for-humans`](../../plugins/docs-hygiene/skills/write-for-humans/SKILL.md) | Derived, re-posture | **Taken:** the four-layer model and the question each layer answers (mode / address / load / ambiguity); the Diátaxis mode picker with all four modes, the compass, "use it on one sentence too", and the don't-mix-split-and-link rule; upstream's three above-the-layers rules (cut every word that does no work; use the short everyday word; when a rule makes a sentence worse, fix the sentence another way or leave it alone) — our third always-rule, write the real name and do not invent jargon, is drawn from upstream's separate word-list and anti-jargon paragraphs rather than from that trio; the "vary the rhythm" section, which is the sharpest thing in the upstream file — a document can obey every layer and still read machine-written, and *be specific over sterile* names the failure exactly; the address, load and ambiguity rule sets; the STE fidelity caveat, kept because it is why this ships a paraphrase rather than a claim of conformance; and the review checklist, minus two items. **Re-postured — the whole point of the port.** Upstream ships the four standards as house rules. Here they are a **named, replaceable default set**, applied only after a search for the consuming project's own declared guide comes back empty, with the fallback stated out loud. `PLUGIN-PHILOSOPHY.md:198-202` admits a shipped default "only when it is a good-practice value that cannot conflict in *any* repo the plugin drops into", and names Conventional Commits as the archetype of what fails that test; Google style, ASD-STE100 and Global English are that class. The draft plan carried its own disproof — a decision existed solely to delete two Global English punctuation rules because they already conflicted with this repository's measured em-dash ruling. Those rules are therefore **kept**, where a consumer's own guide disables them, rather than deleted for every consumer because one repository disagreed; `ai-slop`'s own charter states the principle ("a deliberate house style is config in the consuming repo, never a shipped-default change"). **Rejected — the commit-message and PR-body scope.** Upstream applies every layer except Diátaxis to them. Here `ai-slop:audit` already excludes commit messages and PR bodies from the markdown-prose regime, shape is owned by `source-control:commit`'s subject-convention ladder and the PR-body-sections convention, and both `write-for-*` skills scope to markdown *files*, which a commit message is not. **Rejected — review-checklist items 1 and 8.** Item 1 is scoped "only to document sets" (a cross-document audit) and item 8 demands verifying counts and regeneration commands (a verification action); either would smuggle an audit into a write-time skill. The count rule survives in the body as a writing rule. **Rejected — "add new offenders to unslop's abstract-metaphor rule".** That rule lives in `ai-slop`'s `skills/audit/reference/catalog.md`, which is a private surface under the encapsulation contract *and* CC BY-SA 4.0 material derived from a pinned Wikipedia revision; instructing a consumer to edit another plugin's internals fails on both counts. For the same reason the audit's counter-proposal to absorb the three sentence layers into that catalog was declined: it would contaminate an attributed corpus and falsify its drift claim. **Rejected — "indent code snippets with tabs".** A hard formatting convention that collides with a consuming repo's own linter config, by the same test that re-postured the rest. **Rejected — the worked example.** Upstream's is about its own `budget.mjs`; a substitute path from this repository would be the identical defect with a different string, and a consumer reading a path that does not exist in their tree is what `audit-noise` classifies as a ghost ref. Rewritten fully generic, labelled as placeholders. **Renamed:** `write-for-humans`, not `technical-writing` — the latter is a noun phrase and the grammar takes an imperative verb phrase. Bare `write` both collides (the leaf-name registry records `write bug-report,testing`) and under-specifies the reader, which is exactly when `PLUGIN-PHILOSOPHY.md:67` prescribes a hyphenated qualifier, so this is grammar-conformant rather than a new exception. **Upgraded:** upstream's four source stamps carry a fetch date and no recheck trigger; the drift convention bars a bare date, so each now carries a full four-part stamp. | | `blast-radius` | [`review:quality-gate downstream`](../../plugins/review/skills/quality-gate/context/downstream.md) | Partial (scope adopted, mechanics rejected) | **Taken:** the scope, which is the only part that was genuinely missing — the whole review lane is diff-scoped and nothing in it looks outward (verified by reading: `architecture-guardian` stops at mapping changed files to layers, `code-reviewer` and `doc-drift-detector` carry no caller item, `fanout` fans across surfaces all diffing one merge-base, `mutation-testing:audit` is `git diff`-scoped by construction). Also taken: "listing the callers is not the job"; the where-grep-stops surfaces (library source and pinned version, serialization boundaries, timing and lifecycle, flag reach, cross-language readers); the confirmed-vs-cleared split as two deliverables; "a search that finds nothing is still an answer"; and the cheapest-test handback, strengthened into a presence-gated handoff to `/testing:write` + `/mutation-testing:audit`. **Rejected — the five-rung proof ladder.** It would be this fleet's *ninth* evidence ladder (severity's confidence axis, `improvement:find`'s evidence ladder, research source tiers, `codebase-health`'s verified/likely/needs-review, `repo-fleet-hygiene`'s confidence model, `trace-intent`'s intent-evidence tiers, fable-5's calibration grades and inference-distance rungs, mutation-testing's productive/equivalent/arid/unclassified). `discipline:reuse-or-replace` names that exactly: "leaving the established way in place and quietly adding a divergent way alongside it". The unverified-claim floor it encodes is kept, citing fable-5's verification chapter as owner. And this port's own departure argument condemns its bottom rung specifically — a rung that is cheapest to fill when the evidence is worst is a rung that will be filled. **Rejected — "the one fact it's safe because of" as the report's spine**, demoted to a first probe. As an organizing structure it makes secondary risks structurally invisible on any change with several independent ones, and this marketplace models change risk as multi-dimensional (`autonomy`'s work-classes names four risk properties; `devils-advocate` Round 4 sweeps ten operational categories precisely because assumption-driven rounds miss traps). **Rejected — a third axis in `review/context/severity.md`**, which its own Vocabulary section closes at two and which `review/skills/quality-gate/context/spec.md` had already declined to widen; it is also a cross-plugin convention surface with a CI gate. **Rejected — the `arena` routing**, no such skill existing here. **Renamed:** `downstream`, not `impact` (generic, and already prose-loaded in six always-listed descriptions (`ai-slop:audit`, `architecture:improve`, `claude-ops:changelog`, `docs-hygiene:rename-references`, `improvement:find`, `work-items:work`)) and not `blast-radius` (a three-way collision), while the "blast radius" trigger phrases are carried deliberately rather than suppressed. | | `unslop` | [`ai-slop:audit`'s tell catalog, "Cursor unslop additions"](../../plugins/ai-slop/skills/audit/reference/catalog.md) and [`reference/rewrite-guide.md`](../../plugins/ai-slop/skills/audit/reference/rewrite-guide.md), in [`ai-slop` 0.2.0](../../plugins/ai-slop/CHANGELOG.md) | Absorbed (skill omitted) | **Landed before this record** — derived at `ai-slop` 0.2.0 on 2026-08-19 (`reference/catalog.md`, "Second pass"), so this file's git history dates the *row*, not the derivation — and so it is not one of the ten lanes decided below; the row exists because the collection's attribution is incomplete without it, and because the recheck trigger above reaches only the rows this table names. **No skill:** `ai-slop:audit` already owned the axis over a Wikipedia-derived tell inventory and already shipped the detect-then-guarded-fix flow upstream's four-step process describes, so the port lands as entries in an existing catalog rather than as a skill; the `unslop this` trigger phrase is carried in that skill's description rather than suppressed. **Taken:** the seven patterns the Wikipedia inventory did not already carry — three script rules (`rule-chatbot-artifacts`, which merges upstream's separate chatbot-phrase and sycophantic-tone patterns and argues IMPORTANT in the [detector-findings crosswalk](../conventions/detector-findings/README.md); `rule-filler-phrases` and `rule-stacked-hedging`, both SUGGESTION) and four rubric tells (`rule-false-ranges`, `rule-colon-crutch`, `rule-abstract-metaphor-jargon`, `rule-mechanism-free-claims`); the plain-word trio `utilize` / `leverage` / `facilitate` into the shipped AI-vocabulary default, density-gated and measured quiet on the calibration corpus, so the shipped default stays neutral while saturated files still flag; and the upstream file's fix-time half, which a catalog that only decides *what flags* had nowhere to put — it becomes `reference/rewrite-guide.md`, carrying the plain-speech rewrites, the substitution guardrail (an em dash becomes a period or a comma, never a parenthesis, an en dash, or a spaced hyphen, because swapping one tell for another is not a fix), and the closing self-audit pass. **Deduplicated rather than absorbed:** every remaining upstream pattern already had a Wikipedia-derived entry, and the catalog records that in an overlap map accounting for all of them. The map says **catalogued by**, deliberately weaker than "covered by": a row pointing at a `recorded-only` entry says so, and `rule-bold-overuse`, `rule-inline-header-lists` and `rule-title-case` are each catalogued and dormant, so nothing runs them in either layer — and upstream's own carve-out for a bold lead-in that ends in a period and introduces genuinely new detail is recorded on `rule-inline-header-lists` as calibration pre-work, not as a live boundary. **Rejected — Name-dropping**, deliberately out of scope for general prose: the Wikipedia-specific form is `rule-canned-notability`, whose entry says there is no general-prose analogue worth a rule. **Rejected — the general half of Generic conclusions.** Only the formulaic closer that `rule-challenges-conclusion`'s pattern actually matches is detected; a bare optimism line matches no shipped rule, and the overlap map records that rather than papering over it. **Rejected as a script rule — abstract metaphor nouns.** Upstream ships a word list; calibrated against this marketplace's corpus, "substrate" alone measured 114 legitimate technical uses, so the tell stays rubric, where the literal-versus-metaphor call has a reader. **Rejected — "let some mess in".** Five of the six adding-soul bullets survive as the rewrite guide's Adding voice section; that one does not, and the section is bounded twice over — by document register (never API reference tables) and by the fix flow's meaning-preservation guard, so voice changes how a kept claim is phrased and never invents one. **Adaptation note:** upstream's description ends "Must always apply"; the additions inherited the incumbent's posture instead — triggered, read-only by default, rewriting only when `fix` is passed as an explicit argument. **Not audited at the pin above.** This verdict was formed at integration time against upstream `main` with no revision recorded — the catalog and the rewrite guide both cite an unpinned blob URL, and the catalog's own four-part drift record covers the Wikipedia source page only — so `main@60c641e4` is this row's baseline for the next diff, not the state it was audited at. | +| `show-me-your-work` | Four rules in [`implement-dispatch`'s deviation log](../../plugins/implementation/skills/implement-dispatch/SKILL.md), in [`implementation` 0.15.0](../../plugins/implementation/CHANGELOG.md); the formula-injection guard in [`claude-ops:audit-install-state`'s `install_state.py`](../../plugins/claude-ops/skills/audit-install-state/scripts/install_state.py), in [`claude-ops` 0.35.1](../../plugins/claude-ops/CHANGELOG.md) — see [below](#why-show-me-your-work-ships-neither-a-skill-nor-a-convention) | Absorbed (skill omitted) | **One of the ten lanes decided below** — unlike the `unslop` row above, which is not — and it gains a row because the recheck trigger reaches only the rows this table names, while this lane ships derived surfaces in two plugins. The omission argument, the eight-surface classification table it rests on, and the shape mismatch that killed the `session-flow:running-retro` premise are below and are not restated here; this row records what crossed over. **Taken — four rules into `implement-dispatch`'s `DEVIATIONS.md`:** append and supersede rather than edit or delete, the new entry naming what it supersedes, because rewriting history hides the reversal a PR reviewer most needs to see; evidence is a pointer (a SHA, a `file:line`, a test name, an artifact path) and preferably one a committed script produced, so the reviewer can re-run it rather than believe it — upstream splits that across its `evidence` column definition and a separate rule, merged here into one; an entry carries its outcome and says `unverified` rather than reading as settled; and one entry is one decision, since an entry that does not fit on a line or two is a decision that is not crisp yet. **Taken separately — the formula-injection guard from `scripts/log.sh`,** which prefixes any cell opening with `=`, `+`, `-`, or `@` with a single quote so a spreadsheet cannot execute it. It was absent fleet-wide, and looking for a landing site found a live exposure rather than a hypothetical one: `audit-install-state`'s `write_csv` already passed six walk-derived cells (`relpath`, `surface`, `number_meaning`, `liveness`, `liveness_reason`, `evidence`) straight through `csv.writer` into the artifact whose whole point is that a reader opens it row by row. It is now `csv_safe`, with `TestCsvFormulaInjection` confirmed discriminating against the guard disabled in memory. **Adapted — the guard is stricter here than upstream's.** Upstream's `clean()` rewrites tab, CR, and LF to spaces and only then tests the four leaders; `csv_safe` quotes rather than strips and treats a leading tab, CR, or LF as a formula leader in its own right, because a spreadsheet strips them before deciding, so `\t=cmd()` evaluates exactly as `=cmd()` does. Non-string cells — the integer byte counts, the boolean deny flag — pass through untouched. **Adapted — the trail's substance, not its artifact.** The four rules land as prose in an existing markdown log that a PR review reads, not as upstream's six-column TSV plus a shell appender; `DEVIATIONS.md` carries no `ts` or `phase` axis and gains none. **Adapted — the `unverified` rule cites rather than restates,** naming the identical grounding discipline `work-items:work-loop` and `source-control:babysit-loop` already apply to their cycle reports. **Rejected — the skill, and with it the marketplace convention it proposes.** Upstream's "Composing this skill" section tells other skills to route their audit trail here and let it own the format; that is a convention, and the classification below finds one genuine adopter — two if `session-flow:handoff` counts, and those two disagree about the one thing a shared format would have to fix. Upstream's own frontmatter sets `disable-model-invocation: true`, so even there the skill is reachable only by a typed invocation and its working value is the format other skills borrow, which is what was borrowed. **Rejected — the mandatory cross-model review of the trail.** Upstream is unconditional ("you **must** spawn a subagent on a different model family"), and it is this lane, not `arena`, that the `arena` row points at when separating a preference from a demand; it loses against the ~15 presence-gated-with-a-named-fallback sites counted below. **Rejected — the standing "Attention" section on every reply,** a session-wide output posture, which is a declared species here with exactly one member (`adhd:shape`). **Rejected as a duplicate — the log-versus-transcript self-audit,** whose discipline already ships verbatim in the two loop lanes named above. **Audited at the pin above.** Unlike the `unslop` row, this verdict was formed against `main@60c641e4`: the change that set that pin (`228a2b19`, 2026-08-21) is the same one that landed both absorbs and this file, so git history dates the derivation correctly and no date correction applies. Re-verified while adding this row — `pstack/skills/show-me-your-work/` is byte-identical between the pin and upstream `main@46125561` (read 2026-08-21), so the row lands with no drift outstanding. | ### The one deliberate departure