Wiki docs accuracy review #110

Closed
opened 2026-09-10 00:05:24 +00:00 by fen · 1 comment
Collaborator

Accuracy review of the wiki against the code (commit e17ea4f). Verified: routes, request/response shapes, status codes, rate limiting, burn-after-read behavior, sweeper, cookies, README, and all Home links.

Inaccuracies found

1. API.md — slug errors return 400, not 409 (most significant)

  • Page: API
  • Doc says: slug_taken / slug_reserved409 (error-code table), and slug_invalid → "400/409".
  • Code does: handleCreatePaste always responds 400 for create errors (writeErrCode(w, 400, createErrCode(err), ...)). Verified live: duplicate slug → 400 {"code":"slug_taken"}; malformed slug → 400 {"code":"slug_invalid"}.
  • Evidence: internal/api/server.go:235 (unconditional 400), internal/api/server.go:64-77; confirmed via test probe.
  • Fix: change the table to 400 for all three slug codes (or make the handler emit 409 — but the doc must match the code).

2. README.md — build command fails as written

  • Page: README (Get Started → Build from source)
  • Doc says: go build -o palette . from the repo root; "Requires Go 1.21+".
  • Code does: there is no root main package; the entrypoint is ./cmd/palette (the Dockerfile builds ./cmd/palette). go.mod requires Go 1.27.x.
  • Evidence: repo root has no .go files; Dockerfile:12; cmd/palette/main.go.
  • Fix: go build -o palette ./cmd/palette and update the Go version requirement.

3. performance-notes.md — wrong client fetch limit

  • Page: performance-notes
  • Doc says: "limit=500 per query is the current client cap in static/table.js" and that the client queries /api/public?limit=500.
  • Code does: table.js uses opts.fetchLimit || 100, and neither history.html nor mine.html sets fetchLimit, so the client fetches limit=100. The server also clamps list limit at 100 (parseLimit(r, 25, 100)), so 500 would silently clamp to 100 anyway.
  • Evidence: internal/web/static/table.js:66; internal/api/server.go:361,382; internal/api/validate.go:68-74.
  • Fix: change "500" to "100" and note the server-side clamp.

4. performance-notes.md — list-row field list is incomplete

  • Page: performance-notes
  • Doc says: rows return "(id, title, language, created_at, view_count, size, custom_slug, is_can)".
  • Code does: the item maps also include visibility on both /api/public and /api/mine.
  • Evidence: internal/api/server.go:371-376,392-397.
  • Fix: add visibility to the field list.

5. design-attachments-storage.md — wrong env var name

  • Page: design-attachments-storage (Part B, item 5)
  • Doc says: "PALETTE_DB_PATH env already implies the deployment choice".
  • Code does: the env var is PALETTE_DB (cmd/palette/main.go:24, docker-compose.yml:22, README table).
  • Fix: use PALETTE_DB.

6. design-e2e-encryption.md — malformed markdown in §5

  • Page: design-e2e-encryption
  • Doc says: the "Three sharing modes" table is preceded by a corrupted duplicate header row (| malformed JSON / wrong key | | | plus a stray table header), garbling the table; section numbering is also broken (two "§5" sections, then "6.2" with no 6.1).
  • Fix: remove the stray duplicate header lines and renumber sections.

7. design-e2e-encryption.md — references a deleted doc path

  • Page: design-e2e-encryption (Related docs; also §3.2 cites "docs/API.md")
  • Doc says: links to ../API.md.
  • Code does: docs/ was deleted from the repo (commit e17ea4f "Move docs to Gitea wiki"); the API doc now lives in the wiki at API.
  • Fix: link to the wiki API page.

8. README.md — design-doc link lands on the wiki pages index

  • Page: README (Design docs section)
  • Doc says: links to https://git.archfox.org/poslop/palette/wiki/design/attachments-storage.
  • Code does: that wiki slug does not exist; Gitea redirects it to the wiki pages index (?action=_pages), not the doc. The actual page is wiki/design-attachments-storage. (Still HTTP 200, so it does not 404 — but the reader does not land on the design doc.)
  • Fix: link to wiki/design-attachments-storage (or wiki/Home).

