config.org is the canonical literate configuration. Its code blocks tangle to
the init files of a named Emacs profile; generated profile files are not edited
in this repository. After changing config.org, tangle it through the live
profile machinery:
emacsclient -e '(init-build-profile (file-name-directory user-init-file))'This command matters because the target paths are computed by the profile. A
plain org-babel-tangle-file can write to the wrong profile. The active profile
name is available as init-current-profile and should be queried rather than
hard-coded:
emacsclient -e 'init-current-profile'The bin/emacs wrapper starts Emacs with optional profile selection, and
the command index documents the related launchers.
The files in extras/ are personal packages that extend built-in or external
packages. Most use the -extras suffix. Their Org manuals live in
extras/doc/; generated Texinfo counterparts are tracked beside the manuals
that produce them. Tests live in extras/test/, and the full development and reload
procedure is documented in
the Elisp development workflow.
The main configuration declares extras with use-personal-package. Elpaca
therefore installs them from this repository and loads them from the active
profile’s checkout, normally:
~/.config/emacs-profiles/<profile>/elpaca/sources/dotfiles/
That checkout is a read-only runtime mirror. All edits belong in
~/My Drive/dotfiles/. bin/elpaca-package-path dotfiles resolves this special
case to the canonical repository; other packages resolve to the active Elpaca
profile.
Public snippets are under yasnippets/. Private snippets are under
yasnippets-private/ and are encrypted with git-crypt. The configuration
adds both directories to yas-snippet-dirs, together with the installed
yasnippet-snippets collection. abbrev/abbrev_defs is the tracked Emacs
abbreviation file.
lockfile.el records the Elpaca package revisions used for a dotfiles release.
The release workflow rewrites it from the current profile with
elpaca-extras-write-lock-file-excluding; it should not be maintained by hand.
Every package runs unsandboxed, and a fresh dev profile used to clone all
third-party packages at upstream HEAD. bin/elpaca-cooldown keeps a
compromised upstream commit from reaching a profile on the day it is pushed:
| Command | Behavior |
|---|---|
observe | Runs daily from a LaunchAgent owned by the separate launchd repository. Records the tip of every third-party remote named in lockfile.el and when that tip was first seen, in ~/.local/state/elpaca-cooldown/observations.json. It runs git ls-remote only. |
plan --out FILE | Writes the candidate lockfile a dev profile is built from. Packages whose remote owner is listed in exempt-owners.txt move to their remote tip. Third-party packages move to the newest tip first seen at least seven days ago, provided it is still in the branch and descends from the pinned commit; otherwise they keep the previous release’s ref and the report says why. A package whose recipe in config.org carries :ref or :tag is planned at that pin, which Elpaca honours over the lockfile. --take-now PACKAGE bypasses the wait for one package and is named in the report. |
verify-build --candidate FILE --built FILE | Fails when a profile built from the candidate checked out any other ref, and lists packages that are new in the release, which are built at upstream HEAD. |
unused [--days N] | Lists the third-party packages that the package usage log (~/.config/emacs-profiles/var/package-usage.log, written by the “package usage log” section of config.org) has not seen loaded in the last 60 days. It reports nothing until the log itself covers that many days. A package that the configuration loads eagerly at startup always counts as loaded. |
First-seen time is recorded locally because commit dates can be forged. Until an observation is seven days old a package stays where the last release pinned it. The cooldown does not protect against a maintainer who waits it out, nor cover binaries that a package downloads or compiles.
The canonical Git directory has post-commit and post-rewrite hooks that
delegate to sync-elpaca-clone.sh. They fetch the committed current-branch state
into the active profile’s dotfiles checkout and reset that mirror to the fetched
commit; pushing is unrelated to this local activation path.
For changed files under emacs/extras/, the same hook creates a per-commit,
per-package pending state and starts the bounded elpaca-rebuild-wait helper.
The helper records finished or failed under
~/.cache/dotfiles/elpaca-reload/COMMIT/, so later verification can observe the
actual reload result.
This means an uncommitted extras edit is not yet the code loaded by Emacs. The
safe order is: edit the canonical file, run the source-aware batch test, commit,
then run ~/My\ Drive/dotfiles/claude/bin/elisp-live-verify PACKAGE -- EXPR.
That helper observes the post-commit rebuild, runs the package-named expression
in live Emacs, and emits repository/package/commit-bound evidence. Batch
evidence is separately bound to the repository, package, and source revision.
Manual rebuilds should name the individual extras package; they should not
rebuild the aggregate dotfiles package.
The complete extras suite runs with:
bash emacs/extras/test/run-tests.shIndividual packages have focused batch commands described in the development workflow. The GitHub copy of the extras suite is defined in test-extras.yml.
Project-local Emacs skills live under emacs/.claude/ and emacs/.codex/.
Their names and trigger descriptions are generated in the
tracked agent skill inventory rather than copied into this README.
The project-local document-elisp-extras entries load the matching runtime’s
global workflow from this repository. They keep local discovery without a
second procedure that can drift from the maintained documentation rules.
The emacs-freeze skill is global (claude/skills/ and codex/skills/),
because freezes are reported from sessions in any project. It reads
the freeze incident record first. The workflow binds evidence to a specific process and distinguishes
UI responsiveness from server replies. Its client helper bounds only its owned
child process; timeouts do not establish recovery or cancel queued Emacs work.
Recovery requires explicit authority and checks for session data and debugger
state, without treating sampled stacks or shutdown autosaving as guarantees.
The migrate-profile workflow inventories exact profile/project mappings and
uses the runtime-specific move-session-log adapters for offline history
relocation. It preserves unsupported memory/configuration merges and conflicting
sources, keeps trust transfer and additional deletion separately authorized, and
distinguishes metadata checks from live history/resume verification.
The rename-package workflow separates library/API edits from hosted repository
renames, publication, checkout relocation and live activation. It resolves the
actual package registry/source and verification support before changing a main
library, and preserves unrelated commits, trust state and older profiles.