summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--AGENTS.md13
-rw-r--r--README.md93
-rw-r--r--config.org33
3 files changed, 102 insertions, 37 deletions
diff --git a/AGENTS.md b/AGENTS.md
index 0c11b3e..92cf972 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -6,13 +6,18 @@ This repository is for the creation and maintenance of Emacs 30 configuration fi
## Repository Layout
-- `config.org` is the single hand-edited source of truth for the configuration.
+- `config.org` is the single hand-edited source of truth for Emacs configuration.
- `init.el` and `early-init.el` are generated from `config.org` and should not be edited directly.
- Structure the literate config by startup responsibility first, then by workflow domain.
- The current Org workflow lives under `~/org/` with `daily/`, `projects/`, `areas/`, `areas/people/people.org`, `resources/`, and `archives/`.
+- `~/org/` is external to this repository and must already exist.
+- The configuration may open files in `~/org/`, but it must not create directories, create files, or validate note structure.
+- `~/org/moc.org` is a normal note. The configuration may open it, but it must not create or manage it.
- Daily notes stay as plain Org files under `~/org/daily/`; longer-lived notes are handled through Denote in the same root.
-- Agenda files are discovered dynamically from the project, area, and resource directories rather than from a fixed file list.
-- The config also includes a small gptel workflow that uses GitHub Copilot as the backend.
+- Agenda files are discovered by recursively scanning `.org` files under `~/org/projects/`, `~/org/areas/`, and `~/org/resources/`.
+- Agenda discovery must exclude `~/org/daily/` and `~/org/archives/`.
+- PARA is the organising model for durable notes, and folder placement carries meaning.
+- The config includes an experimental `gptel` setup that uses GitHub Copilot as the backend.
- Do not treat `auto-save-list/` as source content.
## Editing Expectations
@@ -47,6 +52,8 @@ This repository is for the creation and maintenance of Emacs 30 configuration fi
- Document non-obvious conventions close to the relevant configuration in `config.org`.
- Update `README.md` whenever configuration or workflow changes alter package usage, startup behavior, keybindings, directory layout, capture flow, or other documented behavior.
- `README.md` must describe the current configuration truthfully. Do not leave stale documentation behind and do not document planned behavior as current behavior.
+- Keep README and AGENTS consistent. State rules explicitly and avoid hidden or heuristic behavior in documentation.
+- Use `~/org` consistently when describing the external notes directory.
- Before claiming a change is complete or asking to commit it, review whether `README.md` needs an update; if it does not, say so explicitly in the summary.
- Update AGENTS.md when the repo workflow, Org layout, or verification expectations materially change.
- Keep AGENTS.md concise and update it only when the repository structure or working rules actually change.
diff --git a/README.md b/README.md
index 0ffa1fe..3edcd7b 100644
--- a/README.md
+++ b/README.md
@@ -1,12 +1,24 @@
# Emacs Configuration
-This repository contains a literate Emacs configuration built around Org mode, Denote, a PARA-style note layout, and a small completion stack. The hand-edited source is `config.org`; `init.el` and `early-init.el` are generated from it.
+This repository contains a literate Emacs configuration built around Org mode, Denote, a PARA-style note layout, and a small completion stack. The hand-edited configuration source is `config.org`; `init.el` and `early-init.el` are generated from it.
+
+## System Model
+
+This repository configures Emacs. It does not define, create, or validate the `~/org` note system.
+
+- `config.org` is the source of truth for Emacs configuration only.
+- `~/org` is external to this repository and must already exist.
+- The configuration may open files in `~/org`, but it must not create directories, create files, or validate note structure.
+- `~/org/moc.org` is a normal note. The configuration may open it, but it must not create or manage it.
+- PARA is the organising model for durable notes. Folder placement carries meaning, and workflows must respect that placement.
+- The system optimises for speed of capture and minimal friction.
+- The system must prefer explicit rules over implicit behaviour and must avoid over-structuring, manual overhead, and inconsistency.
## Emacs Setup
### Source of truth and generated files
-`config.org` is the only file intended for manual configuration edits. The generated startup files are:
+`config.org` is the only file intended for manual Emacs configuration edits. The generated startup files are:
- `early-init.el` for settings that must exist before the first GUI frame.
- `init.el` for the main runtime configuration.
@@ -23,18 +35,18 @@ The current setup uses these packages and built-in modules:
- `org` and `org-capture` for agenda, capture, daily notes, and the literate configuration itself.
- `denote` for durable notes, naming, keywords, and linking.
-- `git-auto-commit-mode` for automatic note commits on save inside the notes repo.
+- `git-auto-commit-mode` for optional automatic commits inside `~/org` when enabled by directory-local settings.
- `vertico` for minibuffer completion UI.
- `orderless` for flexible completion matching.
- `marginalia` for minibuffer annotations.
-- `gptel` with the GitHub Copilot backend for chat and rewrite workflows inside Emacs.
+- `gptel` with the GitHub Copilot backend, currently being trialled as an experimental tool rather than a defined workflow.
- `dired` with a macOS-safe `ls` configuration.
- `time` for the modeline clock.
- `modus-themes`, using `modus-vivendi` in the current config.
### Org mode and note layout
-The note system lives under `~/org/` and is organized like this:
+The note system lives under `~/org/` and is organised like this:
- `daily/` for plain daily Org files.
- `projects/` for project notes.
@@ -43,9 +55,15 @@ The note system lives under `~/org/` and is organized like this:
- `resources/` for reference material.
- `archives/` for archived notes.
-This is a PARA-style layout, but the agenda is intentionally narrower than the full tree. Agenda files are discovered dynamically from `projects/` and `areas/` only. Daily notes, archives, and resources are excluded from the agenda scan.
+This is a PARA-style layout. Folder placement carries meaning. Denote keywords are used sparingly, with `project` kept as the only built-in structural keyword because project titles are often ambiguous outside their folder.
+
+### Agenda Rules
-Folder placement carries most of the structural meaning in this setup. Denote keywords are used sparingly, with `project` kept as the only built-in structural keyword because project titles are often ambiguous outside their folder.
+The agenda is rule-based.
+
+- The agenda must include recursive scans of `.org` files under `~/org/projects/`, `~/org/areas/`, and `~/org/resources/`.
+- The agenda must exclude `~/org/daily/` and `~/org/archives/`.
+- The agenda must use recursive discovery and explicit include and exclude rules rather than heuristic selection.
### Completion setup
@@ -56,15 +74,29 @@ The minibuffer stack is intentionally small:
- `marginalia` adds annotations.
- `corfu` handles in-buffer completion popups for text and Org buffers.
-Name entry uses fixed abbrevs plus the rolodex:
+## People System
+
+The people system is a structured rolodex rooted at `~/org/areas/people/people.org`.
+
+- Each top-level heading represents one person.
+- Entries are strictly structured around heading text and properties.
+- The system generates abbrevs from the rolodex.
+- The system provides canonical-name completion through a CAPF.
+- The system provides reporting views grouped by person properties.
+- The system rebuilds on any rolodex change, whether the change comes from manual editing or from a command.
+- The rolodex must remain up to date after changes.
+- Failures must surface visibly. The system must not silently fall back to stale state.
+- `CURRENT_FOCUS` must stay short and phrase-like so summaries and completion annotations remain readable.
+
+Name entry uses fixed abbrevs plus the people rolodex:
- `abbrev` provides deterministic one-shot shortcuts for fixed name expansions.
-- people-specific abbrevs are generated dynamically from top-level cards in `~/org/areas/people/people.org`.
-- a CAPF feeds Corfu canonical names from `people.org`, while alias matching stays available for lookup and completion.
+- people-specific abbrevs are generated from top-level cards in `~/org/areas/people/people.org`.
+- a CAPF feeds Corfu canonical names from `~/org/areas/people/people.org`, while alias matching stays available for lookup and completion.
- Marginalia annotates person candidates with `role | location | engagement | current focus`.
-- `M-x ss/people-open` opens `~/org/areas/people/people.org` in overview mode.
+- `M-x ss/people-open` opens `~/org/areas/people/people.org` in overview mode through `ss/people-overview`.
- `M-x ss/people-find` opens a person card narrowed to that subtree.
-- `M-x ss/people-overview` exits card view by widening and restoring the overview.
+- `M-x ss/people-overview` opens the rolodex in overview mode, resetting the file by widening and restoring the overview when leaving card view.
- `M-x ss/people-insert-name` inserts the canonical name at point.
- `M-x ss/people-insert-summary` inserts a compact single-line summary at point.
- `M-x ss/people-add` adds a new person card directly to `~/org/areas/people/people.org`.
@@ -95,27 +127,44 @@ emacs --batch -Q --load ./init.el
### MOC
-There is a central `~/org/moc.org` note. It is a deliberately small, curated navigation surface for the notes system rather than an exhaustive index or system of record, and the config assumes the file already exists.
+`~/org/moc.org` is a normal note. It serves as a small curated navigation surface rather than an exhaustive index or system of record, and the configuration assumes the file already exists.
-The MOC opens automatically on Emacs startup through startup-hook behavior, but the config now just opens the file directly rather than creating it. `C-c n M` opens it manually at any time.
+The configuration may open the MOC automatically on startup, and `C-c n M` opens it manually. The configuration must not create or manage the file.
Its Quick Access section provides actionable links for opening the agenda, today's note, capture, and a new note, while the rest of the file stays lightweight and curated around active projects, areas, and a few high-leverage resources.
+### Capture Model
+
+The capture model has two distinct modes.
+
### Daily notes
-Daily notes are plain Org files in `~/org/daily/`, named by date. When a daily note is created through the config, it starts with these headings:
+Daily notes are plain Org files in `~/org/daily/`, named by date. The workflow expects these headings:
- `Tasks`
- `Notes`
- `Open Loops`
-Daily capture stays fast without routing everything through Denote.
+Daily notes are a work journal. They use light structure and are optimised for speed.
+
+### Durable notes
+
+Durable notes use Denote and live in the PARA directories under `~/org/`.
+
+- Durable notes are created through capture plus Denote.
+- Durable notes are structured at creation time.
+- Folder placement carries meaning.
+- The workflow must respect PARA placement rather than relying on later manual cleanup.
### Agenda usage
-The agenda is opened through `ss/open-agenda`, bound to `C-c a`. That command explicitly loads `org-agenda`, and the config refreshes `org-agenda-files` immediately before each `org-agenda` invocation so the agenda sees the current PARA files without relying on a fixed file list.
+The agenda is opened through `ss/open-agenda`, bound to `C-c a`. That command explicitly loads `org-agenda`, and the config refreshes `org-agenda-files` immediately before each `org-agenda` invocation.
+
+The agenda scan is explicit:
-This means the agenda reflects the current project and area files at runtime instead of relying on a fixed file list. Daily notes, archives, and resources are outside the agenda scan.
+- It recursively includes `.org` files from `~/org/projects/`, `~/org/areas/`, and `~/org/resources/`.
+- It excludes `~/org/daily/` and `~/org/archives/`.
+- It does not rely on heuristics.
### Capture flow
@@ -129,6 +178,7 @@ This means the agenda reflects the current project and area files at runtime ins
Daily task capture writes under `Tasks`. Daily note capture and daily meeting capture both write under `Notes`, and the meeting template prefixes the heading with a timestamp and the word `meeting`.
Denote captures still prompt for title, keywords, and subdirectory placement where appropriate, but folder placement does most of the classification work. The project capture template prepopulates the `project` keyword. Area and resource captures do not inject structural keywords automatically, and there is no Denote-backed meeting capture template.
+
The people rolodex is intentionally outside `org-capture`: `M-x ss/people-add` writes a compact card directly into `~/org/areas/people/people.org`, keeping the rolodex as a fast reference file instead of another capture sink.
### Note creation and linking
@@ -143,7 +193,6 @@ Denote handles long-lived notes. The main bindings are:
- `C-c n i` to insert a canonical person name.
- `C-c n I` to insert a compact person summary.
- `C-c n L` to show people grouped by location.
-- `C-c n m` to create a PARA subdirectory from the minibuffer before capturing into it.
- `C-c n d` to open today's daily note.
- `C-c n o` to restore the rolodex overview.
- `C-c n O` to show people grouped by role.
@@ -155,11 +204,11 @@ Keyword prompts and directory placement are part of the workflow, not an afterth
### Automatic note commits
-The notes tree can opt into `git-auto-commit-mode` through a directory-local file at `~/org/.dir-locals.el`. In the current setup, the Emacs config installs the package and configures shell command chaining based on the active shell, while the notes repository carries its own auto-commit policy in directory locals.
+The configuration provides `git-auto-commit-mode` capability. Behaviour is defined in `~/org/.dir-locals.el`.
-When enabled for the notes tree, saving a file in `~/org/` makes Emacs try to commit that change to the notes repository. In the current `~/org/.dir-locals.el`, new files are added automatically, commits are debounced by 60 seconds, automatic pushing is enabled, and the default commit message is a timestamp in the form `Auto-commit: YYYY-MM-DD HH:MM:SS`.
+When enabled in `~/org/.dir-locals.el`, saving a file in `~/org/` makes Emacs try to commit that change. The configuration must not enforce policy for add, push, debounce, or commit-message behaviour.
-Place this file at the root of the notes repository:
+Place this file at `~/org/.dir-locals.el`:
```emacs-lisp
((nil .
diff --git a/config.org b/config.org
index 4a5c426..ed8e7e6 100644
--- a/config.org
+++ b/config.org
@@ -277,14 +277,19 @@ annotations.
(global-corfu-mode 1))
#+end_src
-* Name shortcuts
+* People rolodex
-The people workflow is a lightweight rolodex backed by a single =~/org/areas/people/people.org=
-file. Each top-level heading is a compact card with properties for lookup,
-completion, reports, and abbrevs. Abbrev remains the fast path for names you
-type all the time, while CAPF plus Corfu remains the discovery path. The
-machine-facing layer only reads heading text and properties; the =Context= and
-=TODOs= sections stay human-facing notes.
+The people workflow is a lightweight rolodex backed by the canonical
+=~/org/areas/people/people.org= file. Each top-level heading is a compact card
+with properties for lookup, completion, reports, and abbrevs. Abbrev remains
+the fast path for names you type all the time, while CAPF plus Corfu remains
+the discovery path. The machine-facing layer only reads heading text and
+properties; the =Context= and =TODOs= sections stay human-facing notes.
+
+The rolodex is designed around =ss/people-overview=: opening the file starts in
+overview mode, direct visits reset back to overview mode, and exiting card view
+means widening the buffer and restoring that overview. Keep =CURRENT_FOCUS=
+short and phrase-like so summaries and completion annotations stay readable.
#+begin_src emacs-lisp
(require 'seq)
@@ -497,7 +502,7 @@ machine-facing layer only reads heading text and properties; the =Context= and
t))))
(defun ss/people-overview ()
- "Show `ss/people-file' in overview mode."
+ "Open `ss/people-file' in overview mode, widening first when needed."
(interactive)
(unless (and buffer-file-name
(string= (file-truename buffer-file-name)
@@ -509,7 +514,7 @@ machine-facing layer only reads heading text and properties; the =Context= and
(org-cycle-hide-drawers 'all))
(defun ss/people-open ()
- "Open the rolodex in overview mode."
+ "Open the people rolodex by delegating to `ss/people-overview'."
(interactive)
(ss/people-overview))
@@ -527,7 +532,7 @@ machine-facing layer only reads heading text and properties; the =Context= and
(file-truename ss/people-file))))
(defun ss/people--open-entry (entry)
- "Open the people rolodex file and narrow to ENTRY."
+ "Open the people rolodex file, then narrow to ENTRY for card view."
(find-file (ss/people--ensure-file))
(widen)
(let ((position (org-find-exact-headline-in-buffer
@@ -580,7 +585,10 @@ machine-facing layer only reads heading text and properties; the =Context= and
(insert "#+title: " title "\n\n")
(dolist (group groups)
(insert "* " (car group) "\n")
- (dolist (entry (cdr group))
+ (dolist (entry (sort (copy-sequence (cdr group))
+ (lambda (left right)
+ (string< (ss/people--entry-name left)
+ (ss/people--entry-name right)))))
(insert "- " (ss/people--display entry) "\n")))
(goto-char (point-min))
(read-only-mode 1)
@@ -703,6 +711,7 @@ machine-facing layer only reads heading text and properties; the =Context= and
(skip-syntax-backward "w_")
(let ((beg (point)))
(when (< beg end)
+ ;; Verify this in real Org/text writing buffers, not just by inspection.
(let ((annotation
(lambda (candidate)
(when-let ((entry (ss/people--entry-by-name candidate)))
@@ -723,7 +732,7 @@ machine-facing layer only reads heading text and properties; the =Context= and
(add-hook 'completion-at-point-functions #'ss/people-capf nil t)))
(defun ss/people--maybe-overview-buffer ()
- "Reset the people rolodex file to overview when visiting it directly."
+ "Reset the people rolodex buffer to overview when visiting it directly."
(when (and buffer-file-name
(string= (file-truename buffer-file-name)
(file-truename ss/people-file)))