8 Commits

Author SHA1 Message Date
05fe766c62 Improve quickstart commands with two-pass workflow
All checks were successful
check / check (push) Successful in 4s
Split quickstart into separate repo-policy and code-style passes, clone
prompts repo once instead of per-command, and make each prompt
self-contained so agents don't need memory of prior runs.
2026-02-23 00:33:15 +07:00
cb5d630158 add note about makefile being authoritative docs
All checks were successful
check / check (push) Successful in 8s
2026-02-23 00:09:13 +07:00
b5575b9f59 Add test requirements to checklists, .dockerignore URLs, root symlink, and Makefile comment
All checks were successful
check / check (push) Successful in 7s
- Add test requirement item to both checklists (must not be a no-op)
- Add .dockerignore template URL to Dockerfile items in both checklists
- Add REPO_POLICIES.md symlink in repo root pointing to prompts/
- Add comment to Makefile explaining why prettier flags are repeated
2026-02-22 17:21:42 +01:00
e97b48eea4 Fix review issues: front matter, headings, consistency, typos
All checks were successful
check / check (push) Successful in 9s
- Move title and last_modified to YAML front matter (all policy docs)
- Make all document sections H1, subsections H2
- Update version rule to reference front matter format
- Fix "our" → "your" typo in Go styleguide
- Fix Python styleguide numbering (2. → 1.)
- Fix README: "flat collection" → accurate description, remove stale TODO
- Remove Makefile items from code styleguides (repo stuff, not code),
  add note linking to Repository Policies
- Change zerolog → slog in Go styleguide
- Fix JS styleguide npm reference: both work, but use make targets
- Drop .json from healthcheck path, add JSON content-type requirement
- Add Author/License to Go HTTP Server Conventions
- Convert hyperlinks to backtick URLs in checklists for consistency
- Add version/front matter to both checklists
2026-02-22 17:15:06 +01:00
3768b8ca02 Add rule: all software repos must have tests
All checks were successful
check / check (push) Successful in 7s
Require at least minimal tests (e.g. import/compile check) using the
platform-standard test framework. make test must never be a no-op.
2026-02-22 16:56:03 +01:00
03bf0b8445 Add authoritative URLs to checklists and copy .golangci.yml
All checks were successful
check / check (push) Successful in 7s
- Add .golangci.yml from upaas as authoritative copy in this repo
- Update REPO_POLICIES.md to reference .golangci.yml by URL
- Add fetch URLs for all template files in both checklists:
  .gitignore, .editorconfig, Makefile, .prettierrc, .prettierignore,
  REPO_POLICIES.md, .golangci.yml, check.yml
2026-02-22 16:52:33 +01:00
3a5ac2d72f Fix typo and match second quickstart example to first
All checks were successful
check / check (push) Successful in 7s
- Fix "do you work" → "do your work"
- Reformat new-repo quickstart to use same multi-line style
2026-02-22 16:47:12 +01:00
00c21cc5c5 Fix heading, scope, version placement, and consistency across policy docs
- Rename REPO_POLICIES.md heading from "Development Policies" to
  "Repository Policies" to distinguish from code styleguides
- Move version line above heading per convention
- Add scope statement and links to code styleguide documents
- Add missing Makefile and LICENSE to minimum files list
- Add version lines to all cross-project docs (CODE_STYLEGUIDE*.md,
  GO_HTTP_SERVER_CONVENTIONS.md)
- Clean up CODE_STYLEGUIDE.md heading (was old repo name)
- Update EXISTING_REPO_CHECKLIST.md link text to match new heading
2026-02-22 16:40:34 +01:00
12 changed files with 336 additions and 171 deletions

32
.golangci.yml Normal file
View File

@@ -0,0 +1,32 @@
version: "2"
run:
timeout: 5m
modules-download-mode: readonly
linters:
default: all
disable:
# Genuinely incompatible with project patterns
- exhaustruct # Requires all struct fields
- depguard # Dependency allow/block lists
- godot # Requires comments to end with periods
- wsl # Deprecated, replaced by wsl_v5
- wrapcheck # Too verbose for internal packages
- varnamelen # Short names like db, id are idiomatic Go
linters-settings:
lll:
line-length: 88
funlen:
lines: 80
statements: 50
cyclop:
max-complexity: 15
dupl:
threshold: 100
issues:
exclude-use-default: false
max-issues-per-linter: 0
max-same-issues: 0

View File

@@ -1,5 +1,7 @@
.PHONY: test lint fmt fmt-check check docker hooks .PHONY: test lint fmt fmt-check check docker hooks
# flags are repeated here (also in .prettierrc) so this Makefile works
# standalone when copied as a template
PRETTIER := yarn run prettier PRETTIER := yarn run prettier
test: test:

View File

