aboutsummaryrefslogtreecommitdiff
path: root/todo.org
Commit message (Collapse)AuthorAgeFilesLines
* refactor(load-graph): route C-; registration through the keymap APICraig Jennings12 days1-11/+3
| | | | | | Migrated all 31 cj/custom-keymap registration sites across 24 modules from direct (keymap-set cj/custom-keymap ...) calls to cj/register-prefix-map and cj/register-command. Consumers no longer reference cj/custom-keymap directly, so keybindings.el is the sole owner of the C-; prefix and modules reach it only through the API (each already requires keybindings from Phase 2). Behavior-preserving: I dumped every C-; binding before and after the migration and they're identical: 279 bindings, each resolving to the same command. The which-key label blocks are untouched, since they use string key descriptions and never assumed the keymap existed. I byte-compiled all 24 files (no new free-variable warnings, because the cj/custom-keymap references are gone), and make test, validate-modules, and an init load all pass.
* feat(keybindings): add cj/custom-keymap registration APICraig Jennings12 days1-1/+1
| | | | | | Phase 3 of the load-graph project. cj/register-prefix-map and cj/register-command bind a prefix map or command under the C-; prefix and register the which-key label once which-key loads. Feature modules will route their registration through these instead of mutating cj/custom-keymap directly, so keybindings.el stays the sole owner of the prefix and modules stop assuming the keymap already exists at load. Adds test-init-keymap-registration.el covering prefix-map and command resolution, the optional label, and invalid-key rejection. No modules are migrated yet; that follows in batches.
* refactor(load-graph): make hidden module dependencies explicitCraig Jennings12 days1-15/+4
| | | | | | | | | | | | | Phase 2 of the load-graph project. I fixed the seven hidden dependencies the classification surfaced, so each module declares what it uses instead of relying on init order. - system-defaults now requires host-environment and user-constants at runtime. They were eval-when-compile only, but env-bsd-p and user-home-dir are read at load, so the compiled module couldn't load standalone. - custom-buffer-file, dev-fkeys, calendar-sync, and video-audio-recording require keybindings and drop their (when (boundp 'cj/custom-keymap) ...) shims. The shim silently dropped the C-; binding when the module loaded before keybindings. The explicit require makes the dependency real. - flycheck-config and mail-config require keybindings for their cj/custom-keymap bindings (a use-package :map and a direct keymap-set). - Removed a dead eval-when-compile (defvar cj/custom-keymap) in transcription-config; nothing there used the variable. No init.el load-order change. keybindings and the foundation modules already load before these, so the requires are no-ops at startup and only fix standalone and test loading. I verified each fix with a fresh emacs --batch (require 'X), then swept all modules standalone: every one loads or fails only with a clear missing-package message. Full make test, make validate-modules, and an init smoke all pass. Module headers and the inventory's hidden-dependency section are updated to mark the seven resolved.
* docs(todo): close module-classification task, split out elfeed-configCraig Jennings12 days1-16/+4
| | | | Rewrote the classify-modules child as a dated log entry now that 101 of 102 modules carry load-graph headers. Pulled the lone deferral — annotating elfeed-config — into its own task, blocked on the elfeed test-byte-compile fix.
* docs(load-graph): classify domain, integration, and optional modulesCraig Jennings12 days1-0/+3
| | | | | | | | | | Eighth classification batch: 17 domain/integration/optional modules — ai-config, ai-vterm, browser-config, calendar-sync, calibredb-epub-config, chrono-tools, dirvish-config, dwim-shell-config, erc-config, eshell-config, eww-config, flyspell-and-abbrev, games-config, gloss-config, httpd-config, jumper, latex-config. I annotated each header, added a Batch 8 table to the inventory, and extended the validation allowlist. 82 of 102 modules are now classified. Almost all are eager only by init order and become command/hook/mode-loaded. calendar-sync stays eager when its .local.el is present. One new hidden dependency: calendar-sync guards its C-; g registration with a boundp shim and doesn't require keybindings, so the binding drops standalone. I deferred elfeed-config rather than annotate it. Its header edit triggers byte-compilation, and the existing tests only pass when the module loads as interpreted source — the compiled cj/elfeed-process-entries inlines an elfeed struct accessor the stubs can't intercept, and the batch test environment has no elfeed package to build real structs. It needs its tests rewritten first, recorded in the inventory and a new todo task. Also made the header allowlist scoping test durable: it used games-config (now classified) as its unclassified example; switched to a sentinel name plus a duplicate-entry guard.
* docs(init): retire stale module comments and track follow-upsCraig Jennings12 days1-1/+7
| | | | Three init.el requires carried vague comments: latex-config "WIP need to fix", prog-shell "combine elsewhere", and a "Modules In Test" banner. I replaced them with descriptive comments and moved the real follow-up work into todo.org tasks: investigate the latex-config state, and decide whether prog-shell config folds into prog-general. I also marked the module-classification task DOING.
* docs(todo): close coverage backlog after assessing the sub-60% clusterload-graph-classify-startCraig Jennings12 days1-19/+13
| | | | 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.
* docs(todo): refresh stale coverage backlog against a clean runCraig Jennings12 days1-318/+18
| | | | The per-module percentages in the coverage audit were stale — this session's test-writing covered most of the listed modules (prog-python 0%->100%, hugo-config 17.7%->91.7%, undead-buffers 5.7%->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.
* docs(todo): log the third solo-hardening batch (move-branch, keymaps, ↵Craig Jennings12 days1-64/+10
| | | | export, elfeed/eww, capture tests)
* docs(todo): log the second solo-hardening batch (webclip, qvc timers, dir ↵Craig Jennings12 days1-50/+11
| | | | scans, vc cache, region scope)
* docs(todo): log the org-drill, git-clone, and video-capture hardeningCraig Jennings13 days1-33/+7
|
* docs(dwim-shell): record accepted 7z password-on-argv tradeoffCraig Jennings13 days1-8/+3
| | | | 7-Zip 26.01 reads the encryption password only from its controlling TTY, not stdin or a file — a piped password silently becomes an empty one — so it has to go on argv and is briefly visible in the process list. Rather than switch off the .7z format to gpg-wrapped tar, the exposure is accepted: single-user workstation, short-lived process, password already kept out of shell history by the mode-600 temp file. Documented the evaluated tradeoff in both encrypt/decrypt docstrings so it's visible at the call site.
* docs(todo): log the defensive restart/shutdown hardeningCraig Jennings13 days1-15/+3
|
* docs(todo): log the three video-audio-recording hardening fixesCraig Jennings13 days1-30/+6
| | | | Closed the X11/audio shell-quoting, the scoped wf-recorder stop signal, and the selected-directory creation as dated event-log entries under the recording hardening tree.
* docs(todo): close C-s isearch task — verified non-bug on Emacs 30.2Craig Jennings13 days1-10/+3
| | | | While isearch is active, overriding-terminal-local-map is isearch-mode-map, so C-s resolves to isearch-repeat-forward and the global cj/consult-line-or-repeat binding can't shadow it. isearch-mode-map already binds C-s to that default, so I left selection-framework.el unchanged.
* docs(ai-kb): fold in review 6 and resolve the build-time decisionsCraig Jennings13 days1-11/+17
| | | | | | The latest design review was a UX and performance pass, and I folded its findings into the spec and the implementation tasks. The important one: human Emacs edits now use the same write path as agent writes. An ai-kb minor mode runs index, full lint, and commit under flock on after-save, so a hand edit can't quietly skip the safety gate. The rest: the generated index.org is now invisible to backlink and orphan logic (excluded from the scan, referenced as plain text rather than id-links), a required :SUMMARY: property feeds the index and query without inference, query gains lexical ranking with recency only as a tie-break, the switch installs a full org-roam profile rather than a two-variable swap, and the browsing surface (dashboard, find, search, show, backlinks, map) is named. I also answered the six build-time decisions: concrete raw and curation limits, performance budgets for the perf fixtures, the lexical scoring weights, org-roam-graph as the first map implementation, the after-save failure UX (the save always lands, the commit is gated, and a failure shows without trapping the buffer), and the after-save recursion guard. The numeric limits and budgets are starting points to calibrate. The rest are firm. Step 1 stays buildable.
* docs(todo): split Implement ai-kb tasks into 1a/1b and fold in review-5 ↵Craig Jennings13 days1-0/+43
| | | | | | hardening I reorganized the Implement ai-kb children into the Step 1a / 1b phases from the spec: 1a is the safe write path (store, contract, the index/lint/remember/doctor CLI, the adapter, provisioning), and 1b is query/curate/sync, the push timer, and the curation workflow. The remember task now gates the commit on the full ai-kb lint rather than node org-lint, the test tasks target the org-lint fatal-check list and the query --json contract, the push task carries the failure-observability surfaces, and the pointer convention is ID-first throughout.
* chore(todo): archive resolved dashboard tasks to ResolvedCraig Jennings13 days1-98/+93
|
* docs(todo): close broad/misleading file-op clarificationCraig Jennings13 days1-14/+2
|
* docs(todo): close video-concat filelist rebuildCraig Jennings13 days1-8/+2
|
* docs(todo): close babel-confirm hardening, file keybinding follow-upCraig Jennings13 days1-11/+7
|
* docs(todo): close dwim-shell input-quoting, file concat-list follow-upCraig Jennings13 days1-20/+11
|
* docs(todo): close password temp-file fix, file 7z argv follow-upCraig Jennings13 days1-15/+11
|
* docs(todo): close SkyFi key-injection removalCraig Jennings13 days1-12/+2
|
* docs(todo): triage hardening backlog — close done, tag soloCraig Jennings14 days1-89/+40
| | | | I triaged the ~50 open hardening findings against the codebase. Closed five whose premise was stale because the work already shipped: the personal-calendar-config split, the shared cache helper, the cache idle-timer gating, and AI-conversation-persistence coverage. Tagged 31 findings :solo: — bounded work an agent can finish and verify without a decision from me. The rest carry a preference, policy, or design call and stay untagged.
* docs(todo): record kill-compose-buffers-on-exit decisionCraig Jennings14 days1-2/+2
|
* docs(todo): close mail compose lifecycle clarificationCraig Jennings14 days1-11/+2
|
* docs(todo): close org-babel structure-template fixCraig Jennings14 days1-11/+2
|
* docs(todo): close flyspell-and-abbrev coverageCraig Jennings14 days1-10/+2
|
* docs(todo): close external-open/media-utils coverageCraig Jennings14 days1-13/+2
|
* docs(todo): close title-case edge coverage and mail/system-commands coverageCraig Jennings14 days1-21/+4
|
* docs(todo): close host-env predicate cleanupCraig Jennings14 days1-16/+3
|
* docs(todo): close dirvish hardening and coverage tasksCraig Jennings14 days1-25/+4
|
* docs(todo): add :solo: tag and mark Claude-doable hardening tasksCraig Jennings14 days1-22/+19
| | | | I added a :solo: tag to the legend for tasks Claude can take end to end with no input from me: bounded scope, no design or preference call, verifiable locally. Tagged the nine hardening findings I've already assessed that way. Also closed the dirvish runtime-require task, shipped in b63c4f83.
* docs(todo): record TRAMP/dirvish "?" root cause, leave fix to verifyCraig Jennings14 days1-15/+15
| | | | | | I traced why remote dirvish shows "?" for dates: dirvish fetches remote attributes through an async `ls -1lahi` parser that only runs when the connection has direct-async and the remote has GNU ls. It falls back to skipping `file-attributes` (rendering "?") when either gate is shut. That's why the earlier dired-listing-switches attempts missed the real path, and why disabling direct-async made it worse. The config already enables direct-async, so the rest is per-host and needs a live remote. I left the three diagnostic evals and the likely fixes in the task body.
* docs(todo): close org-log-done reconcileCraig Jennings14 days1-2/+3
|
* docs(todo): close always-save-daily taskCraig Jennings14 days1-2/+3
|
* docs(todo): close auth-source consolidationCraig Jennings14 days1-1/+3
| | | | I closed the auth-source-idiom consolidation. The four copies now delegate to one system-lib helper.
* docs(todo): close dashboard navigator/keymap dedupCraig Jennings2026-05-221-1/+3
| | | | I closed the navigator and keymap duplication task. Both now derive from one launcher table.
* docs(todo): close dashboard subtitle and color bugs, file navigator-color ↵Craig Jennings2026-05-221-4/+11
| | | | | | follow-up I closed the subtitle-centering and the navigator/item color bugs, and filed a follow-up to give the navigator its own color separate from the list items, which is blocked by the shared dashboard-items-face overlay.
* docs(todo): close test-name abort bugCraig Jennings2026-05-221-1/+4
| | | | The real cause wasn't gptel: the gptel-tools tests already stub the constructors. test-name aborted because a test file leaked default-directory at load. Fixed with absolute load paths plus containment.
* docs(todo): close gptel backend-load bugCraig Jennings2026-05-221-1/+2
| | | | The fork's backend constructors load again, verified end-to-end.
* docs(todo): close finalize-task keybinding, file follow-upsCraig Jennings2026-05-221-29/+23
| | | | I closed the finalize-task keybinding work and recorded its design in the task body. Three follow-ups came out of it: reconcile the duplicate org-log-done setting, always save the daily after a journal task-copy, and manually verify the live journal copy that the unit tests mock out.
* docs(todo): review all tasks, re-grade gptel, expand Corfu subtasksCraig Jennings2026-05-221-3/+133
| | | | | | | | | | | | I walked all 24 unreviewed top-level tasks in one pass and stamped each with :LAST_REVIEWED: 2026-05-22. That dropped the threshold-7 staleness count from 24 to 0. I re-graded "gptel fork not loading: gptel-make-anthropic void" from [#C] to [#B]. It breaks gptel chat entirely and is the root cause of the test-name batch-load abort, so it shouldn't sit at the bottom of the pile. I reworded the sentence-shaped keybinding task to a terse topic and tagged it :quick:. Then I answered its embedded request with a cj/org-heading-to-dated-log sketch that drops the keyword and priority cookie and prepends a sortable timestamp, plus three mnemonic key candidates. I switched the org-noter task from VERIFY to TODO. It's in-progress implementation work, not an open question waiting on input. I expanded the Company-to-Corfu task with the migration spec's nine implementation steps as sub-tasks, so the work is ready to pick up without re-reading the design doc.
* docs(todo): log launch + dashboard bugs, tag quick tasks, close shipped workCraig Jennings2026-05-211-25/+50
| | | | I filed the gptel-fork-load error, the org-contacts launch error, and two dashboard polish bugs (off-center banner subtitle, uncolored navigator icons + titles). I tagged the genuinely quick tasks :quick:, dropped all gptel work to #C, and closed the two tasks shipped this session: the ai-vterm graceful close and the org-contacts launch fix.
* docs(todo): archive shipped tasks, file calendar and harness follow-upsCraig Jennings2026-05-211-8/+79
| | | | Moved the ai-vterm sizing and dashboard fixes to Resolved now that they've shipped. Filed two follow-ups: make test-name aborting on gptel-dependent test files, and consolidating the duplicated auth-source secret-funcall idiom.
* chore(todo): claim dashboard task + dated-log subtask rewritesCraig Jennings2026-05-181-57/+78
| | | | | | | | | | - Claim [#C] Dashboard buffer too long as DOING :bug: with expanded body. - File [#C] Collapse dashboard navigator + keymap duplication :refactor: surfaced by the audit of dashboard-config.el. - Mechanical: rewrote completed sub-tasks (level *** and deeper) from "DONE [#priority]" keyword form to "YYYY-MM-DD Day" dated-log form per the project's depth-based completion rule.
* chore(todo): shorten title to "Emacs Config"Craig Jennings2026-05-181-1/+1
|
* chore(todo): close Phase 1 ai-mcp foundationCraig Jennings2026-05-171-13/+2
|
* docs(design): MCP-into-gptel + gh-as-gptel-tool specs + MCP phasesCraig Jennings2026-05-171-1/+149
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Two new design docs in docs/design/ covering the next two GPTel work items, plus matching task scaffolding in todo.org. mcp-el-gptel-integration.org wires mcp.el into the config so GPTel gets access to the nine MCP servers Claude Code already uses (linear, notion, figma, slack-deepsat, drawio, google-calendar, google-docs-personal, google-docs-work, google-keep). The design covers async startup, the write-confirmation policy, a server-enablement defcustom, a doctor with live-auth-check, the audit buffer, and the mcp.el compatibility layer. The spec is at revision 3 after two code-review passes flagged a critical confirmation gap (gptel-confirm-tool-calls nil at ai-config.el:386 silently ignored per-tool :confirm slots) and several incorrect mcp.el API assumptions. Both are addressed. gptel-gh-tool.org wraps the gh CLI as a hybrid surface: 14 typed read wrappers plus one general write tool gated by :confirm t. Host/repo resolution is command-aware: --repo HOST/OWNER/REPO for repo commands, --hostname only for api and auth status. The runner enforces an irreversible-command blocklist, a 64KB in-flight output cap, and a debug-record plus last-error-buffer story. The spec is at revision 2 after a code-review pass corrected gh flag assumptions and reframed the safety story around per-tool confirm. todo.org gains a link to the MCP spec under the parent task plus nine TODO sub-tasks (one per implementation phase), and a new gh-tool TODO with the same spec-link shape.