diff --git a/REPO_POLICIES.md b/REPO_POLICIES.md index 9f8e5dd..5f8e062 100644 --- a/REPO_POLICIES.md +++ b/REPO_POLICIES.md @@ -1,6 +1,6 @@ --- title: Repository Policies -last_modified: 2026-03-10 +last_modified: 2026-02-22 --- This document covers repository structure, tooling, and workflow standards. Code @@ -98,13 +98,6 @@ style conventions are in separate documents: `https://git.eeqj.de/sneak/prompts/raw/branch/main/.gitignore` when setting up a new repo. -- **No build artifacts in version control.** Code-derived data (compiled - bundles, minified output, generated assets) must never be committed to the - repository if it can be avoided. The build process (e.g. Dockerfile, Makefile) - should generate these at build time. Notable exception: Go protobuf generated - files (`.pb.go`) ARE committed because repos need to work with `go get`, which - downloads code but does not execute code generation. - - Never use `git add -A` or `git add .`. Always stage files explicitly by name. - Never force-push to `main`. @@ -128,80 +121,20 @@ style conventions are in separate documents: - Dockerized web services listen on port 8080 by default, overridable with `PORT`. -- **HTTP/web services must be hardened for production internet exposure before - tagging 1.0.** This means full compliance with security best practices - including, without limitation, all of the following: - - **Security headers** on every response: - - `Strict-Transport-Security` (HSTS) with `max-age` of at least one year - and `includeSubDomains`. - - `Content-Security-Policy` (CSP) with a restrictive default policy - (`default-src 'self'` as a baseline, tightened per-resource as - needed). Never use `unsafe-inline` or `unsafe-eval` unless - unavoidable, and document the reason. - - `X-Frame-Options: DENY` (or `SAMEORIGIN` if framing is required). - Prefer the `frame-ancestors` CSP directive as the primary control. - - `X-Content-Type-Options: nosniff`. - - `Referrer-Policy: strict-origin-when-cross-origin` (or stricter). - - `Permissions-Policy` restricting access to browser features the - application does not use (camera, microphone, geolocation, etc.). - - **Request and response limits:** - - Maximum request body size enforced on all endpoints (e.g. Go - `http.MaxBytesReader`). Choose a sane default per-route; never accept - unbounded input. - - Maximum response body size where applicable (e.g. paginated APIs). - - `ReadTimeout` and `ReadHeaderTimeout` on the `http.Server` to defend - against slowloris attacks. - - `WriteTimeout` on the `http.Server`. - - `IdleTimeout` on the `http.Server`. - - Per-handler execution time limits via `context.WithTimeout` or - chi/stdlib `middleware.Timeout`. - - **Authentication and session security:** - - Rate limiting on password-based authentication endpoints. API keys are - high-entropy and not susceptible to brute force, so they are exempt. - - CSRF tokens on all state-mutating HTML forms. API endpoints - authenticated via `Authorization` header (Bearer token, API key) are - exempt because the browser does not attach these automatically. - - Passwords stored using bcrypt, scrypt, or argon2 — never plain-text, - MD5, or SHA. - - Session cookies set with `HttpOnly`, `Secure`, and `SameSite=Lax` (or - `Strict`) attributes. - - **Reverse proxy awareness:** - - True client IP detection when behind a reverse proxy - (`X-Forwarded-For`, `X-Real-IP`). The application must accept - forwarded headers only from a configured set of trusted proxy - addresses — never trust `X-Forwarded-For` unconditionally. - - **CORS:** - - Authenticated endpoints must restrict `Access-Control-Allow-Origin` to - an explicit allowlist of known origins. Wildcard (`*`) is acceptable - only for public, unauthenticated read-only APIs. - - **Error handling:** - - Internal errors must never leak stack traces, SQL queries, file paths, - or other implementation details to the client. Return generic error - messages in production; detailed errors only when `DEBUG` is enabled. - - **TLS:** - - Services never terminate TLS directly. They are always deployed behind - a TLS-terminating reverse proxy. The service itself listens on plain - HTTP. However, HSTS headers and `Secure` cookie flags must still be - set by the application so that the browser enforces HTTPS end-to-end. - - This list is non-exhaustive. Apply defense-in-depth: if a standard security - hardening measure exists for HTTP services and is not listed here, it is - still expected. When in doubt, harden. - - `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). + - **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`. @@ -211,14 +144,8 @@ style conventions are in separate documents: - Use SemVer. - Database migrations live in `internal/db/migrations/` and must be embedded in - the binary. - - `000_migration.sql` — contains ONLY the creation of the migrations - tracking table itself. Nothing else. - - `001_schema.sql` — the full application schema. - - **Pre-1.0.0:** never add additional migration files (002, 003, etc.). - There is no installed base to migrate. Edit `001_schema.sql` directly. - - **Post-1.0.0:** add new numbered migration files for each schema change. - Never edit existing migrations after release. + 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. @@ -228,28 +155,28 @@ style conventions are in separate documents: `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 + - `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 - When setting up a new repo, files from the `prompts` repo may be used as templates. Fetch them from `https://git.eeqj.de/sneak/prompts/raw/branch/main/`. - New repos must contain at minimum: - - `README.md`, `.git`, `.gitignore`, `.editorconfig` - - `LICENSE`, `REPO_POLICIES.md` (copy from the `prompts` repo) - - `Makefile` - - `Dockerfile`, `.dockerignore` - - `.gitea/workflows/check.yml` - - Go: `go.mod`, `go.sum`, `.golangci.yml` - - JS: `package.json`, `yarn.lock`, `.prettierrc`, `.prettierignore` - - Python: `pyproject.toml` + - `README.md`, `.git`, `.gitignore`, `.editorconfig` + - `LICENSE`, `REPO_POLICIES.md` (copy from the `prompts` repo) + - `Makefile` + - `Dockerfile`, `.dockerignore` + - `.gitea/workflows/check.yml` + - Go: `go.mod`, `go.sum`, `.golangci.yml` + - JS: `package.json`, `yarn.lock`, `.prettierrc`, `.prettierignore` + - Python: `pyproject.toml`