<feed xmlns='http://www.w3.org/2005/Atom'>
<title>rulesets/claude-templates/.ai/scripts/tests/test-lint-org.el, 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-07-02T01:35:16+00:00</updated>
<entry>
<title>feat(todo-cleanup): add --convert-subtasks dated-rewrite mode</title>
<updated>2026-07-02T01:35:16+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-07-02T01:35:16+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/rulesets/commit/?id=19ba7cb40c5a448bb28f0217d8cc4718dd450f91'/>
<id>urn:sha1:19ba7cb40c5a448bb28f0217d8cc4718dd450f91</id>
<content type='text'>
Rewrites every level-3+ DONE/CANCELLED/FAILED heading into a dated event-log entry from its CLOSED cookie, enforcing the todo-format depth rule that interactive closes and --archive-done (level-2 only) leave unapplied. A new lint-org checker (subtask-done-not-dated) flags stragglers, and the clean-todo, wrap-up, open-tasks, and task-review workflows now run the converter before archiving.

Removing the CLOSED cookie keeps a DEADLINE or SCHEDULED cookie that shares its planning line, rather than dropping the whole line.

From the .emacs.d handoff (2026-07-01 convert-subtasks bundle).
</content>
</entry>
<entry>
<title>feat(lint-org): add four structural heading checkers org-lint misses</title>
<updated>2026-06-30T17:50:22+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-06-30T17:50:22+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/rulesets/commit/?id=d9d8ce79da82b8c0fbbc8d6090548cd1f508b4c0'/>
<id>urn:sha1:d9d8ce79da82b8c0fbbc8d6090548cd1f508b4c0</id>
<content type='text'>
org-lint validates links, drawers, blocks, and babel, but not heading well-formedness. These four catch hand-edit defects it stays silent on: an indented heading demoted to body text (the task vanishes from the agenda and never archives), bare stars with no title, a malformed priority cookie org rejected, and a level-2 DONE/CANCELLED with no CLOSED line. All judgment-only and regex-based, wired in after the existing dated-header check. The last one pairs with the new aging step, which archives an undated completed task immediately.

I tightened the indented-heading check to two-or-more stars. The proposed one-or-more-stars regex flagged indented single-star lines, but an indented single * is a valid plain-list bullet, not a lost heading, so it false-positived on legitimate lists (confirmed: three valid bullets flagged). A ** is never a bullet, so an indented one is unambiguously a demoted heading. Added a test that a single-star list stays silent.
</content>
</entry>
<entry>
<title>feat(lint-org): flag level-2 dated headers as a completion defect</title>
<updated>2026-06-21T03:28:47+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-06-21T03:28:47+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/rulesets/commit/?id=f6dde4e0fe21022966196e19d535f2bb7abcfcdb'/>
<id>urn:sha1:f6dde4e0fe21022966196e19d535f2bb7abcfcdb</id>
<content type='text'>
A `** &lt;YYYY-MM-DD&gt; …` heading carries no keyword, so todo-cleanup's --archive-done can never archive it and task-review drops it from selection. The new level-2-dated-header check (custom, like org-table-standard) emits a judgment item per offending heading so the wrap-up sweep routes it to the next morning's review. Judgment-only, never auto-fixed: the repair needs a DONE-vs-CANCELLED call and the original heading text. Three ERT cases cover it (flagged at level 2, clean for DONE+CLOSED, clean for a level-3 dated entry).
</content>
</entry>
<entry>
<title>fix(scripts): lint-org pre-registers runtime org link types</title>
<updated>2026-06-12T07:28:43+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-06-12T07:28:43+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/rulesets/commit/?id=1dba35cc182691390d80c789502b174292b14777'/>
<id>urn:sha1:1dba35cc182691390d80c789502b174292b14777</id>
<content type='text'>
mu4e registers its link type in a live Emacs, so batch org-lint parsed [[mu4e:msgid:...]] links as fuzzy heading refs and flagged "Unknown fuzzy location" on links that work interactively. lint-org now registers each type in lo-runtime-link-types as a no-op before linting. org-link-set-parameters merges rather than replaces, so a genuinely loaded mu4e keeps its real parameters.
</content>
</entry>
<entry>
<title>feat(org): table standard as a rule, reflow helper, and lint check</title>
<updated>2026-06-11T19:25:55+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-06-11T19:25:55+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/rulesets/commit/?id=8d790f371e54a8cc3e79a5ce72cd4dd5b3fa4513'/>
<id>urn:sha1:8d790f371e54a8cc3e79a5ce72cd4dd5b3fa4513</id>
<content type='text'>
Wide org tables overflow the page in exported PDF/docx, and hand-wrapping a cell into continuation rows is tedious and error-prone. The standard existed only as a work-project convention with nothing enforcing it.

claude-rules/org-tables.md carries the generalized standard: 120-column budget measured at render width (a link counts as its visible label and is never split), over-budget cells wrap onto continuation rows, and a rule sits under the header and every logical row.

wrap-org-table.el reflows a table to that shape mechanically. Columns shrink from natural width toward a floor of their widest atomic token, cells wrap link-safe, and rule-delimited continuation groups merge back into their logical row before re-wrapping, which makes the reflow idempotent. A table whose floors still exceed the budget reflows best-effort and stays flagged for restructuring.

