<feed xmlns='http://www.w3.org/2005/Atom'>
<title>dotemacs, branch load-graph-classify-start</title>
<subtitle>My Emacs configuration
</subtitle>
<id>https://git.cjennings.net/dotemacs/atom?h=load-graph-classify-start</id>
<link rel='self' href='https://git.cjennings.net/dotemacs/atom?h=load-graph-classify-start'/>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/dotemacs/'/>
<updated>2026-05-24T20:33:04+00:00</updated>
<entry>
<title>docs(todo): close coverage backlog after assessing the sub-60% cluster</title>
<updated>2026-05-24T20:33:04+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-05-24T20:33:04+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/dotemacs/commit/?id=6479f122c3544d29fefedd749f6adaf29aca04af'/>
<id>urn:sha1:6479f122c3544d29fefedd749f6adaf29aca04af</id>
<content type='text'>
Read each remaining sub-60% module to separate real untested logic from interactive/config glue. Filled the three genuine gaps (markdown-html, media-utils select-media-player, elfeed helpers — committed separately). The rest — flyspell, dashboard, ai-quick-ask — already have their pure logic tested with Normal/Boundary/Error; their low percentages come entirely from interactive commands. prog-general, restclient, vc-config, quick-video-capture are config/interactive-only with no pure logic to cover. Backlog cleared: every module's testable logic is covered; residual low % is code the testing rules say not to chase.
</content>
</entry>
<entry>
<title>test: cover markdown-html filter and media-player selector</title>
<updated>2026-05-24T20:31:07+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-05-24T20:31:07+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/dotemacs/commit/?id=c6a81743f95638bc8275bea1b590f4ca9f7cbc39'/>
<id>urn:sha1:c6a81743f95638bc8275bea1b590f4ca9f7cbc39</id>
<content type='text'>
Two real-logic gaps from the refreshed coverage backlog. cj/markdown-html (markdown-config) is the impatient-mode filter that wraps a source buffer's text in the strapdown HTML shell — tested for normal content and an empty buffer. cj/select-media-player (media-utils) was the one untested function there — tested that choosing an available player updates cj/default-media-player and that a non-matching selection leaves it unchanged. Both mock at the boundary (completing-read, the source buffer).
</content>
</entry>
<entry>
<title>docs(todo): refresh stale coverage backlog against a clean run</title>
<updated>2026-05-24T20:29:10+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-05-24T20:29:10+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/dotemacs/commit/?id=810665a72ddb7721585e045113a82a8c218072e7'/>
<id>urn:sha1:810665a72ddb7721585e045113a82a8c218072e7</id>
<content type='text'>
The per-module percentages in the coverage audit were stale — this session's test-writing covered most of the listed modules (prog-python 0%-&gt;100%, hugo-config 17.7%-&gt;91.7%, undead-buffers 5.7%-&gt;85.7%, and selection-framework / keyboard-compat / system-utils / system-defaults / ui-navigation / prog-go now ~100%). Re-measured against a clean make-coverage run and replaced the ~75 stale entries with current numbers for only the modules genuinely below ~60%. Modules in the 60-80% band are adequately covered and dropped. vc-config and quick-video-capture are flagged config/interactive-only (their pure logic is tested; the uncovered lines are use-package/interactive glue), so they're recorded as no-action rather than chased.
</content>
</entry>
<entry>
<title>test(elfeed): cover extract-stream-url and process-entries helpers</title>
<updated>2026-05-24T20:03:39+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-05-24T20:03:39+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/dotemacs/commit/?id=35fa629759978cb123e4a1ccd6747a2d4cc9a17b'/>
<id>urn:sha1:35fa629759978cb123e4a1ccd6747a2d4cc9a17b</id>
<content type='text'>
elfeed-config had only the youtube-feed-format helper under test; cj/extract-stream-url and cj/elfeed-process-entries were untested despite having clear error/boundary paths. Added characterization + Normal/Boundary/Error coverage: extract-stream-url returns the trimmed URL on success, nil on non-URL output or nonzero exit, and signals when yt-dlp is absent; process-entries applies the action per selected entry and marks read, errors when nothing is selected, skips entries with no link, catches per-entry action errors by default, and propagates them under skip-error-handling. yt-dlp (call-process) and the elfeed-search API are stubbed at the boundary.
</content>
</entry>
<entry>
<title>docs(todo): log the third solo-hardening batch (move-branch, keymaps, export, elfeed/eww, capture tests)</title>
<updated>2026-05-24T19:44:14+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-05-24T19:44:14+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/dotemacs/commit/?id=7619d8a47c5f26f73b9cd4ab1c5c41f7aa76ef03'/>
<id>urn:sha1:7619d8a47c5f26f73b9cd4ab1c5c41f7aa76ef03</id>
<content type='text'>
</content>
</entry>
<entry>
<title>test(org-capture): smoke-test template key uniqueness and file targets</title>
<updated>2026-05-24T19:42:58+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-05-24T19:42:58+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/dotemacs/commit/?id=2e3905c728bacb713ee7857091d1d69d2b0473f4'/>
<id>urn:sha1:2e3905c728bacb713ee7857091d1d69d2b0473f4</id>
<content type='text'>
Org capture templates are assembled across org-capture-config, quick-video-capture, org-contacts-config and other modules, so a duplicate dispatch key or a file target pointing at an unset path variable would be easy to miss. Added a smoke test that loads the cleanly-loadable capture modules, applies their lazy additions, and asserts no two templates share a key and that every symbol-valued file target resolves to a non-empty string path. Literal-string targets (the video template's no-save (file "")) and lambda targets (the drill file pickers) are intentionally excluded; webclipper templates need org-web-tools and are covered by their own test.
</content>
</entry>
<entry>
<title>fix(elfeed): bound and clean up the synchronous YouTube fetch</title>
<updated>2026-05-24T19:40:03+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-05-24T19:40:03+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/dotemacs/commit/?id=c097b5b4540d51fd279a81c0834b008331e936c9'/>
<id>urn:sha1:c097b5b4540d51fd279a81c0834b008331e936c9</id>
<content type='text'>
cj/youtube-to-elfeed-feed-format called url-retrieve-synchronously with no timeout, so a hung YouTube request would block Emacs indefinitely, and it only killed the temporary URL buffer when an ID was successfully extracted — a page without the expected markers leaked the buffer.

Passed cj/elfeed-url-fetch-timeout (10s) to the synchronous fetch, and moved the fetch+parse into an unwind-protect that always kills the temp buffer (live-p guarded), including the parse-failure path. Tests mock the network boundary and cover a normal channel parse, that a timeout is passed, and that the buffer is not leaked when parsing fails.

Also added tests for the EWW user-agent advice (no code change): it already injects the desktop UA only from eww-mode buffers, so package.el and other non-EWW url callers pass through untouched — the tests pin that scoping and the replace-not-duplicate header behavior.
</content>
</entry>
<entry>
<title>fix(org-export): remove contradictory org-export-with-tasks default</title>
<updated>2026-05-24T19:36:43+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-05-24T19:36:43+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/dotemacs/commit/?id=94ef5242e72a39faa9eb14a705387ccad339be14'/>
<id>urn:sha1:94ef5242e72a39faa9eb14a705387ccad339be14</id>
<content type='text'>
org-export-config.el set org-export-with-tasks twice in a row — first to ("TODO"), then to nil. The final value won (export no tasks), but the stale first assignment and its "export with tasks by default" comment contradicted it, so the intended policy was ambiguous on a read.

Removed the leftover ("TODO") line. nil is the deliberate default: it is the value that was already winning, its comment matches, and it sits with the adjacent "export without tags / section numbers by default" settings. Added a smoke test that fires the deferred ox :config and pins org-export-with-tasks to nil so a future flip is caught.
</content>
</entry>
<entry>
<title>refactor: declare cross-module commands bound in custom keymaps</title>
<updated>2026-05-24T19:34:57+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-05-24T19:34:57+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/dotemacs/commit/?id=ad173a77fbbe2e9ffb178b8765d0a3cc6b972aac'/>
<id>urn:sha1:ad173a77fbbe2e9ffb178b8765d0a3cc6b972aac</id>
<content type='text'>
custom-ordering.el binds cj/org-sort-by-todo-and-priority (owned by org-config) and custom-text-enclose.el binds change-inner/change-outer (the change-inner package). Both work at runtime — org-config loads eagerly and text-config autoloads change-inner via use-package :commands — but byte-compiling either module standalone warned "not known to be defined", and the dependency was implicit.

Added declare-function for each so the compile is clean and the cross-module relationship is explicit at the top of the file. No autoload needed: the runtime autoload/eager-load already exists, so only the compiler needed telling. custom-buffer-file.el byte-compiles clean already, so it needed no change.
</content>
</entry>
<entry>
<title>fix(org-roam): guard move-branch-to-roam against data loss</title>
<updated>2026-05-24T19:33:21+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-05-24T19:33:21+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/dotemacs/commit/?id=5c0fa15d1d5bbe48f85f21e98bb6e91e9b9bcd85'/>
<id>urn:sha1:5c0fa15d1d5bbe48f85f21e98bb6e91e9b9bcd85</id>
<content type='text'>
cj/move-org-branch-to-roam cut the subtree from the source buffer before writing the new roam file, so a failure in the demote/format/write/db-sync steps left the subtree gone from the source and not persisted anywhere — a destructive operation with no rollback.

Reordered so the node file is written and verified on disk before org-cut-subtree runs; a failed write now aborts with the source untouched. Added a no-clobber guard (refuse an existing target file) and a confirmation prompt for large subtrees (&gt;= cj/move-org-branch-confirm-lines, 30) or buffers with unsaved changes. The source buffer is deliberately left modified and undoable rather than auto-saved, so the move stays reversible. New test drives the write-failure-preserves-source invariant via an unwritable roam dir; the existing creates-roam-file test gained the confirm mock.
</content>
</entry>
</feed>
