# Development Policies Version: 2026-02-22 - Cross-project documentation (such as this file) must include a `Version: YYYY-MM-DD` line near the top so it can be kept in sync with the authoritative source as policies evolve. - All references to Docker images, Go modules, and packages must use cryptographic hashes. Mutable references (tags, `@latest`, etc.) are remote code execution vulnerabilities. - Every repo with software must have a root `Makefile` with these targets: `make test`, `make lint`, `make fmt` (writes), `make fmt-check` (read-only), `make check` (prereqs: `test`, `lint`, `fmt-check`), and `make docker`. - Always use Makefile targets (`make fmt`, `make test`, `make lint`, etc.) instead of invoking the underlying tools directly. The Makefile is the single source of truth for how these operations are run. - Every repo should have a `Dockerfile`. For non-server repos, the Dockerfile should bring up a development environment and run `make check` (the build should fail if the branch is not green). - Use platform-standard formatters: `black` for Python, `prettier` for JS/CSS/Markdown/HTML, `go fmt` for Go. Always use default configuration with one exception: set four-space indents for everything except Go. Documentation and writing repos (Markdown, HTML, CSS) should also have `.prettierrc` and `.prettierignore`. - Pre-commit hook: `make check` if local testing is possible, otherwise `make lint && make fmt-check`. The Makefile should provide a `make hooks` target to install the pre-commit hook. - `make test` must complete in under 20 seconds. Add a 30-second timeout in the Makefile. - Docker builds must complete in under 5 minutes. - `make check` must not modify any files in the repo. Tests may use temporary directories. - `main` must always pass `make check`, no exceptions. - Never use `git add -A` or `git add .`. Always stage files explicitly by name. - Make all changes on a feature branch. You can do whatever you want on a feature branch. - `.golangci.yml` is standardized and must _NEVER_ be modified by an agent, only manually by the user. Copy from `~/dev/upaas/.golangci.yml` if available. - When pinning images or packages by hash, add a comment above the reference with the version and date (YYYY-MM-DD). - Use `yarn`, not `npm`. - Write all dates as YYYY-MM-DD (ISO 8601). - Simple projects should be configured with environment variables. - Dockerized web services listen on port 8080 by default, overridable with `PORT`. - `README.md` is the primary documentation. Required sections: - **Description**: First line must include the project name, purpose, category (web server, SPA, CLI tool, etc.), license, and author. Example: "µPaaS is an MIT-licensed Go web application by @sneak that receives git-frontend webhooks and deploys applications via Docker in realtime." - **Getting Started**: Copy-pasteable install/usage code block. - **Rationale**: Why does this exist? - **Design**: How is the program structured? - **TODO**: Update meticulously, even between commits. When planning, put the todo list in the README so a new agent can pick up where the last one left off. - **License**: MIT, GPL, or WTFPL. Ask the user for new projects. Include a `LICENSE` file in the repo root and a License section in the README. - **Author**: [@sneak](https://sneak.berlin). - First commit of a new repo should contain only `README.md`. - Go module root: `sneak.berlin/go/`. - Use SemVer. - Database migrations live in `internal/db/migrations/` and must be embedded in the binary. Pre-1.0.0: modify existing migrations (no installed base assumed). Post-1.0.0: add new migration files. - All repos should have an `.editorconfig` enforcing the project's indentation settings. - Avoid putting files in the repo root unless necessary. Root should contain only project-level config files (`README.md`, `Makefile`, `Dockerfile`, `LICENSE`, `.gitignore`, `.editorconfig`, `REPO_POLICIES.md`, and language-specific config). Everything else goes in a subdirectory. Canonical subdirectory names: - `bin/` — executable scripts and tools - `cmd/` — Go command entrypoints - `configs/` — configuration templates and examples - `deploy/` — deployment manifests (k8s, compose, terraform) - `docs/` — documentation and markdown (README.md stays in root) - `internal/` — Go internal packages - `internal/db/migrations/` — database migrations - `pkg/` — Go library packages - `share/` — systemd units, data files - `static/` — static assets (images, fonts, etc.) - `web/` — web frontend source - New repos must contain at minimum: - `README.md`, `.git`, `.gitignore`, `.editorconfig` - `REPO_POLICIES.md` (copy from the `prompts` repo) - `Dockerfile`, `.dockerignore` - Go: `go.mod`, `go.sum`, `.golangci.yml` - JS: `package.json`, `yarn.lock`, `.prettierrc`, `.prettierignore` - Python: `pyproject.toml`