| Commit message (Collapse) | Author | Age | Files | Lines |
| |
|
|
|
|
|
|
| |
invariants
From the 2026-06-11 usage report. The debug skill gains a hypothesis-discipline contract (rank candidate causes by cheapest empirical test, run probes in parallel, report only confirmed findings) targeting the serial theory-cycling the report flagged. commits.md's pre-commit checklist gains a staged-files guard covering the untracked-set and canonical-vs-mirror conventions. A small tracked CLAUDE.md carries the rulesets mirror invariant at turn zero. Two [#C] pilots filed: a read-only morning ops orchestrator and a monthly session-harvest workflow.
The report's 500-token-cap finding was a mislabel: the underlying transcripts show 529 Overloaded and stream-idle-timeout errors with no token cap configured anywhere, so nothing to change there.
|
| |
|
|
|
|
|
|
|
|
|
|
| |
artifact budgets
Two patterns kept failing in practice despite being documented (#40 praise asymmetry and the #38 terse cut), so I made the walk verifiable and closed the content gap behind tangled review text.
The high-recurrence set (#13, #37, #38, #40, #42) now gets per-pattern attestation receipts. The anti-AI audit runs after the terse pass so the audited text is the text that ships. Short personal-mode artifacts get a compact output format, and a write-back step puts the voiced text in the file the publish flow posts from.
Four patterns are new: #42 finding stems (one claim per sentence in review findings), #43 single-sentence paragraph cadence, #44 parenthetical asides, #45 declarative register marker. #37 exempts verdict formulas. #40 covers verification narration. #13 and #33 carry the self-discipline framing. A per-artifact budgets table makes terse a checkable budget instead of an adjective.
The profile gains paired entries with the approved worked examples, and commits.md plus no-approvals.org drop hardcoded pattern counts so the next addition doesn't re-drift them.
|
| |
|
|
|
|
|
|
| |
Pattern #38 (omit needless words) was one of 41 walked mid-list, so it got glossed as a checkbox instead of the real "cut it in half" sweep. A commit message went out today needing two manual Orwell-walk requests before it read terse, even though /voice personal had run.
The rule already said to cut hard. The gap was position. Buried in the middle of the walk, #38 lost to the categorical detectors that come back clean while the text still runs a third too long.
I moved it to an explicit standalone last step in the SKILL.md Process, run after every other pattern and right before the draft is shown. Now the first draft the user sees is already terse, not terse only after they ask. Profile §38 gains an execution-position rule and a history entry. The commits.md publish gate points at #38 as the last pass.
|
| |
|
|
|
|
|
|
|
|
|
|
| |
fragments, formatting
The personal voice patterns only ran for commits and PRs, so the emails and documents I author never got my actual writing voice. General mode deliberately skips them. I added a third mode, prose, that applies my voice patterns to prose I write or send without dragging in the publish-artifact mechanics that misfire on free text.
The modes now nest. General (#1-31) handles anyone's prose, prose adds my voice patterns (em-dash zero-tolerance, contractions, semicolons to periods, sentence-split, felt-experience cut, fragment rewrite, terse-cut, no-emphasis-formatting), and personal adds the three artifact-mechanics patterns on top (first-person rewrite, public-artifact scope flag, praise/correction asymmetry). Those three stay personal-only because they assume a commit or PR: a document is legitimately third-person, a journal has no public-scope concern, and praise/correction asymmetry is a PR-review rule.
Three gaps closed along the way. #13 (em-dash) was "use fewer". It's now zero-tolerance in prose and personal modes, and the rule holds inside examples and quoted text, not just running prose. #37 (every prose sentence needs a subject and a verb) was locked to personal mode. It now applies to my prose too. And #41 is new: I make points with words, not bold or italics or underscores, so emphasis markup gets rephrased so the stress lives in the wording.
I updated commits.md to match. The publish flow still uses personal mode, but the pattern count is now 41 and the personal-only set is the three artifact-mechanics patterns.
|
| |
|
|
| |
The publish flow made the /voice pass mandatory but had no fallback for when the skill isn't installed, which a fresh or partial environment can hit. Added one to the Single-skill gate: when /voice can't run, walk the patterns inline (the flow already names which matter), state the skill was unavailable and the pass was applied by hand, and flag the missing skill for install. The gate is the pattern walk, not the tooling — the skill is just the convenient way to run it. The original audit framed this as a "humanizer unavailable" gap. Humanizer is /voice now, so only the /voice-unavailable case remained.
|
| |
|
|
|
|
|
|
|
|
|
|
| |
The global commits.md carried DeepSat-specific publishing steps — Linear ticket-state moves, the Slack notification protocol with its channel ID and engineer names, the deepsat.ghe.com host, the team merge norm. Those are symlinked into every project on the machine, so they sat as dead weight in personal repos and risked misfiring where there's no Linear ticket to move or Slack mpdm to ping.
I split them out. commits.md keeps the universal skeleton (identity, attribution, commit format, the review-and-publish gate, verification) and replaces the team steps with seams: "run the project's publishing overlay here if it defines one," the same pattern startup.org uses for startup-extras. A project with no overlay runs the complete flow, just without ticket and chat integration.
The DeepSat specifics move to teams/deepsat/claude/rules/publishing.md. That file is not a global rule — install-team.sh copies it into one project's .claude/rules/ (make install-team TEAM=deepsat PROJECT=...), keyed on the PROJECT argument, so only the named project gets it. Location decides distribution: claude-rules/ is the global-symlink set, teams/ is targeted-copy, so the overlay reaches DeepSat and nowhere else.
The startup freshness check (sync-language-bundle.sh) now covers team overlays alongside language bundles: a process_bundle function handles both, with a team syncing only its own rule (no generic rules, hooks, or settings — those belong to a language bundle). A drifted overlay rule auto-fixes from canonical at the project's next startup, the same mechanism language bundles already ride.
Tested: 3 new bats cases (team overlay clean / drifted-and-fixed / does-not-pull-generic-rules) on top of the 11 existing; install-team + sync verified end-to-end against a temp project. make test green, shellcheck clean.
|
| |
|
|
|
|
| |
The .ai/-tracking check used to decide two things at once: which voice patterns ran and whether the approval gate fired. In a team repo that meant losing the 8 personal patterns and the gate together. I split them. Publish artifacts (commit messages, PR titles and bodies, PR review comments) always run /voice personal now, because they go out under my name regardless of the repo. The .ai/ check decides only the gate: applied in my personal repos, skipped for velocity in shared ones.
The gap this closes: a team-repo PR comment used to skip pattern #39, the public-artifact scope flag, which is exactly the check that matters most when teammates can read it.
|
| |
|
|
|
|
| |
review-code was a command with disable-model-invocation set, so the model could never reach for it on its own. Every time a review fit the moment, the agent had to hand back to me to type the slash command. Moving it to a skill makes it model-invocable while it stays slash-invocable as /review-code.
git mv keeps the file history (99% rename). The frontmatter drops disable-model-invocation and gains name: review-code; the body is unchanged. It also drops the discovery-check paragraph in commits.md, which only existed to find the command on disk when it was missing from the skills list, moot now that the skill shows up there.
|
| |
|
|
|
|
|
|
| |
Step 1 told the agent to run /review-code but didn't say what to do when the skill exists on disk yet isn't in the session's available-skills list. The list covers plugin-installed skills only. User commands under ~/.claude/commands/ are routable as slash-commands but don't appear in it, so the agent could declare /review-code unavailable and fall through to the trivial-one-liner exception in Step 2.
The new Discovery check tells the agent to verify both ~/.claude/commands/review-code.md and ./.claude/commands/review-code.md on disk before declaring the skill unavailable, and surface the mismatch rather than auto-skipping.
Also drops three absorbed or stale inbox files: the skill-discovery handoff (signal absorbed by this edit), the missing-inbox-dir handoff (already resolved by 470085f), and a stale date-coverage scan output (deferred until the task-review habit lands).
|
| |
|
|
| |
The MCP's `conversations_add_message` tool takes the raw mrkdwn body in `payload`, not a Slack API JSON envelope. Wrapping the body in `{"text": "..."}` posts the literal JSON to the channel — `<@>` mention strips, escaped `\n` renders as a literal `n`, and the `text:` key prefix shows up in the post. Step 8 now documents the format + mrkdwn list so PR-review notifications don't garble.
|
| |
|
|
| |
Step 8 of the publish flow referenced C0AM2MWHCJU as the channel for the Slack PR-author ping. That ID is actually a 3-person mpdm (Craig/Vrezh/Kostya), not the intended 4-person PR-review group. Corrected to C0B1B0NH2N5 (Craig/Eric/Vrezh/Kostya) and added a clarifying note that the 3-person mpdm is not an "#ai" channel despite older references calling it that.
|
| |
|
|
|
|
|
|
| |
The publish flow had no fetch step before commit, PR creation, or push. Long sessions or multi-machine work could land local commits on a stale base, producing non-fast-forward push failures that you have to unwind under publish-step pressure.
Step 0 fetches all remotes and checks the current branch against its upstream before Step 1's code review. If the branch is behind, the rule branches on tree state and divergence shape: clean fast-forward, surface dirty-tree behind, or surface a true divergence and ask before rebasing or merging. The Step 0 wording covers the new-branch case (no upstream → skip the divergence check, the first push sets it).
The Pre-push reconcile bullet in Merge Strategy handles the smaller window between Step 0 and the actual push. Reviewing and drafting can take several minutes; another machine or teammate can push during that window. One more fetch immediately before push is cheaper than recovering after a failed push.
|
| |
|
|
|
|
|
|
| |
The detection command for personal vs. general voice mode used `git ls-files .ai/`, which returns no matches when run from a subdirectory of the repo, even when `.ai/` is tracked at the root. That silently misclassified projects as personal-voice when they should have been general-voice.
Switching to `git ls-files :/.ai/` anchors the search to the repo root via the `:/` pathspec, so the command works correctly from any cwd.
I hit this myself today: ran the check from `claude-rules/` inside the rulesets repo, got an empty result, and applied `/voice personal` to a commit that should have used `/voice` (general mode).
|
| |
|
|
|
|
|
|
| |
I rewrote the PR review subflow into three explicit shapes. Shape 1 is a single review that bundles the verdict, the summary body, and zero or more inline pins into one `gh api .../reviews` call. Shape 2 is an issue-thread comment with no verdict. Shape 3 is a reply on an existing inline thread. The single-review path replaces the prior pattern where a Request-Changes verdict with line-specific findings needed separate `gh pr review` + `gh pr comment` calls. That fragmented the Slack notification and the review history.
I migrated all `humanizer` references to `/voice personal`. The voice skill replaced humanizer, so the old name was dead. I dropped the two lineage mentions of "humanizer's signs of AI writing" since they pointed at a skill that no longer exists.
I added a Voice mode and approval gate preamble at the top of Step 2. The mode is decided by whether `.ai/` is tracked in the repo. Gitignored or absent means personal-voice with the full approval gate. Tracked means general-voice and the gate is skipped, since the personal-only patterns (first-person rewrite, contractions, semicolon swap) don't fit a shared rules file. I also updated the Single-skill gate wrap-up paragraph at the end of Step 2 to reference both modes.
|
| |
|
|
|
|
|
|
|
|
| |
I switched the three publish subflows in commits.md (commit messages, PR descriptions, PR review comments) from "run humanizer; apply five personal-style passes in order" to a single "run /voice personal" invocation. The new skill walks 39 patterns in one editorial review and absorbs the five passes wholesale, plus four more personal-style additions (felt-experience cut, fragment-in-prose rewrite, terse cut, public-artifact scope flag) and six universal good-writing patterns. The numbered steps in each subflow collapse from 5 to 4 (commits) and 9 to 8 (PRs) since the dedicated personal-style step folds into the voice invocation.
The Multi-pass gate paragraph becomes a Single-skill gate. The mid-flow "all the passes" prompt now means re-run the full 39-pattern walk in personal mode rather than reapplying six discrete steps.
I also updated respond-to-cj-comments.md to invoke /voice personal for public writing and /voice general for the lighter pass on internal notes when wanted, and updated start-work.md's Phase 7 summary to match.
The humanizer skill itself stays in place for now. The next commit removes it.
|
| | |
|
| | |
|
| | |
|
| |
|
|
|
|
| |
I told Claude that the commit-message draft should sound personal, like it's coming from me. That move wasn't in the documented passes, so the drafts kept landing on impersonal third-person ("Add a test for X", "The change introduces Y"). I had to ask for the rewrite each time.
First person is now the new pass (a) in all three subflows: commit messages, PR descriptions, PR review comments. The subject line and PR title stay imperative per Conventional Commits, and I left an exception for purely mechanical bodies where the subject already carries the message. I bumped the Multi-pass gate counts and the example announcement string to match.
|
| |
|
|
|
|
|
|
| |
Step 8 of the PR review/publish flow now sends a one-line message to channel C0AM2MWHCJU after every approve or changes-requested verdict. The new step skips humanizer and personal-style passes since the message is short and templated.
The approve case sends "Approved on PR #N." with the PR URL on the next line. The changes-requested case sends "Changes Requested on PR #N" with the PR URL on the next line.
I also added an explicit line saying approve doesn't authorize a merge. That keeps the merge decision with the PR author. The team's practice is approve-then-author-merges, not approve-and-merge.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
I reworked commits.md with two structural shifts and five smaller rule changes.
Structural:
- Drafts print inline in the terminal. `emacsclient` only opens when asked. Was: editor by default, humanize after.
- Adopted the full Conventional Commits spec. New sections: Structure, Types, Scope, Breaking changes (`!` and `BREAKING CHANGE:` footer), Subject line, Body, Footers, How to write, Examples.
Smaller:
- Personal-tooling files (`claude-rules/*.md`, any `CLAUDE.md`, `.claude/`, `.ai/`, `SKILL.md`) aren't cited as authority in shared messages. State the reason, not the rule. Carve-out for when one of these files IS the change.
- Voice and Focus opens with a colleague-tone framing. Four anti-patterns called out below it: no felt-experience narration, no verb-as-noun ("the ask", "a learn"), no sentence fragments in prose, and no first-person "I" for software behavior — all caught real drafting tics today. "Brief. Terse is fine." also tightened to "Brief. Terse is preferred."
- Future-debugger framing added to message-writing guidance. Imperative summaries beat diary notes, and the body becomes a lightweight decision log of the constraint or tradeoff.
- PR titles end with the ticket ID in parens, e.g. `refactor: drop dead check (SE-289)`.
- Multi-pass gate tightened to match the new mandatory ordering.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
safety
commits.md gets two additions. A new "## Merge Strategy" section makes
squash-merge the default for feature branches and requires explicit
confirmation of the merge approach before pushing or merging. A new
"Multi-pass gate" paragraph in Review and Publish requires every
humanizer-flow pass to run and be named when declaring done, so
silent skips become defects.
testing.md gets a new bullet under "### Determinism": time/clock-mocking
helpers must not recurse against the primitive they're mocking, and must
not let-bind over a defvar — the binding shadows only inside the test
scope, so production code reading the symbol still gets the original
value (silent test miss).
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
skills
Linear ticket bodies are now Problem + Fix only. PR descriptions keep
the four-section format (Problem, Fix, Why this fixes it, How it was
tested). Linear's GitHub integration handles the cross-link via the
PR body's Linear: line.
Cross-ref to the content-scope rule appended at the end of each Tier 1
skill that produces public artifacts: testing.md, arch-document,
arch-decide, arch-design, review-code, respond-to-review, brainstorm,
codify. Single-source the rule in commits.md, point at it from each
output-producing skill.
|
| |
|
|
|
|
|
|
| |
PR descriptions, Linear ticket bodies, and PR review comments are
visible to the team. New section codifies what not to mention (local
paths, private repos, personal tooling) and a concise four-section
structure for shipped-fix descriptions: Problem, Fix, Why this fixes
it, How it was tested.
|
| |
|
|
|
|
|
|
|
| |
Adds step 7 to the Review-and-Publish PR-description flow: pass
--reviewer at create time or use gh pr edit --add-reviewer right
after. Notes that CODEOWNERS auto-suggestions aren't requests, that
picking reviewers should follow the team's per-repo convention, and
that follow-up PRs benefit from tagging the parent PR's author.
Renumbers the Linear-comment and Dev-Review status steps accordingly.
|
| |
|
|
|
|
|
|
| |
Three new paragraphs under "Voice and Focus": first person where it fits, brief/terse, kind. The section now applies to PR comments (review replies, follow-up notes, thread responses) as well as commit bodies and PR descriptions.
New "For PR review comments and replies" subsection under Step 2 mirrors the commit-message and PR-description flows: draft to /tmp/pr-<N>-comment.md, humanizer skill, plain-English pass, user approval, then post with the right gh command for the comment type.
The trivial-one-liner exception at the bottom of Step 2 now covers acknowledgment-style replies ("thanks for the review") alongside trivial commits.
|
| |
|
|
|
|
| |
Added a new Voice and Focus section between Commit Message Format and Review and Publish. It covers three rules that kept coming up in practice. Write in the user's voice — first person fits, and "This PR introduces X" reads as press-release self-narration. Focus on what was wrong and what was corrected, not the mechanics. Don't stack three or more type signatures or API names in a single sentence.
Also extended the post-humanizer checklist in both the commit-message and PR-description flows. Items (c) "prefer contractions" and (d) "break up long sentences" now sit alongside the existing (a) "rewrite dev-jargon" and (b) "replace semicolons". Uncontracted English reads stiff in short prose, and stacked-clause sentences read easier split on a conjunction.
|
| |
|
|
|
|
|
|
|
|
| |
Three additions to claude-rules/commits.md.
A new conventions section adds two rules. First, do not hard-wrap commit body lines. Let the renderer soft-wrap instead. Hard wraps shrink the visible width in web UIs and cause awkward mid-sentence breaks. Second, do not reference how the change was produced (code review, linting, test runs) in the message. The body is for the what and the why. The how belongs in the PR discussion.
A new Review and Publish section defines a two-step gate for every commit and PR. Step 1 runs /review-code against the change and blocks on Critical or Important findings unless the user overrides. Step 2 drafts the message to /tmp, opens it in the user's editor, runs the humanizer skill, and waits for explicit approval before committing or pushing. PRs also require a Linear cross-link line, a Linear comment with the PR URL after creation, and a status transition to Dev Review.
A short hook-level authorization note clarifies that the review-plus-approval flow is the authorization gate. Tools like git-commit-confirm should not add a second independent prompt once Step 2 has been approved.
|
|
|
New generic rule at claude-rules/commits.md covers author identity,
absence of Claude/Anthropic/LLM/AI attribution (messages, PRs,
comments, trailers, emojis), and conventional commit format. Applies
to all repos.
Bundle settings.json now sets attribution.commit: "" and
attribution.pr: "" so Claude Code's default attribution is suppressed
belt-and-suspenders with the written rule.
Elisp CLAUDE.md template trimmed to reference commits.md instead of
inlining the rules.
|