Compare commits
1 Commits
59999115b1
...
llm-prose-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0e09ce4646 |
@@ -136,15 +136,8 @@ last_modified: 2026-02-22
|
|||||||
1. Provide a .gitignore file that ignores at least `*.log`, `*.out`, and
|
1. Provide a .gitignore file that ignores at least `*.log`, `*.out`, and
|
||||||
`*.test` files, as well as any binaries.
|
`*.test` files, as well as any binaries.
|
||||||
|
|
||||||
1. Constructors **must** be called `New()`. `modulename.New()` works great if
|
1. Constructors should be called `New()` whenever possible. `modulename.New()`
|
||||||
you name the packages properly. If the constructor creates an instance from
|
works great if you name the packages properly.
|
||||||
an existing value or representation, `From<Something>()` (e.g. `FromBytes()`,
|
|
||||||
`FromConfig()`) is also acceptable. If the package contains multiple types
|
|
||||||
and `New()` is ambiguous, `NewThing()` is occasionally acceptable — but
|
|
||||||
prefer restructuring packages so each type gets its own package and a plain
|
|
||||||
`New()`. Do not invent creative constructor names like `Create()`, `Make()`,
|
|
||||||
`Build()`, `Open()` (unless wrapping an OS resource), or `Init()`. If you
|
|
||||||
see a constructor with a non-standard name, rename it.
|
|
||||||
|
|
||||||
1. Don't make packages too big. Break them up.
|
1. Don't make packages too big. Break them up.
|
||||||
|
|
||||||
@@ -156,15 +149,9 @@ last_modified: 2026-02-22
|
|||||||
1. Use descriptive names for modules and filenames. Avoid generic names like
|
1. Use descriptive names for modules and filenames. Avoid generic names like
|
||||||
`server`. `util` is banned.
|
`server`. `util` is banned.
|
||||||
|
|
||||||
1. Constructors **must** take a `Params` struct (or `ThingParams` when
|
1. Constructors should take a Params struct if they need more than 1-2
|
||||||
`NewThing()` is used), even for a single argument. Named fields in a Params
|
arguments. Positional arguments are an endless source of bugs and should be
|
||||||
struct are always clearer than positional arguments. Positional arguments
|
avoided whenever possible.
|
||||||
for constructors are an endless source of bugs — they make call sites
|
|
||||||
unreadable, invite wrong-order errors that the compiler can't catch when
|
|
||||||
types coincide, and force every caller to update when a new field is added.
|
|
||||||
The only exception is when the single argument is stupidly obvious from
|
|
||||||
context — e.g. `featureflag.New(true)` or `thing.NewFromReader(r)`. When in
|
|
||||||
doubt, use a Params struct.
|
|
||||||
|
|
||||||
1. Use `context.Context` for all functions that need it. If you don't need it,
|
1. Use `context.Context` for all functions that need it. If you don't need it,
|
||||||
you can pass `context.Background()`. Anything long-running should get and
|
you can pass `context.Background()`. Anything long-running should get and
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
title: Existing Repo Checklist
|
title: Existing Repo Checklist
|
||||||
last_modified: 2026-03-10
|
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
|
||||||
@@ -78,22 +78,6 @@ with your task.
|
|||||||
`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
|
||||||
|
|
||||||
# HTTP Service Hardening (if targeting 1.0 and the repo is an HTTP/web service)
|
|
||||||
|
|
||||||
- [ ] Security headers set on all responses (HSTS, CSP, X-Frame-Options,
|
|
||||||
X-Content-Type-Options, Referrer-Policy, Permissions-Policy)
|
|
||||||
- [ ] Request body size limits enforced on all endpoints
|
|
||||||
- [ ] Read/write/idle timeouts configured on the HTTP server (slowloris defense)
|
|
||||||
- [ ] Per-handler execution time limits in place
|
|
||||||
- [ ] Password-based auth endpoints are rate-limited
|
|
||||||
- [ ] CSRF tokens on all state-mutating HTML forms
|
|
||||||
- [ ] Passwords hashed with bcrypt, scrypt, or argon2
|
|
||||||
- [ ] Session cookies use HttpOnly, Secure, and SameSite attributes
|
|
||||||
- [ ] True client IP correctly detected behind reverse proxy (trusted proxy
|
|
||||||
allowlist configured)
|
|
||||||
- [ ] CORS restricted to explicit origin allowlist for authenticated endpoints
|
|
||||||
- [ ] Error responses do not leak stack traces, SQL queries, or internal paths
|
|
||||||
|
|
||||||
# Final
|
# Final
|
||||||
|
|
||||||
- [ ] `make check` passes
|
- [ ] `make check` passes
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
# LLM Prose Tells
|
# LLM Prose Tells
|
||||||
|
|
||||||
A catalog of patterns found in LLM-generated prose.
|
A catalog of structural, lexical, and rhetorical patterns found in LLM-generated
|
||||||
|
prose.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -17,7 +18,7 @@ A negation followed by an em-dash and a reframe.
|
|||||||
|
|
||||||
Even outside the "not X but Y" pivot, models substitute em-dashes for commas,
|
Even outside the "not X but Y" pivot, models substitute em-dashes for commas,
|
||||||
semicolons, parentheses, colons, and periods. The em-dash can replace any other
|
semicolons, parentheses, colons, and periods. The em-dash can replace any other
|
||||||
punctuation mark, so models default to it.
|
punctuation mark, and models default to it for that reason.
|
||||||
|
|
||||||
### The Colon Elaboration
|
### The Colon Elaboration
|
||||||
|
|
||||||
@@ -78,7 +79,8 @@ zero information. The actual point is always in the next paragraph.
|
|||||||
|
|
||||||
> "This is, of course, a simplification." "There are, to be fair, exceptions."
|
> "This is, of course, a simplification." "There are, to be fair, exceptions."
|
||||||
|
|
||||||
Parenthetical asides inserted to perform nuance without changing the argument.
|
Parenthetical asides inserted to perform nuance without ever changing the
|
||||||
|
argument.
|
||||||
|
|
||||||
### The Unnecessary Contrast
|
### The Unnecessary Contrast
|
||||||
|
|
||||||
@@ -125,10 +127,10 @@ precedent), "navigate," "foster," "underscores," "resonates," "embark,"
|
|||||||
|
|
||||||
### Elevated Register Drift
|
### Elevated Register Drift
|
||||||
|
|
||||||
Models write one register above where a human would, replacing "use" with
|
Models write one register above where a human would. "Use" becomes "utilize."
|
||||||
"utilize," "start" with "commence," "help" with "facilitate," "show" with
|
"Start" becomes "commence." "Help" becomes "facilitate." "Show" becomes
|
||||||
"demonstrate," "try" with "endeavor," "change" with "transform," and "make" with
|
"demonstrate." "Try" becomes "endeavor." "Change" becomes "transform." "Make"
|
||||||
"craft."
|
becomes "craft."
|
||||||
|
|
||||||
### Filler Adverbs
|
### Filler Adverbs
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
title: Repository Policies
|
title: Repository Policies
|
||||||
last_modified: 2026-03-12
|
last_modified: 2026-02-22
|
||||||
---
|
---
|
||||||
|
|
||||||
This document covers repository structure, tooling, and workflow standards. Code
|
This document covers repository structure, tooling, and workflow standards. Code
|
||||||
@@ -59,73 +59,6 @@ style conventions are in separate documents:
|
|||||||
`make check`. For server repos, `make check` should run as an early build
|
`make check`. For server repos, `make check` should run as an early build
|
||||||
stage before the final image is assembled.
|
stage before the final image is assembled.
|
||||||
|
|
||||||
- **Dockerfiles must use a separate lint stage for fail-fast feedback.** Go
|
|
||||||
repos use a multistage build where linting runs in an independent stage based
|
|
||||||
on the `golangci/golangci-lint` image (pinned by hash). This stage runs
|
|
||||||
`make fmt-check` and `make lint` before the full build begins. The build stage
|
|
||||||
then declares an explicit dependency on the lint stage via
|
|
||||||
`COPY --from=lint /src/go.sum /dev/null`, which forces BuildKit to complete
|
|
||||||
linting before proceeding to compilation and tests. This ensures lint failures
|
|
||||||
surface in seconds rather than minutes, without blocking on dependency
|
|
||||||
download or compilation in the build stage.
|
|
||||||
|
|
||||||
The standard pattern for a Go repo Dockerfile is:
|
|
||||||
|
|
||||||
```dockerfile
|
|
||||||
# Lint stage — fast feedback on formatting and lint issues
|
|
||||||
# golangci/golangci-lint:v2.x.x, YYYY-MM-DD
|
|
||||||
FROM golangci/golangci-lint@sha256:... AS lint
|
|
||||||
WORKDIR /src
|
|
||||||
COPY go.mod go.sum ./
|
|
||||||
RUN go mod download
|
|
||||||
COPY . .
|
|
||||||
RUN make fmt-check
|
|
||||||
RUN make lint
|
|
||||||
|
|
||||||
# Build stage
|
|
||||||
# golang:1.x-alpine, YYYY-MM-DD
|
|
||||||
FROM golang@sha256:... AS builder
|
|
||||||
WORKDIR /src
|
|
||||||
|
|
||||||
# Force BuildKit to run the lint stage before proceeding
|
|
||||||
COPY --from=lint /src/go.sum /dev/null
|
|
||||||
|
|
||||||
COPY go.mod go.sum ./
|
|
||||||
RUN go mod download
|
|
||||||
COPY . .
|
|
||||||
RUN make test
|
|
||||||
|
|
||||||
ARG VERSION=dev
|
|
||||||
RUN CGO_ENABLED=0 go build -trimpath \
|
|
||||||
-ldflags="-s -w -X main.Version=${VERSION}" \
|
|
||||||
-o /app ./cmd/app/
|
|
||||||
|
|
||||||
# Runtime stage
|
|
||||||
FROM alpine@sha256:...
|
|
||||||
COPY --from=builder /app /usr/local/bin/app
|
|
||||||
ENTRYPOINT ["app"]
|
|
||||||
```
|
|
||||||
|
|
||||||
Key points:
|
|
||||||
- The lint stage uses the `golangci/golangci-lint` image directly (it
|
|
||||||
includes both Go and the linter), so there is no need to install the
|
|
||||||
linter separately.
|
|
||||||
- `COPY --from=lint /src/go.sum /dev/null` is a no-op file copy that creates
|
|
||||||
a stage dependency. BuildKit runs stages in parallel by default; without
|
|
||||||
this line, the build stage would not wait for lint to finish and a lint
|
|
||||||
failure might not fail the overall build.
|
|
||||||
- If the project uses `//go:embed` directives that reference build artifacts
|
|
||||||
(e.g. a web frontend compiled in a separate stage), the lint stage must
|
|
||||||
create placeholder files so the embed directives resolve. Example:
|
|
||||||
`RUN mkdir -p web/dist && touch web/dist/index.html web/dist/style.css`.
|
|
||||||
The lint stage should not depend on the actual build output — it exists to
|
|
||||||
fail fast.
|
|
||||||
- If the project requires CGO or system libraries for linting (e.g.
|
|
||||||
`vips-dev`), install them in the lint stage with `apk add`.
|
|
||||||
- The build stage runs `make test` after compilation setup. Tests run in the
|
|
||||||
build stage, not the lint stage, because they may require compiled
|
|
||||||
artifacts or heavier dependencies.
|
|
||||||
|
|
||||||
- Every repo should have a Gitea Actions workflow (`.gitea/workflows/`) that
|
- Every repo should have a Gitea Actions workflow (`.gitea/workflows/`) that
|
||||||
runs `docker build .` on push. Since the Dockerfile already runs `make check`,
|
runs `docker build .` on push. Since the Dockerfile already runs `make check`,
|
||||||
a successful build implies all checks pass.
|
a successful build implies all checks pass.
|
||||||
@@ -165,13 +98,6 @@ style conventions are in separate documents:
|
|||||||
`https://git.eeqj.de/sneak/prompts/raw/branch/main/.gitignore` when setting up
|
`https://git.eeqj.de/sneak/prompts/raw/branch/main/.gitignore` when setting up
|
||||||
a new repo.
|
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 use `git add -A` or `git add .`. Always stage files explicitly by name.
|
||||||
|
|
||||||
- Never force-push to `main`.
|
- Never force-push to `main`.
|
||||||
@@ -195,66 +121,6 @@ style conventions are in separate documents:
|
|||||||
- Dockerized web services listen on port 8080 by default, overridable with
|
- Dockerized web services listen on port 8080 by default, overridable with
|
||||||
`PORT`.
|
`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:
|
- `README.md` is the primary documentation. Required sections:
|
||||||
- **Description**: First line must include the project name, purpose,
|
- **Description**: First line must include the project name, purpose,
|
||||||
category (web server, SPA, CLI tool, etc.), license, and author. Example:
|
category (web server, SPA, CLI tool, etc.), license, and author. Example:
|
||||||
|
|||||||
Reference in New Issue
Block a user