<feed xmlns='http://www.w3.org/2005/Atom'>
<title>rulesets/working, branch main</title>
<subtitle>Claude Code skills, rules, and language bundles
</subtitle>
<id>https://git.cjennings.net/rulesets/atom?h=main</id>
<link rel='self' href='https://git.cjennings.net/rulesets/atom?h=main'/>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/rulesets/'/>
<updated>2026-08-01T03:42:08+00:00</updated>
<entry>
<title>chore: track the parked sync-model handoff</title>
<updated>2026-08-01T03:42:08+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-08-01T03:42:08+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/rulesets/commit/?id=1c222cb563d729870ef9bd3b24805df9a76dd4b6'/>
<id>urn:sha1:1c222cb563d729870ef9bd3b24805df9a76dd4b6</id>
<content type='text'>
Design input for the last-synced manifest, which is the other half of the propagation fix and still unbuilt. Its point: the locally-edited-and-diverging state isn't rare, because the propagation rule tells projects to patch locally as a stopgap. So an overwrite-and-report has to carry the diff, not just a backup path. A reader needs to tell in one look whether the canonical already contains their patch or whether their change was thrown away and needs re-sending.

working/ is tracked from creation, and this sat untracked while the narrowing shipped around it.
</content>
</entry>
<entry>
<title>chore: archive work records and park incoming handoffs</title>
<updated>2026-07-31T11:33:44+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-07-31T11:33:44+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/rulesets/commit/?id=cbcd972fbea65c315713113572f9334efe8d1ca3'/>
<id>urn:sha1:cbcd972fbea65c315713113572f9334efe8d1ca3</id>
<content type='text'>
Records for the helper-launcher and sync-extraction work, plus four sets of
handoffs received from other projects. Each set is parked beside the decision it
still needs: sentry's CronCreate correction and its pass-3 reframe, the
per-project channel declaration model, the template-sync revert finding, and the
nag-event vocabulary.

