aboutsummaryrefslogtreecommitdiff
path: root/docs/design/naming-audit.org
blob: f053ccb25d5302337ae212f093b0ef8008300060 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
#+TITLE: Naming Audit — Public/Private Boundaries in Owned Elisp
#+AUTHOR: Craig Jennings
#+DATE: 2026-06-29

* Purpose

A one-time audit of symbol-naming boundaries across config-owned Elisp, plus
the standing allowlist future reviews cite instead of re-arguing. The
convention itself lives in =.claude/rules/elisp.md=; this file records what the
scan found and how each finding was classified.

* Convention (summary)

- User-facing commands and shared helpers: =cj/name=.
- Private helpers inside cj-owned modules: =cj/--name=.
- Package-like standalone modules: =package-name= for public API,
  =package--name= for internals (e.g. =calendar-sync--=, =mouse-trap--=,
  =localrepo-=).
- No new unprefixed =defun=/=defvar=/=defcustom=/=defconst= in owned modules.
- Tested private helpers may stay private; the test references them directly.

* Scan method

#+begin_src sh
rg -n '^\((defun|defvar|defcustom|defconst|defgroup|defmacro) [^ )/]+' modules custom
#+end_src

The raw scan over-reports. Two large classes are not findings:

- *Foreign forward-declarations.* A bare =(defvar foreign-var)= with no value
  declares another package's special variable to quiet the byte-compiler. It
  defines nothing owned. The bulk of the raw hits are these (=org-*=, =emms-*=,
  =lsp-*=, =eat-*=, =mu4e-*=, and so on).
- *Vendored third-party files* under =custom/= (=elpa-mirror.el= =elpamr-=,
  =eplot.el= =eplot-=). These keep their upstream prefixes by policy.

* Findings

** Renamed (clear low-risk, done 2026-06-29)

| Old                                      | New                           | Why                                       |
|------------------------------------------+-------------------------------+-------------------------------------------|
| =car-member= (local-repository.el)       | =localrepo--car-member=       | Unprefixed, generic name with real        |
|                                          |                               | collision risk; pure non-interactive      |
|                                          |                               | helper used only within its module +      |
|                                          |                               | test.                                     |
|------------------------------------------+-------------------------------+-------------------------------------------|
| =unpropertize-kill-ring=                 | =cj/--unpropertize-kill-ring= | Unprefixed; non-interactive               |
| (system-defaults.el)                     |                               | =kill-emacs-hook= function, contained to  |
|                                          |                               | its module + tests.                       |
|------------------------------------------+-------------------------------+-------------------------------------------|

** Acceptable package prefixes (allowlist — no change)

These are deliberate, consistent module prefixes, not unprefixed leaks:

- =env-= / =env--= — host-environment.el.
- =localrepo-= — local-repository.el (public API + defcustoms).
- =mouse-trap-= / =mouse-trap--= — mousetrap-mode.el.
- =show-kill-= — show-kill-ring.el.
- =my-eww-= / =my-eww--= — eww-config.el.
- =signel-= / =signel--= — signal-config.el.

** Deferred — needs a focused, approved pass (not unattended)

Each carries a risk that argues for Craig's eyes rather than a no-approvals
rename:

- *Keybound / interactive commands*: =toggle-window-split= (bound =M-S-t=),
  =ensure-macros-file=, =empty-kill-ring=. A rename touches muscle-memory keys
  and =M-x= history; do it with =defalias= shims and a live check.
- *Cross-module macro*: =with-timer= (config-utilities.el, used in wrap-up.el
  and an architecture test). A macro rename forces recompilation of every
  caller; verify the whole graph.
- *defcustoms*: =theme-file=, =fallback-theme-name= (ui-theme.el). Renaming a
  =defcustom= orphans any persisted Customize value; use
  =define-obsolete-variable-alias=. (No custom-file currently sets them, so the
  risk is latent, not active.)
- *High-blast user constants*: the unprefixed =*-dir= / =*-file= constants in
  user-constants.el (=org-dir=, =projects-dir=, =books-dir=, and so on) are
  referenced across the whole config. They want their own dedicated rename
  task, not a drive-by.

* Acceptance

- The scan resolves to: two renames done, a documented allowlist of acceptable
  prefixes, and a deferred list with rationale. No unexplained unprefixed owned
  symbols remain.
- The two renames are covered by their existing module tests (updated in place).
- Future module reviews cite this file and =elisp.md= rather than re-deriving
  the boundary.