mirror of
https://github.com/conorbronsdon/avoid-ai-writing.git
synced 2026-09-19 01:32:11 +08:00
v3.31.0
15 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
def5e3825f |
Drop frontmatter metadata from the OpenAI copy of the canonical skill (#146)
* Drop frontmatter metadata from the OpenAI copy of the canonical skill The OpenAI plugin portal rejected the Skills-only ZIP on skills/avoid-ai-writing/SKILL.md: "Skill interface settings must use agents/openai.yaml ... `metadata` in SKILL.md does not configure the skill interface." That copy was byte-identical to root SKILL.md, whose frontmatter carries an agentskills.io/OpenClaw `metadata` block (author, repository, tags, agentskills_spec, openclaw.emoji). - sync-plugin-skill.sh writes the OpenAI copy with the `metadata` block removed from the frontmatter; everything else stays identical. The Claude plugin copy is unchanged. - validate-openai-plugin.py compares root-minus-metadata to the copy for its drift check and rejects a `metadata` key in any packaged skill's SKILL.md, so the portal error cannot recur silently. - validate-openai-plugin.test.py covers the transform (body untouched, version/license/compatibility kept, no-frontmatter passthrough, copy in sync) and three red controls: a byte-identical copy fails both rules, a body edit still reads as drift, and `metadata` in another skill fails. Verified: validate-openai-plugin.test.py, validate-openai-plugin.py . (OK), npm test, and the rebuilt archive validates after extraction. The rebuilt ZIP was accepted by the portal's upload validation. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UaeXzpBoBZKa1dWxVS1bTE * Single-source the metadata strip and correct the exact-copy wording Codex review of the previous commit found the awk and Python transforms could diverge (CRLF files, a frontmatter without a closing delimiter, a missing final newline) and that both ended the metadata block at a blank line, leaving orphaned nested keys. - sync-plugin-skill.sh now calls validate-openai-plugin.py --strip-frontmatter-metadata, so one implementation produces the copy and checks it. - strip_frontmatter_metadata keeps line endings byte-exact, treats blank lines inside the block as part of it, and returns text without a well-formed frontmatter unchanged; the drift check compares bytes again. - Tests add the edge inputs from the review and a CLI-vs-function byte-equality check. - OPENAI_PLUGIN.md, NOTICE.md, and submission-pack.json no longer call the bundled copy an exact copy; they state the one omitted block. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UaeXzpBoBZKa1dWxVS1bTE * Match only the top-level metadata key and keep comments inside the block Codex second pass: `metadata:extra:` is a distinct YAML key and was being stripped by the prefix match; a column-zero `#` comment inside the metadata block ended the block early and left an orphaned nested key. The key match now requires whitespace or end of line after `metadata:`, comment lines inside the block are skipped with it, and both cases have tests. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UaeXzpBoBZKa1dWxVS1bTE --------- Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com> |
||
|
|
905c8902dc |
Harden OpenAI plugin validation for deferred port gaps (#145)
* Harden OpenAI plugin validation for deferred port gaps * Fix validator fail-closed review gaps * Address maintainer review on plugin validation * Reject scalar OpenAI metadata sections * Accept quoted inline product values * Parse quoted product scalars safely --------- Co-authored-by: UniversePeak <120674402+UniversePeak@users.noreply.github.com> Co-authored-by: Conor Bronsdon <120674402+conorbronsdon@users.noreply.github.com> |
||
|
|
788c6675c1 |
Bring Avoid AI Writing to ChatGPT and Codex (#135)
* feat: seed OpenAI plugin skill resources * feat: add OpenAI plugin manifest and public metadata * feat: add routed ChatGPT and Codex skill graph * test: add OpenAI plugin validation and submission pack * fix: correct listing character-count evidence * feat: add typed cross-skill handoff contract * docs: encode agency review lenses for orchestration * feat: add machine-validated typed skill graph * feat: upgrade router to typed orchestration protocol * feat: connect detector to typed handoff network * feat: connect rewriter to verification and representation guards * feat: add typed file-edit handoffs and repair loop * feat: make preservation verifier a blocking typed gate * feat: connect interpretation guardrail to evidence handoffs * refactor: replace legacy yaml graph with validated json graph * test: validate skill graph and cross-skill contracts * ci: validate cross-skill orchestration graph * refactor: package connection validator inside router skill * refactor: keep connection validator inside packaged router skill * ci: run packaged connection validator before and after extraction * docs: align routing matrix with typed graph * test: expand routing evals for connected skill graph * fix: remove unintended reviewer detector cycle * fix: make interpretation reviewer terminal in skill graph * test: reject terminal outgoing edges and unbounded graph cycles * docs: align handoff contract with terminal reviewer semantics * docs: route fresh interpretation evidence through router * docs: document graph v2 and connection validation * fix: route fresh detector requests through orchestrator * test: enforce agency lenses and router-return semantics * test: cover terminal reviewer return-to-router flow * docs: add connected skill graph v2 to release notes * fix: remove unsupported skill policy products * fix: remove unsupported skill policy products * fix: remove unsupported skill policy products * fix: remove unsupported skill policy products * fix: remove unsupported skill policy products * fix: remove unsupported skill policy products * fix: remove unsupported skill policy products * fix: align plugin validator with graph v2 and ingestion policy * fix: synchronize bundled detector and verifier resources * fix: bundle detector beside preservation validator * ci: watch canonical detector resources for plugin drift * test: smoke packaged preservation residual detector * ci: exercise residual detector before and after packaging * fix(port): sync ChatGPT/Codex plugin version with canonical SKILL.md The merge with main moves the canonical skill to 3.28.0; the plugin manifest, listing, and submission pack still carried 3.25.1, so scripts/sync-plugin-skill.sh and scripts/validate-openai-plugin.py both exit 1 on the effective merge. Bump the three manifests and regenerate the copies the sync script owns. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * fix(port): publish the plugin from the canonical repository Every public destination in the ChatGPT/Codex package pointed at the contributor's fork: websiteURL, privacyPolicyURL, termsOfServiceURL, homepage, repository, the submission listing, and SUPPORT.md. After a merge the canonical owner would not control the published legal and support pages. Point them all at conorbronsdon/avoid-ai-writing and make developerName/packagePublisher the identity that will be verified in the OpenAI portal. Packaging credit stays: NOTICE.md and listing.json now name the contributor explicitly. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * fix(detector): CRLF input no longer bypasses the preservation validator validate() extracts frontmatter, tables and headings with regexes that anchor on a bare newline. A CRLF document matched none of them, so changing 'title: one' to 'title: two' in Windows-formatted frontmatter returned { ok: true, errors: [] }. This is a pre-existing bug in the canonical detector, not something PR #135 introduced - the bundled plugin copy is byte-identical to detector/validate.js - so the fix and the must-fire fixtures go in the canonical source and the generated copy is re-synced from it. Adds four CRLF fixtures to detector/validate.test.js; all four fail against the unpatched validator. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * fix(port): make the manifest the only source for listing metadata submission/listing.json restates twelve manifest fields and only three of them were asserted, so the listing could ship a different developer name, support URL or description than the manifest it claims to describe - which is exactly the drift that put a fork's URLs into the public package. Assert every duplicated field against .codex-plugin/plugin.json, derive the hand-maintained character counts instead of trusting them, and require every public URL to sit under the canonical author.url so publication cannot move off this repository without turning the check red. Also: guard the canonical-copy comparison against a missing plugin copy (it raised FileNotFoundError instead of reporting), scope the hygiene scan to the packaged surface instead of walking .git, and restore the CLAUDE.md path-filter rationale the port deleted from the workflow. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * fix(port): bundle every resource the canonical skill references OpenAI's submission contract says each skill must include any referenced scripts, templates, or assets, and the Codex skill layout has no shared- resource mechanism, so skills/avoid-ai-writing/SKILL.md (byte-identical to root SKILL.md) now ships with synced copies of detector/patterns.js, detector/validate.js, detector/CATEGORIES.md, scripts/check-style.js, and examples/ at the same relative paths. scripts/sync-plugin-skill.sh produces them and the existing regenerate-then-diff CI gate covers them. A new smoke test runs check-style and the preservation validator from inside the bundled tree and from an extracted package. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * fix(port): manifest supportURL, ancestry-checked baseCommit, policy.products interface.supportURL now lives in .codex-plugin/plugin.json and the listing value is validated against it. Both submission files record baseCommit as the origin/main merge-base and the validator checks it is an ancestor of HEAD so it cannot drift silently; the verifier's copied patterns.js joins the deterministic-resource inventory. The validator accepts policy.products with CHAT and/or CODEX per the current agents/openai.yaml schema and keeps rejecting unknown policy keys, with tests. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * fix(port): follow main to 3.29.0 after #128 landed Bump .codex-plugin/plugin.json and the submission metadata to 3.29.0, set baseCommit to the new origin/main merge-base, and regenerate the bundled copies so the sync gate is clean on the merge ref. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * fix(port): changelog and README for the plugin package; harden packager and validator Qodo re-review items: a dated 3.29.0 changelog entry and a README section for the native ChatGPT/Codex package; the packager and validator now reject symlinked top-level package files; JSON loading rejects a non-object root with a validation error instead of crashing, with tests for list and null roots and for the symlink case (skipped where symlinks need privileges). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * fix(port): packager and validator hardening, lone-CR preservation, workflow paths Qodo re-review items 6-11: the marketplace policy no longer demands install-time authentication for a skills-only package (ON_USE, the only other documented value); the packager rejects an output path that is a packaged input or sits inside an included directory and fails on a missing top-level package file instead of silently omitting it; the validator type-checks nested submission objects before access; the preservation validator normalizes CRLF only, so a lone carriage return changed inside code is reported again; LICENSE joins the workflow path filters. Tests for each; bundled validator copies re-synced. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * fix(port): marketplace authentication policy is first-use, not install-time The skills-only package has no authentication flow or hosted service. The marketplace docs say policy.authentication decides whether auth happens on install or first use; first use never triggers for local skills, so ON_USE replaces ON_INSTALL. (Qodo item 6, deferred from the previous commit because the implementer sandbox could not write .agents/.) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * fix(port): graph validator rejects malformed JSON cleanly; canonical URL is a constant Qodo items 8 and 9. validate_connections.py now checks the graph root and edge field types and reports through its validation path instead of raising, with a test script wired into CI. validate-openai-plugin.py pins CANONICAL_PROJECT_URL and requires author.url to equal it, so changing every public URL to a fork no longer passes; test added. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * fix(port): bound SVG parsing and stop empty skill names polluting the graph set Qodo items 19 and 20. The validator rejects SVGs carrying <!DOCTYPE or <!ENTITY declarations and anything over 256 KiB before handing text to ElementTree, closing the entity-expansion path; a skill whose frontmatter lacks a name reports that error once instead of inserting an empty name that cascades into router-graph errors. Tests for both. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * ci(port): full-history checkout so the baseCommit ancestry check can run The validator's merge-base --is-ancestor check needs the base commit in the checkout; actions/checkout's default depth of 1 made CI report it as "not a valid commit name". Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> --------- Co-authored-by: Conor Bronsdon <120674402+conorbronsdon@users.noreply.github.com> Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com> |
||
|
|
58a95fc997 |
docs: add seed coverage for missing corpus registers (#141)
* docs: add seed coverage for missing corpus registers * fix: address maintainer feedback on corpus seeds |
||
|
|
9a83f231b5 |
matrix: pin the multi-ref hit count (#110 review finding 3) (#115)
The finditer fix shipped in #114 without a test that can fail — a reversion to first-match-only scanning would stay green and quietly undercount. One assertion closes it: a two-ref line must report 2 hits. Verified: intact script passes; mutating scan_line to first-match-only fails with "expected 2 hits on a two-ref line, got ['scripts/check-style.js']". Co-authored-by: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
ba42fec5eb |
cursor-rules gate: nested paths, boundaries, link-form alignment, self-test matrix (#114)
Delivers the outstanding findings from the #110 reviews, which were posted before merge but not addressed in it: - FILENAME can accept path segments, so plugins/avoid-ai-writing/SKILL.md and corpus/human/essay-01.md now block — every real file under plugins/ is nested, so that REPO_DIRS entry could previously never fire (the hole) - right boundary: patterns.json no longer blocks via its patterns.js prefix - left guard includes _, so my_scripts/foo.js is prose - a markdown link with an http(s) target drops text and target together — the error message recommends exactly that form, so the gate no longer blocks its own advice - finditer per line: the count and the quoted matches are now honest when one line carries two refs - the review's precision matrix is committed as an always-on self-test (assert on every run; CI executes this script for the drift check, so it rides along with no workflow change). examples/.json documented as a deliberate pass per the review's ruling. Co-authored-by: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
6e425f2e5d |
check-pattern-count: assert CLAUDE.md's category-count copy on every push (#111)
* check-pattern-count: assert CLAUDE.md's copy of the category count on every push CLAUDE.md's don't-restate-it sentence quotes the README bullet, and its copy is tracked only by .ssot.yaml, which runs on release and weekly cron - so a same-repo edit could sit stale for up to a week (how #95's 46-vs-61 lived unnoticed). The sed pattern mirrors .ssot.yaml's regex for the copy, so the two guards cannot read different sentences. Controls: clean tree passes; 61->62 mutation fails with the drift message; a reworded sentence fails with its own message pointing at both guards. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EKwz2XfwaMD6uR5ABmVaKq * count guard: actually trigger on CLAUDE.md edits, survive a missing file, take the first match All three findings from the adversarial review of #111: - HIGH: plugin-skill-sync.yml's paths filter omitted CLAUDE.md, so the guard never ran on the edits it exists to catch (PR #106: zero check runs). Added to both triggers. - MEDIUM: under set -euo pipefail a missing CLAUDE.md killed the script with sed's raw error and exit 2 before the friendly branch. Explicit -f check with its own message and exit 1. - LOW: greedy sed took the LAST match on a line where a first-match regex engine takes the first; extraction is now grep -o | head -n1 (file-order first match) and the mirror-claim comment states the semantics honestly. Controls, exit codes checked unpiped: clean 0; mutation 1; reworded 1; missing file 1; same-line double-mention resolves to the first match. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EKwz2XfwaMD6uR5ABmVaKq --------- Co-authored-by: Claude <noreply@anthropic.com> |
||
|
|
2988a27e0b |
cursor-rules: fail on repo references a new SKILL.md section introduces (#103) (#110)
The anchored rewrites catch EDITS to a span they already know about. A brand new SKILL.md section that names a repo path passes them untouched and lands in a rule users curl into a project where none of this repo's files exist. That is how the --style section nearly shipped pointing at scripts/check-style.js and examples/, caught by hand in #99 rather than by the guard. The gate scans the generated body and exits 1, naming the match and the line number it would occupy in the rule. Two structural choices: Only `body` is scanned. The attribution header names scripts/sync-cursor-rules.sh and lives in cursor_fm, so it is exempt by construction rather than by a line-range carve-out that would drift when the header changes. It runs before the write, so a failing generation leaves no bad artifact on disk to be committed by accident. Precision is the whole difficulty, since the bare directory names collide with ordinary prose in this document. A match therefore has to name a FILE (`scripts/check-style.js`, `examples/<name>.json`), which is what every real reference here looks like. An earlier revision matched bare directories and false-positived on unmodified SKILL.md: `docs/technical-blog` is a context pair, not a path. Three further exemptions, each a precision call: a left word boundary, so `manuscripts/x.md` stays prose; anything inside an http(s) URL, which is the portable form and also what this gate's own message tells an author to switch to; and README/CHANGELOG/CONTRIBUTING/CLAUDE, which every project has and which this skill's prose already names. Verified with a 15-case matrix. Must-pass: manuscripts/, transcripts/, superscripts/, examples/counterexamples, docs/technical-blog, README.md, and two GitHub URLs whose paths contain detector/ and examples/. Must-block: the #99 near-miss shape, `examples/<name>.json`, `detector/CATEGORIES.md`, ./scripts/self-scan.js, and the bare filenames validate.js and PROOF.md. Removing the probe line returns exit 0 and leaves the rule unchanged. Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
f666087e52 |
feat: optional --style house-style layer (config-driven, points at Vale) (#99)
* feat: optional --style house-style layer (config-driven, points at Vale) Implements the config-driven design recorded in #88, which #76 and the fork review converged on. No bundled guides: the layer applies register/voice directives and removes AI tells on top of whatever mechanics you enforce. --style ./house.json applies a user-supplied JSON config (register + mechanics) and scripts/check-style.js verifies the CHECKABLE mechanics deterministically: quotes and latinAbbrev gate the exit code (0 clean / 1 hard / 2 tool error), headings, emDash and spellNumbersUpTo are advisory, serialComma is never checked. The docs scope the verb accordingly rather than claiming "mechanics are verified" flatly. examples/ ships two generic, guide-neutral starters plus the schema, and links #88 for the licensing rule. A bare --style "APA" is a best-effort fallback, not a feature: SKILL.md instructs the model to print a no-compliance-claim status line and not to reproduce the guide's text. Those are instructions rather than checked rules, and the docs say so instead of asserting the behaviour as fact. --style is listed in the SKILL.md invocation line and has an explicit composition rule with --voice/--context, since the file specifies composition for every other axis. README: the "House style is a different job" section said "There's no --style input", which this makes false. The first paragraph now describes the config input and reconciles with the heading (enforcing a PUBLISHED guide is the different job). The Vale paragraph and the heading anchor are unchanged. cursor-rules: the ported rule would have told a Cursor user to run scripts/check-style.js and read examples/, neither of which ships in the .mdc. Two anchored spans in sync-cursor-rules.sh rewrite those the way span 3 already handles detector/validate.js, so the port stays self-contained. Worth noting the drift guard only covers edits to anchored spans, not newly added SKILL.md sections that introduce repo references. The checker went through three adversarial review rounds, and each round found the previous round's fix had introduced a new way to hard-fail a correct document or to miss a real one. The tests pin all of them: markdown link titles, reference definitions (including escaped quotes in a title), HTML attribute values, nested and tilde fences, BOM'd frontmatter, URLs containing parentheses, parentheticals that wrap or span a code block, and a stray "(" that must not suppress later findings, and prose containing a comparison ("n<N ... >") that must not be mistaken for an HTML tag. Masking runs refdef -> links -> tags, in that order, because masking a link destination first makes an ordinary "[a](url): text" line look like a reference definition. Link masking walks to the matching paren and scans linearly; the regex form was quadratic (22.7s on a hostile line, now 4ms). resolveConfig decides path-vs-name by shape so a cwd file can't shadow a bundled example, the CLI parses by position, a config with "mechanics": null or [] exits 2 rather than a false-green 0, and advisory findings print instead of hiding behind --json. Version 3.22.3 -> 3.23.0 in SKILL.md frontmatter, package.json and plugin.json; CHANGELOG entry under a dated heading; plugin and cursor copies regenerated. No detector changes: catalog counts unchanged (61 / 112). 32 tests in scripts/check-style.test.js under npm test; detector-test.yml path filters extended to scripts/** and examples/**. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * style: mask indented code, tighten frontmatter open, announce the resolved mode Review fixes applied on top of the submitted branch: - Indented code blocks (4+ spaces / tab after a blank line, outside a list) are masked, so pasted terminal output can't hard-fail a correct document. Lazy continuation and list-item content stay checked; a code block nested in a list item needs a fence. Was the largest undocumented false positive. - A document opening with a thematic break is no longer read as frontmatter (which silently swallowed everything to the next ---). - The bare-name traversal regex was dead code its test never reached; a bare name is a single path segment by construction, so the guard is now a comment stating that argument, and a test pins dot-bearing names. - Config runs open by naming the resolved config, mirroring the fallback's status line, so which of the two modes ran is always explicit in output. - Known-limitations lists gain the double-backtick span and next-line reference-definition title gaps; examples/README.md joins the self-scan budgets; CHANGELOG updated; cursor-rule anchors follow the SKILL.md edit. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> Co-authored-by: Conor Bronsdon <120674402+conorbronsdon@users.noreply.github.com> |
||
|
|
2c82c30c23 |
cursor-rules: regenerate from SKILL.md and guard against drift (#98)
The Cursor port was a hand-made copy stranded at v3.16.0 while SKILL.md reached v3.22.3 — its own README said 'no automated sync today, open an issue if drift becomes a problem.' It did. scripts/sync-cursor-rules.sh now generates the .mdc from SKILL.md: Cursor frontmatter with the version derived from the SKILL.md frontmatter, plus the three portability rewrites a copied-out rule needs (no repo self-reference, no CATEGORIES.md citation, manual preservation check instead of node detector/validate.js). Each rewrite is anchored on exact upstream text and exits non-zero if the anchor stops matching once, so an upstream edit to a ported span breaks CI here instead of silently shipping a wrong rule. plugin-skill-sync workflow regenerates the rule on every SKILL.md change and fails on drift; cursor-rules/** added to its path filters so a hand-edit to the .mdc alone can't dodge the check. Negative control run: mutating a ported span in SKILL.md makes the script exit 1 with an actionable message; restoring it regenerates byte-identically (second run idempotent). Co-authored-by: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
cc0c2f43ab |
Catch promo-surface drift from the release that causes it (#80)
* Catch promo-surface drift from the release that causes it The pattern count and word-table count are already policed inside this repo: check-pattern-count.sh derives both from SKILL.md and fails CI if the README disagrees. Nothing policed the second link — four surfaces in other repos quote those numbers, and a release moves the number here while they sit still. That drift cannot be caught from the other side. Their files do not change on release day, so no pre-commit hook over there ever has a commit to fire on. It went unnoticed for three weeks: three of the four surfaces were still on 53 pattern categories and 109 table entries. So the check runs here, on release, with a weekly backstop: - .ssot.yaml declares the README bullets as canonical and the four surfaces as copies (dogfoods conorbronsdon/ssot-check) - promo-drift.yml clones the surfaces as siblings and runs the check - promo-drift-report.py turns the JSON into a readable issue body A surface that cannot be read is reported as NOT CHECKED and does not fail the job — conorbronsdon-site is private, and failing red every week over a missing token trains people to ignore the check. It is always printed. Set SITE_REPO_TOKEN to bring it into coverage; no code change needed. Verified against real clones of all four surfaces: in-sync exits 0, a stale number exits 1 with file:line, an unreadable surface exits 0 and says so, and a reworded canonical bullet is a hard failure rather than a silent pass. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YA7143ow5qvWZghbeQKiUd * Drop the site from the manifest; the check now needs no credential conorbronsdon.com/builds floors both counts instead of quoting them, so there is nothing left to keep in sync there. That removes the only private surface, which removes the only reason this workflow wanted a PAT. Every tracked surface is now a public repo and the job runs on its own GITHUB_TOKEN. The not-checked path stays — a surface repo can still be renamed or fail to clone, and that must read as a coverage gap, not a pass. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YA7143ow5qvWZghbeQKiUd --------- Co-authored-by: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
fba57d3c38 |
Enforcement, self-scan proof, and the first measured accuracy numbers (v3.22.0) (#68)
Adds a preservation validator, a self-scan with PROOF.md, over-correction guardrails, a false-positive intake, and a two-class control corpus with the project's first FPR, TPR, and AUC. Splits Tier 1 into 1A frequency markers and 1B clarity edits, and fixes two detector defects the measurement found (#67, #69). Findings and open decisions: #70, #71, #72, #73. |
||
|
|
af346121e8 |
Fix word-table count (109 → 111) and guard it in CI (#57)
The README advertised a "109-entry word replacement table". The real count is 111 (59 Tier 1 + 40 Tier 2 + 12 Tier 3). Stale since
|
||
|
|
c892a8e013 |
docs: reconcile pattern count to 46 + add CI count-guard (#28)
Comprehensive doc review after the 3.4->3.7.2 churn. The pattern count had rotted across files (README said 42, CLAUDE.md said 36, reality is 46 detection categories in SKILL.md). - Fix the count to 46 and keep it in ONE user-facing place (the README "46 pattern categories" bullet). README heading reframed to "Pattern reference" (representative examples, not an exhaustive census), and the table extended with the 7 missing categories (placeholders, citation markup, UTM, gap-filling, hyphenated-pair, infomercial, low-TTR). - De-duplicate the count: CLAUDE.md and detector/CATEGORIES.md now reference SKILL.md + CI instead of restating their own numbers. - Add scripts/check-pattern-count.sh + wire into the CI workflow: it derives the count from SKILL.md's detection ### entries (excluding the 3 writer-side tests) and fails if the README number drifts. Drift is now a red check, not silent rot. - Fix stale detector/patterns.js version comment and the marketplace.json description (was "detection-only mode"). No SKILL.md / version change — docs + CI only. Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
||
|
|
049463a806 |
Distribute as a Claude Code / Cowork plugin (#17)
* feat: distribute as a Claude Code / Cowork plugin Package the skill as a single-plugin marketplace so it can be installed via /plugin instead of a bare clone. This is the only path that works in Claude Cowork, which loads skills exclusively from installed plugins (see #12). Root SKILL.md stays the single source of truth; the plugin's bundled copy at plugins/avoid-ai-writing/skills/avoid-ai-writing/SKILL.md is generated by scripts/sync-plugin-skill.sh. A CI workflow regenerates it and fails on drift or a plugin.json/SKILL.md version mismatch. Validated with `claude plugin validate` and a full local add-marketplace / install / inspect / uninstall cycle. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix: parse plugin version safely in sync script * fix: harden plugin version parsing in sync script * harden skill-version parsing + plugin install docs Builds on Copilot's plugin.json JSON-parser fix: - sync-plugin-skill.sh: read the version only from the SKILL.md frontmatter block (not anywhere in the file), strip CR, and fail with a clear message if it's unparseable — closes the loose/false-green side of the version check that the JSON parser already closed for plugin.json. - .gitattributes: pin *.md to LF so a CRLF checkout can't forge a version mismatch or mask skill drift. - README: add /reload-plugins to the install steps (skills don't activate until reload/restart) and note updates are version-gated. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> |