diff --git a/plugins/ai-slop/.claude-plugin/plugin.json b/plugins/ai-slop/.claude-plugin/plugin.json index f143caf63b..0d26914cbb 100644 --- a/plugins/ai-slop/.claude-plugin/plugin.json +++ b/plugins/ai-slop/.claude-plugin/plugin.json @@ -1,7 +1,7 @@ { "$schema": "https://json.schemastore.org/claude-code-plugin-manifest.json", "name": "ai-slop", - "version": "0.3.3", + "version": "0.3.4", "description": "Detects and removes AI-writing tells (slop) in checked-in markdown prose: em dashes, emoji formatting, AI vocabulary, negative parallelisms, chatbot phrases, filler, stacked hedging, citation artifacts, and the rest of a catalog distilled from Wikipedia's Signs of AI writing. Read-only audit by default with a deterministic detector plus a judgment rubric; an explicit fix action rewrites findings behind a semantic-diff guard. Findings conform to the detector-findings convention so the review fanout fix relay can consume them.", "author": { "name": "Melodic Software", diff --git a/plugins/ai-slop/CHANGELOG.md b/plugins/ai-slop/CHANGELOG.md index 5d4b13e3c2..aa83381872 100644 --- a/plugins/ai-slop/CHANGELOG.md +++ b/plugins/ai-slop/CHANGELOG.md @@ -1,5 +1,16 @@ # Changelog +## [0.3.4] + +- **The README now points back at the upstream ledger.** `docs/upstream/cursor-pstack.md` names + this plugin's catalog and rewrite guide as where the Cursor `unslop` skill landed, but nothing + under `plugins/ai-slop/` pointed the other way — the only derived plugin in the marketplace with + no citation of that file, so a reader who arrived at the catalog through the README had no route + to what the port took, deduplicated, or rejected, nor to the row that decides the next drift + recheck. The README's existing sentence naming Cursor's skill now carries that link. The pointer + belongs here rather than appended to the earlier entry that recorded the port, because a published + changelog entry is history and is not edited. Documentation only. + ## [0.3.3] Three corrections found by re-reading what 0.3.1 and the 2.4.0 contract release actually shipped. diff --git a/plugins/ai-slop/README.md b/plugins/ai-slop/README.md index 3ab2f186fc..fc43707eb8 100644 --- a/plugins/ai-slop/README.md +++ b/plugins/ai-slop/README.md @@ -26,8 +26,11 @@ distilled from Wikipedia's ["Signs of AI writing"](https://en.wikipedia.org/wiki/Wikipedia:Signs_of_AI_writing) (revision-pinned, tracked under the upstream-drift convention), plus a set of additions inspired by [Cursor's `unslop` skill](https://github.com/cursor/plugins/blob/main/pstack/skills/unslop/SKILL.md) -and deduplicated against it in the catalog's overlap map. Fix-time rewrite guidance (plain speech, -substitution guardrails, adding voice) lives in +and deduplicated against it in the catalog's overlap map. What that port took, deduplicated, and +rejected is recorded in the marketplace's upstream ledger, +[`docs/upstream/cursor-pstack.md`](../../docs/upstream/cursor-pstack.md) (the `unslop` row), which +is also where the next drift recheck against upstream is decided. Fix-time rewrite guidance (plain +speech, substitution guardrails, adding voice) lives in [`skills/audit/reference/rewrite-guide.md`](skills/audit/reference/rewrite-guide.md), which the `fix` action applies. diff --git a/plugins/overengineering/.claude-plugin/plugin.json b/plugins/overengineering/.claude-plugin/plugin.json index b055b92e81..031e947911 100644 --- a/plugins/overengineering/.claude-plugin/plugin.json +++ b/plugins/overengineering/.claude-plugin/plugin.json @@ -1,7 +1,7 @@ { "$schema": "https://json.schemastore.org/claude-code-plugin-manifest.json", "name": "overengineering", - "version": "0.2.0", + "version": "0.2.1", "description": "Evidence-earned-keep audit of an existing enforcement surface — agent hooks and standing instructions, repository and version-control hooks, CI lanes and gate scripts, branch protections, forge apps, declared external integrations — treating every incumbent mechanism as a retirement candidate until empirical evidence earns its keep, arguing every verdict in cost of carry, capping retirement-direction verdicts on security-class artifacts at FLAG-FOR-HUMAN, and realigning to the simplest adequate solution behind an explicit per-item human gate. The audit is read-only and emits a diffable findings artifact; realignment is a separate, explicitly invoked skill; and a third read-only lane re-runs the audit on whatever cadence the consumer wires and reports only what moved since the last run, above a configurable noise budget.", "author": { "name": "Melodic Software", diff --git a/plugins/overengineering/CHANGELOG.md b/plugins/overengineering/CHANGELOG.md index cf44aef757..799e7883e0 100644 --- a/plugins/overengineering/CHANGELOG.md +++ b/plugins/overengineering/CHANGELOG.md @@ -3,6 +3,23 @@ All notable changes to the `overengineering` plugin are documented here. Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/); this plugin uses semantic versioning. +## [0.2.1] + +### Fixed + +- **The findings artifact's `date:` field was justified by a property it cannot have.** + `context/findings-artifact.md` argued the field as "Colon-free UTC, **Windows-safe**, lexically + sortable". Windows-safety is a *filename* property — a colon is illegal in a Windows path + component — and is meaningless for a field written *inside* a file; this contract fixes one + stable filename per home (`findings.md`) and deliberately rejects a timestamped one, so there is + no filename here for the claim to attach to either. The row now argues the format on what is + actually true of it: compact, unambiguous about its zone, and lexically sortable, so string order + is chronological order. **The format is unchanged.** ISO-basic `YYYYMMDDTHHMMSSZ` is valid + ISO-8601 and this artifact is not a detector-findings adopter — its only consumer is + `/overengineering:realign` — so nothing obliges it to match any neighbor's extended form, and a + wrong rationale is not grounds to move a contract that works. Documentation only; no consumer + reads the rationale cell. + ## [0.2.0] ### Added diff --git a/plugins/overengineering/context/findings-artifact.md b/plugins/overengineering/context/findings-artifact.md index 1b9aa07fe3..4e3d8418b8 100644 --- a/plugins/overengineering/context/findings-artifact.md +++ b/plugins/overengineering/context/findings-artifact.md @@ -73,7 +73,7 @@ branch: |---|---|---| | `type` | yes | Exactly `overengineering-findings`. The selector realign matches on. | | `schema` | yes | Integer contract version, currently `1`. A consumer reading an unrecognized value **stops with a visible message** rather than guessing at the shape. | -| `date` | yes | Colon-free UTC, Windows-safe, lexically sortable. The only record of when the audit actually ran. | +| `date` | yes | ISO-basic UTC (`YYYYMMDDTHHMMSSZ`): compact, unambiguous about its zone, and lexically sortable — string order is chronological order. The only record of when the audit actually ran. (Colon-freedom buys nothing *inside* a file; it is a **filename** property, and this contract fixes one stable filename per home rather than a timestamped one.) | | `scope` | yes | The layers walked, from the layer vocabulary below. A layer-scoped pass says so here; **a layer absent from `scope` was not walked, and is not the same as a layer walked and found empty.** The merge rules depend on this distinction. | | `branch` | yes | The branch at audit time. Realign refuses an artifact whose `branch:` does not match the current branch, naming the mismatch. | diff --git a/plugins/testing/.claude-plugin/plugin.json b/plugins/testing/.claude-plugin/plugin.json index 2df2ea6cc5..a5bde68c49 100644 --- a/plugins/testing/.claude-plugin/plugin.json +++ b/plugins/testing/.claude-plugin/plugin.json @@ -1,7 +1,7 @@ { "$schema": "https://json.schemastore.org/claude-code-plugin-manifest.json", "name": "testing", - "version": "0.7.3", + "version": "0.7.4", "description": "Test-stage discipline across all ecosystems: coverage-gap analysis and test planning (`/testing:plan`), TDD test authoring and placement (`/testing:write`), live E2E plus non-UI smoke verification (`/testing:run-e2e`), failing-test root-cause diagnosis with the reproduce → isolate → fix → retest loop (`/testing:diagnose`), and a deterministic can't-fail test audit with a fail-closed gate mode and opt-in findings persistence (`/testing:audit`).", "author": { "name": "Melodic Software", diff --git a/plugins/testing/CHANGELOG.md b/plugins/testing/CHANGELOG.md index d1a14d8b1d..148e2edc38 100644 --- a/plugins/testing/CHANGELOG.md +++ b/plugins/testing/CHANGELOG.md @@ -3,6 +3,32 @@ All notable changes to the `testing` plugin are documented here. Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/); this plugin uses semantic versioning. +## [0.7.4] + +### Fixed + +- **`audit`'s own unit suite carried a can't-fail assertion for the `date:` frontmatter + field.** `cant-fail-scan.test.sh` asserted `date: 20` under the name "date frontmatter is + present" — a truncated prefix of a structured value, so it passed for the emitter's real + `2026-08-23T04:37:40Z` and equally for `2026-08-21T13-36-00Z`, a hyphenated time that is + ISO-8601 in neither the extended nor the basic profile. That is the same assertion shape + that pinned `ai-slop`'s emitter bug rather than catching it (#3097), sitting inside the + skill whose whole purpose is finding tests that cannot fail. The assertion now anchors the + full extended form with an explicit `Z` + (`^date: [0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z$`), and was confirmed + discriminating: it FAILS against both malformed shapes above and PASSES against + `cant-fail-scan.sh --findings` output. Test-only — the emitter already stamped the correct + format, so no scanner behavior changes. + +### Added + +- **`assert_matches ` in `cant-fail-scan.test.sh`.** An assertion about + the *shape* of a field's value now has somewhere to go other than a substring test on part + of that value, which is what produced the guard above. The file's sibling assertions were + re-read at the same time: every other one pins an exact literal that a malformed value would + not contain, so that was the only non-discriminating guard present and nothing else was + rewritten. + ## [0.7.3] ### Changed diff --git a/plugins/testing/skills/audit/scripts/cant-fail-scan.test.sh b/plugins/testing/skills/audit/scripts/cant-fail-scan.test.sh index 9c647c5aa8..891e7ac64a 100755 --- a/plugins/testing/skills/audit/scripts/cant-fail-scan.test.sh +++ b/plugins/testing/skills/audit/scripts/cant-fail-scan.test.sh @@ -40,6 +40,17 @@ assert_not_contains() { *) pass "$1" ;; esac } +assert_matches() { + # assert_matches . Use this wherever the assertion is + # about the SHAPE of a field's value: a substring check on a prefix of that + # value passes for every malformed value sharing the prefix, which is the + # can't-fail shape this scanner exists to find. + if printf '%s\n' "$2" | LC_ALL=C grep -qE "$3"; then + pass "$1" + else + fail "$1" "expected output to match ERE: $3" + fi +} count_lines() { printf '%s\n' "$1" | grep -c "$2"; } TMP_ROOT="$(mktemp -d)" @@ -144,7 +155,14 @@ out="$(CANT_FAIL_SCAN_ROOT="$REPO" bash "$SCAN" --findings 2>/dev/null)" || rc=$ assert_exit "--findings completes in a git repo" 0 "$rc" assert_contains "frontmatter declares the findings type" "$out" "type: review-findings" assert_contains "branch frontmatter is the checked-out branch, verbatim" "$out" "branch: findings-branch" -assert_contains "date frontmatter is present" "$out" "date: 20" +# The `date:` value is a contract SHAPE, not a presence flag. `date: 20` also +# matches `date: 2026-08-21T13-36-00Z` — a hyphenated time that is ISO-8601 in +# neither the extended nor the basic profile — so it is the same assertion that +# pinned ai-slop's emitter bug instead of catching it (#3097). Anchoring the +# full extended form with an explicit `Z` makes a format-string regression in +# the emitter fail here. +assert_matches "date frontmatter is ISO-8601 extended UTC (YYYY-MM-DDThh:mm:ssZ)" "$out" \ + '^date: [0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z$' assert_not_contains "tier: is omitted (no lifecycle-tier analogue)" "$out" "tier:" assert_contains "table header matches the consumed shape" "$out" "| Rank | Tier | Confidence | Location | Surface(s) | Finding | Action |" assert_contains "row carries tier and confidence" "$out" "| IMPORTANT | high |"