aboutsummaryrefslogtreecommitdiff
path: root/todo.org
diff options
context:
space:
mode:
authorCraig Jennings <c@cjennings.net>2026-05-07 09:36:14 -0500
committerCraig Jennings <c@cjennings.net>2026-05-07 09:36:14 -0500
commit9858611afcdf848b6e483ba78f89c576aa5c8743 (patch)
treee46cc1049ef12d54faebddb4cb3f035bef2259b5 /todo.org
parent5bee32b3e11dfc8fa3eefa589a8fc18932abaa79 (diff)
downloadrulesets-9858611afcdf848b6e483ba78f89c576aa5c8743.tar.gz
rulesets-9858611afcdf848b6e483ba78f89c576aa5c8743.zip
chore(skills): remove humanizer (superseded by voice)
I deleted humanizer/SKILL.md now that all three callers (commits.md, respond-to-cj-comments.md, start-work.md) invoke /voice instead. The 25 humanizer patterns live on as patterns 1-25 in voice/SKILL.md. Same source (Wikipedia's Signs of AI writing), same prose, same examples — just renumbered alongside the universal good-writing additions and the personal-only patterns. I also updated .ai/notes.org and .ai/workflows/wrap-it-up.org to reference /voice personal instead of the old humanizer + manual-passes flow. The wrap-it-up change landed upstream in claude-templates first so it survives the next startup rsync. todo.org gets the matching update: the voice TODO is marked DONE with a "Built and shipped" timestamp, the publish-mode terminology is renamed to personal-mode throughout, the V1 scope checklist is ticked, the open questions are resolved with the answers we landed on during implementation, and the migration section records the delete-not-alias decision.
Diffstat (limited to 'todo.org')
-rw-r--r--todo.org210
1 files changed, 210 insertions, 0 deletions
diff --git a/todo.org b/todo.org
index 9dda3e8..99adf6a 100644
--- a/todo.org
+++ b/todo.org
@@ -686,6 +686,101 @@ Source notes used in this pass:
[[https://www.nist.gov/publications/practical-combinatorial-testing-beyond-pairwise][NIST beyond pairwise]],
[[https://www.nist.gov/publications/combinatorial-software-testing][NIST combinatorial testing]]
+** Grouped index (for batching by area)
+
+Each item below is a one-line summary of a sub-TODO further down. Tick the box when the matching sub-TODO is moved to =DONE=. Items are grouped by area so they can be batched (e.g., "do all Playwright items in one session").
+
+*** Browser testing
+- [ ] [#A] =playwright-js=: locator/assertion-first guidance (replace raw CSS, =networkidle=)
+- [ ] [#B] =playwright-js= + =playwright-py=: reconcile headless/visible defaults
+- [ ] [#B] =playwright-js= + =playwright-py=: remove emoji console markers from examples
+
+*** Frontend / UI
+- [ ] [#B] =frontend-design=: WCAG 2.2 alignment, accessibility non-optional
+- [ ] [#B] =frontend-design=: harmonize aesthetic guidance with anti-pattern rules
+
+*** Security
+- [ ] [#A] =security-check=: OWASP 2021 + WSTG coverage
+- [ ] [#B] =security-check=: tooling and offline/network caveats
+
+*** Combinatorial testing
+- [ ] [#B] =pairwise-tests=: t-way escalation guidance beyond pairwise
+- [ ] [#B] =pairwise-tests=: clarify negative value syntax + generator availability
+
+*** V2MOM
+- [ ] [#A] =create-v2mom=: rename Metrics → Measures (Salesforce alignment)
+- [ ] [#B] =create-v2mom=: prevent task migration from turning V2MOM into a backlog
+- [ ] [#B] =create-v2mom=: mitigation/owner fields for Obstacles
+
+*** Prompt engineering
+- [ ] [#A] =prompt-engineering=: correct/narrow Meincke citation
+- [ ] [#B] =prompt-engineering=: eval-harness requirement for production prompts
+
+*** Codify
+- [ ] [#B] =codify=: stale-entry review + privacy checks before writing project =CLAUDE.md=
+
+*** Code review
+- [ ] [#A] =review-code=: resolve local-verification vs CI boundary
+- [ ] [#B] =review-code=: =CLAUDE.md= citation scope for public artifacts
+- [ ] [#B] =review-code=: relax three-strengths rule for tiny/failing diffs
+
+*** PR / review responses
+- [ ] [#A] =respond-to-review=: remove review-process language from commit messages
+- [ ] [#B] =respond-to-review=: use unresolved threads + resolution state
+- [ ] [#B] =respond-to-cj-comments=: drop personal absolute paths from public-writing
+- [ ] [#B] =respond-to-cj-comments=: fallback when =humanizer= or =emacsclient= unavailable
+
+*** Branch workflow
+- [ ] [#A] =finish-branch=: fix base-branch detection
+- [ ] [#B] =finish-branch=: worktree-aware pull/merge safety
+- [ ] [#B] =start-work=: tool-availability + ceremony-scaling rules
+- [ ] [#B] =start-work=: claim-before-justify rollback risk
+
+*** Tests / TDD
+- [ ] [#B] =add-tests=: fix missing =typescript-testing.md= reference or add ruleset
+- [ ] [#B] =add-tests=: explicit exceptions to "all three categories per function"
+
+*** Debugging / RCA
+- [ ] [#B] =debug=: capture environment + recent-change context before hypotheses
+- [ ] [#B] =root-cause-trace=: constrain defense-in-depth to trust boundaries
+- [ ] [#B] =five-whys=: require evidence + counterfactual validation per why
+
+*** Brainstorming
+- [ ] [#B] =brainstorm=: timebox + research/source rules for high-stakes designs
+
+*** Architecture
+- [ ] [#B] =arch-decide=: timeless examples, drop unverifiable claims
+- [ ] [#B] =arch-decide=: standardize statuses + immutability language
+- [ ] [#B] =arch-design=: threat modeling + privacy/compliance as first-class inputs
+- [ ] [#B] =arch-design=: separate paradigms from tactical patterns
+- [ ] [#B] =arch-document=: arc42/Q42 quality scenarios
+- [ ] [#B] =arch-document=: staleness + ownership metadata for generated docs
+- [ ] [#B] =arch-evaluate=: confidence levels for framework-agnostic findings
+- [ ] [#B] =arch-evaluate=: report skipped tool checks explicitly
+
+*** C4 modeling
+- [ ] [#A] =c4-analyze= + =c4-diagram=: notation/output fallback (not draw.io-only)
+- [ ] [#B] =c4-analyze= + =c4-diagram=: clarify abstraction boundaries
+
+*** Global rules
+- [ ] [#B] =commits.md=: split DeepSat/Linear/Slack-specific from global rules
+- [ ] [#A] =commits.md= + publish flows: =humanizer=-unavailable fallback
+- [ ] [#B] =verification.md=: explicit "unable to verify" reporting standard
+- [ ] [#B] =testing.md=: property-based + mutation testing as escalation paths
+- [ ] [#B] =testing.md=: soften absolute TDD with explicit spike protocol
+- [ ] [#B] =subagents.md=: capability/availability + cost checks
+
+*** Languages
+- [ ] [#A] =python-testing.md=: revisit in-memory SQLite guidance
+- [ ] [#B] =python-testing.md=: separate "never mock ORM" from unit-test boundaries
+- [ ] [#B] =elisp.md=: drop tool-specific advice
+- [ ] [#B] =elisp-testing.md=: batch-mode + native-comp caveats
+
+*** Hooks
+- [ ] [#A] =hooks/README.md=: include =destructive-bash-confirm.py= in install/settings snippets
+- [ ] [#A] =hooks/git-commit-confirm.py= + =gh-pr-create-confirm.py=: inspect message/body files referenced by =-F= / =--body-file=
+- [ ] [#B] =hooks/destructive-bash-confirm.py=: shell-aware command parsing (not regex)
+
** TODO [#A] =playwright-js=: replace raw CSS/page actions and =networkidle= defaults with locator/assertion-first guidance
Current examples lean on =page.click=, =page.fill=, =waitForSelector=, and
@@ -1611,3 +1706,118 @@ rm /tmp/secrets.env.tmp
#+end_src
The flow tonight worked but took a handful of manual steps. One script collapses it.
+
+* DONE [#A] Build =voice= skill — combine =humanizer= with universal + personal style passes :feature:
+
+Combine =humanizer= with universal good-writing passes (Strunk & White, Orwell, Plain English) and the personal-style passes from =commits.md=. Two modes — =general= for arbitrary writing, =personal= for commits/PRs/comments — share a foundation and diverge on register.
+
+Built and shipped 2026-05-07: =voice/SKILL.md= with 39 numbered patterns walked sequentially. Patterns 1-25 carried over from humanizer, 26-31 are universal good-writing additions, 32-39 are personal-only. Migrated three callers (=commits.md=, =respond-to-cj-comments.md=, =start-work.md=). Removed the standalone =humanizer= skill since voice supersedes it.
+
+** Why this matters
+
+Three transformations want to run together for personal-mode artifacts (commits, PR titles + bodies, PR comments) but lived in three places: =humanizer= as a skill, S&W-style universal rules nowhere (applied ad-hoc), and the personal-style passes as prose steps in =commits.md= that got re-applied by hand each time. Costs: (1) the "I forgot pass (e)" failure mode — skipping a pass without flagging is a defect but happens in practice. (2) No single-call invocation of the full transform. (3) General-mode writing (research notes, philosophy, history) got only humanizer with no universal-prose pass at all. Combining brings them under one skill with one invocation.
+
+** Design
+
+Two modes:
+
+- *general* (default) — for arbitrary writing not bound for commit/PR/comment publishing (research notes, philosophy/history essays, emails, README prose). Runs:
+ - humanizer (current behavior — strip AI-generated-writing fingerprints)
+ - tier-1 universal passes (canonical good-writing rules)
+ - the 2 personal-style passes that have no register conflict (jargon-fragment rewrite, noun-ified verbs)
+
+- *personal* — for commits, PR titles + bodies, PR comments. Runs general PLUS:
+ - 8 personal-only passes (first-person rewrite, semicolons, contractions, sentence-split, felt-experience, sentence fragments, terse cut, public-artifact scope check)
+
+The 8 personal-only passes are explicitly *not* in general mode. They conflict with academic / literary / philosophical register. Forcing first-person on a Foucault essay or stripping felt-experience from a journal entry would damage the writing.
+
+** Tier 1 universals (v1)
+
+From Strunk & White, Orwell's "Politics and the English Language", Plain English Campaign, and Garner's Modern English Usage. Each is a detection-pattern + rewrite-rule pair, mechanical enough to apply consistently across runs.
+
+- *Omit needless words* — curated phrase list (=the fact that= → =that=/=because=, =in order to= → =to=, =at this point in time= → =now=, =due to the fact that= → =because=, =for the purpose of= → =to=, =in spite of= → =despite=, etc.)
+- *Long word → short word* — Plain English wordlist (~150 entries: =utilize=→=use=, =commence=→=start=, =terminate=→=end=, =facilitate=→=help=, =demonstrate=→=show=, =sufficient=→=enough=, =prior to=→=before=, =subsequent to=→=after=, =in the event that=→=if=, =a great deal of=→=much=)
+- *Active over passive voice* — detect "to be + past-participle" patterns. Suggestion-only in v1 (auto-rewrite is risky in technical contexts where passive is appropriate); graduate to auto-rewrite for unambiguous cases in v2.
+- *Comma splices* — detect independent clauses joined only by comma; rewrite to period or semicolon-then-period.
+- *Cliché flag* — small curated list (=at the end of the day=, =moving forward=, =going forward=, =at this juncture=, =circle back=, =low-hanging fruit=, =deep dive=, =leverage= as verb).
+
+** Tier 2 universals (v2)
+
+- *Positive over negative form* (S&W) — =not unlike= → =like=, =do not fail to= → =remember to=, =did not pay any attention= → =ignored=
+- *Garner-style word-pair corrections* — comprise/compose, less/fewer, that/which (restrictive vs nonrestrictive), affect/effect, principal/principle
+- *Parallelism in lists* — detect mismatched grammar in bullet items
+- *Tense consistency* — flag mid-paragraph tense shifts
+- *Acronym definition on first use* — detect uppercase tokens used before being expanded
+
+** Tier 3 (v3, may not land)
+
+- *Concrete-over-abstract* preference
+- *Emphatic word at sentence end* (S&W rule 18)
+- *Vary sentence length / rhythm*
+- *Reading-grade-level scoring* (Hemingway-style)
+
+** Personal-style pass placement
+
+| # | Pass | Mode | Why |
+|---|------|------|-----|
+| 1 | First-person voice rewrite | personal only | Forces "I" voice; wrong for academic prose where third-person and "we" are conventional |
+| 2 | Jargon-fragment → complete sentence | both | Universal clarity, no genre conflict |
+| 3 | Semicolon → period/comma | personal only | Semicolons are conventional in long-form / academic prose |
+| 4 | Contractions ("it's", "don't") | personal only | Academic and formal writing typically avoids contractions |
+| 5 | Sentence split on conjunctions | personal only | Foucault, Hegel, Adorno deliberately use long compound sentences |
+| 6 | Felt-experience narration ("I'll feel this every time") | personal only | Personal essays *use* felt-experience as content |
+| 7 | Noun-ified verbs ("the ask", "a learn", "the spend") | both | Targets corporate-speak with curated wordlist; doesn't catch philosophical nominalizations like "the becoming" |
+| 8 | Sentence fragments → complete (in prose) | personal only | Fragments are valid stylistic devices in literary prose |
+| 9 | Terse cut (rhetorical padding: "worth noting", "it's important to understand") | personal only | Tier 1 omit-needless-words covers the worst offenders universally; aggressive cut conflicts with academic register |
+| 10 | Public-artifact scope check (local paths, private repos, personal tooling) | personal only — *flag-only*, no auto-rewrite | Operational/safety check, not stylistic; auto-masking risks silently editing meaningful text |
+
+** Inclusive-language pass — explicitly excluded
+
+Considered and rejected. Conflicts with planned writing on philosophy/history topics (Foucault on sexuality and gender, history of slavery in New Orleans). Wordlist substitutions would override deliberate vocabulary choices in those genres.
+
+** V1 scope
+
+- [ ] Skill at =~/code/rulesets/voice/= with =SKILL.md=
+- [ ] Frontmatter with positive triggers (commit, PR, comment, "humanize", "voice pass") and negative triggers (code, structured data, plain bullet lists)
+- [X] Mode invocation: default = =general= when invoked bare; =personal= invoked explicitly by publish-context callers
+- [X] humanizer content migrated from =humanizer/= → =voice/=
+- [X] Tier 1 universal passes implemented (5 patterns: #26-30, plus #31 noun-ified verbs as a universal personal addition)
+- [X] 2 personal passes that run in both modes (#30 jargon-fragment, #31 noun-ified verbs)
+- [X] 8 personal passes that run in personal mode only (#32 first-person, #33 semicolons, #34 contractions, #35 sentence-split, #36 felt-experience, #37 fragments, #38 terse cut, #39 scope check)
+- [X] Each pass = detection-pattern + rewrite-rule pair (#39 is detection + flag-only)
+- [X] Total v1 pattern count: 31 in general mode (humanizer's 25 + 4 tier-1 + 2 universal personal); +8 personal-only = 39 in personal mode
+- [X] Update =commits.md= to invoke =/voice personal= instead of "run =humanizer= and apply five passes manually"
+- [X] Remove the existing =humanizer/= skill (no callers outside this repo, all migrated)
+- [X] =make doctor= still passes
+- [X] =make lint= clean
+
+** v2 (deferred)
+
+- [ ] Tier 2 universals (positive form, word-pair corrections, parallelism, tense consistency, acronym definition)
+- [ ] Per-pass severity flags for Tier 1 active-voice (suggestion-only when actor is implicit; auto-rewrite when actor is named)
+- [ ] Reporting mode: list which passes fired and which were no-ops
+
+** v3 (aspirational, may not land)
+
+- [ ] Tier 3 (concrete-over-abstract, emphatic-word position, sentence-length variation, reading-grade scoring)
+- [ ] Progressive disclosure split: =voice/SKILL.md= orchestrator + =voice/passes/<pass-name>.md= per pass with worked examples
+
+** Migration (resolved)
+
+Decision: deleted =humanizer/= entirely. Three callers (=commits.md=, =respond-to-cj-comments.md=, =start-work.md=) all updated to invoke =/voice= directly. No alias needed since nothing outside the repo invoked humanizer.
+
+** Naming alternatives considered
+
+- =voice= — chosen. Captures both modes; broad enough.
+- =polish= — descriptive of multi-pass nature; less prescriptive about whose voice.
+- =house-style= — signals "this is the house style"; appropriate for personal repo.
+- =commit-voice= — too narrow (passes apply to research notes, emails, etc. in general mode).
+- =humanize= (extending current) — undersells the universal + personal additions.
+
+** Open questions before implementation
+
+Resolved during implementation:
+- Default mode when =/voice= is invoked bare: =general=. Personal-context callers (=commits.md= publish flow, =respond-to-cj-comments.md=) invoke =/voice personal= explicitly. Avoids accidentally first-person-ifying research notes.
+- Reporting: skill prints "Summary of changes" listing which patterns fired (audit value).
+- Public-artifact scope check (#39): flag-only, user resolves manually. Blocking would frustrate on legitimate path mentions.
+- Tier 1 active-voice detection: suggestion-only in v1. Auto-rewrite for unambiguous cases deferred to v2.