@@ -6,16 +6,90 @@ useful prompts for working with large language models.
## Quick Start ## Quick Start
Bring an existing repo up to standards (run from within the repo): ### Existing Repo
Run from within the repo you want to bring up to standards. Clone the prompts
repo once, then run both commands in order.
```bash ```bash
P=$(mktemp -d) && git clone --depth 1 https://git.eeqj.de/sneak/prompts.git "$P" && claude "Read $P/prompts/REPO_POLICIES.md and $P/prompts/EXISTING_REPO_CHECKLIST.md, then bring this repo up to those standards." export TD="$(mktemp -d)"
git clone --depth 1 https://git.eeqj.de/sneak/prompts.git "$TD"
``` ```
Start a new repo from scratch: **Repository structure and policies:**
```bash ```bash
P=$(mktemp -d) && git clone --depth 1 https://git.eeqj.de/sneak/prompts.git "$P" && claude "Read $P/prompts/REPO_POLICIES.md and $P/prompts/NEW_REPO_CHECKLIST.md, then set up this new repo according to those standards." claude "Read $TD/prompts/REPO_POLICIES.md and
$TD/prompts/EXISTING_REPO_CHECKLIST.md, then bring this repo up to those
standards. Your scope is repo scaffolding and policy compliance:
Makefile, Dockerfile, .dockerignore, .gitignore, .editorconfig, CI
workflow, README sections, LICENSE, REPO_POLICIES.md, and any
language-specific config files (.golangci.yml, .prettierrc, etc.).
You must also run the formatter (make fmt) and fix any linter errors
(make lint) so that make check passes — this will touch source code,
but do not restructure, refactor, or rewrite any application logic.
Follow the policies yourself: work on a feature branch, never git add -A,
and make each logical change a separate commit (e.g. one commit for
formatting, one for linter fixes, one for README updates, one for each
new repo file added, etc.)."
```
**Code style and conventions:**
```bash
claude "Read $TD/prompts/CODE_STYLEGUIDE.md and whichever
language-specific styleguides in $TD/prompts/ apply to this repo
(CODE_STYLEGUIDE_GO.md, CODE_STYLEGUIDE_JS.md, CODE_STYLEGUIDE_PYTHON.md,
GO_HTTP_SERVER_CONVENTIONS.md). Then review the application code in this
repo and bring it into compliance with those coding standards. Your scope
is application code structure and style: naming, patterns, error
handling, project layout, and conventions described in the styleguides.
Do not modify repo scaffolding (Makefile, Dockerfile, CI workflow,
.gitignore, .editorconfig, etc.) — only application code. Work on a
feature branch, never git add -A, and make each logical change a
separate commit."
```
### New Repo
Run from inside the directory where you want to create a new repo. Clone the
prompts repo once, then run both commands in order.
```bash
export TD="$(mktemp -d)"
git clone --depth 1 https://git.eeqj.de/sneak/prompts.git "$TD"
```
**Repository scaffolding:**
```bash
claude "Read $TD/prompts/REPO_POLICIES.md and
$TD/prompts/NEW_REPO_CHECKLIST.md, then set up this new repo according
to those standards. Your scope is repo structure and required files:
README.md, LICENSE, REPO_POLICIES.md, Makefile, Dockerfile, .dockerignore,
.gitignore, .editorconfig, CI workflow, and language-specific config.
Run the formatter (make fmt) and fix any linter errors (make lint) so
that make check passes — this will touch source code, but do not
restructure, refactor, or rewrite any application logic. Follow the
policies yourself: work on a feature branch, never git add -A, and make
each logical change a separate commit (e.g. one commit for formatting,
one for linter fixes, one for README, one for each new repo file, etc.)."
```
**Code style and conventions:**
```bash
claude "Read $TD/prompts/CODE_STYLEGUIDE.md and whichever
language-specific styleguides in $TD/prompts/ apply to this repo
(CODE_STYLEGUIDE_GO.md, CODE_STYLEGUIDE_JS.md, CODE_STYLEGUIDE_PYTHON.md,
GO_HTTP_SERVER_CONVENTIONS.md). Then review the application code in this
repo and bring it into compliance with those coding standards. Your scope
is application code structure and style: naming, patterns, error
handling, project layout, and conventions described in the styleguides.
Do not modify repo scaffolding (Makefile, Dockerfile, CI workflow,
.gitignore, .editorconfig, etc.) — only application code. Work on a
feature branch, never git add -A, and make each logical change a
separate commit."
``` ```
## Getting Started ## Getting Started
@@ -36,15 +110,14 @@ share, and evolve prompts across projects.
## Design ## Design
The repository is a flat collection of Markdown files. Each file contains one or The repository is a collection of Markdown files organized in the `prompts/`
more related prompts or policy documents. There is no build step or runtime subdirectory. Each file contains one or more related prompts or policy
component; the prompts are consumed by copying them into other projects or documents. There is no build step or runtime component; the prompts are consumed
referencing them directly. by copying them into other projects or referencing them directly.
## TODO ## TODO
- Add more prompt templates for common development tasks - Add more prompt templates for common development tasks
- Add CI to lint Markdown
## License ## License

1
REPO_POLICIES.md Symbolic link
View File

@@ -0,0 +1 @@
prompts/REPO_POLICIES.md

View File