lint-org.el gains an org-table-standard judgment check: width overruns and missing rules surface during the sweep with a pointer to the helper. Conformant wrapped tables don't false-flag, since the check reuses the helper's continuation-group reading. The check is judgment-only by design: reflowing is a visible layout change the sweep shouldn't make silently.
</content>
</entry>
<entry>
<title>feat(lint-org): reconcile follow-ups on write instead of appending</title>
<updated>2026-06-03T02:31:37+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-06-03T02:31:37+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/rulesets/commit/?id=ac693a6b7fa7abe88f7778f8e793d5ddfd32f24e'/>
<id>urn:sha1:ac693a6b7fa7abe88f7778f8e793d5ddfd32f24e</id>
<content type='text'>
Every run appended a fresh dated "lint-org follow-ups" section with line-number-keyed entries, so the follow-ups file grew an unbounded pile of near-duplicate sections, kept entries whose finding had since resolved, and broke whenever the target file's line numbers shifted. Running an audit against a large todo.org surfaced exactly that drift: dead-link flags pointing at docs that now exist, and three stacked dated runs for one file.

Now lint-org rewrites the current file's section from the current run. Findings that no longer reproduce simply are not re-emitted, re-runs dedupe to one section, and entries key on checker plus message with the line as a trailing annotation, so a finding survives line shifts as the same entry. Other files' sections are left intact, and the strip step tolerates the old dated-header shape so existing follow-ups files migrate on first run. This changes the follow-ups file from an append-only log to the current outstanding findings per file.

task-audit's Phase C link-hygiene step now also reaps a matching dead-link entry when it fixes or verifies the link, scoped strictly to dead-link entries, so the audit and the follow-ups file stop drifting between lint runs.

Five follow-ups tests cover record-by-content, dedupe across runs, drop-on-resolve, and preserve-other-files. Mirrors synced.
</content>
</entry>
<entry>
<title>fix(lint-org): suppress verbatim-asterisk misplaced-heading false positives</title>
<updated>2026-05-30T22:20:24+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-05-30T22:20:24+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/rulesets/commit/?id=1f79945dd4ab386a9ea4ac58fb2161c174a26bba'/>
<id>urn:sha1:1f79945dd4ab386a9ea4ac58fb2161c174a26bba</id>
<content type='text'>
org-lint reads an =** Foo= verbatim span in body prose as a possible misplaced heading, but verbatim markup is never a real heading. lint-org kept surfacing these as judgment items, so they recurred in lint-followups.org on every wrap and could never be acted on, since the todo.org content was already correct.

I added lo--verbatim-asterisk-at-line-p, which mirrors the markdown-bold detector: it checks the reported line and the one before it, since org-lint marks the blank line after the offender. A match is now suppressed silently, the same way the cj-comment false positives already are. I flipped the two tests that pinned the old judgment behavior, and confirmed todo.org lints clean (judgment=0). This resolves the checker-bug report I filed in the inbox earlier, which I removed.
</content>
</entry>
<entry>
<title>feat(lint-org): recognize cj-comment blocks and suppress false-positive warnings</title>
<updated>2026-05-16T12:33:46+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-05-16T12:33:46+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/rulesets/commit/?id=3fb4c80eb00d6e89b594eb4e5ce570f20fe2e63b'/>
<id>urn:sha1:3fb4c80eb00d6e89b594eb4e5ce570f20fe2e63b</id>
<content type='text'>
org-lint emits three warnings for every `#+begin_src cj: comment ... #+end_src` annotation block: suspicious-language-in-src-block (the language `cj:` isn't a known Babel slug), wrong-header-argument (the trailing `comment` looks like a header arg without a colon), and empty-header-argument (that same `comment` has no value). All three are false positives. The cj-comment block is a Craig-specific annotation marker, not Babel src-block syntax.

I added a helper `lo--cj-comment-block-opener-p` that pattern-matches the opener line, then a short-circuit branch at the top of `lo--handle-item` that silently drops any of the three checkers when they fire on a cj-comment opener. No fix is counted, no judgment is emitted, and the warnings disappear.

Two new tests cover the change. The normal case is a solo cj-comment block, which should produce zero judgments and zero fixes with all three flagged checkers absent from the issue list. The boundary case is a cj-comment block alongside a real `#+begin_src markdown` block. The markdown warning still surfaces, which scopes the suppression to cj openers only — no leak into other src blocks.

Test count goes from 22 to 24, all green. I smoke-tested against rulesets/todo.org: judgment count drops from 7 to 1. Six cj-comment false positives at lines 16 and 1291 are gone, and the unrelated misplaced-heading at 2139 still surfaces correctly.
</content>
</entry>
<entry>
<title>Merge commit '69c5e4ace81586c05dea6a9a3afd54dafa61a73b' as 'claude-templates'</title>
<updated>2026-05-15T21:56:39+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-05-15T21:56:39+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/rulesets/commit/?id=c1d4e3c4a42abd01bc7ef83b1d6ae036ee32ef1d'/>
<id>urn:sha1:c1d4e3c4a42abd01bc7ef83b1d6ae036ee32ef1d</id>
<content type='text'>
</content>
</entry>
</feed>
