RuleStack

Configs

Stacks

Compare

Diff

RuleStack

Configs

Stacks

Compare

Diff

Read API

RuleStack

Configs

Stacks

Compare

Diff

Read API

Diff/photoprism-photoprism-github-copilot-instructions ↔ photoprism-photoprism-internal-service-cluster-agents

Comparison

A · Copilot instructions · photoprism/photoprismB · AGENTS.md · photoprism/photoprism
What each file covers, counted
DimensionSharedOnly in AOnly in BOverlap
Sections01460%
Commands12373%
Section tags27120%

What each file covers

Sections

0 shared · 14 only in A · 6 only in B
  • − Instructions for GitHub Copilot
  • − Purpose
  • − Single Sources of Truth (SOT)
  • − Build & Run (local dev; use Makefile first)
  • − Tests & Lint
  • − Project Structure & Languages
  • − Code Review Instructions (for Copilot)
  • − Style & Patterns
  • − Commits & Pull Requests
  • − Performance & Reliability
  • − When Unsure
  • − References To Help Copilot Answer Questions
  • − Output Expectations
  • − Safety Checklist Before Proposing a CLI Command
  • + Cluster Guidelines
  • + Bootstrap & Registration
  • + Registry, DTOs & Provisioning
  • + Cluster API & Theme Changes
  • + Cluster Tests
  • + Cluster Preflight

Commands

1 shared · 23 only in A · 7 only in B
  • − make help
  • − make list
  • − make docker-build
  • − docker compose up
  • − docker compose logs -f --tail=100 photoprism
  • − make dep
  • − make build-js
  • − make build-go
  • − make watch-js
  • − make test
  • − make test-js
  • − make vitest-watch
  • − make vitest-coverage
  • − make test-go
  • − make test-short
  • − go test ./internal/<pkg> -run '<TestName>' -count=1
  • − make fmt-go
  • − make lint-go
  • − make fmt-js
  • − make lint-js
  • − go.mod
  • − go.sum
  • − make notice
  • + node.uuid
  • + make -C portal test-start
  • + make -C portal test-env NODES=2
  • + go build ./...
  • + go test ./internal/service/cluster/registry -count=1
  • + go test ./internal/api -run 'Cluster' -count=1
  • + go test ./internal/commands -run 'ClusterRegister|ClusterNodesRotate' -count=1
  •   make fmt-go swag-fmt swag

Section tags

2 shared · 7 only in A · 1 only in B
  • − lint-format
  • − code-style
  • − architecture
  • − git-pr
  • − performance
  • − do-not
  • − agent-behaviour
  • + api
  •   build
  •   test

Line diff