Checked and accurate (not counted)

  • API.md routes/methods match internal/api/server.go:84-135; create response fields (id, url, raw_url, api_url, expires_at, created_at, deletion_token) match server.go:238-247; reads_remaining present, null when no budget (server.go:297, internal/store/burn.go).
  • 429 responses carry Retry-After + rate_limited code (internal/api/ratelimit.go:113-117); unlock limiter returns 60s retry-after; per-IP token buckets match the documented limits.
  • 15-minute burn viewer window default (internal/api/burn.go:13-20), per-viewer dedupe via paste_views (internal/store/burn.go:53-66), raw reads count against the budget (server.go:421-428).
  • Sweeper every minute (cmd/palette/main.go:39), 7-day soft-delete grace (internal/store/store.go:19,406), burn → soft delete once budget exhausted (store/burn.go:84-87).
  • 1-minute–1-year expiry bounds (internal/store/store.go:166-172); public boolean overrides string visibility (#83, store.go:223-233).
  • Cookie mechanics match design-cookie-preferences: vwr (1y, HttpOnly/Lax, server.go:139-153), pw_<id> = HMAC of paste id under unlock secret, 1h (internal/web/web.go:91-110,242), tok_<id> 60s handoff (web.go:270); pw_ cookies never authorize delete (cans.go:149-164, server.go:341-352).
  • Home page links (API, performance-notes, 3 design docs, 4 theme preview PNGs) all resolve 200 to real pages/images.
Accuracy review of the wiki against the code (commit e17ea4f). Verified: routes, request/response shapes, status codes, rate limiting, burn-after-read behavior, sweeper, cookies, README, and all Home links. ## Inaccuracies found ### 1. API.md — slug errors return 400, not 409 (most significant) - **Page:** API - **Doc says:** `slug_taken` / `slug_reserved` → **409** (error-code table), and `slug_invalid` → "400/409". - **Code does:** `handleCreatePaste` always responds **400** for create errors (`writeErrCode(w, 400, createErrCode(err), ...)`). Verified live: duplicate slug → `400 {"code":"slug_taken"}`; malformed slug → `400 {"code":"slug_invalid"}`. - **Evidence:** `internal/api/server.go:235` (unconditional 400), `internal/api/server.go:64-77`; confirmed via test probe. - **Fix:** change the table to 400 for all three slug codes (or make the handler emit 409 — but the doc must match the code). ### 2. README.md — build command fails as written - **Page:** README (Get Started → Build from source) - **Doc says:** `go build -o palette .` from the repo root; "Requires Go 1.21+". - **Code does:** there is no root main package; the entrypoint is `./cmd/palette` (the Dockerfile builds `./cmd/palette`). go.mod requires Go 1.27.x. - **Evidence:** repo root has no `.go` files; `Dockerfile:12`; `cmd/palette/main.go`. - **Fix:** `go build -o palette ./cmd/palette` and update the Go version requirement. ### 3. performance-notes.md — wrong client fetch limit - **Page:** performance-notes - **Doc says:** "limit=500 per query is the current client cap in `static/table.js`" and that the client queries `/api/public?limit=500`. - **Code does:** `table.js` uses `opts.fetchLimit || 100`, and neither `history.html` nor `mine.html` sets `fetchLimit`, so the client fetches **limit=100**. The server also clamps list `limit` at 100 (`parseLimit(r, 25, 100)`), so 500 would silently clamp to 100 anyway. - **Evidence:** `internal/web/static/table.js:66`; `internal/api/server.go:361,382`; `internal/api/validate.go:68-74`. - **Fix:** change "500" to "100" and note the server-side clamp. ### 4. performance-notes.md — list-row field list is incomplete - **Page:** performance-notes - **Doc says:** rows return "(id, title, language, created_at, view_count, size, custom_slug, is_can)". - **Code does:** the item maps also include `visibility` on both `/api/public` and `/api/mine`. - **Evidence:** `internal/api/server.go:371-376,392-397`. - **Fix:** add `visibility` to the field list. ### 5. design-attachments-storage.md — wrong env var name - **Page:** design-attachments-storage (Part B, item 5) - **Doc says:** "`PALETTE_DB_PATH` env already implies the deployment choice". - **Code does:** the env var is `PALETTE_DB` (`cmd/palette/main.go:24`, `docker-compose.yml:22`, README table). - **Fix:** use `PALETTE_DB`. ### 6. design-e2e-encryption.md — malformed markdown in §5 - **Page:** design-e2e-encryption - **Doc says:** the "Three sharing modes" table is preceded by a corrupted duplicate header row (`| malformed JSON / wrong key | | |` plus a stray table header), garbling the table; section numbering is also broken (two "§5" sections, then "6.2" with no 6.1). - **Fix:** remove the stray duplicate header lines and renumber sections. ### 7. design-e2e-encryption.md — references a deleted doc path - **Page:** design-e2e-encryption (Related docs; also §3.2 cites "docs/API.md") - **Doc says:** links to `../API.md`. - **Code does:** `docs/` was deleted from the repo (commit e17ea4f "Move docs to Gitea wiki"); the API doc now lives in the wiki at `API`. - **Fix:** link to the wiki `API` page. ### 8. README.md — design-doc link lands on the wiki pages index - **Page:** README (Design docs section) - **Doc says:** links to `https://git.archfox.org/poslop/palette/wiki/design/attachments-storage`. - **Code does:** that wiki slug does not exist; Gitea redirects it to the wiki **pages index** (`?action=_pages`), not the doc. The actual page is `wiki/design-attachments-storage`. (Still HTTP 200, so it does not 404 — but the reader does not land on the design doc.) - **Fix:** link to `wiki/design-attachments-storage` (or `wiki/Home`). ## Checked and accurate (not counted) - API.md routes/methods match `internal/api/server.go:84-135`; create response fields (`id`, `url`, `raw_url`, `api_url`, `expires_at`, `created_at`, `deletion_token`) match `server.go:238-247`; `reads_remaining` present, null when no budget (`server.go:297`, `internal/store/burn.go`). - 429 responses carry `Retry-After` + `rate_limited` code (`internal/api/ratelimit.go:113-117`); unlock limiter returns 60s retry-after; per-IP token buckets match the documented limits. - 15-minute burn viewer window default (`internal/api/burn.go:13-20`), per-viewer dedupe via `paste_views` (`internal/store/burn.go:53-66`), raw reads count against the budget (`server.go:421-428`). - Sweeper every minute (`cmd/palette/main.go:39`), 7-day soft-delete grace (`internal/store/store.go:19,406`), burn → soft delete once budget exhausted (`store/burn.go:84-87`). - 1-minute–1-year expiry bounds (`internal/store/store.go:166-172`); `public` boolean overrides string `visibility` (#83, `store.go:223-233`). - Cookie mechanics match design-cookie-preferences: `vwr` (1y, HttpOnly/Lax, `server.go:139-153`), `pw_<id>` = HMAC of paste id under unlock secret, 1h (`internal/web/web.go:91-110,242`), `tok_<id>` 60s handoff (`web.go:270`); pw_ cookies never authorize delete (`cans.go:149-164`, `server.go:341-352`). - Home page links (API, performance-notes, 3 design docs, 4 theme preview PNGs) all resolve 200 to real pages/images.
fen added the QA label 2026-09-10 00:05:24 +00:00
fen added spent time 1 minute 2026-09-10 00:14:31 +00:00
fen closed this issue 2026-09-10 00:20:17 +00:00
Author
Collaborator

QA passed: all 8 fixes verified against code/live server; README fixes merged to dev via PR #111; wiki edits pushed directly.

QA passed: all 8 fixes verified against code/live server; README fixes merged to dev via PR #111; wiki edits pushed directly.
fen added spent time 1 hour 28 minutes 2026-09-10 13:57:37 +00:00
Sign in to join this conversation.
1 Participants
Notifications
Total Time Spent: 1 hour 30 minutes
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: poslop/palette#110