9.5 KiB
Repository Agent Guidelines
Instruction hierarchy
- The rules in this file apply to every repository task.
- Before changing files in a scoped module, read and follow that module's
AGENTS.mdin addition to this file. - For cross-module work, apply every relevant scoped instruction file and completion workflow.
Autogenerated code
- Never commit autogenerated code to the repository. This applies to backend, frontend, shared packages, and every other module, including generated protobuf bindings, API clients, serializers, and framework-generated code.
- Commit the source definitions, generator configuration, and reproducible generation commands instead. Generate code locally or during build and CI workflows before any dependent validation or compilation steps.
- Keep generated outputs ignored by Git. Do not force-add ignored generated files or copy generated code into tracked source files.
- Change the source definitions or generator inputs rather than editing generated outputs. Document the generation workflow so a clean checkout can build without committed generated code.
Local development tooling
Use Make and shell for local development orchestration. Do not introduce Python scripts or a Python runtime dependency. Keep bootstrap tools inside Docker so the host needs only Make, a POSIX shell and Docker with Compose/BuildKit.
Container versions
Use only the latest stable upstream releases for infrastructure, product base images, build stages and disposable test containers. Exclude prereleases and vendor mainline channels when a separate stable channel exists. Resolve stable versions when building, pull fresh manifests, and pin the resolved image digests for that local build. Fail when stable release resolution fails; never silently fall back to an older cached version. Keep the reproducible resolver tracked and its generated local pins ignored by Git.
Data and state architecture
Preserve explicit DTO → mapper → service → data model → provider → UI boundaries across the project. This is a standing requirement for application features, shared packages, stub services and future mobile clients.
- DTOs describe transport data; mappers convert it to/from domain data models.
- Services own external I/O and use mappers. Service contracts return data models, never transport DTOs or untyped response maps to the UI.
- Data models remain distinct from provider state and transport serialization.
- Providers sit on top of services, coordinating loading, errors and state and exposing models to the UI. Widgets render models and invoke provider actions.
- Keep reusable domain models, services and providers in shared packages; clients compose them rather than copy business logic or create alternate data paths.
- Preserve these boundaries when replacing stubs with real backend adapters.
Review every changed feature against them before delivery. Apply the detailed
frontend requirements in
frontend/AGENTS.mdto all Flutter clients/packages.
UX
For any user-facing interface work, follow the UX Design and UX Observability skills. UX is not considered complete unless the interface is both usable and measurable. Before considering UI work complete, apply the UX Review checklist from these skills.
Gitea task policy
Whenever creating or updating a Gitea task, correcting its tracker metadata, or
preparing its implementation branch, use the
$manage-gitea-task skill.
Every created task must have:
- A concise, outcome-oriented title.
- One or more relevant existing labels.
- A responsible person assigned as owner.
- The appropriate existing Gitea project.
- A self-contained body with
Goal,Approach,Acceptance criteria, andNotessections.
Do not guess an assignee, project, label, repository, task number, or module. Resolve missing metadata from authoritative repository or Gitea data, and ask the user when it cannot be determined. Do not create labels or projects unless explicitly requested. Never print, log, or commit API tokens or Git credentials.
Implementation branch policy
Every Gitea task that requires code changes must use a dedicated branch after the task exists and before repository files are changed. Tasks without repository changes do not require a branch.
- Name the branch
<module>-<task-number>using the numeric Gitea task number without#and a specific lowercase kebab-case primary module. - Do not add a
codex/prefix, task title, summary, or generic module such asfeature,fix, orbackendwhen a more specific module is known. - For cross-module work, name the primary module and document secondary modules in the task or pull request.
- Push the branch and attach its exact short name to the issue
refbefore changing repository files. - Verify the issue response contains the intended branch, project, labels, and assignee before implementation begins.
Scoped implementation requirements
- For backend code under
backend/, read and followbackend/AGENTS.md. Before reporting completion, use the$review-backend-changeskill. - For Dart or Flutter code under
frontend/, read and followfrontend/AGENTS.md. Before reporting completion, use the$review-frontend-changeskill. - For a change spanning both modules, use both completion-review skills.
These references are explicit because nested AGENTS.md and .agents/skills
discovery depends on the working directory. Keeping the skills at the repository
root makes them available to tasks launched from any repository subtree.
Optional security validation
Security checks are not mandatory prerequisites for completing a task, committing changes, or pushing a branch. Do not run security scans solely because files changed or a commit or push is planned. Run them when the user requests security validation or when security validation is an explicit part of the task's acceptance criteria.
References in scoped AGENTS.md files and completion-review skills to the
root security requirements follow this optional policy; they do not create
an automatic security gate for completion, commits, or pushes.
When security validation is requested, select commands from the task's own diff, including its uncommitted files, and ignore unrelated pre-existing worktree changes:
- Use
make security-source-frontendfor frontend source, dependencies, configuration, assets, or executable tests. - Use
make security-source-backendfor backend Go source, dependencies, configuration, or protobuf contracts that affect generated backend code. - Use
make security-sourcefor changes spanning both source areas or shared source-security inputs. - Use
make security-images SERVICES="..."for the exact affected Compose services when container contents, Dockerfiles, container dependencies, Compose image/build configuration, or deployment image selection change. - Use
make test-securityfor changes to the security gate, scanner wrappers, lock handling, exception evaluation, database handling, security-related Make targets, or deployment-gate orchestration. Pair it with the relevant live scan when that behavior is part of the requested validation. - Use the full
make securitygate when the requested validation covers the canonical service set or requires a combined source and image verdict.
For scans that are run, use the latest stable scanner images, current validated databases, and the canonical exception manifest. Do not add native scanner suppressions or weaken thresholds. Any reviewed temporary exception must use the canonical exception manifest and satisfy its validation policy.
Report commands actually run and their outcomes, including any failures or external blockers. Do not claim successful validation for checks that were not run. This policy does not change executable CI or deployment gates.
Delivery workflow
For implementation work, finish the authorized delivery workflow: validate, commit the task contribution, push the implementation branch, and create or update its Gitea pull request. Do not leave completed implementation solely in an uncommitted working tree. Preserve unrelated changes and avoid mixing them into task commits. Record scope, validation, limitations, and PR links in the task and durable repository documentation. Merge only when authorized by the user. If work is delivered as stacked PRs, document dependencies and merge order.
Local infrastructure ownership
Keep infrastructure Dockerfiles under infra/images/ and local Compose, service
configuration and shell tooling under infra/local/. Keep product source under
backend/ and frontend/. Organize Vault KV paths by owning service under
services/<service>/<purpose>, infrastructure under infrastructure/<component>/<purpose>,
and bootstrap administration under infrastructure/<component>/bootstrap.
Do not add BFF-to-notifications caller authentication on the trusted private network.
Preserve NATS authentication.
Use Caddy for local browser HTTPS and certificate management. Treat the private
local Docker network as trusted; do not add internal gRPC TLS or Vault-managed
local TLS certificates without an explicit requirement.
Store only secret values in Vault. Driver selection, sender identities, endpoints
and other non-secret runtime settings belong in service configuration files.