3f8201d532f975abb36debd928c33b5630a3503c
9
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
3f8201d532 |
Require thin cmd/ entrypoints: all logic in internal/ or pkg/ (#54)
check / check (push) Successful in 13s
Codifies your ruling (2026-08-30, filed as homoicon issue 555): no project logic outside `internal/` or `pkg/`; each `cmd/<name>/` is a single `main.go` whose body is one call into library code. - `CODE_STYLEGUIDE_GO.md`: strengthens the "keep `main` small" rule to the single-call form and adds the no-logic-outside-`internal/`-or-`pkg/` rule. - `REPO_POLICIES.md`: annotates `cmd/` in the canonical subdirectory list accordingly. (Root copy is a symlink; one edit covers both.) Co-authored-by: sneak <sneak@sneak.berlin> Reviewed-on: #54 Co-authored-by: clawbot <clawbot@noreply.example.org> Co-committed-by: clawbot <clawbot@noreply.example.org> |
||
|
|
a8686891ba |
Raise org-wide make test cap to 60s, backstop timeout to 90s (#42)
check / check (push) Successful in 4s
## The question this answers Is the 60-second test-time cap the new **org-wide** ceiling, or an approved **dnswatcher-only** divergence? - Question: #41 - Origin: sneak/dnswatcher#93 This PR implements **org-wide**. ## The ruling On sneak/dnswatcher#93 (comment) (2026-08-09), verbatim: > make the cap 60s in both and never use mocking, always use live resolvers and > assume the build and run environments have full unmodified unrestricted > internet access. it is ok if they fail due to a bad build environment that > alters dns packets. And on #41 (comment), disambiguating the scope: > org wide. the hard cap is 60 for ci/green, but over 20s should be filed as an > improvement bug. That second comment landed after this work was started, and it confirms the option implemented here. The two-tier shape it describes (60s hard, 20s target, overage filed as a bug) is encoded in the policy text. ## What changed, and the number chosen The backstop moves from `30s` to **`90s`**. The old pairing was incoherent under the new cap: a 60-second ceiling with a 30-second `-timeout` means the timeout kills the suite long before the ceiling is reached, so the ceiling would never be the thing that fails. The backstop has to sit above the cap, where it does its actual job of catching a hung test rather than a merely slow one. `90s` preserves the 1.5x backstop-to-cap ratio the old `20s`/`30s` pair already had, so the relationship between the two numbers is unchanged and only the scale moves. Every place a number changed: | File | What | | --- | --- | | `prompts/REPO_POLICIES.md` | Prose ceiling: `20 seconds` to `60 seconds`, plus the new 20s target / improvement-bug tier | | `prompts/REPO_POLICIES.md` | Backstop prose: `30-second timeout` to `90-second timeout`, with the rationale for why it exceeds the cap | | `prompts/REPO_POLICIES.md` | Go example Makefile snippet, first run: `go test -timeout 30s` to `-timeout 90s` | | `prompts/REPO_POLICIES.md` | Go example Makefile snippet, verbose rerun: `go test -timeout 30s` to `-timeout 90s` | | `prompts/EXISTING_REPO_CHECKLIST.md` | `make test` has a `30-second` timeout, to `90-second` timeout plus the 60s hard cap and the 20s filing rule | | `prompts/NEW_REPO_CHECKLIST.md` | `script/test` / `make test` entrypoint line: `30-second timeout` to `90-second timeout, 60-second hard cap on wall time` | I swept the whole repo for `20 second`, `30-second`, `20s`, `30s`, `timeout 20`, `timeout 30`, and `under 20`/`under 30`. After this change the only remaining occurrences of `20` in a test-timing context are the two intentional references to the new 20-second target. The other `timeout` hits in the repo are unrelated (`.golangci.yml` lint timeout, HTTP server `ReadTimeout`/`WriteTimeout` examples, `middleware.Timeout`) and were left alone. One deliberate non-change: the Python example Makefile snippet in `prompts/REPO_POLICIES.md` carries no timeout flag today and still carries none. `pytest` has no built-in timeout, so adding one would mean mandating the `pytest-timeout` plugin org-wide, which is a new dependency requirement rather than a renumbering, and outside what was ruled on. It is a pre-existing gap between the prose and that snippet, not one this PR introduces. Happy to file it separately or add `--timeout=90` here if you want it in scope. ## The alternative that was not implemented **Keep canonical at 20s and let `sneak/dnswatcher` carry a documented per-repo divergence.** That was the recommendation originally written up in #41, on the reasoning that the 20s ceiling is doing real work in repos with fast deterministic suites and only dnswatcher needs the headroom. Org-wide was chosen instead for two reasons. First, the pressure is not specific to DNS: any repo whose tests exercise real infrastructure over the network inherits the same variance, and there is no principled line that admits dnswatcher and excludes the next such repo. Second, and more decisively, `REPO_POLICIES.md` is a vendored file. A sanctioned per-repo divergence in a vendored file is indistinguishable, on inspection, from a stale vendored copy: the next re-vendoring silently reverts the divergence, and nobody reading a consuming repo can tell whether the number they are looking at is an intentional exception or drift. That is the bidirectional-drift problem already tracked in #31. The two-tier cap gets the same outcome without the drift, since a fast repo that regresses from 4s to 45s still generates an improvement bug. ## Status This PR was opened speculatively, ahead of a decision, on the standing "open it rather than wait" instruction. The scope question has since been answered org-wide in the issue, but the specific backstop value of `90s` and the two-tier wording are still my proposals rather than anything ruled on, so closing this or sending it back for a different number is a perfectly fine outcome. `make check` passes; `make fmt` was run and the result is included (it was a no-op, the edits were already prettier-conformant). `sneak/dnswatcher` is landing the matching 60s edit to its vendored copy in parallel, and will match whichever way this is decided. Co-authored-by: clawbot <clawbot@eeqj.de> Reviewed-on: #42 Co-authored-by: clawbot <clawbot@noreply.example.org> Co-committed-by: clawbot <clawbot@noreply.example.org> |
||
|
|
0f8efafe68 |
Set canonical .golangci.yml to the org-standard v2 config (golangci-lint v2.12.2) (#24)
check / check (push) Has been cancelled
Requested by sneak. Sets the canonical `.golangci.yml` to the org-standard v2-schema config already deployed byte-identical across the org's Go repos (vaultik, sfdupes, attrsum, upaas, simplelog, mfer, secret, rgoue, bsfirehose). sha256: `021cc83f4e6fc7c31b95b34b846723dfcf20b66b7baeea1dc40406e643346bcb`. Why: settings live under `linters.settings`, so the lll/funlen/cyclop/dupl thresholds actually apply under golangci-lint v2. The old canonical file kept them under top-level `linters-settings`, which v2 ignores. Version note: golangci-lint v2.12.2 tag = commit `c0d3ddc9cf3faa61a4e378e879ece580256d76e5`, recorded for consuming repos. This repo itself has no version pins; the `v2.x.x` / `@sha256:...` strings in `prompts/REPO_POLICIES.md` are intentional placeholders and are unchanged. Known informational note: this config does not disable the deprecated `gomodguard` linter, so golangci-lint 2.12.x prints a deprecation warning. Harmless, accepted. Matches dnswatcher PR #96: sneak/dnswatcher#96 Verification: `make check` green (prettier fmt-check on all markdown) after `make fmt`; `.golangci.yml` sha256 verified as `021cc83f...` matching the org-standard file. Co-authored-by: sneak <sneak@sneak.berlin> Co-authored-by: clawbot <clawbot@eeqj.de> Reviewed-on: #24 Co-authored-by: clawbot <clawbot@noreply.example.org> Co-committed-by: clawbot <clawbot@noreply.example.org> |
||
|
|
4b64c213f8 |
style: strengthen constructor naming and Params struct rules (#19)
check / check (push) Successful in 5s
Per sneak's instruction: - Constructors **must** be `New()`, `From<Something>()`, or `NewThing()` (multi-type packages only) - Strongly discourage creative names (`Create`, `Make`, `Build`, `Init`) - Constructors **must** use a `Params` struct (or `ThingParams`) for 2+ arguments — no exceptions - Single obvious argument (`ctx`, bytes) is the only exception - `context.Context` does not count against the argument limit (already documented) Co-authored-by: user <user@Mac.lan guest wan> Co-authored-by: clawbot <clawbot@noreply.git.eeqj.de> Reviewed-on: #19 Co-authored-by: clawbot <clawbot@noreply.example.org> Co-committed-by: clawbot <clawbot@noreply.example.org> |
||
|
|
777822e50e |
docs: document conditional -v test rerun pattern in REPO_POLICIES.md (#21)
check / check (push) Successful in 8s
## Summary Adds the conditional verbose test rerun pattern as a policy recommendation in REPO_POLICIES.md. Per sneak's request from [sneak/chat PR #82](sneak/chat#82): document the pattern where `make test` runs tests without `-v` first, then automatically reruns with `-v` on failure for full diagnostic output. ## Changes **`prompts/REPO_POLICIES.md`** (root `REPO_POLICIES.md` is a symlink to this): - Added new policy bullet after the `make test` timeout rule - Explains the rationale: clean CI/Docker build logs on success, full verbose output on failure - Includes a generic shell pattern template - Includes concrete Go and Python examples - Documents that `exit 1` ensures the target always fails after a rerun (the rerun is solely for diagnostic output) - Updated `last_modified` from 2026-03-12 to 2026-03-18 ## The Pattern ```makefile test: @go test -timeout 30s -race -cover ./... || \ { echo "--- Rerunning with -v for details ---"; \ go test -timeout 30s -race -v ./...; exit 1; } ``` - **On success**: concise package summaries only, no per-test noise - **On failure**: automatic verbose rerun shows every test case and assertion - **Always fails**: `exit 1` ensures the build fails regardless of second run's exit code closes #20 Co-authored-by: clawbot <clawbot@noreply.git.eeqj.de> Reviewed-on: #21 Co-authored-by: clawbot <clawbot@noreply.example.org> Co-committed-by: clawbot <clawbot@noreply.example.org> |
||
|
|
1c84344978 |
docs: document fail-fast lint stage pattern for Dockerfiles (#18)
check / check (push) Successful in 5s
Documents the multistage Docker build pattern we now use across repos (chat, pixa, etc.) where a separate `lint` stage runs `make fmt-check` and `make lint` independently from the build stage. Key additions to REPO_POLICIES.md: - Full Dockerfile template showing the lint → build → runtime stage pattern - Explanation of `COPY --from=lint /src/go.sum /dev/null` as the BuildKit dependency trick - Handling `//go:embed` placeholders in the lint stage - CGO/system library notes for the lint stage - Clarification that tests run in the build stage, not the lint stage Reference implementations: `sneak/chat`, `sneak/pixa`. Co-authored-by: user <user@Mac.lan guest wan> Reviewed-on: #18 Co-authored-by: clawbot <clawbot@noreply.example.org> Co-committed-by: clawbot <clawbot@noreply.example.org> |
||
|
|
41005ecbe5 |
Add HTTP service hardening policy for 1.0 releases (#17)
check / check (push) Successful in 8s
Closes #16 Adds a comprehensive HTTP/web service security hardening policy to `REPO_POLICIES.md` that must be satisfied before tagging 1.0. The policy covers all items sneak specified (without limitation): **Security headers** — HSTS (min 1 year, includeSubDomains), CSP (restrictive `default-src 'self'` baseline), X-Frame-Options / frame-ancestors, X-Content-Type-Options: nosniff, Referrer-Policy, Permissions-Policy. **Request/response limits** — max request body size on all endpoints, max response size for paginated APIs, ReadTimeout + ReadHeaderTimeout (slowloris defense), WriteTimeout, IdleTimeout, per-handler execution time limits. **Authentication & session security** — rate limiting on password-based auth (API keys exempt as high-entropy), CSRF tokens on state-mutating forms (header-auth APIs exempt), bcrypt/scrypt/argon2 for passwords, session cookies with HttpOnly + Secure + SameSite. **Reverse proxy awareness** — true client IP detection via X-Forwarded-For/X-Real-IP with trusted proxy allowlist (never trust unconditionally). **CORS** — explicit origin allowlist for authenticated endpoints; wildcard only for public unauthenticated read-only APIs. **Error handling** — no leaking stack traces, SQL queries, file paths, or implementation details to clients. **TLS** — HSTS and secure cookie flags required regardless of whether the service terminates TLS directly or sits behind a reverse proxy. The policy is explicitly non-exhaustive (defense-in-depth: "when in doubt, harden"). Also adds corresponding checklist sections to `EXISTING_REPO_CHECKLIST.md` and `NEW_REPO_CHECKLIST.md` so that HTTP hardening is verified during repo setup and 1.0 preparation. Co-authored-by: user <user@Mac.lan guest wan> Co-authored-by: clawbot <clawbot@eeqj.de> Reviewed-on: #17 Co-authored-by: clawbot <clawbot@noreply.example.org> Co-committed-by: clawbot <clawbot@noreply.example.org> |
||
|
|
eb6b11ee23 |
policy: no build artifacts in repos (#15)
check / check (push) Successful in 5s
Add policy rule: build artifacts and code-derived data must not be committed to repos if they can be generated during the build process. Notable exception: Go protobuf-generated files (`.pb.go`) may be committed because `go get` downloads source but does not execute build steps. This addresses feedback from sneak/chat PR [#61](sneak/chat#61). Co-authored-by: clawbot <clawbot@noreply.git.eeqj.de> Reviewed-on: #15 Co-authored-by: clawbot <clawbot@noreply.example.org> Co-committed-by: clawbot <clawbot@noreply.example.org> |
||
|
|
58d564b641 |
Update LLM prose tells: new patterns + lol section (#8)
check / check (push) Successful in 3s
Updates LLM_PROSE_TELLS.md with three new patterns (two-clause compound sentence, almost-hedge, unnecessary contrast), the lol section with conversation excerpts, fixes for instances of these patterns throughout, and a bracket escaping fix for prettier idempotency. Checklist is now 24 items. Co-authored-by: user <user@Mac.lan guest wan> Reviewed-on: #8 Co-authored-by: clawbot <clawbot@noreply.example.org> Co-committed-by: clawbot <clawbot@noreply.example.org> |