# Cline rules for the "beam" project ## Role Act as an expert Go backend/web developer. This is a small, public-facing HTTP file-transfer service (upload/download via curl or a web UI). Prioritize idiomatic, stdlib-first Go, correctness, and security — anonymous users can upload arbitrary files, so treat all input as untrusted. ## Project architecture facts - Single-file `main.go` using only the Go standard library (`net/http`, `html/template`, etc.) — no web framework, router, or third-party dependencies. Keep `go.mod` dependency-free unless the user explicitly approves adding one. - `index.html.tmpl` is the only frontend asset, rendered via `html/template` with inline CSS/JS. Keep it self-contained — no external asset build step, no CDN dependencies. - Configuration is via environment variables only (`UPLOAD_DIR`, `PORT`, `FILE_DURATION`, `DRYRUN_CLEAN`, `MAX_UPLOAD_SIZE`, etc.). Follow this pattern for any new configuration knob, validate it at startup with `log.Fatalf` on invalid values, log the effective value, and document it in `README.md`. - The background cleanup goroutine (`cleanupProcedure`) follows a dry-run-by-default, structured-logging pattern. Any new periodic background job should follow the same style: reset per-cycle state, dry-run support, and clear log messages for what was/would be done. ## Go version - The toolchain version is pinned in `go.mod` (currently `go 1.27`). Match `go.mod` and the Dockerfile's `golang:X-alpine` builder image tag whenever bumping — never let the two drift apart. Don't use stdlib APIs newer than the pinned version. ## Kubernetes / TLS ingress deployment implications This service runs in Kubernetes behind a TLS-terminating ingress. - Never rely on `r.TLS != nil` to detect HTTPS. Always honor `X-Forwarded-Proto` / `X-Forwarded-Host` / `Forwarded` headers for any URL generation, matching the existing `getProtocol`/`getHost` helpers. - `/healthz` is used for k8s liveness/readiness probes: keep it fast and cheap (e.g. `os.Stat` on the upload dir is fine). Do not add slow checks, external calls, or heavy I/O to it. - The process receives SIGTERM on pod termination followed by SIGKILL after the grace period. Any new long-running goroutine or in-flight request handling must respect context cancellation / `srv.Shutdown` and not block graceful shutdown. - Assume horizontal scaling with multiple replicas: do not add in-memory state that must be shared/consistent across pods (e.g. in-memory rate limiting, sessions, counters) without explicitly calling out that it is per-pod-only and confirming that's acceptable. - `UPLOAD_DIR` may be backed by a PersistentVolume. Don't assume it's ephemeral, and don't assume it's shared across replicas (RWX) unless confirmed — flag this tradeoff if a feature depends on it. - The container runs as a non-root user (see Dockerfile `USER beam`). New code must not require root-only operations (binding privileged ports, chown, etc.). ## Coding conventions - Always run `go build ./...`, `go vet ./...`, and `gofmt -l .` before considering a change complete; fix any findings. - Prefer the standard library over new dependencies (e.g. use `log/slog` if structured logging is ever introduced, rather than a third-party logger). - All path handling derived from user input (upload/download IDs, filenames) must be validated with `filepath.IsLocal` and/or `filepath.Clean`/`filepath.Base` before use — never trust raw path segments from the URL or multipart form. - All upload code paths must enforce `maxUploadSize` via `http.MaxBytesReader`, and clean up any partially written file/directory on failure. - New HTTP handlers must call `logRequest` with an accurate status code for every response path. - Keep the JSON error shape for `/upload` consistent with `writeMultipartError` (`{"error": "..."}`). ## Git workflow - One logical change per commit. - Commit subject is a single line, no body. - Keep `.gitignore` up to date rather than leaving stray build/test artifacts untracked in the working tree. ## Testing - There are currently no `*_test.go` files. When adding or changing logic that is easy to regress (path safety, ID generation, header parsing, upload size limits), add table-driven tests using the standard `testing` package and `net/http/httptest` where applicable. ## Documentation - Keep `README.md` and the in-page instructions/labels in `index.html.tmpl` (e.g. max upload size, usage examples) in sync with actual runtime behavior.