Nothing here is code. The handoffs are kept rather than deleted because two of
them turn on the difference between two readings of the same rule, and that
difference is the useful part.
</content>
</entry>
<entry>
<title>chore: remove the completed telegram working dirs</title>
<updated>2026-07-28T23:50:27+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-07-28T23:50:27+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/rulesets/commit/?id=614e3b1dc664c913788a591c74f25701bad1a62e'/>
<id>urn:sha1:614e3b1dc664c913788a591c74f25701bad1a62e</id>
<content type='text'>
Both dirs are finished-task artifacts now that the merge and the liveness check have landed. Every file is already in git history via b19d420 and bff0138. Deleting the working copies loses nothing, and a copy under assets/ would only duplicate what git holds. Nothing links to either dir.
</content>
</entry>
<entry>
<title>fix(triage): pass the TL object to loadChats, not a bare symbol</title>
<updated>2026-07-28T19:07:05+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-07-28T19:07:05+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/rulesets/commit/?id=bff01385a17fd8435f202d70362db13a139774d6'/>
<id>urn:sha1:bff01385a17fd8435f202d70362db13a139774d6</id>
<content type='text'>
Step 1 called (telega--loadChats 'main). That's a raw TL wrapper, so it drops its argument into the request as :chat_list untouched. The symbol went out on the wire as main, and the C parser aborts on any value it can't start. Every telegram sweep has been killing telega-server. Both call sites now pass '(:@type "chatListMain"), which is what telega's own callers use.

I merged this with the down-is-launch fix parked since 2026-07-24 rather than applying either alone. The parked file still carried the bad call, and its new prose cited the segfault gotcha as the reason docker mode is mandatory. That's the same gotcha this rewrites to say the deaths were our own bad argument. Shipping them in sequence would have left the file arguing against itself, so I reconciled the prose in both places and kept the docker requirement on its own evidence.

The gotcha keeps two caveats. A crash with no triage verb running needs its own investigation. And a short chat list is a real short list, because 19 was the true account size measured at both ends, not a scan truncated by this bug.
</content>
</entry>
<entry>
<title>docs: correct the rightsizing docs against live measurements</title>
<updated>2026-07-27T18:46:32+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-07-27T18:46:32+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/rulesets/commit/?id=d74d98d03e7321b6c69dae9ef427da66b0f6fbc6'/>
<id>urn:sha1:d74d98d03e7321b6c69dae9ef427da66b0f6fbc6</id>
<content type='text'>
I had the goal backwards in the lead. Craig's framing is output quality first, with token reduction real but second, and where they conflict quality wins. Anthropic's 80% was a finding rather than a target, and aiming at it directly optimizes the thing we don't care about. P4 falls to that and is dropped: lowering effort buys tokens by spending quality. P5 rises for the same reason, since positive framing over prohibition is what actually targets guardrails working against output.

My token figures were low by about 45%. I converted word counts at a guessed ratio when /context reports real per-file numbers, so I used an estimate because it was easier to compute from inside the repo. The live ratio is 2.28 tokens per word. commits.md is 12,800 tokens rather than the 7,000 I estimated, and claude-rules was near 57,800 per session before today.

I also conflated two loading paths. Memory files come in through the harness at session start. protocols.org and the workflows are read by startup and land in Messages, so they never appear under Memory files at all. They shrink by editing the workflow, not by scoping a rule, and treating them as one surface made protocols.org look like it competed with commits.md for the same fix.

Path-scoping is confirmed working at user level, and the de-duplication holds. That splits the remaining work: anything scopable to a file type or directory ships with no trial, because a glob match is deterministic. Only the semantic rules need the skills route and the stop conditions, and commits.md is the one that matters there at 12,800 tokens of publish machinery that only applies when a commit is in play.

I recorded one caution the confirmation doesn't cover. Path-scoping fires when a matching file is read, so creating a new org file from scratch never triggers todo-format.md. Edits are safe because Edit requires a prior read.

I also wrote up the day's two guard failures, both mine. wrap-org-table reflowed a table into a worse shape and lint-org certified it clean, and the teardown hook consumed a stale sentinel and killed a live work session. The plan leans on mechanical detectors because they have no stake, which is still right, but a detector can be confidently wrong and a green check from a guard that never looked is indistinguishable from one that did.
</content>
</entry>
<entry>
<title>docs: add context-engineering rightsizing analysis and rollout</title>
<updated>2026-07-27T18:15:14+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-07-27T18:15:14+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/rulesets/commit/?id=79ed3b09a9ee2a63fb55d2354aa0c77ea24c6efa'/>
<id>urn:sha1:79ed3b09a9ee2a63fb55d2354aa0c77ea24c6efa</id>
<content type='text'>
I wrote three working documents while reviewing the Claude 5 context-engineering post, the Opus 5 prompting guide, and the Fable field guide against what this repo ships downstream.

In proposals.org I measured the always-loaded surface at 32,123 words and ranked six changes, plus two places where a post contradicts something we arrived at deliberately. I also reread the rules as your prompts rather than as agent context, which is where the sharper finding is: 41 execution and hygiene workflows against 6 discovery and design ones, on a system whose bottleneck has moved.

In rollout.org I phased the work and named the seven decisions that gate it. My lead finding is that the harness system prompt already carries most of what the Opus 5 guide recommends adding, so the posts' value here is subtractive. Applying them additively would make the duplication worse.

In metrics.org I split the posts into separable claims and marked which are testable here and which are judgment calls, rather than inventing a metric for the ones an eval harness would be needed to settle. I also stated the pilot's stop conditions in advance, including a zero-tolerance threshold on the load-bearing rules, so I can't renegotiate that threshold later under pressure to make a phase succeed.
</content>
</entry>
<entry>
<title>chore(inbox): park lint-org and telegram fixes from home and .emacs.d</title>
<updated>2026-07-24T22:42:54+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-07-24T22:42:54+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/rulesets/commit/?id=b19d420b11af77e991b4bf14ef5a312c70cbfa3e'/>
<id>urn:sha1:b19d420b11af77e991b4bf14ef5a312c70cbfa3e</id>
<content type='text'>
</content>
</entry>
<entry>
<title>fix(hooks): the secret scan no longer passes when git fails</title>
<updated>2026-07-24T17:28:18+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-07-24T17:28:18+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/rulesets/commit/?id=f0c1bc40708615d5b423922c08c1f27e6cf96259'/>
<id>urn:sha1:f0c1bc40708615d5b423922c08c1f27e6cf96259</id>
<content type='text'>
Every bundle built its scan input as `git diff --cached ... | grep ... || true`. The `|| true` has to stay, since grep exits 1 when it matches nothing and that is the ordinary case. But with no pipefail it also swallowed a failure of git itself, so an empty result made the scan search nothing, find nothing, and report clean with a real credential staged. A gate that passes without having looked.

.emacs.d found it in elisp. It was in all five: bash, elisp, go, python and typescript, eleven sites once each bundle's staged-file list is counted. Two of those bundles are ones I wrote yesterday by copying bash, so I propagated it while closing an unrelated gap in the same file. Each site now reads the diff on its own and aborts if git fails, leaving the greps their `|| true`.

Verified per bundle on three axes: refuses when the diff cannot be read, still blocks a real staged secret, still passes a clean commit.

The cross-bundle test suite had its own version of the same disease. Its VARIANTS list read "elisp bash go" while python and typescript also shipped hooks, so every "in every variant" assertion had quietly skipped two bundles since the day they were added. VARIANTS is now discovered from the tree. Two fail-closed assertions join it, and .emacs.d's elisp suite is adopted here beside the canonical hook, because a test living in the consuming project cannot fail when the canonical regresses.

Also removes the validate-el auto-test cap, Craig's call. Above 20 matching test files the runner skipped everything and exited 0 with no output. The premise was speed and it did not hold: a whole family runs in about a second. The cap was also hiding a real cross-test pollution bug that only surfaces when a family runs in one process.
</content>
</entry>
<entry>
<title>chore(inbox): park two hook fail-open fixes from .emacs.d</title>
<updated>2026-07-24T16:00:39+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-07-24T16:00:39+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/rulesets/commit/?id=781fa0786e2096797e630dcb81ffbc62ed98460b'/>
<id>urn:sha1:781fa0786e2096797e630dcb81ffbc62ed98460b</id>
<content type='text'>
</content>
</entry>
<entry>
<title>chore(inbox): park the question-capture workflow idea</title>
<updated>2026-07-24T05:43:07+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-07-24T05:43:07+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/rulesets/commit/?id=d3315714d0553f41739ed3ea602b5d42c8113a47'/>
<id>urn:sha1:d3315714d0553f41739ed3ea602b5d42c8113a47</id>
<content type='text'>
Craig's idea, via archsetup: drop a question into the roam inbox, have the agent retrieve it during a pass but hold rather than auto-answer, then answer it live at the next conversation and close on his acknowledgement. The inverse of a VERIFY — the agent owes the answer, not the other way round.

Parked as a spec candidate rather than a direct build: the value is clear, but marking a question item, tracking the answer-owed state, and the new-keyword-vs-VERIFY-variant call are decisions to make with Craig. The proposal is staged under working/.
</content>
</entry>
</feed>