+34 added−99 removed12 unchanged10.8% identical
photoprism/photoprism · .github/copilot-instructions.md
@@ −1 @@
1# Instructions for GitHub Copilot
2 
3**Last Updated:** July 28, 2026
4 
5## Purpose
6 
7- Provide Copilot with the single sources of truth for building, testing, and contributing to PhotoPrism.
8- Improve PR reviews and code suggestions by aligning them with our documented workflows and style.
9- Path-specific rules that apply on top of this file live in `.github/instructions/*.instructions.md`.
 
 
10 
11## Single Sources of Truth (SOT)
12 
13- Makefile targets (always prefer existing targets): https://github.com/photoprism/photoprism/blob/develop/Makefile
14- Developer Guide – Setup: https://docs.photoprism.app/developer-guide/setup/
15- Developer Guide – Tests: https://docs.photoprism.app/developer-guide/tests/
16- Contributing: https://github.com/photoprism/photoprism/blob/develop/CONTRIBUTING.md
17- Security: https://github.com/photoprism/photoprism/blob/develop/SECURITY.md
18- REST API (Swagger): https://docs.photoprism.dev/
19- REST API Guide: https://docs.photoprism.app/developer-guide/api/
20- Agents reference for tools/commands: https://github.com/photoprism/photoprism/blob/develop/AGENTS.md
21- Code maps: https://github.com/photoprism/photoprism/blob/develop/CODEMAP.md (backend) and https://github.com/photoprism/photoprism/blob/develop/frontend/CODEMAP.md (frontend)
22- Terminology: https://github.com/photoprism/photoprism/blob/develop/GLOSSARY.md
23 
24## Build & Run (local dev; use Makefile first)
25 
26- Show common tasks: `make help` (`make list` shows all targets)
27- Build local image: `make docker-build`
28- Start dev env: `docker compose up` (add `-d` for detached, or run `make up`)
29- Logs: `docker compose logs -f --tail=100 photoprism`
30- Open app: http://localhost:2342/ (HTTP) / https://app.localssl.dev/ (TLS via Traefik when enabled)
31- From the dev container:
32 - Install deps: `make dep`
33 - Build frontend: `make build-js` (or `cd frontend && npm run build`)
34 - Build backend: `make build-go`
35 - Watch frontend: `make watch-js` (stop with Ctrl+C)
36 - Run server binary: `./photoprism start`
37 
38## Tests & Lint
39 
40- Full tests: `make test`
41- Frontend tests (Vitest): `make test-js` (watch: `make vitest-watch`, coverage: `make vitest-coverage`)
42- Backend tests: `make test-go` (slow); `make test-short` for a fast parallel run
43- Targeted Go tests: `go test ./internal/<pkg> -run '<TestName>' -count=1`
44- Formatting and linting:
45 - Go: `make fmt-go` (gofmt + goimports) and `make lint-go` (golangci-lint)
46 - JS/Vue: `make fmt-js` and `make lint-js`. ESLint owns JS and Vue; Prettier owns CSS/SCSS/SASS only. ESLint does not run Prettier, so do not propose reflowing JS to satisfy Prettier.
47- Swagger: after changing API handlers or annotations, run `make fmt-go swag-fmt swag`; never edit `internal/api/swagger.json` by hand.
48- Dependencies: when `go.mod`, `go.sum`, or `package-lock.json` change, regenerate the license reports with `make notice`; never edit `NOTICE` or `frontend/NOTICE` manually.
49 
50## Project Structure & Languages
51 
52- Backend: Go (`internal/`, `pkg/`, `cmd/`) + MariaDB/SQLite
53- Frontend: Vue 3 + Vuetify 3 (`frontend/`)
54- Docker/compose for dev/CI; Traefik used for local TLS in dev profile when enabled.
55- A maintainer's working copy may contain private subdirectories (`plus/`, `pro/`, `portal/`, `specs/`) that are not part of this repository. Never reference their paths from public artifacts such as pull request descriptions, issue comments, or code comments — external readers only see a broken link.
56 
57## Code Review Instructions (for Copilot)
58 
59- Respect SOT above; do not invent flags, env vars, or Compose options. If a command/env var is not in the docs/Makefile/CLI help, say "not documented" and suggest checking the SOT.
60- Prefer minimal, surgical diffs. Propose changes as concrete patches and reference the relevant Makefile target or doc section.
61- Before suggesting refactors, check tests and build tasks exist and can pass with the change. If tests are missing, suggest specific Vitest/Go test snippets.
62- Security: never suggest committing secrets; prefer env vars and `.env` in dev only. Point to SECURITY.md for disclosures.
63- Data safety: never run or recommend destructive CLI operations in examples without explicit backups and `--yes`. Avoid `photoprism reset`, `photoprism users reset`, `photoprism auth reset`, or `photoprism audit reset` in PR comments unless the change is specifically about those commands; if unavoidable, add bold warnings and backup steps.
64- Database/schema: if a change touches persistence, check for migrations and mention `photoprism migrate` / `migrations` commands.
65- API changes: align with the REST API docs/spec; include curl examples only if they match current endpoints and auth notes.
66- UX/i18n: keep UI strings concise, translatable, and consistent; avoid hard-coded language constructs; prefer existing patterns/components.
67 
68## Style & Patterns
69 
70- Go: idiomatic Go, clear error handling, small functions, packages with focused responsibilities. Keep the public surface minimal.
71 - Every added function, including unexported helpers and helpers extracted by a refactor, needs focused coverage in a sibling `*_test.go`.
72 - Code in `pkg/*` must not import from `internal/*`; new code that needs config, entity, or DB access belongs under `internal/`.
73 - Use the permission constants in `pkg/fs` (`fs.ModeDir`, `fs.ModeFile`, `fs.ModeConfigFile`, `fs.ModeSecretFile`) instead of literal file modes.
74 - Doc comments start with the name and stay compact — one line for the "what", plus a line or two only when the "why" cannot be inferred from the code. No issue numbers or change history in comments.
75- Vue/JS: Options API only. Do not introduce TypeScript (no `.ts` files, no `<script lang="ts">`), Composition API, or `<script setup>`.
76 - Shared state lives in reactive singleton modules under `src/common/` and `src/app/`. Do not propose Vuex or Pinia.
77 - Every user-visible string must go through `$gettext`, so it reaches `frontend/src/locales/translations.pot`. Standardized technical identifiers (`Client ID`, `OIDC`, `UUID`) stay literal.
78 - Prefer existing components and model methods over raw `$api` calls in components.
79- Config & flags: suggest `photoprism --help`, `photoprism show config-options` or `photoprism show config-yaml` to verify names before using them.
80 
81## Commits & Pull Requests
82 
83- Commit subjects use the imperative mood with a one-word scope prefix, for example `Config: Add tests for "darktable-cli" path detection`, and must not exceed 80 characters.
84- Reference related issue or PR IDs in the message when applicable, for example `Docker: Use two stage build to reduce image size #123 #5632`.
85- Do not add AI-authorship trailers such as `Co-Authored-By: Copilot` — this repository uses no commit trailers.
86- Issue titles follow the same prefix style; descriptions open with a bold user story (`**As a <role>, I want <goal>, so that <outcome>.**`) and close with a checklist of acceptance criteria using MUST, SHOULD, or MAY.
87- Commit messages, code comments, and public issue or PR text must not describe exploitable details of a security fix; present such changes as general hardening.
88 
89## Performance & Reliability
90 
91- Prefer using existing caches, workers, and batching strategies referenced in code and Makefile. Consider memory/CPU impact; suggest benchmarks or profiling only when justified.
92 
93## When Unsure
94 
95- Ask for the exact Makefile target or doc link you need, then proceed. Defer to SOT if any conflict arises.
96 
97## References To Help Copilot Answer Questions
98 
99- Show supported formats/filters: run `photoprism show file-formats` and `photoprism show search-filters` (use results rather than guessing).
100- For CI/dev containers, assume a Linux/Unix shell on amd64 or arm64 by default; for Windows specifics, link https://docs.photoprism.app/developer-guide/faq/
101 
102## Output Expectations
103 
104- Prefer short, actionable comments with code blocks that pass tests locally: `make test-js` (frontend) / `make test-go` (backend)
105- If a suggestion requires additional context (e.g., DB access, external service), call it out explicitly.
106 
107## Safety Checklist Before Proposing a CLI Command
108 
109- Include a dry-run or non-destructive variant if possible.
110- Recommend creating/using backups before any reset/migrate.
111 
photoprism/photoprism · internal/service/cluster/AGENTS.md
@@ +1 @@
1# Cluster Guidelines
2 
3**Last Updated:** April 9, 2026
4 
5## Bootstrap & Registration
6 
7- Keep bootstrap code decoupled: do not import `internal/service/cluster/node/*` from `internal/config` or the cluster root; nodes talk to the Portal over HTTP(S) and use `internal/service/cluster/const.go`.
8- On `401` or `403`, bootstrap refreshes node OAuth credentials by rotating the secret and retrying; log that at info level. If the secret file cannot be written, keep the rotated value in memory.
9- Portal validation may accept HTTP advertise URLs only for loopback or cluster-internal domains such as `*.svc`, `*.cluster.local`, and `*.internal`; all other advertise URLs must use HTTPS.
10- Registration flow: send `rotate=true` only for MySQL or MariaDB nodes without credentials, treat `401`, `403`, and `404` as terminal, include `ClientID` plus `ClientSecret` when renaming an existing node, and persist only newly generated secrets or DB settings.
11- Config init order for cluster-aware startup is: load `options.yml` with `c.initSettings()`, run `EarlyExt().InitEarly(c)`, connect or register the DB, then invoke `Ext().Init(c)`.
12 
13## Registry, DTOs & Provisioning
14 
15- Use `NewClientRegistryWithConfig`; the file-backed registry is legacy.
16- Nodes are keyed by UUID v7 at `/api/v1/cluster/nodes/{uuid}`. Keep the registry interface UUID-first: `Get`, `FindByNodeUUID`, `FindByClientID`, `RotateSecret`, and `DeleteAllByUUID`.
17- CLI lookups should resolve `uuid -> ClientID -> name`.
18- DTOs normalize `Database.{Name,User,Driver,RotatedAt}` and expose `ClientSecret` only during creation or rotation.
19- `nodes rm --all-ids` must clean duplicate client rows.
20- Registry files live under `conf.PortalConfigPath()/nodes/` with mode `0600`, and `ClientData` no longer stores `NodeUUID`.
21- Database and user names use UUID-based HMACs in `<prefix>d<hmac11>` and `<prefix>u<hmac11>` form; the prefix defaults to `cluster_` and may be overridden only by the portal-only `database-provision-prefix` flag.
22- `BuildDSN` accepts a `driver` but falls back to MySQL format with a warning when the driver is unsupported.
23- If Postgres provisioning is added, extend both `BuildDSN` and `provisioner.DatabaseDriver`, add validations, and return `driver=postgres` consistently in API and CLI output.
 
24 
25## Cluster API & Theme Changes
26 
27- When renaming or adding cluster response fields, update DTOs in `internal/service/cluster/response.go`, handlers, Swagger, tests, specs, and grep for old and new field names.
28- The theme endpoint `GET /api/v1/cluster/theme` streams a zip from `conf.ThemePath()`. Reinstall only when `app.js` is missing and use the shared helpers in `pkg/http/header`.
29- Admin responses may include `AdvertiseUrl` and `Database`; client and user sessions must remain redacted.
 
 
 
 
 
 
 
 
30 
31## Cluster Tests
32 
33- Generate OAuth client IDs with `rnd.GenerateUID(entity.ClientUID)` and node UUIDs with `rnd.UUIDv7()`; treat `node.uuid` as required in responses.
34- Cluster registry tests under `internal/service/cluster/registry` intentionally use a full `config.TestConfig()` because they persist `entity.Client` rows. Do not switch them to minimal config helpers unless the tests stop touching the database.
35- Exercise Portal endpoints with `httptest`, guard extraction paths with `pkg/fs.Unzip` size caps, and confirm admin-only fields disappear for client or user sessions.
36- Portal proxy URI validation must use the Portal test environment with `NODES=2` and verify both instance routes when changing `PHOTOPRISM_PORTAL_PROXY_URI` or matching node `PHOTOPRISM_SITE_URL` prefixes; use `PORTAL_TEST_ENV_ARGS=--proxy-uri=/instance/` to regenerate consistent `.env` values.
37- Before `make -C portal test-start`, run a full rebuild with `make -C portal test-env NODES=2`; avoid `--no-build` refreshes unless you are intentionally validating env-only changes.
 
 
 
 
38 
39## Cluster Preflight
40 
41- `go build ./...`
42- `make fmt-go swag-fmt swag`
43- `go test ./internal/service/cluster/registry -count=1`
44- `go test ./internal/api -run 'Cluster' -count=1`
45- `go test ./internal/commands -run 'ClusterRegister|ClusterNodesRotate' -count=1`
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
46 
@@ −1 +1 @@
1−# Instructions for GitHub Copilot
1+# Cluster Guidelines
22  
3−**Last Updated:** July 28, 2026
3+**Last Updated:** April 9, 2026
44  
5−## Purpose
5+## Bootstrap & Registration
66  
7−- Provide Copilot with the single sources of truth for building, testing, and contributing to PhotoPrism.
8−- Improve PR reviews and code suggestions by aligning them with our documented workflows and style.
9−- Path-specific rules that apply on top of this file live in `.github/instructions/*.instructions.md`.
7+- Keep bootstrap code decoupled: do not import `internal/service/cluster/node/*` from `internal/config` or the cluster root; nodes talk to the Portal over HTTP(S) and use `internal/service/cluster/const.go`.
8+- On `401` or `403`, bootstrap refreshes node OAuth credentials by rotating the secret and retrying; log that at info level. If the secret file cannot be written, keep the rotated value in memory.
9+- Portal validation may accept HTTP advertise URLs only for loopback or cluster-internal domains such as `*.svc`, `*.cluster.local`, and `*.internal`; all other advertise URLs must use HTTPS.
10+- Registration flow: send `rotate=true` only for MySQL or MariaDB nodes without credentials, treat `401`, `403`, and `404` as terminal, include `ClientID` plus `ClientSecret` when renaming an existing node, and persist only newly generated secrets or DB settings.
11+- Config init order for cluster-aware startup is: load `options.yml` with `c.initSettings()`, run `EarlyExt().InitEarly(c)`, connect or register the DB, then invoke `Ext().Init(c)`.
1012  
11−## Single Sources of Truth (SOT)
13+## Registry, DTOs & Provisioning
1214  
13−- Makefile targets (always prefer existing targets): https://github.com/photoprism/photoprism/blob/develop/Makefile
14−- Developer Guide – Setup: https://docs.photoprism.app/developer-guide/setup/
15−- Developer Guide – Tests: https://docs.photoprism.app/developer-guide/tests/
16−- Contributing: https://github.com/photoprism/photoprism/blob/develop/CONTRIBUTING.md
17−- Security: https://github.com/photoprism/photoprism/blob/develop/SECURITY.md
18−- REST API (Swagger): https://docs.photoprism.dev/
19−- REST API Guide: https://docs.photoprism.app/developer-guide/api/
20−- Agents reference for tools/commands: https://github.com/photoprism/photoprism/blob/develop/AGENTS.md
21−- Code maps: https://github.com/photoprism/photoprism/blob/develop/CODEMAP.md (backend) and https://github.com/photoprism/photoprism/blob/develop/frontend/CODEMAP.md (frontend)
22−- Terminology: https://github.com/photoprism/photoprism/blob/develop/GLOSSARY.md
15+- Use `NewClientRegistryWithConfig`; the file-backed registry is legacy.
16+- Nodes are keyed by UUID v7 at `/api/v1/cluster/nodes/{uuid}`. Keep the registry interface UUID-first: `Get`, `FindByNodeUUID`, `FindByClientID`, `RotateSecret`, and `DeleteAllByUUID`.
17+- CLI lookups should resolve `uuid -> ClientID -> name`.
18+- DTOs normalize `Database.{Name,User,Driver,RotatedAt}` and expose `ClientSecret` only during creation or rotation.
19+- `nodes rm --all-ids` must clean duplicate client rows.
20+- Registry files live under `conf.PortalConfigPath()/nodes/` with mode `0600`, and `ClientData` no longer stores `NodeUUID`.
21+- Database and user names use UUID-based HMACs in `<prefix>d<hmac11>` and `<prefix>u<hmac11>` form; the prefix defaults to `cluster_` and may be overridden only by the portal-only `database-provision-prefix` flag.
22+- `BuildDSN` accepts a `driver` but falls back to MySQL format with a warning when the driver is unsupported.
23+- If Postgres provisioning is added, extend both `BuildDSN` and `provisioner.DatabaseDriver`, add validations, and return `driver=postgres` consistently in API and CLI output.
2324  
24−## Build & Run (local dev; use Makefile first)
25+## Cluster API & Theme Changes
2526  
26−- Show common tasks: `make help` (`make list` shows all targets)
27−- Build local image: `make docker-build`
28−- Start dev env: `docker compose up` (add `-d` for detached, or run `make up`)
29−- Logs: `docker compose logs -f --tail=100 photoprism`
30−- Open app: http://localhost:2342/ (HTTP) / https://app.localssl.dev/ (TLS via Traefik when enabled)
31−- From the dev container:
32− - Install deps: `make dep`
33− - Build frontend: `make build-js` (or `cd frontend && npm run build`)
34− - Build backend: `make build-go`
35− - Watch frontend: `make watch-js` (stop with Ctrl+C)
36− - Run server binary: `./photoprism start`
27+- When renaming or adding cluster response fields, update DTOs in `internal/service/cluster/response.go`, handlers, Swagger, tests, specs, and grep for old and new field names.
28+- The theme endpoint `GET /api/v1/cluster/theme` streams a zip from `conf.ThemePath()`. Reinstall only when `app.js` is missing and use the shared helpers in `pkg/http/header`.
29+- Admin responses may include `AdvertiseUrl` and `Database`; client and user sessions must remain redacted.
3730  
38−## Tests & Lint
31+## Cluster Tests
3932  
40−- Full tests: `make test`
41−- Frontend tests (Vitest): `make test-js` (watch: `make vitest-watch`, coverage: `make vitest-coverage`)
42−- Backend tests: `make test-go` (slow); `make test-short` for a fast parallel run
43−- Targeted Go tests: `go test ./internal/<pkg> -run '<TestName>' -count=1`
44−- Formatting and linting:
45− - Go: `make fmt-go` (gofmt + goimports) and `make lint-go` (golangci-lint)
46− - JS/Vue: `make fmt-js` and `make lint-js`. ESLint owns JS and Vue; Prettier owns CSS/SCSS/SASS only. ESLint does not run Prettier, so do not propose reflowing JS to satisfy Prettier.
47−- Swagger: after changing API handlers or annotations, run `make fmt-go swag-fmt swag`; never edit `internal/api/swagger.json` by hand.
48−- Dependencies: when `go.mod`, `go.sum`, or `package-lock.json` change, regenerate the license reports with `make notice`; never edit `NOTICE` or `frontend/NOTICE` manually.
33+- Generate OAuth client IDs with `rnd.GenerateUID(entity.ClientUID)` and node UUIDs with `rnd.UUIDv7()`; treat `node.uuid` as required in responses.
34+- Cluster registry tests under `internal/service/cluster/registry` intentionally use a full `config.TestConfig()` because they persist `entity.Client` rows. Do not switch them to minimal config helpers unless the tests stop touching the database.
35+- Exercise Portal endpoints with `httptest`, guard extraction paths with `pkg/fs.Unzip` size caps, and confirm admin-only fields disappear for client or user sessions.
36+- Portal proxy URI validation must use the Portal test environment with `NODES=2` and verify both instance routes when changing `PHOTOPRISM_PORTAL_PROXY_URI` or matching node `PHOTOPRISM_SITE_URL` prefixes; use `PORTAL_TEST_ENV_ARGS=--proxy-uri=/instance/` to regenerate consistent `.env` values.
37+- Before `make -C portal test-start`, run a full rebuild with `make -C portal test-env NODES=2`; avoid `--no-build` refreshes unless you are intentionally validating env-only changes.
4938  
50−## Project Structure & Languages
39+## Cluster Preflight
5140  
52−- Backend: Go (`internal/`, `pkg/`, `cmd/`) + MariaDB/SQLite
53−- Frontend: Vue 3 + Vuetify 3 (`frontend/`)
54−- Docker/compose for dev/CI; Traefik used for local TLS in dev profile when enabled.
55−- A maintainer's working copy may contain private subdirectories (`plus/`, `pro/`, `portal/`, `specs/`) that are not part of this repository. Never reference their paths from public artifacts such as pull request descriptions, issue comments, or code comments — external readers only see a broken link.
56− 
57−## Code Review Instructions (for Copilot)
58− 
59−- Respect SOT above; do not invent flags, env vars, or Compose options. If a command/env var is not in the docs/Makefile/CLI help, say "not documented" and suggest checking the SOT.
60−- Prefer minimal, surgical diffs. Propose changes as concrete patches and reference the relevant Makefile target or doc section.
61−- Before suggesting refactors, check tests and build tasks exist and can pass with the change. If tests are missing, suggest specific Vitest/Go test snippets.
62−- Security: never suggest committing secrets; prefer env vars and `.env` in dev only. Point to SECURITY.md for disclosures.
63−- Data safety: never run or recommend destructive CLI operations in examples without explicit backups and `--yes`. Avoid `photoprism reset`, `photoprism users reset`, `photoprism auth reset`, or `photoprism audit reset` in PR comments unless the change is specifically about those commands; if unavoidable, add bold warnings and backup steps.
64−- Database/schema: if a change touches persistence, check for migrations and mention `photoprism migrate` / `migrations` commands.
65−- API changes: align with the REST API docs/spec; include curl examples only if they match current endpoints and auth notes.
66−- UX/i18n: keep UI strings concise, translatable, and consistent; avoid hard-coded language constructs; prefer existing patterns/components.
67− 
68−## Style & Patterns
69− 
70−- Go: idiomatic Go, clear error handling, small functions, packages with focused responsibilities. Keep the public surface minimal.
71− - Every added function, including unexported helpers and helpers extracted by a refactor, needs focused coverage in a sibling `*_test.go`.
72− - Code in `pkg/*` must not import from `internal/*`; new code that needs config, entity, or DB access belongs under `internal/`.
73− - Use the permission constants in `pkg/fs` (`fs.ModeDir`, `fs.ModeFile`, `fs.ModeConfigFile`, `fs.ModeSecretFile`) instead of literal file modes.
74− - Doc comments start with the name and stay compact — one line for the "what", plus a line or two only when the "why" cannot be inferred from the code. No issue numbers or change history in comments.
75−- Vue/JS: Options API only. Do not introduce TypeScript (no `.ts` files, no `<script lang="ts">`), Composition API, or `<script setup>`.
76− - Shared state lives in reactive singleton modules under `src/common/` and `src/app/`. Do not propose Vuex or Pinia.
77− - Every user-visible string must go through `$gettext`, so it reaches `frontend/src/locales/translations.pot`. Standardized technical identifiers (`Client ID`, `OIDC`, `UUID`) stay literal.
78− - Prefer existing components and model methods over raw `$api` calls in components.
79−- Config & flags: suggest `photoprism --help`, `photoprism show config-options` or `photoprism show config-yaml` to verify names before using them.
80− 
81−## Commits & Pull Requests
82− 
83−- Commit subjects use the imperative mood with a one-word scope prefix, for example `Config: Add tests for "darktable-cli" path detection`, and must not exceed 80 characters.
84−- Reference related issue or PR IDs in the message when applicable, for example `Docker: Use two stage build to reduce image size #123 #5632`.
85−- Do not add AI-authorship trailers such as `Co-Authored-By: Copilot` — this repository uses no commit trailers.
86−- Issue titles follow the same prefix style; descriptions open with a bold user story (`**As a <role>, I want <goal>, so that <outcome>.**`) and close with a checklist of acceptance criteria using MUST, SHOULD, or MAY.
87−- Commit messages, code comments, and public issue or PR text must not describe exploitable details of a security fix; present such changes as general hardening.
88− 
89−## Performance & Reliability
90− 
91−- Prefer using existing caches, workers, and batching strategies referenced in code and Makefile. Consider memory/CPU impact; suggest benchmarks or profiling only when justified.
92− 
93−## When Unsure
94− 
95−- Ask for the exact Makefile target or doc link you need, then proceed. Defer to SOT if any conflict arises.
96− 
97−## References To Help Copilot Answer Questions
98− 
99−- Show supported formats/filters: run `photoprism show file-formats` and `photoprism show search-filters` (use results rather than guessing).
100−- For CI/dev containers, assume a Linux/Unix shell on amd64 or arm64 by default; for Windows specifics, link https://docs.photoprism.app/developer-guide/faq/
101− 
102−## Output Expectations
103− 
104−- Prefer short, actionable comments with code blocks that pass tests locally: `make test-js` (frontend) / `make test-go` (backend)
105−- If a suggestion requires additional context (e.g., DB access, external service), call it out explicitly.
106− 
107−## Safety Checklist Before Proposing a CLI Command
108− 
109−- Include a dry-run or non-destructive variant if possible.
110−- Recommend creating/using backups before any reset/migrate.
41+- `go build ./...`
42+- `make fmt-go swag-fmt swag`
43+- `go test ./internal/service/cluster/registry -count=1`
44+- `go test ./internal/api -run 'Cluster' -count=1`
45+- `go test ./internal/commands -run 'ClusterRegister|ClusterNodesRotate' -count=1`
11146  
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