RuleStack

Configs

Stacks

Compare

Diff

RuleStack

Configs

Stacks

Compare

Diff

Read API

RuleStack

Configs

Stacks

Compare

Diff

Read API

Diff/photoprism-photoprism-claude-claude ↔ photoprism-photoprism-agents

Comparison

A · CLAUDE.md · photoprism/photoprismB · AGENTS.md · photoprism/photoprism
What each file covers, counted
DimensionSharedOnly in AOnly in BOverlap
Sections113153%
Commands14261625%
Section tags83453%

What each file covers

Sections

1 shared · 13 only in A · 15 only in B
  • − CLAUDE.md
  • − Build Commands
  • − Testing
  • − Formatting & Linting
  • − Schema Migrations
  • − or via Makefile:
  • − Architecture Overview
  • − Backend (`internal/`, `pkg/`, `cmd/`)
  • − Frontend (`frontend/`)
  • − API Conventions
  • − Config & Flags
  • − Verify Before Propagating
  • − Detailed Rules
  • + PhotoPrism Repository Guidelines
  • + Purpose
  • + Sources of Truth
  • + Subtree Guides
  • + Local Agent Progress
  • + Style Notes
  • + Commit Messages
  • + GitHub Issues
  • + Specifications & Documentation
  • + Safety & Data
  • + Project Layout & Shared Rules
  • + JS/Go Code Comments
  • + Agent Runtime
  • + Build, Format & Test
  • + Container Image Builds
  •   Continuous Integration

Commands

14 shared · 26 only in A · 16 only in B
  • − go test ./internal/api -run 'TestFunctionName' -count=1
  • − go test ./internal/photoprism -run 'TestMediaFile_' -count=1
  • − go test ./internal/entity/... -count=1 -tags="slow,develop"
  • − go run cmd/photoprism/photoprism.go migrations ls
  • − go run cmd/photoprism/photoprism.go migrations run
  • − make migrate
  • − make build-all
  • − go build ./...
  • − make dep-js
  • − make test-go
  • − make test-js
  • − make test-short
  • − make vitest-watch
  • − make vitest-coverage
  • − make reset-testdb
  • − make test-pkg
  • − make test-api
  • − make test-entity
  • − make test-commands
  • − make test-photoprism
  • − make test-ai
  • − make fmt
  • − make fmt-js
  • − make fmt-swag
  • − make swag
  • − make lint-go
  • + make notice
  • + git status
  • + git config
  • + npm exec --yes <agent> -- --help
  • + npx <agent> ...
  • + npm install
  • + make
  • + docker compose up -d
  • + docker compose logs -f --tail=100 photoprism
  • + docker compose exec photoprism ./photoprism help
  • + docker compose exec -u "$(id -u):$(id -g)" photoprism <command>
  • + docker compose --profile=all down --remove-orphans
  • + make down
  • + make lint
  • + make check-make-help
  • + go test ./path/to/pkg -run Name -count=1
  •   make help
  •   make list
  •   make build-go
  •   make build-js
  •   make watch-js
  •   make dep
  •   npm ci
  •   npm rebuild --ignore-scripts=false <pkg>
  •   npm rebuild
  •   make docker-build
  •   docker compose up
  •   make terminal
  •   make test
  •   make fmt-go

Section tags

8 shared · 3 only in A · 4 only in B
  • − types
  • − database
  • − api
  • + setup
  • + testing-strategy
  • + security
  • + docs
  •   build
  •   test
  •   lint-format
  •   code-style
  •   architecture
  •   git-pr
  •   do-not
  •   agent-behaviour

Line diff

+143 added−120 removed37 unchanged20.6% identical
photoprism/photoprism · .claude/CLAUDE.md
@@ −1 @@
1# CLAUDE.md
2 
3This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. Detailed rules are in `.claude/rules/*.md` files organized by topic.
4 
5## Build Commands
6 
7Run `make help` for an overview of the most common targets, and `make list` to list all of them. Key commands:
8 
9**Backend (Go):**
10- `make build-go` — build the `photoprism` binary (develop mode)
11- `make build-all` — build backend + frontend
12- `go build ./...` — compile all Go packages
13 
14**Frontend (Vue 3):**
15- `make build-js` — production build of the frontend
16- `make watch-js` — watch mode for frontend development (Ctrl+C to stop)
 
 
 
 
 
 
 
 
 
17 
18**Dependencies:**
19- `make dep` — install all dependencies (TensorFlow models, ONNX models, JS packages)
20- `make dep-js` — install JS dependencies only (`npm ci`). The `photoprism/develop` image and the repo `Makefile` both set `NPM_CONFIG_IGNORE_SCRIPTS=true`, so install scripts are skipped automatically; when running npm directly in an env without that default, pass `--ignore-scripts`. Rebuild native addons with `npm rebuild --ignore-scripts=false <pkg>` — a bare `npm rebuild` no-ops wherever the env default is active.
21 
22**Docker dev environment:**
23- `make docker-build` — build local Docker image
24- `docker compose up` — start dev environment (app at http://localhost:2342/)
25- `make terminal` — open shell in dev container
 
 
 
 
26 
27## Testing
28 
29**Run all tests:**
30- `make test` — runs both JS and Go tests
31- `make test-go` — all Go tests (slow, ~20 min)
32- `make test-js` — frontend unit tests (Vitest)
33- `make test-short` — short Go tests in parallel (~5 min)
34 
35**Run targeted Go tests:**
36```bash
37go test ./internal/api -run 'TestFunctionName' -count=1
38go test ./internal/photoprism -run 'TestMediaFile_' -count=1
39go test ./internal/entity/... -count=1 -tags="slow,develop"
40```
41 
42**Run targeted JS tests:**
43- `make vitest-watch` — Vitest in watch mode
44- `make vitest-coverage` — Vitest with coverage report
45 
46**Reset test databases before running Go tests:**
47- `make reset-testdb` — clears SQLite test DBs and MariaDB testdb
48 
49**Subset targets:** `make test-pkg`, `make test-api`, `make test-entity`, `make test-commands`, `make test-photoprism`, `make test-ai`
 
 
50 
51## Formatting & Linting
52 
53Available targets: `make fmt` (everything), `make fmt-go`, `make fmt-js`, `make fmt-swag` / `make swag` (Swagger), `make lint-go`, `make lint-js`. Detailed conventions live in `.claude/rules/go-code-style.md` and `.claude/rules/frontend-rules.md`.
 
 
 
 
 
 
 
 
 
54 
55When creating or editing shell scripts, run `shellcheck <file>` and resolve warnings. When editing Markdown files that contain tables, format them with `npx --yes markdown-table-formatter <filename>`.
56 
57The curated `make help` overviews are maintained by hand in a `HELP_TEXT` block per Makefile. After renaming or removing a target, run `make check-make-help` (also part of `make lint`) to confirm that no overview still advertises it.
 
 
 
 
 
 
 
58 
59## Continuous Integration
 
 
 
 
 
 
60 
61**GitHub Actions is not enabled for this repository.** The workflow files under `.github/workflows/` do not execute, so pushes and pull requests produce no check runs. Treat them as dormant configuration: do not diagnose the absence of runs as a broken workflow, do not propose enabling Actions, and do not add workflows or bot configuration that assumes they will run. Ask a maintainer before changing anything under `.github/workflows/`.
62 
63The `make` targets above are the authoritative build, format, and test gate — run them locally and report the output rather than relying on a hosted runner.
 
 
 
 
 
 
 
64 
65## Schema Migrations
66 
67If a change touches database schema, check migrations:
68```bash
69go run cmd/photoprism/photoprism.go migrations ls
70go run cmd/photoprism/photoprism.go migrations run
71# or via Makefile:
72make migrate
73```
 
 
 
 
 
 
 
 
 
 
74 
75Migration files live in `internal/entity/migrate/`.
76 
77## Architecture Overview
 
 
 
78 
79PhotoPrism is a self-hosted photo management app. The backend is Go, the frontend is Vue 3 + Vuetify 3, and the database is MariaDB or SQLite (via GORM).
80 
81### Backend (`internal/`, `pkg/`, `cmd/`)
82 
83| Package | Purpose |
84|-------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
85| `internal/photoprism` | **Core application logic**: indexing originals, metadata extraction, thumbnail generation, import/stacking, converter orchestration (FFmpeg/ImageMagick/ExifTool). Entry point for workers and CLI. |
86| `internal/entity` | **Database models** (GORM): Photo, File, Album, Label, Face, User, Session, etc. Contains fixtures for tests and migration helpers. |
87| `internal/entity/query` | Database query helpers used by the API and core packages. |
88| `internal/api` | **REST API handlers** (Gin): thin handlers that validate input, enforce ACL/auth, delegate to services. Annotated with Swagger comments. |
89| `internal/server` | HTTP server setup, routing (Gin engine), WebDAV, static assets, middleware wiring. Routes are registered in `routes.go`. |
90| `internal/config` | Application configuration: CLI flags, env vars, client config sent to the frontend. |
91| `internal/workers` | Background workers: indexing scheduler, metadata sync, sharing, backup, vision jobs. |
92| `internal/commands` | CLI command implementations (`github.com/urfave/cli/v2`). |
93| `internal/auth` | Authentication: ACL (`auth/acl`), JWT (`auth/jwt`), OIDC (`auth/oidc`), session management. |
94| `internal/form` | Request form/binding structs for the API layer. |
95| `internal/meta` | Metadata extraction from EXIF, XMP, JSON sidecars. |
96| `internal/ffmpeg` | FFmpeg/transcoding helpers. |
97| `internal/thumb` | Thumbnail generation helpers. |
98| `internal/ai` | AI/vision model integration (TensorFlow, ONNX). |
99| `internal/service` | Services: maps geocoding, hub (membership), cluster, WebDAV client, CIDR helpers. |
100| `internal/event` | Event bus for structured logging and audit events. |
101| `pkg/` | Standalone, reusable packages: `fs`, `geo`, `media`, `txt`, `clean`, `rnd`, `i18n`, `http`, `time`, etc. No dependency on `internal/`. |
102 
103**Request flow:** HTTP request → Gin middleware (auth, rate limiting) → `internal/api` handler → `internal/photoprism` or `internal/entity` → response.
104 
105**Audit logging convention** (`event.AuditInfo/Warn/Err`): slices must follow the pattern **Who → What → Outcome**:
106- Who: `ClientIP(c)` + actor context (`"session %s"`, `"user %s"`)
107- What: resource constant + action segments
108- Outcome: single token like `status.Succeeded`, `status.Failed`, `status.Denied`, `status.Error(err)`
 
 
 
109 
110### Frontend (`frontend/`)
111 
112Vue 3 app using the Options API and Vuetify 3.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
113 
114| Directory | Purpose |
115|---------------------------|-------------------------------------------------------------------------------------------------|
116| `frontend/src/model/` | Client-side models mirroring API responses (Photo, Album, File, User, etc.) |
117| `frontend/src/app/` | App bootstrap, routing (`routes.js`), and the `$session` reactive singleton |
118| `frontend/src/page/` | Page-level components |
119| `frontend/src/component/` | Reusable UI components |
120| `frontend/src/common/` | Shared utilities, the API client (`$api`), and reactive singletons (`$config`, `$view`, `$log`) |
121| `frontend/src/locales/` | i18n translation files |
122| `frontend/tests/` | Vitest unit tests + TestCafe acceptance tests |
 
123 
124State management uses reactive singleton modules in `src/common/` and `src/app/`, not Vuex or Pinia. Frontend code-style, formatting, testing, translation, and Playwright rules live in `.claude/rules/frontend-rules.md`.
125 
126### API Conventions
 
127 
128- REST API v1 base path: `/api/v1/` (configured via `conf.BaseUri()`)
129- Authentication: Bearer token (`Authorization` header) or `X-Auth-Token` header
130- Pagination: `count`, `offset`, `limit` parameters (default 100, max 1000)
131- After adding/changing API handlers, regenerate Swagger docs: `make fmt-go swag-fmt swag`
132- New routes must be registered in `internal/server/routes.go`
133 
134### Config & Flags
135 
136Verify config option names before using them:
137```bash
138./photoprism --help
139./photoprism show config-options
140./photoprism show config-yaml
141```
142 
143### Verify Before Propagating
144 
145Before promoting a claim from `CLAUDE.md`, `AGENTS.md`, a memory entry, or another spec into a new rule, spec, code comment, or commit message, verify it against the current code (grep imports, list directories, read the cited file). Stale documentation silently turns into stale rules and stale specs that future sessions will trust. When the claim names a package, function, file, or framework, the cost of one grep is much smaller than the cost of repeating an error across multiple files.
146 
147### Detailed Rules
148 
149Topic-specific conventions live under `.claude/rules/` and are loaded alongside this file:
150 
151- `code-comments.md` — shared JS/Go doc comment rules (length cap, what to omit); referenced by both style files.
152- `go-code-style.md`, `go-testing.md` — Go style, package boundaries, test patterns, fixtures.
153- `frontend-rules.md` — JS/Vue code style, formatting, dependencies, tests, Playwright, translations.
154- `commit-and-docs-style.md` — commit-message format, GitHub issue templates, spec heading style.
155- `safety-and-security.md` — Git/data safety, destructive commands, file I/O and archive-extraction policies, HTTP download helpers.
156- `api-and-config.md`, `cluster-operations.md`, `import-index-download.md`, `build-and-runtime.md`, `sources-of-truth.md` — domain-specific guidance.
157 
photoprism/photoprism · AGENTS.md
@@ +1 @@
1# PhotoPrism Repository Guidelines
2 
3**Last Updated:** July 28, 2026
4 
5## Purpose
6 
7Entry point for agents and humans.
8 
9## Sources of Truth
 
 
 
10 
11- Makefile: https://github.com/photoprism/photoprism/blob/develop/Makefile
12- Setup guide: https://docs.photoprism.app/developer-guide/setup/
13- Test guide: https://docs.photoprism.app/developer-guide/tests/
14- Contributing: https://github.com/photoprism/photoprism/blob/develop/CONTRIBUTING.md
15- Security: https://github.com/photoprism/photoprism/blob/develop/SECURITY.md
16- REST API: https://docs.photoprism.dev/ and https://docs.photoprism.app/developer-guide/api/
17- Code maps: [`CODEMAP.md`](CODEMAP.md), [`frontend/CODEMAP.md`](frontend/CODEMAP.md)
18- Package docs: `README.md` files under `internal/`, `pkg/`, `frontend/`, and `frontend/src/`
19- Frontend dependency pins, override layer, and orphan-audit pattern: [`frontend/README.md`](frontend/README.md) (read before bumping any non-caret pin or adding/removing a top-level dep)
20- AI/Vision docs: [`internal/ai/face/README.md`](internal/ai/face/README.md), [`internal/ai/vision/README.md`](internal/ai/vision/README.md), [`internal/ai/vision/openai/README.md`](internal/ai/vision/openai/README.md), [`internal/ai/vision/ollama/README.md`](internal/ai/vision/ollama/README.md)
21- Glossary: [`GLOSSARY.md`](GLOSSARY.md)
22- When dependencies change, regenerate `NOTICE` files with `make notice`; do not edit `NOTICE` or `frontend/NOTICE` manually.
23 
24## Subtree Guides
 
 
25 
26- [`internal/AGENTS.md`](internal/AGENTS.md): internal Go rules.
27- [`internal/api/AGENTS.md`](internal/api/AGENTS.md): API rules.
28- [`internal/config/AGENTS.md`](internal/config/AGENTS.md): config rules.
29- [`internal/commands/AGENTS.md`](internal/commands/AGENTS.md): CLI rules.
30- [`internal/photoprism/AGENTS.md`](internal/photoprism/AGENTS.md): import and index rules.
31- [`internal/service/cluster/AGENTS.md`](internal/service/cluster/AGENTS.md): cluster rules.
32- [`frontend/AGENTS.md`](frontend/AGENTS.md): frontend rules.
33- [`pkg/AGENTS.md`](pkg/AGENTS.md): `pkg/*` security and test rules.
34 
35Optional nested repositories such as `plus/`, `pro/`, `portal/`, and `specs/` may contain their own `AGENTS.md` files. When present, treat those files as additional directory-local guidance.
36 
37## Local Agent Progress
 
 
 
 
38 
39- Use `.agents/TODO.md` for actionable tasks and `.agents/DONE.md` for completed work.
40- These files are local workflow aids and may not exist in every workspace.
 
 
 
 
41 
42## Style Notes
 
 
43 
44### Commit Messages
 
45 
46- Use concise imperative subjects with a one-word prefix, for example `Config: Add tests for "darktable-cli" path detection`.
47- Append issue or PR IDs when relevant.
48- Commit messages must not exceed 80 characters.
49 
50### GitHub Issues
51 
52- Titles MUST be concise, imperative, and start with one capitalized prefix plus `: `, for example `Search: Add filter for RAW image formats`.
53- Descriptions MUST begin with a one-sentence bold user story: `**As a <role>, I want <goal>, so that <outcome>.**`
54- Use level-3 Markdown headings for sections within issue descriptions, for example `### Acceptance Criteria`.
55- Follow with behavior, rationale, technical considerations, and constraints.
56- End with `- [ ]` checklist items for the acceptance criteria, each using `MUST`, `SHOULD`, or `MAY`.
57 - Keep the checklist current: once the work for a criterion is implemented **and verified**, mark it done (`- [x]`).
58 - Leave items that are unverified, not yet implemented, or skipped optional (`MAY`) enhancements unchecked.
59 - An issue is complete only when every `MUST` is checked; never tick a box on the strength of a plan alone or an unrun test.
60 - When referencing an issue from a commit that fulfills some of its criteria, update the matching boxes first.
61- Agents MUST create, edit, close, reopen, relabel, or otherwise modify GitHub issues only when explicitly requested by the user.
62 
63### Specifications & Documentation
64 
65- Markdown headings use a Chicago-style title case, with additional code- and path-aware normalization rules (see *Title Case rules* below). Always spell the product name as `PhotoPrism`.
66- Put option flags before positional arguments unless the command requires another order.
67- Use RFC 3339 UTC timestamps and valid ID, UID, and UUID examples in docs and tests.
68- The nested `specs/` repository may be absent. Do not add main-repo `Makefile` targets that depend on it; when present, you may run its tools manually.
69- Testing guides live at `specs/dev/backend-testing.md` and `specs/dev/frontend-testing.md`.
70- Do not read, analyze, or modify `specs/generated/`; refer humans to `specs/generated/README.md` when regeneration is needed.
71- Refresh `**Last Updated:**` when you change document contents, but leave it unchanged for whitespace-only or formatting-only edits.
72- Nested Git repositories may appear ignored; change into them before staging or committing updates.
73 
74Title Case rules (Chicago-style, with code- and path-aware normalization):
75- Capitalize the first word, the first word after a colon, dash, or end punctuation, and all major words, including the second part of a hyphenated major word.
76- Lowercase only articles, short conjunctions, and short prepositions of three letters or fewer when they are not in one of those positions.
77- Preserve known acronyms (for example, API, CLI, HTTP, JSON) and slash-separated acronym groups (for example, CSV/TSV) as uppercase.
78- Preserve RFC 2119 / RFC 8174 normative keywords (MUST, SHOULD, MAY, SHALL, REQUIRED, RECOMMENDED, OPTIONAL) as uppercase when used in their normative sense.
79- Preserve inline code spans (`` `foo` ``), file paths (e.g. `docs/foo-bar.md`), and slash commands (e.g. `/grill-me`) verbatim; do not recase their contents.
80- Use `&` instead of `And`/`Or` in headings.
81 
82## Safety & Data
83 
84- If `git status` shows unexpected changes, assume a human may be editing; ask before using reset-style commands.
85- Do not run `git config` at either the global or repository level.
86- Do not run destructive commands against production data; prefer ephemeral volumes and test fixtures for acceptance tests.
87- Never commit secrets, local configurations, or cache files; use environment variables or a local `.env`.
88- Ensure `.env`, `.config`, `.local`, `.codex`, and `.gocache` are ignored in `.gitignore` and `.dockerignore`.
89- Prefer existing caches, workers, and batching strategies already referenced by the code and `Makefile`.
90- Consider CPU and memory impact; only suggest profiling or benchmarks when justified.
91- If anything here conflicts with the `Makefile` or the sources of truth, ask for clarification before proceeding.
92 
93## Project Layout & Shared Rules
94 
95- Backend: Go in `internal/`, `pkg/`, and `cmd/`, backed by MariaDB or SQLite.
96- Frontend: Vue 3 plus Vuetify 3 under `frontend/`.
97- Local dev and CI use Docker Compose; Traefik provides local TLS via `*.localssl.dev`.
98- Code in `pkg/*` must not import from `internal/*`. If you need config, entity, or DB access, add code under `internal/`.
99- Shared Go rules:
100 - After Go edits, run `make fmt-go` and keep `gofmt` tab indentation.
101 - Every added/modified Go function, including unexported helpers, must have focused test coverage in the corresponding `*_test.go` files; update existing tests or add new ones as needed.
102 - Every Go package must contain a root `<package>.go` file with the standard license header and a short package description comment.
103 - Use `pkg/fs` permission constants: `fs.ModeDir`, `fs.ModeFile`, `fs.ModeConfigFile`, `fs.ModeSecretFile`, and `fs.ModeBackupFile`.
104 - When importing the stdlib `io/fs`, alias it to avoid collisions, for example `iofs "io/fs"` or `gofs "io/fs"`.
105 - Do not pass stdlib `io/fs` mode flags where permission bits are expected.
106 - Prefer `filepath.Join` for filesystem paths and `path.Join` only for URL paths.
107 - Normalize slash-based logical paths stored in DB, config, or API payloads with `clean.SlashPath(...)`.
108- Shared JS/Vue rules:
109 - Added/modified JavaScript functions, including helpers, should be tested whenever practical; update existing tests or add new ones as needed.
110 - Added/modified Vue components should have component-test coverage, and existing component tests should be updated as needed when behavior changes.
111- When adding a metadata source such as `SrcOllama` or `SrcOpenAI`, update both `internal/entity/src.go` and `frontend/src/common/util.js` so backend and UI stay aligned.
112 
113### JS/Go Code Comments
114 
115A doc comment is **required** for every function (including unexported helpers), as well as for every non-trivial Vue `methods:` / `computed:` / watcher:
116- Keep comments **compact** and default to one line for "what" in the format `// Name does X.`. Skip trivial getters (`isOpen: () => this.open`).
117- Add 1-2 follow-up lines (`// …`) **only** if the "why" is non-obvious: a hidden invariant, a workaround that would otherwise be undone by a future cleanup, a contract a reader can't infer from the code. If readers can infer the "why" from the function body or a nearby line, then omit it.
118- Multi-paragraph explanations belong in `specs/`, package `README.md` files, or GitHub issues — never in the source itself.
119 
120Doc comments for packages and exported identifiers must be complete sentences that begin with the name of the thing being described and end with a period. For short examples in comments, indent code instead of using backticks.
121 
122Use US English spelling in all code comments (`parameterized`, `behavior`, `color`, `serialize`, `normalize`, `optimize`, …) — not the British `-ised`/`-our`/`-re` variants.
123 
124> **Don't include in code comments:** Issue / PR numbers, "previously…" history, alternatives considered, what the function used to do, references to old commits, names of subsequent reviewers, or any narrative that names the change rather than the steady-state behavior. That context belongs in commit messages, specs, or handover notes.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
125 
126## Agent Runtime
127 
128- Detect container mode by checking for `/.dockerenv`.
129- If the repo path is `/go/src/github.com/photoprism/photoprism` and `/.dockerenv` is absent, treat the environment as host mode with a bind mount and prefer host-side Docker commands.
130- Bash check: `[ -f "/.dockerenv" ] && echo container || echo host`
131- Node.js check: `require("fs").existsSync("/.dockerenv")`
132- Inside the container, prefer `npm exec --yes <agent> -- --help` or `npx <agent> ...`; if a global npm install is unavoidable, install it only inside the container.
133- The `photoprism/develop` base image and the repo `Makefile` both set `NPM_CONFIG_IGNORE_SCRIPTS=true`, so `npm ci`/`npm install` via `make` targets skip install scripts out of the box. When running npm directly in an environment that does not set or inherit that default, pass `--ignore-scripts` explicitly to mitigate supply-chain attacks. Rebuild native addons with `npm rebuild --ignore-scripts=false <pkg>` — a bare `npm rebuild` is a silent no-op wherever the env default is active.
134- On the host, use the vendor-recommended install method and run from the repository root so agent discovery sees this file.
135 
136## Build, Format & Test
137 
138- Run `make help` for an overview of the most common targets, and `make list` to see all of them.
139- Host mode:
140 - `make docker-build`
141 - `docker compose up` or `docker compose up -d`
142 - `docker compose logs -f --tail=100 photoprism`
143 - `docker compose exec photoprism ./photoprism help`
144 - `docker compose exec -u "$(id -u):$(id -g)" photoprism <command>` to avoid root-owned files
145 - `make terminal`
146 - `docker compose --profile=all down --remove-orphans` or `make down`
147- Container mode:
148 - `make dep`
149 - `make build-js` and `make build-go`
150 - `make watch-js` or `cd frontend && npm run watch`
151 - `./photoprism start`
152 - Local URLs: `http://localhost:2342/` and, with Traefik, `https://app.localssl.dev/`
153 - Local compose defaults to `admin` / `photoprism`; inspect `compose.yaml` if they differ.
154 - Do not use the Docker CLI inside the container; manage Compose from the host instead.
155- The public CLI name is always `photoprism`; development-only side-by-side binaries may use edition-specific names.
156- Our command examples assume a Linux or Unix shell on 64-bit AMD64 or ARM64; see the Developer Guide FAQ for Windows-specific notes.
157 
158Formatting and test entry points:
159- Full suite: `make test`, `make lint`
160- After renaming or removing a Makefile target, run `make check-make-help` (also included in `make lint`) so that no `make help` overview keeps advertising it.
161- Go-specific lint, format, and package-test rules live in [`internal/AGENTS.md`](internal/AGENTS.md).
162- Frontend lint, Vitest, acceptance, and Playwright rules live in [`frontend/AGENTS.md`](frontend/AGENTS.md).
163- Go tests live next to their sources; use PascalCase `t.Run(...)` names for related subtests. Keep consecutive subtests inside the same `Test*` function back-to-back without blank lines so the cases read as a compact table; reserve blank lines for separating distinct setup blocks.
164- Do not run multiple test commands in parallel; suites share fixtures, assets, and database state.
165- Prefer focused test runs such as `go test ./path/to/pkg -run Name -count=1` while iterating.
166- Use `mariadb -D photoprism` inside the dev shell when you need to inspect MariaDB state directly.
167- Run `shellcheck <file>` on edited shell scripts, or use the corresponding `make` target.
168 
169### Continuous Integration
170 
171- **GitHub Actions is not enabled for this repository.** The workflow files under `.github/workflows/` do not execute, so pushes and pull requests produce no check runs. Treat them as dormant configuration: do not diagnose the absence of runs as a broken workflow, do not propose enabling Actions, and do not add workflows or bot configuration that assumes they will run. Ask a maintainer before changing anything under `.github/workflows/`.
172- The `make` targets above are the authoritative build, format, and test gate. Run them locally and report the output rather than relying on a hosted runner.
173 
174### Container Image Builds
 
 
 
 
175 
176- **Never mix Debian and Ubuntu `apt` repositories in the same image:**
177 - Don't add a Debian source to an Ubuntu base (or vice versa) to install a single missing package — the transitive deps drift, apt's solver pulls newer libraries from the foreign distro, and other build steps in the same `RUN` (e.g. `install-libheif.sh` running `apt-get install libavcodec-dev`) silently link against the wrong soname.
178 - Symptoms surface much later as `dlopen: libfoo.so.N: cannot open shared object file` at image runtime, with the binary referencing a soname that exists only in the foreign distro.
179 - If a package isn't available in the host distro's repos, prefer (a) a same-distro PPA / backports source, (b) a vendor-supplied .deb (e.g. Google Chrome from `dl.google.com`), or (c) a from-source build pinned to a known version.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
180 
@@ −1 +1 @@
1−# CLAUDE.md
1+# PhotoPrism Repository Guidelines
22  
3−This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. Detailed rules are in `.claude/rules/*.md` files organized by topic.
3+**Last Updated:** July 28, 2026
44  
5−## Build Commands
5+## Purpose
66  
7−Run `make help` for an overview of the most common targets, and `make list` to list all of them. Key commands:
7+Entry point for agents and humans.
88  
9−**Backend (Go):**
10−- `make build-go` — build the `photoprism` binary (develop mode)
11−- `make build-all` — build backend + frontend
12−- `go build ./...` — compile all Go packages
9+## Sources of Truth
1310  
14−**Frontend (Vue 3):**
15−- `make build-js` — production build of the frontend
16−- `make watch-js` — watch mode for frontend development (Ctrl+C to stop)
11+- Makefile: https://github.com/photoprism/photoprism/blob/develop/Makefile
12+- Setup guide: https://docs.photoprism.app/developer-guide/setup/
13+- Test guide: https://docs.photoprism.app/developer-guide/tests/
14+- Contributing: https://github.com/photoprism/photoprism/blob/develop/CONTRIBUTING.md
15+- Security: https://github.com/photoprism/photoprism/blob/develop/SECURITY.md
16+- REST API: https://docs.photoprism.dev/ and https://docs.photoprism.app/developer-guide/api/
17+- Code maps: [`CODEMAP.md`](CODEMAP.md), [`frontend/CODEMAP.md`](frontend/CODEMAP.md)
18+- Package docs: `README.md` files under `internal/`, `pkg/`, `frontend/`, and `frontend/src/`
19+- Frontend dependency pins, override layer, and orphan-audit pattern: [`frontend/README.md`](frontend/README.md) (read before bumping any non-caret pin or adding/removing a top-level dep)
20+- AI/Vision docs: [`internal/ai/face/README.md`](internal/ai/face/README.md), [`internal/ai/vision/README.md`](internal/ai/vision/README.md), [`internal/ai/vision/openai/README.md`](internal/ai/vision/openai/README.md), [`internal/ai/vision/ollama/README.md`](internal/ai/vision/ollama/README.md)
21+- Glossary: [`GLOSSARY.md`](GLOSSARY.md)
22+- When dependencies change, regenerate `NOTICE` files with `make notice`; do not edit `NOTICE` or `frontend/NOTICE` manually.
1723  
18−**Dependencies:**
19−- `make dep` — install all dependencies (TensorFlow models, ONNX models, JS packages)
20−- `make dep-js` — install JS dependencies only (`npm ci`). The `photoprism/develop` image and the repo `Makefile` both set `NPM_CONFIG_IGNORE_SCRIPTS=true`, so install scripts are skipped automatically; when running npm directly in an env without that default, pass `--ignore-scripts`. Rebuild native addons with `npm rebuild --ignore-scripts=false <pkg>` — a bare `npm rebuild` no-ops wherever the env default is active.
24+## Subtree Guides
2125  
22−**Docker dev environment:**
23−- `make docker-build` — build local Docker image
24−- `docker compose up` — start dev environment (app at http://localhost:2342/)
25−- `make terminal` — open shell in dev container
26+- [`internal/AGENTS.md`](internal/AGENTS.md): internal Go rules.
27+- [`internal/api/AGENTS.md`](internal/api/AGENTS.md): API rules.
28+- [`internal/config/AGENTS.md`](internal/config/AGENTS.md): config rules.
29+- [`internal/commands/AGENTS.md`](internal/commands/AGENTS.md): CLI rules.
30+- [`internal/photoprism/AGENTS.md`](internal/photoprism/AGENTS.md): import and index rules.
31+- [`internal/service/cluster/AGENTS.md`](internal/service/cluster/AGENTS.md): cluster rules.
32+- [`frontend/AGENTS.md`](frontend/AGENTS.md): frontend rules.
33+- [`pkg/AGENTS.md`](pkg/AGENTS.md): `pkg/*` security and test rules.
2634  
27−## Testing
35+Optional nested repositories such as `plus/`, `pro/`, `portal/`, and `specs/` may contain their own `AGENTS.md` files. When present, treat those files as additional directory-local guidance.
2836  
29−**Run all tests:**
30−- `make test` — runs both JS and Go tests
31−- `make test-go` — all Go tests (slow, ~20 min)
32−- `make test-js` — frontend unit tests (Vitest)
33−- `make test-short` — short Go tests in parallel (~5 min)
37+## Local Agent Progress
3438  
35−**Run targeted Go tests:**
36−```bash
37−go test ./internal/api -run 'TestFunctionName' -count=1
38−go test ./internal/photoprism -run 'TestMediaFile_' -count=1
39−go test ./internal/entity/... -count=1 -tags="slow,develop"
40−```
39+- Use `.agents/TODO.md` for actionable tasks and `.agents/DONE.md` for completed work.
40+- These files are local workflow aids and may not exist in every workspace.
4141  
42−**Run targeted JS tests:**
43−- `make vitest-watch` — Vitest in watch mode
44−- `make vitest-coverage` — Vitest with coverage report
42+## Style Notes
4543  
46−**Reset test databases before running Go tests:**
47−- `make reset-testdb` — clears SQLite test DBs and MariaDB testdb
44+### Commit Messages
4845  
49−**Subset targets:** `make test-pkg`, `make test-api`, `make test-entity`, `make test-commands`, `make test-photoprism`, `make test-ai`
46+- Use concise imperative subjects with a one-word prefix, for example `Config: Add tests for "darktable-cli" path detection`.
47+- Append issue or PR IDs when relevant.
48+- Commit messages must not exceed 80 characters.
5049  
51−## Formatting & Linting
50+### GitHub Issues
5251  
53−Available targets: `make fmt` (everything), `make fmt-go`, `make fmt-js`, `make fmt-swag` / `make swag` (Swagger), `make lint-go`, `make lint-js`. Detailed conventions live in `.claude/rules/go-code-style.md` and `.claude/rules/frontend-rules.md`.
52+- Titles MUST be concise, imperative, and start with one capitalized prefix plus `: `, for example `Search: Add filter for RAW image formats`.
53+- Descriptions MUST begin with a one-sentence bold user story: `**As a <role>, I want <goal>, so that <outcome>.**`
54+- Use level-3 Markdown headings for sections within issue descriptions, for example `### Acceptance Criteria`.
55+- Follow with behavior, rationale, technical considerations, and constraints.
56+- End with `- [ ]` checklist items for the acceptance criteria, each using `MUST`, `SHOULD`, or `MAY`.
57+ - Keep the checklist current: once the work for a criterion is implemented **and verified**, mark it done (`- [x]`).
58+ - Leave items that are unverified, not yet implemented, or skipped optional (`MAY`) enhancements unchecked.
59+ - An issue is complete only when every `MUST` is checked; never tick a box on the strength of a plan alone or an unrun test.
60+ - When referencing an issue from a commit that fulfills some of its criteria, update the matching boxes first.
61+- Agents MUST create, edit, close, reopen, relabel, or otherwise modify GitHub issues only when explicitly requested by the user.
5462  
55−When creating or editing shell scripts, run `shellcheck <file>` and resolve warnings. When editing Markdown files that contain tables, format them with `npx --yes markdown-table-formatter <filename>`.
63+### Specifications & Documentation
5664  
57−The curated `make help` overviews are maintained by hand in a `HELP_TEXT` block per Makefile. After renaming or removing a target, run `make check-make-help` (also part of `make lint`) to confirm that no overview still advertises it.
65+- Markdown headings use a Chicago-style title case, with additional code- and path-aware normalization rules (see *Title Case rules* below). Always spell the product name as `PhotoPrism`.
66+- Put option flags before positional arguments unless the command requires another order.
67+- Use RFC 3339 UTC timestamps and valid ID, UID, and UUID examples in docs and tests.
68+- The nested `specs/` repository may be absent. Do not add main-repo `Makefile` targets that depend on it; when present, you may run its tools manually.
69+- Testing guides live at `specs/dev/backend-testing.md` and `specs/dev/frontend-testing.md`.
70+- Do not read, analyze, or modify `specs/generated/`; refer humans to `specs/generated/README.md` when regeneration is needed.
71+- Refresh `**Last Updated:**` when you change document contents, but leave it unchanged for whitespace-only or formatting-only edits.
72+- Nested Git repositories may appear ignored; change into them before staging or committing updates.
5873  
59−## Continuous Integration
74+Title Case rules (Chicago-style, with code- and path-aware normalization):
75+- Capitalize the first word, the first word after a colon, dash, or end punctuation, and all major words, including the second part of a hyphenated major word.
76+- Lowercase only articles, short conjunctions, and short prepositions of three letters or fewer when they are not in one of those positions.
77+- Preserve known acronyms (for example, API, CLI, HTTP, JSON) and slash-separated acronym groups (for example, CSV/TSV) as uppercase.
78+- Preserve RFC 2119 / RFC 8174 normative keywords (MUST, SHOULD, MAY, SHALL, REQUIRED, RECOMMENDED, OPTIONAL) as uppercase when used in their normative sense.
79+- Preserve inline code spans (`` `foo` ``), file paths (e.g. `docs/foo-bar.md`), and slash commands (e.g. `/grill-me`) verbatim; do not recase their contents.
80+- Use `&` instead of `And`/`Or` in headings.
6081  
61−**GitHub Actions is not enabled for this repository.** The workflow files under `.github/workflows/` do not execute, so pushes and pull requests produce no check runs. Treat them as dormant configuration: do not diagnose the absence of runs as a broken workflow, do not propose enabling Actions, and do not add workflows or bot configuration that assumes they will run. Ask a maintainer before changing anything under `.github/workflows/`.
82+## Safety & Data
6283  
63−The `make` targets above are the authoritative build, format, and test gate — run them locally and report the output rather than relying on a hosted runner.
84+- If `git status` shows unexpected changes, assume a human may be editing; ask before using reset-style commands.
85+- Do not run `git config` at either the global or repository level.
86+- Do not run destructive commands against production data; prefer ephemeral volumes and test fixtures for acceptance tests.
87+- Never commit secrets, local configurations, or cache files; use environment variables or a local `.env`.
88+- Ensure `.env`, `.config`, `.local`, `.codex`, and `.gocache` are ignored in `.gitignore` and `.dockerignore`.
89+- Prefer existing caches, workers, and batching strategies already referenced by the code and `Makefile`.
90+- Consider CPU and memory impact; only suggest profiling or benchmarks when justified.
91+- If anything here conflicts with the `Makefile` or the sources of truth, ask for clarification before proceeding.
6492  
65−## Schema Migrations
93+## Project Layout & Shared Rules
6694  
67−If a change touches database schema, check migrations:
68−```bash
69−go run cmd/photoprism/photoprism.go migrations ls
70−go run cmd/photoprism/photoprism.go migrations run
71−# or via Makefile:
72−make migrate
73−```
95+- Backend: Go in `internal/`, `pkg/`, and `cmd/`, backed by MariaDB or SQLite.
96+- Frontend: Vue 3 plus Vuetify 3 under `frontend/`.
97+- Local dev and CI use Docker Compose; Traefik provides local TLS via `*.localssl.dev`.
98+- Code in `pkg/*` must not import from `internal/*`. If you need config, entity, or DB access, add code under `internal/`.
99+- Shared Go rules:
100+ - After Go edits, run `make fmt-go` and keep `gofmt` tab indentation.
101+ - Every added/modified Go function, including unexported helpers, must have focused test coverage in the corresponding `*_test.go` files; update existing tests or add new ones as needed.
102+ - Every Go package must contain a root `<package>.go` file with the standard license header and a short package description comment.
103+ - Use `pkg/fs` permission constants: `fs.ModeDir`, `fs.ModeFile`, `fs.ModeConfigFile`, `fs.ModeSecretFile`, and `fs.ModeBackupFile`.
104+ - When importing the stdlib `io/fs`, alias it to avoid collisions, for example `iofs "io/fs"` or `gofs "io/fs"`.
105+ - Do not pass stdlib `io/fs` mode flags where permission bits are expected.
106+ - Prefer `filepath.Join` for filesystem paths and `path.Join` only for URL paths.
107+ - Normalize slash-based logical paths stored in DB, config, or API payloads with `clean.SlashPath(...)`.
108+- Shared JS/Vue rules:
109+ - Added/modified JavaScript functions, including helpers, should be tested whenever practical; update existing tests or add new ones as needed.
110+ - Added/modified Vue components should have component-test coverage, and existing component tests should be updated as needed when behavior changes.
111+- When adding a metadata source such as `SrcOllama` or `SrcOpenAI`, update both `internal/entity/src.go` and `frontend/src/common/util.js` so backend and UI stay aligned.
74112  
75−Migration files live in `internal/entity/migrate/`.
113+### JS/Go Code Comments
76114  
77−## Architecture Overview
115+A doc comment is **required** for every function (including unexported helpers), as well as for every non-trivial Vue `methods:` / `computed:` / watcher:
116+- Keep comments **compact** and default to one line for "what" in the format `// Name does X.`. Skip trivial getters (`isOpen: () => this.open`).
117+- Add 1-2 follow-up lines (`// …`) **only** if the "why" is non-obvious: a hidden invariant, a workaround that would otherwise be undone by a future cleanup, a contract a reader can't infer from the code. If readers can infer the "why" from the function body or a nearby line, then omit it.
118+- Multi-paragraph explanations belong in `specs/`, package `README.md` files, or GitHub issues — never in the source itself.
78119  
79−PhotoPrism is a self-hosted photo management app. The backend is Go, the frontend is Vue 3 + Vuetify 3, and the database is MariaDB or SQLite (via GORM).
120+Doc comments for packages and exported identifiers must be complete sentences that begin with the name of the thing being described and end with a period. For short examples in comments, indent code instead of using backticks.
80121  
81−### Backend (`internal/`, `pkg/`, `cmd/`)
122+Use US English spelling in all code comments (`parameterized`, `behavior`, `color`, `serialize`, `normalize`, `optimize`, …) — not the British `-ised`/`-our`/`-re` variants.
82123  
83−| Package | Purpose |
84−|-------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
85−| `internal/photoprism` | **Core application logic**: indexing originals, metadata extraction, thumbnail generation, import/stacking, converter orchestration (FFmpeg/ImageMagick/ExifTool). Entry point for workers and CLI. |
86−| `internal/entity` | **Database models** (GORM): Photo, File, Album, Label, Face, User, Session, etc. Contains fixtures for tests and migration helpers. |
87−| `internal/entity/query` | Database query helpers used by the API and core packages. |
88−| `internal/api` | **REST API handlers** (Gin): thin handlers that validate input, enforce ACL/auth, delegate to services. Annotated with Swagger comments. |
89−| `internal/server` | HTTP server setup, routing (Gin engine), WebDAV, static assets, middleware wiring. Routes are registered in `routes.go`. |
90−| `internal/config` | Application configuration: CLI flags, env vars, client config sent to the frontend. |
91−| `internal/workers` | Background workers: indexing scheduler, metadata sync, sharing, backup, vision jobs. |
92−| `internal/commands` | CLI command implementations (`github.com/urfave/cli/v2`). |
93−| `internal/auth` | Authentication: ACL (`auth/acl`), JWT (`auth/jwt`), OIDC (`auth/oidc`), session management. |
94−| `internal/form` | Request form/binding structs for the API layer. |
95−| `internal/meta` | Metadata extraction from EXIF, XMP, JSON sidecars. |
96−| `internal/ffmpeg` | FFmpeg/transcoding helpers. |
97−| `internal/thumb` | Thumbnail generation helpers. |
98−| `internal/ai` | AI/vision model integration (TensorFlow, ONNX). |
99−| `internal/service` | Services: maps geocoding, hub (membership), cluster, WebDAV client, CIDR helpers. |
100−| `internal/event` | Event bus for structured logging and audit events. |
101−| `pkg/` | Standalone, reusable packages: `fs`, `geo`, `media`, `txt`, `clean`, `rnd`, `i18n`, `http`, `time`, etc. No dependency on `internal/`. |
124+> **Don't include in code comments:** Issue / PR numbers, "previously…" history, alternatives considered, what the function used to do, references to old commits, names of subsequent reviewers, or any narrative that names the change rather than the steady-state behavior. That context belongs in commit messages, specs, or handover notes.
102125  
103−**Request flow:** HTTP request → Gin middleware (auth, rate limiting) → `internal/api` handler → `internal/photoprism` or `internal/entity` → response.
126+## Agent Runtime
104127  
105−**Audit logging convention** (`event.AuditInfo/Warn/Err`): slices must follow the pattern **Who → What → Outcome**:
106−- Who: `ClientIP(c)` + actor context (`"session %s"`, `"user %s"`)
107−- What: resource constant + action segments
108−- Outcome: single token like `status.Succeeded`, `status.Failed`, `status.Denied`, `status.Error(err)`
128+- Detect container mode by checking for `/.dockerenv`.
129+- If the repo path is `/go/src/github.com/photoprism/photoprism` and `/.dockerenv` is absent, treat the environment as host mode with a bind mount and prefer host-side Docker commands.
130+- Bash check: `[ -f "/.dockerenv" ] && echo container || echo host`
131+- Node.js check: `require("fs").existsSync("/.dockerenv")`
132+- Inside the container, prefer `npm exec --yes <agent> -- --help` or `npx <agent> ...`; if a global npm install is unavoidable, install it only inside the container.
133+- The `photoprism/develop` base image and the repo `Makefile` both set `NPM_CONFIG_IGNORE_SCRIPTS=true`, so `npm ci`/`npm install` via `make` targets skip install scripts out of the box. When running npm directly in an environment that does not set or inherit that default, pass `--ignore-scripts` explicitly to mitigate supply-chain attacks. Rebuild native addons with `npm rebuild --ignore-scripts=false <pkg>` — a bare `npm rebuild` is a silent no-op wherever the env default is active.
134+- On the host, use the vendor-recommended install method and run from the repository root so agent discovery sees this file.
109135  
110−### Frontend (`frontend/`)
136+## Build, Format & Test
111137  
112−Vue 3 app using the Options API and Vuetify 3.
138+- Run `make help` for an overview of the most common targets, and `make list` to see all of them.
139+- Host mode:
140+ - `make docker-build`
141+ - `docker compose up` or `docker compose up -d`
142+ - `docker compose logs -f --tail=100 photoprism`
143+ - `docker compose exec photoprism ./photoprism help`
144+ - `docker compose exec -u "$(id -u):$(id -g)" photoprism <command>` to avoid root-owned files
145+ - `make terminal`
146+ - `docker compose --profile=all down --remove-orphans` or `make down`
147+- Container mode:
148+ - `make dep`
149+ - `make build-js` and `make build-go`
150+ - `make watch-js` or `cd frontend && npm run watch`
151+ - `./photoprism start`
152+ - Local URLs: `http://localhost:2342/` and, with Traefik, `https://app.localssl.dev/`
153+ - Local compose defaults to `admin` / `photoprism`; inspect `compose.yaml` if they differ.
154+ - Do not use the Docker CLI inside the container; manage Compose from the host instead.
155+- The public CLI name is always `photoprism`; development-only side-by-side binaries may use edition-specific names.
156+- Our command examples assume a Linux or Unix shell on 64-bit AMD64 or ARM64; see the Developer Guide FAQ for Windows-specific notes.
113157  
114−| Directory | Purpose |
115−|---------------------------|-------------------------------------------------------------------------------------------------|
116−| `frontend/src/model/` | Client-side models mirroring API responses (Photo, Album, File, User, etc.) |
117−| `frontend/src/app/` | App bootstrap, routing (`routes.js`), and the `$session` reactive singleton |
118−| `frontend/src/page/` | Page-level components |
119−| `frontend/src/component/` | Reusable UI components |
120−| `frontend/src/common/` | Shared utilities, the API client (`$api`), and reactive singletons (`$config`, `$view`, `$log`) |
121−| `frontend/src/locales/` | i18n translation files |
122−| `frontend/tests/` | Vitest unit tests + TestCafe acceptance tests |
158+Formatting and test entry points:
159+- Full suite: `make test`, `make lint`
160+- After renaming or removing a Makefile target, run `make check-make-help` (also included in `make lint`) so that no `make help` overview keeps advertising it.
161+- Go-specific lint, format, and package-test rules live in [`internal/AGENTS.md`](internal/AGENTS.md).
162+- Frontend lint, Vitest, acceptance, and Playwright rules live in [`frontend/AGENTS.md`](frontend/AGENTS.md).
163+- Go tests live next to their sources; use PascalCase `t.Run(...)` names for related subtests. Keep consecutive subtests inside the same `Test*` function back-to-back without blank lines so the cases read as a compact table; reserve blank lines for separating distinct setup blocks.
164+- Do not run multiple test commands in parallel; suites share fixtures, assets, and database state.
165+- Prefer focused test runs such as `go test ./path/to/pkg -run Name -count=1` while iterating.
166+- Use `mariadb -D photoprism` inside the dev shell when you need to inspect MariaDB state directly.
167+- Run `shellcheck <file>` on edited shell scripts, or use the corresponding `make` target.
123168  
124−State management uses reactive singleton modules in `src/common/` and `src/app/`, not Vuex or Pinia. Frontend code-style, formatting, testing, translation, and Playwright rules live in `.claude/rules/frontend-rules.md`.
169+### Continuous Integration
125170  
126−### API Conventions
171+- **GitHub Actions is not enabled for this repository.** The workflow files under `.github/workflows/` do not execute, so pushes and pull requests produce no check runs. Treat them as dormant configuration: do not diagnose the absence of runs as a broken workflow, do not propose enabling Actions, and do not add workflows or bot configuration that assumes they will run. Ask a maintainer before changing anything under `.github/workflows/`.
172+- The `make` targets above are the authoritative build, format, and test gate. Run them locally and report the output rather than relying on a hosted runner.
127173  
128−- REST API v1 base path: `/api/v1/` (configured via `conf.BaseUri()`)
129−- Authentication: Bearer token (`Authorization` header) or `X-Auth-Token` header
130−- Pagination: `count`, `offset`, `limit` parameters (default 100, max 1000)
131−- After adding/changing API handlers, regenerate Swagger docs: `make fmt-go swag-fmt swag`
132−- New routes must be registered in `internal/server/routes.go`
174+### Container Image Builds
133175  
134−### Config & Flags
135− 
136−Verify config option names before using them:
137−```bash
138−./photoprism --help
139−./photoprism show config-options
140−./photoprism show config-yaml
141−```
142− 
143−### Verify Before Propagating
144− 
145−Before promoting a claim from `CLAUDE.md`, `AGENTS.md`, a memory entry, or another spec into a new rule, spec, code comment, or commit message, verify it against the current code (grep imports, list directories, read the cited file). Stale documentation silently turns into stale rules and stale specs that future sessions will trust. When the claim names a package, function, file, or framework, the cost of one grep is much smaller than the cost of repeating an error across multiple files.
146− 
147−### Detailed Rules
148− 
149−Topic-specific conventions live under `.claude/rules/` and are loaded alongside this file:
150− 
151−- `code-comments.md` — shared JS/Go doc comment rules (length cap, what to omit); referenced by both style files.
152−- `go-code-style.md`, `go-testing.md` — Go style, package boundaries, test patterns, fixtures.
153−- `frontend-rules.md` — JS/Vue code style, formatting, dependencies, tests, Playwright, translations.
154−- `commit-and-docs-style.md` — commit-message format, GitHub issue templates, spec heading style.
155−- `safety-and-security.md` — Git/data safety, destructive commands, file I/O and archive-extraction policies, HTTP download helpers.
156−- `api-and-config.md`, `cluster-operations.md`, `import-index-download.md`, `build-and-runtime.md`, `sources-of-truth.md` — domain-specific guidance.
176+- **Never mix Debian and Ubuntu `apt` repositories in the same image:**
177+ - Don't add a Debian source to an Ubuntu base (or vice versa) to install a single missing package — the transitive deps drift, apt's solver pulls newer libraries from the foreign distro, and other build steps in the same `RUN` (e.g. `install-libheif.sh` running `apt-get install libavcodec-dev`) silently link against the wrong soname.
178+ - Symptoms surface much later as `dlopen: libfoo.so.N: cannot open shared object file` at image runtime, with the binary referencing a soname that exists only in the foreign distro.
179+ - If a package isn't available in the host distro's repos, prefer (a) a same-distro PPA / backports source, (b) a vendor-supplied .deb (e.g. Google Chrome from `dl.google.com`), or (c) a from-source build pinned to a known version.
157180  
RuleStack

Built by

Kynth Studio

Directory

Configs
Stacks
Compare formats
Diff two configs
Best AGENTS.md examples

Formats

AGENTS.md
CLAUDE.md
Cursor rules
Copilot instructions

Reference

Read API
Corpus health
Privacy Policy
Terms

RuleStack

RuleStack

Built by

Kynth Studio

Directory

Configs
Stacks
Compare formats
Diff two configs
Best AGENTS.md examples

Formats

AGENTS.md
CLAUDE.md
Cursor rules
Copilot instructions

Reference

Read API
Corpus health
Privacy Policy
Terms

RuleStack

RuleStack

Built by

Kynth Studio

Directory

Configs
Stacks
Compare formats
Diff two configs
Best AGENTS.md examples

Formats

AGENTS.md
CLAUDE.md
Cursor rules
Copilot instructions

Reference

Read API
Corpus health
Privacy Policy
Terms

RuleStack