<feed xmlns='http://www.w3.org/2005/Atom'>
<title>gloss, branch main</title>
<subtitle>Emacs glossary lookup with Wiktionary fallback
</subtitle>
<id>https://git.cjennings.net/gloss/atom?h=main</id>
<link rel='self' href='https://git.cjennings.net/gloss/atom?h=main'/>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/gloss/'/>
<updated>2026-05-07T23:25:33+00:00</updated>
<entry>
<title>chore: symlink claude rules to rulesets canonical</title>
<updated>2026-05-07T23:25:33+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-05-07T23:25:33+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/gloss/commit/?id=7073b16f6cb717a9b63c0103ffe91fea47ca1b2b'/>
<id>urn:sha1:7073b16f6cb717a9b63c0103ffe91fea47ca1b2b</id>
<content type='text'>
The .claude/rules/ files (commits.md, testing.md, verification.md) were local copies that drifted from the canonical at ~/code/rulesets. I replaced them with absolute symlinks pointing at the canonical files. This repo now picks up rule updates automatically.

The symlinks are absolute. Cloning this repo on a new machine needs ~/code/rulesets at the same path. Otherwise the symlinks dangle.
</content>
</entry>
<entry>
<title>docs: restore 'and on cjennings.net' in README install intro</title>
<updated>2026-04-30T13:03:02+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-04-30T13:03:02+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/gloss/commit/?id=c7e03f3dd8672b8819b50522396bcd27154b179d'/>
<id>urn:sha1:c7e03f3dd8672b8819b50522396bcd27154b179d</id>
<content type='text'>
</content>
</entry>
<entry>
<title>docs: trim README — drop quick-sdcv comparison + bare-repo aside</title>
<updated>2026-04-30T13:02:31+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-04-30T13:02:31+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/gloss/commit/?id=e4a8deee0b58a80ad2e8232837d6501d08bb7469'/>
<id>urn:sha1:e4a8deee0b58a80ad2e8232837d6501d08bb7469</id>
<content type='text'>
</content>
</entry>
<entry>
<title>docs: expand README with usage examples</title>
<updated>2026-04-30T12:58:24+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-04-30T12:58:24+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/gloss/commit/?id=94ffab27664274f9018bc4c2ca6472ba92c50d00'/>
<id>urn:sha1:94ffab27664274f9018bc4c2ca6472ba92c50d00</id>
<content type='text'>
Replaces the placeholder with full usage docs modelled on chime's
README but tighter — gloss is a smaller package, the doc shouldn't
out-bulk it.

Sections: nav links, status, why-not-quick-sdcv, features, installation
(package-vc-install / use-package :vc / straight / manual), quick start
(lookup and add flows), the C-h g keybinding table plus the
gloss-add-mode binding table, the four defcustoms with rationale,
extending the source registry for v2+, org-drill integration,
troubleshooting (libxml absent, network failures, file corruption,
cache out of sync, side-window dismiss), development (Cask + ert-runner
+ Make targets), license.

The keybinding table is the source of truth — every entry matches what
`gloss-prefix-map' actually binds. The defcustoms section names the
four actual customs only (gloss-file, gloss-fetch-sources,
gloss-fetch-timeout, gloss-debug); no aspirational knobs.
</content>
</entry>
<entry>
<title>docs: record four ADRs for gloss design decisions</title>
<updated>2026-04-30T12:55:28+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-04-30T12:55:28+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/gloss/commit/?id=b0d722d1a985326fb38e4e7fea237b9c4a2adcfd'/>
<id>urn:sha1:b0d722d1a985326fb38e4e7fea237b9c4a2adcfd</id>
<content type='text'>
The four decisions called out in the brainstorm now have their own
files under docs/decisions/, each with Context / Decision /
Consequences / Alternatives Considered.

- 0001 — storage path default: respects org-directory if set, falls
  back to user-emacs-directory.
- 0002 — auto-fetch on local miss: silent fall-through, network
  failures surface via the regular error rollup. No y/n prompt for
  v1.
- 0003 — drill direction: every entry exports as twosided. One card
  per entry, both directions over time, no per-entry override.
- 0004 — HTML strip strategy: libxml-parse-html-region. Plain text
  only, no italic/bold preservation. Online fetch disabled package-wide
  for the session if libxml is missing.

The "Open Questions" section in the design doc is now "Decisions
Recorded" with links into the ADRs.
</content>
</entry>
<entry>
<title>refactor: rework gloss-add UX to single side-window buffer</title>
<updated>2026-04-30T12:27:44+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-04-30T12:27:44+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/gloss/commit/?id=9e90517a98785c450cd13cd940bd1787a4771529'/>
<id>urn:sha1:9e90517a98785c450cd13cd940bd1787a4771529</id>
<content type='text'>
The previous shape opened a regular (non-side) buffer for body input
and showed the saved entry in the side window after C-c C-c. That
left an extra window split during the typing phase and a side popup
the user didn't ask for.

New shape, modeled on `org-capture':

