Compare commits

..
Author SHA1 Message Date
yonluandClaude Opus 5.5 1997276def docs: cut CLAUDE.md to the rules it is for
CI / check (push) Skipped
CI / e2e (push) Skipped
CI / check (pull_request) Successful in 4m22s
CI / e2e (pull_request) Successful in 14m24s
CLAUDE.md had grown to 4,046 lines, ~3,300 of them per-component
write-ups: why a breakpoint is 500px, why a cap is a quarter, what a
spec once missed. Every session loaded all of it, and the rules that
apply to every change were buried among decisions that apply to one.

Those write-ups were already duplicated as comments beside the code
they describe -- every issue number they cite also appears in a code
comment -- so they are deleted rather than moved. What is left is the
tracker workflow, the commands, the verification tiers and a set of
broad engineering rules distilled from them, each pointing at where
its example lives. Three declined decisions recorded nowhere else go
to NOTES.md, and three code comments that cited CLAUDE.md sections by
name no longer do.

Closes #256

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 15:47:13 -04:00
13 changed files with 365 additions and 4018 deletions
+1 -1
View File
@@ -68,7 +68,7 @@ jobs:
SHA: ${{ github.sha }} SHA: ${{ github.sha }}
REF_NAME: ${{ github.ref_name }} REF_NAME: ${{ github.ref_name }}
DEBIAN_FRONTEND: noninteractive DEBIAN_FRONTEND: noninteractive
GO_VERSION: '1.26.0' GO_VERSION: '1.25.0'
npm_config_store_dir: /cache/pnpm-store npm_config_store_dir: /cache/pnpm-store
# The Go half wants the NDK; the Gradle half wants a platform. # The Go half wants the NDK; the Gradle half wants a platform.
ANDROID_HOME: /cache/android-sdk ANDROID_HOME: /cache/android-sdk
+2 -2
View File
@@ -36,7 +36,7 @@ concurrency:
cancel-in-progress: true cancel-in-progress: true
env: env:
GO_VERSION: '1.26.0' GO_VERSION: '1.25.0'
# Shared by all three Playwright consumers (@playwright/cli, e2e/'s # Shared by all three Playwright consumers (@playwright/cli, e2e/'s
# @playwright/test, frontend/'s Vitest provider). See the browsers # @playwright/test, frontend/'s Vitest provider). See the browsers
# step in job 2 for why that is not the whole story. # step in job 2 for why that is not the whole story.
@@ -53,7 +53,7 @@ jobs:
check: check:
runs-on: ubuntu-latest runs-on: ubuntu-latest
container: container:
# Not golang:1.26 — this job runs `make ui-test`, which is Vitest # Not golang:1.25 — this job runs `make ui-test`, which is Vitest
# *browser* mode and needs a Chromium and its system libraries # *browser* mode and needs a Chromium and its system libraries
# anyway, so the "fast job needs no browser" split does not hold. # anyway, so the "fast job needs no browser" split does not hold.
# Not the Playwright image either: e2e/ pins @playwright/test # Not the Playwright image either: e2e/ pins @playwright/test
+1 -1
View File
@@ -48,7 +48,7 @@ jobs:
SHA: ${{ github.sha }} SHA: ${{ github.sha }}
REF_NAME: ${{ github.ref_name }} REF_NAME: ${{ github.ref_name }}
DEBIAN_FRONTEND: noninteractive DEBIAN_FRONTEND: noninteractive
GO_VERSION: '1.26.0' GO_VERSION: '1.25.0'
npm_config_store_dir: /cache/pnpm-store npm_config_store_dir: /cache/pnpm-store
steps: steps:
# The same set ci.yml's check job installs: the app is cgo, and # The same set ci.yml's check job installs: the app is cgo, and
+1 -1
View File
@@ -68,7 +68,7 @@ jobs:
# claim with a test behind it now (cmd/indexbuild/deps_test.go), # claim with a test behind it now (cmd/indexbuild/deps_test.go),
# because the v3 migration quietly broke it and this job was where # because the v3 migration quietly broke it and this job was where
# that surfaced. # that surfaced.
image: golang:1.26 image: golang:1.25
# This host path must exist on the runner and be listed verbatim in # This host path must exist on the runner and be listed verbatim in
# act_runner's container.valid_volumes. It holds explore-staging/ # act_runner's container.valid_volumes. It holds explore-staging/
# (counts.bin + state.json) and yj.db — the checkpoint that makes # (counts.bin + state.json) and yj.db — the checkpoint that makes
+19
View File
@@ -5078,3 +5078,22 @@ last rendered card.
("ask the virtualizer for a larger overscan") is therefore not ("ask the virtualizer for a larger overscan") is therefore not
available without patching a private, which is why the request is available without patching a private, which is why the request is
issued ahead of the element instead. issued ahead of the element instead.
## Declined, and recorded nowhere else (2026-09-25, #256)
When CLAUDE.md was cut down to rules, most of its "considered and
declined" paragraphs already had a home in a code or config comment
beside what they explain. These three did not:
- **`touch-action: manipulation` was declined** (#54). The 300ms tap
delay it is offered for is already absent on a `width=device-width`
viewport; what it would actually change is the gesture stack #63 tuned
by measurement on the reference device.
- **There is no "Go to Genre"** in the phone row menu (#67). That menu
replaces name links a phone cannot use, and there has never been a
genre link to replace — it would be new navigation, which wants its
own issue.
- **The overlaid queue has no tap-outside gutter on a phone** (#171).
The drawer-style gutter would buy the affordance by taking width off a
full-screen surface on a 424px viewport; back and a 44px close button
answer it instead.
+331 -4001
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -13,7 +13,7 @@ frontend, bridged by [Wails v3](https://wails.io/).
| Tool | Version | | Tool | Version |
|------|---------| |------|---------|
| Go | 1.26+ | | Go | 1.25+ |
| Node.js | 22+ | | Node.js | 22+ |
| pnpm | 10+ | | pnpm | 10+ |
| Wails CLI | v3 — vendored, no install needed (`go tool wails3`) | | Wails CLI | v3 — vendored, no install needed (`go tool wails3`) |
+2 -2
View File
@@ -171,8 +171,8 @@ test.describe('search on a phone', () => {
// Attached, not visible: `wa-dialog`'s host is `display: contents`, // Attached, not visible: `wa-dialog`'s host is `display: contents`,
// so the element carrying the testid always reports hidden — what // so the element carrying the testid always reports hidden — what
// is visible is the native `<dialog>` inside it. That awkwardness // is visible is the native `<dialog>` inside it. That awkwardness
// is written down in CLAUDE.md and is why the assertion that this // is why the assertion that this is really up is the role query
// is really up is the role query below. // below.
await expect(dialog).toBeAttached(); await expect(dialog).toBeAttached();
// Named, which `getByRole` can answer and the a11y snapshot cannot // Named, which `getByRole` can answer and the a11y snapshot cannot
@@ -172,8 +172,7 @@ describe('<player-progress-line>', () => {
* The reason this component asks `matchMedia` instead of letting a * The reason this component asks `matchMedia` instead of letting a
* stylesheet hide it: a media query cannot stop a 1 Hz interval * stylesheet hide it: a media query cannot stop a 1 Hz interval
* running for the life of every desktop session. That claim is * running for the life of every desktop session. That claim is
* load-bearing in CLAUDE.md, so it is asserted rather than * load-bearing, so it is asserted rather than described — the timer count, because a desktop render is empty
* described — the timer count, because a desktop render is empty
* either way and so cannot tell the two apart. * either way and so cannot tell the two apart.
*/ */
it('runs no interpolation timer above the breakpoint', async () => { it('runs no interpolation timer above the breakpoint', async () => {
+2 -2
View File
@@ -1,6 +1,6 @@
module yellowjacket module yellowjacket
go 1.26 go 1.25.0
require ( require (
github.com/BurntSushi/toml v1.6.0 github.com/BurntSushi/toml v1.6.0
@@ -144,7 +144,7 @@ require (
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect
github.com/go-git/go-billy/v5 v5.9.0 // indirect github.com/go-git/go-billy/v5 v5.9.0 // indirect
github.com/go-git/go-git/v5 v5.19.2 // indirect github.com/go-git/go-git/v5 v5.19.2 // indirect
github.com/go-json-experiment/json v0.0.0-20260820222146-c27c302e5fc3 // indirect github.com/go-json-experiment/json v0.0.0-20251027170946-4849db3c2f7e // indirect
github.com/go-ole/go-ole v1.3.0 // indirect github.com/go-ole/go-ole v1.3.0 // indirect
github.com/go-resty/resty/v2 v2.17.1 // indirect github.com/go-resty/resty/v2 v2.17.1 // indirect
github.com/go-sql-driver/mysql v1.9.3 // indirect github.com/go-sql-driver/mysql v1.9.3 // indirect
+2 -2
View File
@@ -362,8 +362,8 @@ github.com/go-git/go-git/v5 v5.19.2/go.mod h1:QqCBE1EFN5ddFmrliLQ3/ntRCUjZU3EJuw
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-json-experiment/json v0.0.0-20260820222146-c27c302e5fc3 h1:UADEEmDKgfXbtnGJZ97beY5XLo9ZechG1nlU4KnRrkE= github.com/go-json-experiment/json v0.0.0-20251027170946-4849db3c2f7e h1:Lf/gRkoycfOBPa42vU2bbgPurFong6zXeFtPoxholzU=
github.com/go-json-experiment/json v0.0.0-20260820222146-c27c302e5fc3/go.mod h1:tphK2c80bpPhMOI4v6bIc2xWywPfbqi1Z06+RcrMkDg= github.com/go-json-experiment/json v0.0.0-20251027170946-4849db3c2f7e/go.mod h1:uNVvRXArCGbZ508SxYYTC5v1JWoz2voff5pm25jU1Ok=
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY=
+1 -2
View File
@@ -64,8 +64,7 @@ var frontendDistAssets embed.FS
// Returning early is not a degraded mode: `nativeInit` has already // Returning early is not a degraded mode: `nativeInit` has already
// re-attached the bridge, so the recreated activity's WebView talks to // re-attached the bridge, so the recreated activity's WebView talks to
// the app that is still running, with its queue and its playback // the app that is still running, with its queue and its playback
// position intact. See CLAUDE.md, "An activity is a view onto the // position intact.
// process".
// //
// It is inert off Android, where a process has exactly one main(). // It is inert off Android, where a process has exactly one main().
var mainStarted atomic.Bool var mainStarted atomic.Bool
+1 -1
View File
@@ -18,7 +18,7 @@ arch=('x86_64')
url="https://git.ljones.me/yonlu/yellowjacket" url="https://git.ljones.me/yonlu/yellowjacket"
license=('custom') license=('custom')
depends=('webkitgtk-6.0' 'gtk4' 'alsa-lib' 'hicolor-icon-theme') depends=('webkitgtk-6.0' 'gtk4' 'alsa-lib' 'hicolor-icon-theme')
makedepends=('go>=1.26' 'nodejs>=22' 'pnpm' 'git') makedepends=('go>=1.25' 'nodejs>=22' 'pnpm' 'git')
options=('!lto') options=('!lto')
# Source is overridable so the same PKGBUILD works two ways: # Source is overridable so the same PKGBUILD works two ways: