Warning: this release crash-loops on startup. Use 0.30.1 or later. See the 0.30.1 entry below for the cause.
Added
make rename — the missing step for "Use this template". The repo is a GitHub template (is_template: true), but the docs told people to git clone and never mentioned renaming. A fresh copy therefore kept the module path github.com/calionauta/gogogo, the binary name, the container name and the deploy directory — ~360 occurrences across ~130 files, with no script and no instructions, so a clone-as-template produced a project that compiled fine and deployed to the template's server directory. scripts/rename-project.py (via make rename NAME=my-app [OWNER=myorg] [DRY=1]) rewrites the module path, the bare project name and (with OWNER) the Pages host and owner/repo links; works from git ls-files so artifacts and local databases are never candidates; skips generated site/docs/ and points at make site; shields sibling repos under the same owner (ai-credits, datastar-lint, pi-leakguard) from the owner substitution; and finishes with go build ./cmd/web so a half-renamed tree fails locally rather than in CI. Idempotent, with --dry-run.
A documentation site.site/ (static landing page + site/build.mjs, a dependency-free markdown→HTML generator) published to GitHub Pages by .github/workflows/pages.yml, with docs/ as the 18-page single source of truth. make site / make site-check; --check validates every internal link and heading anchor.
bin/init-secrets — the script internal/secrets and internal/llm had been documenting as the canonical bootstrap, but which did not exist, making the documented secrets setup unrunnable. Generates the age keypair, a template, and the encrypted file, with --reencrypt. Falls back to scripts/agehelper (built on the already-present filippo.io/age) when the age CLI is absent.
"Docs stay truthful" rule in AGENTS.md plus bin/check-docs-staleness.sh, an advisory pre-commit guard that reports the page(s) most likely to need an edit when a behaviour-carrying file changes without a docs/ update.
Fixed
DagNats console writes returned 404, then 502. Two independent bugs, both invisible while the console rendered fine. The reverse proxy registered only GET /dagnats{/...}, but the console is a full CRUD app — creating a trigger, editing a workflow, cancelling a run and deleting a schedule all issue POST/PUT/PATCH/DELETE, and the upstream mux registers method-agnostically. Now registered with Router.Any. Even once routed, every write failed with http: ContentLength=13 with Body length 26: PocketBase wraps the request body in a RereadableReadCloser whose Read() rewinds itself at EOF, and httputil.ReverseProxy streams the body to the Transport, which reads to EOF and therefore reads the payload a second time. The proxy now buffers the body into a bytes.Reader first (8 MiB cap). Covered by router/dagnats_proxy_test.go, which drives a real PocketBase mux against a stub upstream and asserts every method arrives with its body intact.
The Desktop workflow failed on every push since the wails3 pin moved to beta.24. wails3 build has never accepted -o (real flags: -tags -obfuscated -garbleargs -nocolour), and it delegates to wails3 task build, which needs a Taskfile.yml the repo does not have. The flag had been latent because the workflow installed the CLI into GOPATH/bin without adding it to $GITHUB_PATH, so command -v wails3 failed inside the script and the build silently fell through to go build; the pin change added a PATH export that exposed it. The native path is now always plain go build (as make desktop already did), and android, package and cross-universal fail fast with an explanation instead of a cryptic flag error.
Tailwind scanned the landing page and the docs.src/css/input.css used source("../../"), which scans the whole project root, so site/index.html, site/styles.css and the generated docs were read as application source. Any class-shaped token there ended up in web/resources/static/app.min.css — and since that bundle is embedded in the binary, a landing-page edit could change an embedded asset. site/index.html actually loads its own styles.css and uses zero Tailwind utilities. Now source(none) with the roots enumerated (features/, web/, internal/): the bundle is 19 KB smaller, a landing edit no longer affects it, and make smoke still passes on all three skins.
Mobile horizontal scroll and a broken blob URL on the docs site. Grid tracks used a bare 1fr (minmax(auto, 1fr)), whose auto floor is the item's min-content width, so a long heading refused to shrink and the track stayed desktop-wide inside a 390px container. Tracks now use minmax(0, 1fr); tables are wrapped in a scroll container. Blob URLs escaping docs/ resolved against docs/ and kept a literal .., which 302s to tree/ and then 404s — they now resolve against the repo root.
modernc.org/sqlite version drift. The repo pinned 1.59.0 / libc 1.75.7 while PocketBase v0.40.4 expects 1.57.0 / 1.74.4, and PocketBase checks this at runtime (modernc_versions_check.go), warning that a mismatch "could result in unexpected build or runtime errors". The pin came from a blind dependency bump; nothing here imports modernc directly (the active driver is ncruces/go-sqlite3). It only surfaced as a direct requirement because a gitignored spikes/ file imported it — that directory now has its own go.mod, which also fixes go mod tidy disagreeing between local and CI.
15 factually wrong claims in the docs, found by auditing all 18 pages against the source. The worst cluster was deploy: the server layout was documented as /opt/... (it is /home/deploy/services/<app>/), the CI was described as building a Docker image (it cross-compiles the binary; the image is built on the server), and both deploy.md and troubleshooting.md told the reader to verify a deploy with /api/version, an endpoint that has never existed.
Docs-only pushes no longer run CI, Desktop or Deploy. A README edit used to rebuild the Docker image and restart production. deploy.yml uses an allow-list so a new top-level directory cannot silently start deploying; ci.yml/desktop.yml use paths-ignore.
Changed
README reduced from 795 to 186 lines, with the docs site as the single source of truth.
make wails-build is now an explicit "why not" target that exits with the reason, rather than a target that cannot work.
Verification
make ci-local green: templ + datastar-lint + css-check + check-scope + golangci-lint + go test -race -p 1 ./... + build
Browser smoke test passed on all three skins (daisyui, basecoat, morpheus) with zero uncaught client JS errors
site-check green: 18 pages, all links and heading anchors resolve
make rename verified end-to-end on throwaway clones: 0 occurrences left, go build ./... clean, go vet clean, make site regenerates with the new name