- `gloss-add' renders the term and underline as a read-only header in
  *gloss-add: TERM*, leaves the body region beneath it editable, and
  pops the buffer in the side-window slot. Point lands at the body
  start so the user can type immediately.
- `gloss-add-finish' reads the body via the `gloss-add--body-start'
  marker, saves with source `manual', kills the buffer, closes the
  side window, and echoes `gloss-add: saved TERM' for confirmation.
- `gloss-add-abort' kills the buffer and closes the side window.
- The shared `gloss--add-cleanup' helper handles kill + window-close
  for both finish and abort.

Read-only header uses text properties (`read-only', `front-sticky',
`rear-nonsticky') rather than narrowing, so the user can't escape the
restriction with `C-x n w'.

`gloss--add-finish-internal' no longer calls show-entry — the save
is its only responsibility. The display decision (show or not) is
the caller's, which lets `gloss-add-finish' choose "save and close"
while `gloss-lookup' still chooses "save and show."

The previous saved-window-config approach is dropped — the side-slot
takeover means there's nothing to restore. Layout returns to its
pre-add state on either C-c C-c or C-c C-k.

Adds `tests/test-gloss--add-flow-smoke.el' covering the four
interactive moments (open, finish, abort, empty-term guard) plus the
read-only-header invariant. Updates the
`gloss--add-finish-internal' tests to drop the show-entry assertion.

129 tests pass in 0.27s.
</content>
</entry>
<entry>
<title>feat: implement gloss secondary commands</title>
<updated>2026-04-30T06:11:27+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-04-30T06:11:27+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/gloss/commit/?id=5c7bb207081278e41122e62d8f6c282a18574665'/>
<id>urn:sha1:5c7bb207081278e41122e62d8f6c282a18574665</id>
<content type='text'>
Five interactive commands plus the supporting major mode and pure
helpers for `gloss-add'.

`gloss-add' opens a `*gloss-add: TERM*' buffer in `gloss-add-mode',
a `text-mode' derivative with C-c C-c to save and C-c C-k to abort.
The pure save side, `gloss--add-finish-internal', validates term and
body, trims trailing whitespace, and delegates to `gloss-core-save'
with source `manual' before showing the new entry.

`gloss-edit' resolves a term to its source-buffer marker, jumps point
there, unfolds the entry under both the legacy `org-show-entry' and
the post-9.6 `org-fold-show-entry' (with-no-warnings on the fallback),
and installs `gloss--after-save-refresh-cache' as a buffer-local
after-save hook so manual edits keep the cache honest.

`gloss-list-terms' prompts via `completing-read' over
`gloss-core-list' and dispatches the chosen term to
`gloss--lookup-flow'. Empty glossary raises a user-error.

`gloss-stats' formats a multi-line report (total / by-source /
drill-tagged / file size / cache mtime) via the pure helper
`gloss--stats-text' and shows it in `*gloss-stats*' under
`special-mode'. Drill counting walks the file via `org-map-entries'
to be safe against tag-substring false positives.

`gloss-reload' is a thin wrapper that resets the in-memory cache and
re-ensures it from disk.

`gloss-drill-export' is a thin wrapper around
`gloss-drill-export-all'.

Audit fold-in: renamed the stats-text missing-file test from
`-reports-zero-and-never' to `-reports-zero' to match what the
assertion actually checks (the file is auto-created on first call,
so mtime is set, not "never").

Filed as a v1.1 follow-up: `gloss.el' reaches into
`gloss-core--cache-reset' and `gloss-core--cache-ensure'
double-dash-private functions. Decide whether to treat double-dash as
"package-private" idiom or to expose public aliases.

125 tests pass in 0.25s — 111 prior plus 14 new across the six new
files. No byte-compile warnings.
</content>
</entry>
<entry>
<title>test: add gloss secondary commands test suite (red phase)</title>
<updated>2026-04-30T06:07:44+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-04-30T06:07:44+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/gloss/commit/?id=d313c37f14511564849c70c564c14ca51bd4ae7c'/>
<id>urn:sha1:d313c37f14511564849c70c564c14ca51bd4ae7c</id>
<content type='text'>
Six test files for the remaining stub commands. All 14 tests fail at
this commit because the implementations are stubs.

`gloss--add-finish-internal' (the pure save side of `gloss-add') gets
N/B/E coverage on validation and the persistence side effect.
`gloss--stats-text' (the pure stats string formatter) covers empty,
populated, and missing-file cases. The interactive commands
(`gloss-edit', `gloss-list-terms', `gloss-reload', `gloss-drill-export')
get smoke tests only — the design treats them as mode-glue with 70%
coverage targets, since prompts and `switch-to-buffer' are framework
behaviour Emacs already tests.

Two error-path tests assert the message contains a specific substring,
not just that `user-error' was raised. The stubs raise `user-error' too,
so a bare `should-error' would pass for the wrong reason. The substring
check anchors red against the real error path.
</content>
</entry>
<entry>
<title>feat: implement gloss orchestration core (lookup + fetch-online)</title>
<updated>2026-04-30T06:04:47+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-04-30T06:04:47+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/gloss/commit/?id=eefd55510cf6b180a7dcc9be40fde894d9adf3ac'/>
<id>urn:sha1:eefd55510cf6b180a7dcc9be40fde894d9adf3ac</id>
<content type='text'>
Two pure-ish helpers and two interactive entry points.

`gloss--orchestrate-fetch-result' is a pure pattern-matcher that
classifies a fetch result into one of five decision symbols. The
ordering matters: definition count gates first, then the error
taxonomy. All-empty falls through to `:error-no-defs' so the user
never sees a silent no-op.

`gloss--lookup-flow' is the orchestration. Cache hit dispatches
straight to display. Cache miss runs a fetch, classifies via the
helper, and either auto-saves the lone definition, prompts the user
to pick, or messages the right error. The `force-fetch' arg lets
`gloss-fetch-online' reuse the same flow without duplicating logic.

`gloss-core-save' is called with the `replace' collision action so
force-fetch over an existing entry replaces it cleanly. On a real
cache miss the entry is fresh, so `replace' is moot — the action
only matters when the term is already there.

`gloss-lookup' and `gloss-fetch-online' are now thin interactive
wrappers around `gloss--lookup-flow'. The remaining stubs (add, edit,
list-terms, stats, reload, drill-export) still raise user-error.

111 tests pass in 0.23s — 98 prior plus 13 new across the two new
files.
</content>
</entry>
<entry>
<title>test: add gloss orchestration core test suite (red phase)</title>
<updated>2026-04-30T06:03:13+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-04-30T06:03:13+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/gloss/commit/?id=540d805bd917a37d0fafa5393f3bfc7e3603570e'/>
<id>urn:sha1:540d805bd917a37d0fafa5393f3bfc7e3603570e</id>
<content type='text'>
Two test files for the orchestration core. All 13 tests fail at this
commit because the implementation is still stubbed.

`gloss--orchestrate-fetch-result' gets full N/B/E coverage on the
decision matrix: single def, multi def, the &gt;1 boundary, empty defs
with each combination of :no-defs and :failed populated, and the
all-empty degenerate case.

`gloss--lookup-flow' covers cache hit (no fetch), cache miss with one
def (auto-save), cache miss with multiple (picker), cancelled picker
(no save), no-defs error, and the force-fetch override that bypasses
the cache. Mocks live at network and UI boundaries; persistence runs
against a real temp glossary so the save side effect is validated.
</content>
</entry>
</feed>