@@ -1,28 +1,13 @@
# sneak/styleguide ---
title: Code Styleguide
last_modified: 2026-02-22
---
The following is the first released version of my personal code styleguide. # All
There are many like it, but this one is mine.
Only the Go portion is "complete". The others are mostly just placeholders. 1. Every repo must have a `Makefile` and a `Dockerfile`. See
[Repository Policies](https://git.eeqj.de/sneak/prompts/raw/branch/main/prompts/REPO_POLICIES.md)
Feedback and suggestions are not only welcome but explicitly encouraged. for required targets and conventions.
[sneak@sneak.berlin](mailto:sneak@sneak.berlin)
# My 2024 Code Styleguide
## All
1. Every project/repo should have a `Makefile` in the root. At a minimum,
`make clean`, `make run`, `make fmt`, and `make test` should work. Choose a
sane default target (`test` for libraries, `run` or `publish` for binaries).
`fmt` should invoke the appropriate formatters for the files in the repo,
such as `go fmt`, `prettier`, `black`, etc. Other standard `Makefile` targets
include `deploy`, `lint`. Consider the `Makefile` the official documentation
about how to operate the repository.
1. If it's possible to write a `Dockerfile`, include at least a simple one. It
should be possible to build and run the project with `docker build .`.
1. For F/OSS-licensed software, try to include the full source code of the 1. For F/OSS-licensed software, try to include the full source code of the
current version (and any dependencies, such as vendored dependencies) in the current version (and any dependencies, such as vendored dependencies) in the
@@ -51,18 +36,16 @@ Feedback and suggestions are not only welcome but explicitly encouraged.
be enabled in prod. be enabled in prod.
1. For services/servers, make a healthcheck available at 1. For services/servers, make a healthcheck available at
`/.well-known/healthcheck`. This is out of spec but it is my personal `/.well-known/healthcheck`. The response must have a
standard. This should return a 200 OK if the service is healthy, along with a `Content-Type: application/json` header and return a JSON object containing
JSON object containing the service's name, uptime, and any other relevant the service's name, uptime, and a key of `"status"` with a value of `"ok"`.
information, and a key of "status" with a value of "ok" if the service is Return a 200 for healthy, 5xx for unhealthy.
healthy. Make sure that in the event of a failure, the service returns a 5xx
status code for that route.
1. If possible, for services/servers, include a /metrics endpoint that returns 1. If possible, for services/servers, include a /metrics endpoint that returns
Prometheus-formatted metrics. This is not required for all services, but is a Prometheus-formatted metrics. This is not required for all services, but is a
nice-to-have. nice-to-have.
## Bash / Shell # Bash / Shell
1. Use `[[` instead of `[` for conditionals. It's a shell builtin and doesn't 1. Use `[[` instead of `[` for conditionals. It's a shell builtin and doesn't
have to execute a separate process. have to execute a separate process.
@@ -82,7 +65,7 @@ Feedback and suggestions are not only welcome but explicitly encouraged.
1. Put all code in functions, even a main function. Define all functions then 1. Put all code in functions, even a main function. Define all functions then
call main at the bottom of the file. call main at the bottom of the file.
## Docker Containers (for services) # Docker Containers (for services)
1. Use `runit` with `runsvinit` as the entrypoint for all containers. This 1. Use `runit` with `runsvinit` as the entrypoint for all containers. This
allows for easy service management and logging. In startup scripts allows for easy service management and logging. In startup scripts

View File

@@ -1,4 +1,7 @@
# Golang ---
title: Code Styleguide — Go
last_modified: 2026-02-22
---
1. Try to hard wrap long lines at 77 characters or less. 1. Try to hard wrap long lines at 77 characters or less.
@@ -68,11 +71,8 @@
1. Avoid obvious footguns. For example, use range instead of for loops for 1. Avoid obvious footguns. For example, use range instead of for loops for
iterating. iterating.
1. Try to use zerolog for logging. It's fast and has a nice API. For 1. Use `log/slog` for structured logging. Import `sneak.berlin/go/simplelog`
smaller/quick projects, the standard library's `log` package (and for sensible defaults. Example:
specifically `log/slog`) is fine. In that case, log structured logs whenever
possible, and import `sneak.berlin/go/simplelog` to configure it
appropriately. Example:
```go ```go
package main package main
@@ -105,9 +105,9 @@
able-to-be-compiled state, linted, and any tests run. The Docker build able-to-be-compiled state, linted, and any tests run. The Docker build
should fail if linting doesn't pass. should fail if linting doesn't pass.
1. Include a `Makefile` with targets for at least `clean` and `test`. If there 1. Every repo must have a `Makefile`. See
are multiple binaries, include a target for each binary. If there are [Repository Policies](https://git.eeqj.de/sneak/prompts/raw/branch/main/prompts/REPO_POLICIES.md)
multiple binaries, include a target for `all` that builds all binaries. for required targets and conventions.
1. If you are writing a single-module library, `.go` files are okay in the repo 1. If you are writing a single-module library, `.go` files are okay in the repo
root. root.
@@ -130,7 +130,7 @@
single-file scripts. single-file scripts.
1. HTTP HandleFuncs should be returned from methods or functions that need to 1. HTTP HandleFuncs should be returned from methods or functions that need to
handle HTTP requests. Don't use methods or our top level functions as handle HTTP requests. Don't use methods or your top level functions as
handlers. handlers.
1. Provide a .gitignore file that ignores at least `*.log`, `*.out`, and 1. Provide a .gitignore file that ignores at least `*.log`, `*.out`, and
@@ -429,7 +429,7 @@
releasable". "Releasable" in this context means that it builds and functions releasable". "Releasable" in this context means that it builds and functions
as expected, and that all tests and linting passes. as expected, and that all tests and linting passes.
## Other Golang Tips and Best Practices (Optional) # Other Golang Tips and Best Practices (Optional)
1. For any internet-facing http server, set appropriate timeouts and limits to 1. For any internet-facing http server, set appropriate timeouts and limits to
protect against slowloris attacks or huge uploads that can consume server protect against slowloris attacks or huge uploads that can consume server

View File

@@ -1,4 +1,7 @@
# JavaScript / ECMAScript / ES6 ---
title: Code Styleguide — JavaScript
last_modified: 2026-02-22
---
1. Use `const` for everything. If you need to reassign, use `let`. Never use 1. Use `const` for everything. If you need to reassign, use `let`. Never use
`var`. `var`.
@@ -9,9 +12,12 @@
1. Use `prettier` for code formatting, with four spaces for indentation. 1. Use `prettier` for code formatting, with four spaces for indentation.
1. At a minimum, `npm run test` and `npm run build` should work (complete the 1. At a minimum, both `yarn run test`/`yarn run build` and
appropriate scripts in `package.json`). The `Makefile` should call these, do `npm run test`/`npm run build` should work (complete the appropriate scripts
not duplicate the scripts in the `Makefile`. in `package.json`). However, prefer `make test` and `make build` instead —
the Makefile is authoritative on how to interact with the repo. See
[Repository Policies](https://git.eeqj.de/sneak/prompts/raw/branch/main/prompts/REPO_POLICIES.md)
for details.
# Author # Author

View File

@@ -1,8 +1,11 @@
# Python ---
title: Code Styleguide — Python
last_modified: 2026-02-22
---
1. Format all code with `black`, with four space indents. 1. Format all code with `black`, with four space indents.
2. Put all code in functions. If you are writing a script, put the script in a 1. Put all code in functions. If you are writing a script, put the script in a
function called `main` and call `main()` at the end of the script using the function called `main` and call `main()` at the end of the script using the
standard invocation: standard invocation:

View File

@@ -1,56 +1,69 @@
# Existing Repo Checklist ---
title: Existing Repo Checklist
last_modified: 2026-02-22
---
Use this checklist when beginning work in a repo that may not yet conform to our Use this checklist when beginning work in a repo that may not yet conform to our
[development policies](https://git.eeqj.de/sneak/prompts/raw/branch/main/prompts/REPO_POLICIES.md). repository policies
(`https://git.eeqj.de/sneak/prompts/raw/branch/main/prompts/REPO_POLICIES.md`).
Work on a feature branch. Check each item and fix any gaps before proceeding Work on a feature branch. Check each item and fix any gaps before proceeding
with your task. with your task.
## Formatting (do this first) # Formatting (do this first)
- [ ] If the repo has never been formatted to our standards, run `make fmt` and - [ ] If the repo has never been formatted to our standards, run `make fmt` and
commit the result as a standalone branch/commit/PR before any other commit the result as a standalone branch/commit/PR before any other
changes. Formatting diffs can be large and should not be mixed with changes. Formatting diffs can be large and should not be mixed with
functional changes. functional changes.
## Required Files # Required Files
- [ ] `README.md` exists with all required sections (Description, Getting - [ ] `README.md` exists with all required sections (Description, Getting
Started, Rationale, Design, TODO, License, Author) Started, Rationale, Design, TODO, License, Author)
- [ ] `LICENSE` file exists and matches the README - [ ] `LICENSE` file exists and matches the README
- [ ] `REPO_POLICIES.md` exists and version date is current with the - [ ] `REPO_POLICIES.md` exists and version date is current — fetch from
[authoritative source](https://git.eeqj.de/sneak/prompts/raw/branch/main/prompts/REPO_POLICIES.md) `https://git.eeqj.de/sneak/prompts/raw/branch/main/prompts/REPO_POLICIES.md`
- [ ] `.gitignore` is comprehensive (OS, editor, language artifacts, secrets) — - [ ] `.gitignore` is comprehensive (OS, editor, language artifacts, secrets) —
fetch from `https://git.eeqj.de/sneak/prompts/raw/branch/main/.gitignore` fetch from `https://git.eeqj.de/sneak/prompts/raw/branch/main/.gitignore`
if missing if missing
- [ ] `.editorconfig` exists - [ ] `.editorconfig` exists — fetch from
`https://git.eeqj.de/sneak/prompts/raw/branch/main/.editorconfig`
- [ ] `Dockerfile` and `.dockerignore` exist; Dockerfile runs `make check` as a - [ ] `Dockerfile` and `.dockerignore` exist; Dockerfile runs `make check` as a
build step build step — fetch `.dockerignore` from
`https://git.eeqj.de/sneak/prompts/raw/branch/main/.dockerignore`
- [ ] Gitea Actions workflow in `.gitea/workflows/` runs `docker build .` on - [ ] Gitea Actions workflow in `.gitea/workflows/` runs `docker build .` on
push push — reference
`https://git.eeqj.de/sneak/prompts/raw/branch/main/.gitea/workflows/check.yml`
- [ ] Language-specific config: - [ ] Language-specific config:
- [ ] Go: `go.mod`, `go.sum`, `.golangci.yml` - [ ] Go: `go.mod`, `go.sum`, `.golangci.yml` (fetch from
`https://git.eeqj.de/sneak/prompts/raw/branch/main/.golangci.yml`)
- [ ] JS: `package.json`, `yarn.lock`, `.prettierrc`, `.prettierignore` - [ ] JS: `package.json`, `yarn.lock`, `.prettierrc`, `.prettierignore`
(fetch from
`https://git.eeqj.de/sneak/prompts/raw/branch/main/.prettierrc` and
`https://git.eeqj.de/sneak/prompts/raw/branch/main/.prettierignore`)
- [ ] Python: `pyproject.toml` - [ ] Python: `pyproject.toml`
- [ ] Docs/writing: `.prettierrc`, `.prettierignore` - [ ] Docs/writing: `.prettierrc`, `.prettierignore` (same URLs as above)
## Makefile # Makefile
- [ ] `Makefile` exists in root — reference the - [ ] `Makefile` exists in root — reference
[model Makefile](https://git.eeqj.de/sneak/prompts/raw/branch/main/Makefile) `https://git.eeqj.de/sneak/prompts/raw/branch/main/Makefile`
- [ ] Has targets: `test`, `lint`, `fmt`, `fmt-check`, `check`, `docker`, - [ ] Has targets: `test`, `lint`, `fmt`, `fmt-check`, `check`, `docker`,
`hooks` `hooks`
- [ ] `make check` does not modify any files in the repo - [ ] `make check` does not modify any files in the repo
- [ ] `make test` has a 30-second timeout - [ ] `make test` has a 30-second timeout
- [ ] `make test` runs real tests, not a no-op (at minimum, import/compile
check)
- [ ] `make check` passes on current branch - [ ] `make check` passes on current branch
## Formatting # Formatting
- [ ] Platform-standard formatter is configured (`black`, `prettier`, `go fmt`) - [ ] Platform-standard formatter is configured (`black`, `prettier`, `go fmt`)
- [ ] Default formatter config, only exception: four-space indents (except Go) - [ ] Default formatter config, only exception: four-space indents (except Go)
- [ ] All files pass `make fmt-check` - [ ] All files pass `make fmt-check`
## Git Hygiene # Git Hygiene
- [ ] Pre-commit hook is installed (`make hooks`) - [ ] Pre-commit hook is installed (`make hooks`)
- [ ] No secrets in the repo (`.env`, keys, credentials) - [ ] No secrets in the repo (`.env`, keys, credentials)
@@ -58,14 +71,14 @@ with your task.
pinned by cryptographic hash with version/date comment pinned by cryptographic hash with version/date comment
- [ ] Using `yarn`, not `npm` (JS projects) - [ ] Using `yarn`, not `npm` (JS projects)
## Directory Structure # Directory Structure
- [ ] No unnecessary files in repo root - [ ] No unnecessary files in repo root
- [ ] Files organized into canonical subdirectories (`bin/`, `cmd/`, `docs/`, - [ ] Files organized into canonical subdirectories (`bin/`, `cmd/`, `docs/`,
`internal/`, `static/`, etc.) `internal/`, `static/`, etc.)
- [ ] Go migrations in `internal/db/migrations/` and embedded in binary - [ ] Go migrations in `internal/db/migrations/` and embedded in binary
## Final # Final
- [ ] `make check` passes - [ ] `make check` passes
- [ ] `docker build` succeeds - [ ] `docker build` succeeds

View File

@@ -1,10 +1,13 @@
# Go HTTP Server Conventions ---
title: Go HTTP Server Conventions
last_modified: 2026-02-22
---
This document defines the architectural patterns, design decisions, and This document defines the architectural patterns, design decisions, and
conventions for building Go HTTP servers. All new projects must follow these conventions for building Go HTTP servers. All new projects must follow these
standards. standards.
## Table of Contents # Table of Contents
1. [Required Libraries](#1-required-libraries) 1. [Required Libraries](#1-required-libraries)
2. [Project Structure](#2-project-structure) 2. [Project Structure](#2-project-structure)
@@ -23,7 +26,7 @@ standards.
--- ---
## 1. Required Libraries # 1. Required Libraries
These libraries are **mandatory** for all new projects: These libraries are **mandatory** for all new projects:
@@ -42,7 +45,7 @@ These libraries are **mandatory** for all new projects:
--- ---
## 2. Project Structure # 2. Project Structure
``` ```
project-root/ project-root/
@@ -84,7 +87,7 @@ project-root/
└── Dockerfile └── Dockerfile
``` ```
### Key Principles ## Key Principles
- **`cmd/{appname}/`**: Only the entry point. Minimal logic, just bootstrapping. - **`cmd/{appname}/`**: Only the entry point. Minimal logic, just bootstrapping.
- **`internal/`**: All application packages. Not importable by external - **`internal/`**: All application packages. Not importable by external
@@ -94,9 +97,9 @@ project-root/
--- ---
## 3. Dependency Injection (Uber fx) # 3. Dependency Injection (Uber fx)
### Entry Point Pattern ## Entry Point Pattern
```go ```go
// cmd/httpd/main.go // cmd/httpd/main.go
@@ -141,7 +144,7 @@ func main() {
} }
``` ```
### Params Struct Pattern ## Params Struct Pattern
Every component that receives dependencies uses a params struct with `fx.In`: Every component that receives dependencies uses a params struct with `fx.In`:
@@ -161,7 +164,7 @@ type Handlers struct {
} }
``` ```
### Factory Function Pattern ## Factory Function Pattern
All components expose a `New` function with this signature: All components expose a `New` function with this signature:
@@ -185,7 +188,7 @@ func New(lc fx.Lifecycle, params SomeParams) (*Something, error) {
} }
``` ```
### Dependency Order ## Dependency Order
Providers are resolved automatically by fx, but conceptually follow this order: Providers are resolved automatically by fx, but conceptually follow this order:
@@ -201,9 +204,9 @@ Providers are resolved automatically by fx, but conceptually follow this order:
--- ---
## 4. Server Architecture # 4. Server Architecture
### Server Struct ## Server Struct
The Server struct is the central orchestrator: The Server struct is the central orchestrator:
@@ -234,7 +237,7 @@ type Server struct {
} }
``` ```
### Server Factory ## Server Factory
```go ```go
func New(lc fx.Lifecycle, params ServerParams) (*Server, error) { func New(lc fx.Lifecycle, params ServerParams) (*Server, error) {
@@ -259,7 +262,7 @@ func New(lc fx.Lifecycle, params ServerParams) (*Server, error) {
} }
``` ```
### HTTP Server Setup ## HTTP Server Setup
```go ```go
// internal/server/http.go // internal/server/http.go
@@ -289,7 +292,7 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
} }
``` ```
### Signal Handling and Graceful Shutdown ## Signal Handling and Graceful Shutdown
```go ```go
func (s *Server) serve() int { func (s *Server) serve() int {
@@ -333,9 +336,9 @@ func (s *Server) cleanShutdown() {
--- ---
## 5. Routing (go-chi) # 5. Routing (go-chi)
### Route Setup Pattern ## Route Setup Pattern
```go ```go
// internal/server/routes.go // internal/server/routes.go
@@ -378,7 +381,7 @@ func (s *Server) SetupRoutes() {
s.router.Get("/login", auth(s.h.HandleLoginGET()).ServeHTTP) s.router.Get("/login", auth(s.h.HandleLoginGET()).ServeHTTP)
// Health check (standard path) // Health check (standard path)
s.router.Get("/.well-known/healthcheck.json", s.h.HandleHealthCheck()) s.router.Get("/.well-known/healthcheck", s.h.HandleHealthCheck())
// Protected route groups // Protected route groups
if viper.GetString("METRICS_USERNAME") != "" { if viper.GetString("METRICS_USERNAME") != "" {
@@ -390,7 +393,7 @@ func (s *Server) SetupRoutes() {
} }
``` ```
### Middleware Ordering (Critical) ## Middleware Ordering (Critical)
1. `middleware.Recoverer` - Panic recovery (must be first) 1. `middleware.Recoverer` - Panic recovery (must be first)
2. `middleware.RequestID` - Generate request IDs 2. `middleware.RequestID` - Generate request IDs
@@ -400,7 +403,7 @@ func (s *Server) SetupRoutes() {
6. `middleware.Timeout(60s)` - Request timeout 6. `middleware.Timeout(60s)` - Request timeout
7. `sentryhttp.Handler` - Sentry error reporting (if enabled) 7. `sentryhttp.Handler` - Sentry error reporting (if enabled)
### API Versioning ## API Versioning
Use route groups for API versioning: Use route groups for API versioning:
@@ -410,7 +413,7 @@ s.router.Route("/api/v1", func(r chi.Router) {
}) })
``` ```
### Static File Serving ## Static File Serving
Static files are served at `/s/` prefix: Static files are served at `/s/` prefix:
@@ -420,9 +423,9 @@ s.router.Mount("/s", http.StripPrefix("/s", http.FileServer(http.FS(static.Stati
--- ---
## 6. Handler Conventions # 6. Handler Conventions
### Handler Base Struct ## Handler Base Struct
```go ```go
// internal/handlers/handlers.go // internal/handlers/handlers.go
@@ -455,7 +458,7 @@ func New(lc fx.Lifecycle, params HandlersParams) (*Handlers, error) {
} }
``` ```
### Closure-Based Handler Pattern ## Closure-Based Handler Pattern
All handlers return `http.HandlerFunc` using the closure pattern. This allows All handlers return `http.HandlerFunc` using the closure pattern. This allows
initialization logic to run once when the handler is created: initialization logic to run once when the handler is created:
@@ -477,7 +480,7 @@ func (s *Handlers) HandleIndex() http.HandlerFunc {
} }
``` ```
### JSON Handler Pattern ## JSON Handler Pattern
```go ```go
// internal/handlers/now.go // internal/handlers/now.go
@@ -492,7 +495,7 @@ func (s *Handlers) HandleNow() http.HandlerFunc {
} }
``` ```
### Response Helpers ## Response Helpers
```go ```go
// internal/handlers/handlers.go // internal/handlers/handlers.go
@@ -512,7 +515,7 @@ func (s *Handlers) decodeJSON(w http.ResponseWriter, r *http.Request, v interfac
} }
``` ```
### Handler Naming Convention ## Handler Naming Convention
- `HandleIndex()` - Main page - `HandleIndex()` - Main page
- `HandleLoginGET()` / `HandleLoginPOST()` - Form handlers with HTTP method - `HandleLoginGET()` / `HandleLoginPOST()` - Form handlers with HTTP method
@@ -522,9 +525,9 @@ func (s *Handlers) decodeJSON(w http.ResponseWriter, r *http.Request, v interfac
--- ---
## 7. Middleware Conventions # 7. Middleware Conventions
### Middleware Struct ## Middleware Struct
```go ```go
// internal/middleware/middleware.go // internal/middleware/middleware.go
@@ -548,7 +551,7 @@ func New(lc fx.Lifecycle, params MiddlewareParams) (*Middleware, error) {
} }
``` ```
### Middleware Signature ## Middleware Signature
All custom middleware methods return `func(http.Handler) http.Handler`: All custom middleware methods return `func(http.Handler) http.Handler`:
@@ -567,7 +570,7 @@ func (s *Middleware) Auth() func(http.Handler) http.Handler {
} }
``` ```
### Logging Middleware with Status Capture ## Logging Middleware with Status Capture
```go ```go
type loggingResponseWriter struct { type loggingResponseWriter struct {
@@ -611,7 +614,7 @@ func (s *Middleware) Logging() func(http.Handler) http.Handler {
} }
``` ```
### CORS Middleware ## CORS Middleware
```go ```go
func (s *Middleware) CORS() func(http.Handler) http.Handler { func (s *Middleware) CORS() func(http.Handler) http.Handler {
@@ -626,7 +629,7 @@ func (s *Middleware) CORS() func(http.Handler) http.Handler {
} }
``` ```
### Metrics Middleware ## Metrics Middleware
```go ```go
func (s *Middleware) Metrics() func(http.Handler) http.Handler { func (s *Middleware) Metrics() func(http.Handler) http.Handler {
@@ -652,9 +655,9 @@ func (s *Middleware) MetricsAuth() func(http.Handler) http.Handler {
--- ---
## 8. Configuration (Viper) # 8. Configuration (Viper)
### Config Struct ## Config Struct
```go ```go
// internal/config/config.go // internal/config/config.go
@@ -677,7 +680,7 @@ type Config struct {
} }
``` ```
### Configuration Loading ## Configuration Loading
```go ```go
func New(lc fx.Lifecycle, params ConfigParams) (*Config, error) { func New(lc fx.Lifecycle, params ConfigParams) (*Config, error) {
@@ -735,7 +738,7 @@ func New(lc fx.Lifecycle, params ConfigParams) (*Config, error) {
} }
``` ```
### Configuration Precedence ## Configuration Precedence
1. **Environment variables** (highest priority via `AutomaticEnv()`) 1. **Environment variables** (highest priority via `AutomaticEnv()`)
2. **`.env` file** (loaded via `godotenv/autoload` import) 2. **`.env` file** (loaded via `godotenv/autoload` import)
@@ -743,7 +746,7 @@ func New(lc fx.Lifecycle, params ConfigParams) (*Config, error) {
`~/.config/{appname}/{appname}.yaml` `~/.config/{appname}/{appname}.yaml`
4. **Defaults** (lowest priority) 4. **Defaults** (lowest priority)
### Environment Loading ## Environment Loading
Import godotenv with autoload to automatically load `.env` files: Import godotenv with autoload to automatically load `.env` files:
@@ -755,9 +758,9 @@ import (
--- ---
## 9. Logging (slog) # 9. Logging (slog)
### Logger Struct ## Logger Struct
```go ```go
// internal/logger/logger.go // internal/logger/logger.go
@@ -773,7 +776,7 @@ type Logger struct {
} }
``` ```
### Logger Setup with TTY Detection ## Logger Setup with TTY Detection
```go ```go
func New(lc fx.Lifecycle, params LoggerParams) (*Logger, error) { func New(lc fx.Lifecycle, params LoggerParams) (*Logger, error) {
@@ -807,7 +810,7 @@ func New(lc fx.Lifecycle, params LoggerParams) (*Logger, error) {
} }
``` ```
### Logger Methods ## Logger Methods
```go ```go
func (l *Logger) EnableDebugLogging() { func (l *Logger) EnableDebugLogging() {
@@ -828,7 +831,7 @@ func (l *Logger) Identify() {
} }
``` ```
### Logging Patterns ## Logging Patterns
```go ```go
// Info with fields // Info with fields
@@ -864,9 +867,9 @@ s.log.Info("request",
--- ---
## 10. Database Wrapper # 10. Database Wrapper
### Database Struct ## Database Struct
```go ```go
// internal/database/database.go // internal/database/database.go
@@ -883,7 +886,7 @@ type Database struct {
} }
``` ```
### Database Factory with Lifecycle ## Database Factory with Lifecycle
```go ```go
func New(lc fx.Lifecycle, params DatabaseParams) (*Database, error) { func New(lc fx.Lifecycle, params DatabaseParams) (*Database, error) {
@@ -910,7 +913,7 @@ func New(lc fx.Lifecycle, params DatabaseParams) (*Database, error) {
} }
``` ```
### Usage Pattern ## Usage Pattern
The Database struct is injected into handlers and other services: The Database struct is injected into handlers and other services:
@@ -931,9 +934,9 @@ func (s *Handlers) HandleSomething() http.HandlerFunc {
--- ---
## 11. Globals Package # 11. Globals Package
### Package Variables and Struct ## Package Variables and Struct
```go ```go
// internal/globals/globals.go // internal/globals/globals.go
@@ -965,7 +968,7 @@ func New(lc fx.Lifecycle) (*Globals, error) {
} }
``` ```
### Setting Globals in Main ## Setting Globals in Main
```go ```go
// cmd/httpd/main.go // cmd/httpd/main.go
@@ -983,7 +986,7 @@ func main() {
} }
``` ```
### Build-Time Variable Injection ## Build-Time Variable Injection
Use ldflags to inject version information at build time: Use ldflags to inject version information at build time:
@@ -997,9 +1000,9 @@ build:
--- ---
## 12. Static Assets & Templates # 12. Static Assets & Templates
### Static File Embedding ## Static File Embedding
```go ```go
// static/static.go // static/static.go
@@ -1024,7 +1027,7 @@ static/
└── jquery-3.5.1.slim.min.js └── jquery-3.5.1.slim.min.js
``` ```
### Template Embedding and Lazy Parsing ## Template Embedding and Lazy Parsing
```go ```go
// templates/templates.go // templates/templates.go
@@ -1047,7 +1050,7 @@ func GetParsed() *template.Template {
} }
``` ```
### Template Composition ## Template Composition
Templates use Go's template composition: Templates use Go's template composition:
@@ -1062,7 +1065,7 @@ Templates use Go's template composition:
{{ template "pagefooter.html" . }} {{ template "htmlfooter.html" . }} {{ template "pagefooter.html" . }} {{ template "htmlfooter.html" . }}
``` ```
### Static Asset References ## Static Asset References
Reference static files with `/s/` prefix: Reference static files with `/s/` prefix:
@@ -1074,9 +1077,9 @@ Reference static files with `/s/` prefix:
--- ---
## 13. Health Check # 13. Health Check
### Health Check Service ## Health Check Service
```go ```go
// internal/healthcheck/healthcheck.go // internal/healthcheck/healthcheck.go
@@ -1112,7 +1115,7 @@ func New(lc fx.Lifecycle, params HealthcheckParams) (*Healthcheck, error) {
} }
``` ```
### Health Check Response ## Health Check Response
```go ```go
type HealthcheckResponse struct { type HealthcheckResponse struct {
@@ -1142,19 +1145,19 @@ func (s *Healthcheck) Healthcheck() *HealthcheckResponse {
} }
``` ```
### Standard Endpoint ## Standard Endpoint
Health check is served at the standard `.well-known` path: Health check is served at the standard `.well-known` path:
```go ```go
s.router.Get("/.well-known/healthcheck.json", s.h.HandleHealthCheck()) s.router.Get("/.well-known/healthcheck", s.h.HandleHealthCheck())
``` ```
--- ---
## 14. External Integrations # 14. External Integrations
### Sentry Error Reporting ## Sentry Error Reporting
Sentry is conditionally enabled based on `SENTRY_DSN` environment variable: Sentry is conditionally enabled based on `SENTRY_DSN` environment variable:
@@ -1199,7 +1202,7 @@ if s.sentryEnabled {
} }
``` ```
### Prometheus Metrics ## Prometheus Metrics
Metrics are conditionally enabled and protected by basic auth: Metrics are conditionally enabled and protected by basic auth:
@@ -1218,7 +1221,7 @@ if viper.GetString("METRICS_USERNAME") != "" {
} }
``` ```
### Environment Variables Summary ## Environment Variables Summary
| Variable | Description | Default | | Variable | Description | Default |
| ------------------ | -------------------------------- | ------- | | ------------------ | -------------------------------- | ------- |
@@ -1229,3 +1232,11 @@ if viper.GetString("METRICS_USERNAME") != "" {
| `MAINTENANCE_MODE` | Enable maintenance mode | false | | `MAINTENANCE_MODE` | Enable maintenance mode | false |
| `METRICS_USERNAME` | Basic auth username for /metrics | "" | | `METRICS_USERNAME` | Basic auth username for /metrics | "" |
| `METRICS_PASSWORD` | Basic auth password for /metrics | "" | | `METRICS_PASSWORD` | Basic auth password for /metrics | "" |
# Author
[@sneak](https://sneak.berlin) <[sneak@sneak.berlin](mailto:sneak@sneak.berlin)>
# License
MIT. See [LICENSE](../LICENSE).

View File

@@ -1,18 +1,21 @@
# New Repo Checklist ---
title: New Repo Checklist
last_modified: 2026-02-22
---
Use this checklist when creating a new repository from scratch. Follow the steps Use this checklist when creating a new repository from scratch. Follow the steps
in order. Full policies are at: in order. Full policies are at
`https://git.eeqj.de/sneak/prompts/raw/branch/main/prompts/REPO_POLICIES.md` `https://git.eeqj.de/sneak/prompts/raw/branch/main/prompts/REPO_POLICIES.md`.
Template files can be fetched from: Template files can be fetched from:
`https://git.eeqj.de/sneak/prompts/raw/branch/main/<path>` `https://git.eeqj.de/sneak/prompts/raw/branch/main/<path>`
## 1. Initialize # 1. Initialize
- [ ] `git init` - [ ] `git init`
- [ ] Ask the user for the license (MIT, GPL, or WTFPL) - [ ] Ask the user for the license (MIT, GPL, or WTFPL)
## 2. First Commit (README only) # 2. First Commit (README only)
- [ ] Create `README.md` with all required sections: - [ ] Create `README.md` with all required sections:
- [ ] **Description**: name, purpose, category, license, author - [ ] **Description**: name, purpose, category, license, author
@@ -24,40 +27,47 @@ Template files can be fetched from:
- [ ] **Author**: [@sneak](https://sneak.berlin) - [ ] **Author**: [@sneak](https://sneak.berlin)
- [ ] `git add README.md && git commit` - [ ] `git add README.md && git commit`
## 3. Scaffolding (feature branch) # 3. Scaffolding (feature branch)
- [ ] `git checkout -b initial-scaffolding` - [ ] `git checkout -b initial-scaffolding`
### Fetch Template Files ## Fetch Template Files
- [ ] `.gitignore` — fetch from prompts repo, extend for language-specific - [ ] `.gitignore` — fetch from
artifacts `https://git.eeqj.de/sneak/prompts/raw/branch/main/.gitignore`, extend for
- [ ] `.editorconfig` — fetch from prompts repo language-specific artifacts
- [ ] `Makefile` — fetch from prompts repo, adapt targets for the project's - [ ] `.editorconfig` — fetch from
language and tools `https://git.eeqj.de/sneak/prompts/raw/branch/main/.editorconfig`
- [ ] For JS/docs repos: `.prettierrc`, `.prettierignore` - [ ] `Makefile` — fetch from
`https://git.eeqj.de/sneak/prompts/raw/branch/main/Makefile`, adapt
targets for the project's language and tools
- [ ] For JS/docs repos: `.prettierrc` and `.prettierignore` — fetch from
`https://git.eeqj.de/sneak/prompts/raw/branch/main/.prettierrc` and
`https://git.eeqj.de/sneak/prompts/raw/branch/main/.prettierignore`
### Create Project Files ## Create Project Files
- [ ] `LICENSE` file matching the chosen license - [ ] `LICENSE` file matching the chosen license
- [ ] `REPO_POLICIES.md` — fetch from `prompts/REPO_POLICIES.md` in the prompts - [ ] `REPO_POLICIES.md` — fetch from
repo `https://git.eeqj.de/sneak/prompts/raw/branch/main/prompts/REPO_POLICIES.md`
- [ ] `Dockerfile` and `.dockerignore` - [ ] `Dockerfile` and `.dockerignore` — fetch `.dockerignore` from
`https://git.eeqj.de/sneak/prompts/raw/branch/main/.dockerignore`
- All Dockerfiles must run `make check` as a build step - All Dockerfiles must run `make check` as a build step
- Server: also builds and runs the application - Server: also builds and runs the application
- Non-server: brings up dev environment and runs `make check` - Non-server: brings up dev environment and runs `make check`
- Image pinned by sha256 hash with version/date comment - Image pinned by sha256 hash with version/date comment
- [ ] Gitea Actions workflow at `.gitea/workflows/check.yml` that runs - [ ] Gitea Actions workflow at `.gitea/workflows/check.yml` that runs
`docker build .` on push `docker build .` on push — reference
`https://git.eeqj.de/sneak/prompts/raw/branch/main/.gitea/workflows/check.yml`
- [ ] Language-specific: - [ ] Language-specific:
- [ ] Go: `go mod init sneak.berlin/go/<name>`, `.golangci.yml` (copy from - [ ] Go: `go mod init sneak.berlin/go/<name>`, `.golangci.yml` (fetch from
`~/dev/upaas/.golangci.yml`) `https://git.eeqj.de/sneak/prompts/raw/branch/main/.golangci.yml`)
- [ ] JS: `yarn init`, `yarn add --dev prettier` - [ ] JS: `yarn init`, `yarn add --dev prettier`
- [ ] Python: `pyproject.toml` - [ ] Python: `pyproject.toml`
### Configure Makefile ## Configure Makefile
- [ ] `make test` — runs project tests (30-second timeout) - [ ] `make test` — runs real tests, not a no-op (30-second timeout)
- [ ] `make lint` — runs linter - [ ] `make lint` — runs linter
- [ ] `make fmt` — formats code (writes) - [ ] `make fmt` — formats code (writes)
- [ ] `make fmt-check` — checks formatting (read-only) - [ ] `make fmt-check` — checks formatting (read-only)
@@ -65,7 +75,7 @@ Template files can be fetched from:
- [ ] `make docker` — builds Docker image - [ ] `make docker` — builds Docker image
- [ ] `make hooks` — installs pre-commit hook - [ ] `make hooks` — installs pre-commit hook
## 4. Verify # 4. Verify
- [ ] `make check` passes - [ ] `make check` passes
- [ ] `make docker` succeeds - [ ] `make docker` succeeds
@@ -74,7 +84,7 @@ Template files can be fetched from:
- [ ] No unnecessary files in repo root - [ ] No unnecessary files in repo root
- [ ] All dates written as YYYY-MM-DD - [ ] All dates written as YYYY-MM-DD
## 5. Merge and Set Up # 5. Merge and Set Up
- [ ] Commit, merge to `main` - [ ] Commit, merge to `main`
- [ ] `make hooks` to install pre-commit hook - [ ] `make hooks` to install pre-commit hook

View File

@@ -1,10 +1,23 @@
# Development Policies ---
title: Repository Policies
last_modified: 2026-02-22
---
Version: 2026-02-22 This document covers repository structure, tooling, and workflow standards. Code
style conventions are in separate documents:
- Cross-project documentation (such as this file) must include a - [Code Styleguide](https://git.eeqj.de/sneak/prompts/raw/branch/main/prompts/CODE_STYLEGUIDE.md)
`Version: YYYY-MM-DD` line near the top so it can be kept in sync with the (general, bash, Docker)
authoritative source as policies evolve. - [Go](https://git.eeqj.de/sneak/prompts/raw/branch/main/prompts/CODE_STYLEGUIDE_GO.md)
- [JavaScript](https://git.eeqj.de/sneak/prompts/raw/branch/main/prompts/CODE_STYLEGUIDE_JS.md)
- [Python](https://git.eeqj.de/sneak/prompts/raw/branch/main/prompts/CODE_STYLEGUIDE_PYTHON.md)
- [Go HTTP Server Conventions](https://git.eeqj.de/sneak/prompts/raw/branch/main/prompts/GO_HTTP_SERVER_CONVENTIONS.md)
---
- Cross-project documentation (such as this file) must include
`last_modified: YYYY-MM-DD` in the YAML front matter so it can be kept in sync
with the authoritative source as policies evolve.
- **ALL external references must be pinned by cryptographic hash.** This - **ALL external references must be pinned by cryptographic hash.** This
includes Docker base images, Go modules, npm packages, GitHub Actions, and includes Docker base images, Go modules, npm packages, GitHub Actions, and
@@ -30,6 +43,16 @@ Version: 2026-02-22
instead of invoking the underlying tools directly. The Makefile is the single instead of invoking the underlying tools directly. The Makefile is the single
source of truth for how these operations are run. source of truth for how these operations are run.
- The Makefile is authoritative documentation for how the repo is used. Beyond
the required targets above, it should have targets for every common operation:
running a local development server (`make run`, `make dev`), re-initializing
or migrating the database (`make db-reset`, `make migrate`), building
artifacts (`make build`), generating code, seeding data, or anything else a
developer would do regularly. If someone checks out the repo and types
`make<tab>`, they should see every meaningful operation available. A new
contributor should be able to understand the entire development workflow by
reading the Makefile.
- Every repo should have a `Dockerfile`. All Dockerfiles must run `make check` - Every repo should have a `Dockerfile`. All Dockerfiles must run `make check`
as a build step so the build fails if the branch is not green. For non-server as a build step so the build fails if the branch is not green. For non-server
repos, the Dockerfile should bring up a development environment and run repos, the Dockerfile should bring up a development environment and run
@@ -50,6 +73,12 @@ Version: 2026-02-22
`make lint && make fmt-check`. The Makefile should provide a `make hooks` `make lint && make fmt-check`. The Makefile should provide a `make hooks`
target to install the pre-commit hook. target to install the pre-commit hook.
- All repos with software must have tests that run via the platform-standard
test framework (`go test`, `pytest`, `jest`/`vitest`, etc.). If no meaningful
tests exist yet, add the most minimal test possible — e.g. importing the
module under test to verify it compiles/parses. There is no excuse for
`make test` to be a no-op.
- `make test` must complete in under 20 seconds. Add a 30-second timeout in the - `make test` must complete in under 20 seconds. Add a 30-second timeout in the
Makefile. Makefile.
@@ -77,7 +106,8 @@ Version: 2026-02-22
feature branch. feature branch.
- `.golangci.yml` is standardized and must _NEVER_ be modified by an agent, only - `.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. manually by the user. Fetch from
`https://git.eeqj.de/sneak/prompts/raw/branch/main/.golangci.yml`.
- When pinning images or packages by hash, add a comment above the reference - When pinning images or packages by hash, add a comment above the reference
with the version and date (YYYY-MM-DD). with the version and date (YYYY-MM-DD).
@@ -143,7 +173,8 @@ Version: 2026-02-22
- New repos must contain at minimum: - New repos must contain at minimum:
- `README.md`, `.git`, `.gitignore`, `.editorconfig` - `README.md`, `.git`, `.gitignore`, `.editorconfig`
- `REPO_POLICIES.md` (copy from the `prompts` repo) - `LICENSE`, `REPO_POLICIES.md` (copy from the `prompts` repo)
- `Makefile`
- `Dockerfile`, `.dockerignore` - `Dockerfile`, `.dockerignore`
- `.gitea/workflows/check.yml` - `.gitea/workflows/check.yml`
- Go: `go.mod`, `go.sum`, `.golangci.yml` - Go: `go.mod`, `go.sum`, `.golangci.yml`