main · 11 rows
| id | content_hash | title | description | design | acceptance_criteria | notes | status | priority | issue_type | assignee | estimated_minutes | created_at | created_by | owner | updated_at | closed_at | closed_by_session | external_ref | spec_id | compaction_level | compacted_at | compacted_at_commit | original_size | sender | ephemeral | wisp_type | pinned | is_template | mol_type | work_type | source_system | metadata | source_repo | close_reason | event_kind | actor | target | payload | await_type | await_id | timeout_ns | waiters | hook_bead | role_bead | agent_state | last_activity | role_type | rig | due_at | defer_until | no_history | started_at | is_blocked |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| sr-ht-compare-11d | d93cb90c612f995ac19f371322ae99fc738ba4348621e8b6f91e81348d776ffa | Give compare's CSRF guard a rendered deny handler instead of nil | What is wrong: sourcehut-compare/web/router.go installs 'r.Use(csrf.Require(s.chromeSvc.SelfOrigin(), nil))'. Passing nil selects csrf.denyPlain, a bare text/plain http.Error. Every sibling — sourcehut-{tokens,bench,coverage,curator,specs,artifacts,dolt}/web/router.go — passes a renderer, e.g. 'func(w, r) { s.renderError(w, r, http.StatusForbidden, csrf.Message) }'. Status and message already agree with the siblings; only the presentation differs. Why it matters: compare has no POST routes today, so nothing is refused yet — but the first form added gets a naked text/plain 403 on a surface whose every other refusal is a rendered page with nav. The router's own comment explains the guard exists 'because the day somebody adds the first POST is exactly the day nobody remembers to add the check'; the same argument applies to the renderer. csrf.Require's doc calls the nil default 'a usable default rather than an invitation to skip the middleware', and compare already has an error renderer (s.renderError) it simply isn't wiring in. Correct variant: the seven siblings that pass a renderer, e.g. repo/path sourcehut-tokens/web/router.go::csrf.Require call site. Fix: sourcehut-compare/web/router.go — replace the nil argument with 'func(w, r) { s.renderError(w, r, http.StatusForbidden, csrf.Message) }'. Note: the register rates this consistency after two source reports disagreed (one called it cosmetic, one correctness-risk); both agree there are currently no POST routes so nothing is refused today. Audit: D34 (cross-repo audit, 2026-08-17) | open | 3 | chore | NULL | NULL | 2026-08-17T21:37:43Z | bigbes | bigbes@gmail.com | 2026-08-17T21:37:43Z | NULL | NULL | 0 | NULL | NULL | NULL | 0 | 0 | 0 | �{} | 0 | NULL | NULL | NULL | 0 | NULL | 0 | ||||||||||||||||||||||||
| sr-ht-compare-4yv | 3a6f90aef7850f81dba8c5e2c73048f090739410fbe0de7bed713ed762731d1d | Make sourcehut-compare/Makefile's css recipe portable off GNU sha256sum | What is wrong: the css recipe in sourcehut-compare/Makefile ends with 'mv web/static/main.min.css web/static/main.min.$$(sha256sum ... | cut -c1-8).css'. On a machine without GNU coreutils, sha256sum does not exist, the command substitution yields empty, and mv produces web/static/main.min..css. This affects six Makefiles: sourcehut-{artifacts,compare,coverage,dolt,specs,tokens}/Makefile. Why it matters: that filename does not match main.min.*.css, so assets.Resolve answers "" and every page renders unstyled, with no error anywhere (set -e does not catch a failure inside $$( )). Compounded by D09 (compare tracks the old build artefact) and the compare/dolt/specs/artifacts gap in check-version/check-embedded-css (D12). Correct variant: repo/path sourcehut-bench/Makefile and sourcehut-curator/Makefile, which define 'SHA256SUM ?= sha256sum' and use $(SHA256SUM), with a comment naming 'make SHA256SUM="shasum -a 256" css' as the macOS invocation. Fix: add 'SHA256SUM ?= sha256sum' to sourcehut-compare/Makefile and substitute $(SHA256SUM) for the raw sha256sum call in the css recipe. Audit: D08 (cross-repo audit, 2026-08-17) | open | 1 | bug | NULL | NULL | 2026-08-17T21:36:10Z | bigbes | bigbes@gmail.com | 2026-08-17T21:36:10Z | NULL | NULL | 0 | NULL | NULL | NULL | 0 | 0 | 0 | �{} | 0 | NULL | NULL | NULL | 0 | NULL | 0 | ||||||||||||||||||||||||
| sr-ht-compare-65g | c3a07761c446057e82e20332a5c957ced1c742de31ad5dba2c95a43597585d38 | Move compare's inline layout.html CSS into scss/main.scss | What is wrong: sourcehut-compare/web/templates/layout.html has a 28-line inline <style> block (the .diff-status* rules). sourcehut-compare's scss/main.scss is about 200 lines and contains no .diff-status rule at all — the two are unrelated to each other. (Companion finding: sourcehut-dolt has ~467 more lines of inline CSS across four templates, tracked separately in dolt's tracker.) Why it matters: inline CSS is re-sent on every page load, sits outside the hashed-asset immutable cache, cannot use the shared SCSS variables ($font-family-monospace, the dark palette), and — because it lives in layout.html specifically — is paid for on every single page compare serves, including the error page. compare already has a working 'make css' pipeline that the six other siblings use for exactly this content. Correct variant: the six services that keep everything in scss/main.scss below '@import "base"', e.g. repo/path sourcehut-tokens/scss/main.scss. Fix: move the .diff-status* rules from sourcehut-compare/web/templates/layout.html into sourcehut-compare/scss/main.scss, then delete the <style> block from layout.html. Audit: D37 (cross-repo audit, 2026-08-17) | open | 3 | chore | NULL | NULL | 2026-08-17T21:37:44Z | bigbes | bigbes@gmail.com | 2026-08-17T21:37:44Z | NULL | NULL | 0 | NULL | NULL | NULL | 0 | 0 | 0 | �{} | 0 | NULL | NULL | NULL | 0 | NULL | 0 | ||||||||||||||||||||||||
| sr-ht-compare-a7j | 3ba8539d07fbd946f64aed45dd6ab47a1cd460a94806d9a39bed3f65b2f905c0 | Give sourcehut-compare a CLAUDE.md with the family's generalisable rules | What is wrong: sourcehut-compare has neither a CLAUDE.md nor an AGENTS.md — the only one of the nine custom services with no such file at all. (Companion finding, filed in other trackers: eight sibling repos — artifacts, bench, coverage, curator, dolt, federation, specs, sr-ht-ecore — do have a CLAUDE.md, but it's a 77-line unedited stub full of placeholders like '_Add your build and test commands here_'.) Why it matters: sourcehut-tokens/CLAUDE.md (107 lines, no placeholders) already carries several rules that are family-wide, not tokens-specific: the layering rule, the 'make test'/'make test-pg' warning, the 'make css' embedding warning, the doc-comment density rule, and the 'never default to the widest answer' rule. An agent working in compare currently gets none of this context, which is exactly how defects like the sha256sum portability bug (D08) or the missing check-version gate (D12) get reintroduced by an agent that has no repo-local guidance to consult. Correct variant: repo/path sourcehut-tokens/CLAUDE.md. Fix: promote the four generalisable sections of sourcehut-tokens/CLAUDE.md into a new sourcehut-compare/CLAUDE.md, adjusting the env-var names and the layering diagram for compare's own package layout (web/, frontend/, authz/). Audit: D44 (cross-repo audit, 2026-08-17) | open | 3 | chore | NULL | NULL | 2026-08-17T21:38:40Z | bigbes | bigbes@gmail.com | 2026-08-17T21:38:40Z | NULL | NULL | 0 | NULL | NULL | NULL | 0 | 0 | 0 | �{} | 0 | NULL | NULL | NULL | 0 | NULL | 0 | ||||||||||||||||||||||||
| sr-ht-compare-cz1 | d4ed69b8f83cc9d16ac512119174c4e0e047f5c5a5a0d6f22e4e3b9ff078f32c | Add check-version and check-embedded-css targets to sourcehut-compare/Makefile | What is wrong: sourcehut-compare/Makefile defines no check-version: target (nor check-embedded-css); its APKBUILD build() runs only 'make check-css' and package() re-verifies nothing. This gap exists in four repos: sourcehut-{artifacts,compare,dolt,specs}/Makefile. Why it matters: check-version inspects the compiled binary (go version -m $(CHECK_BIN)) for vcs.revision/vcs.modified and fails the build if the tree was dirty; check-embedded-css greps the binary for the embedded stylesheet name and diffs it against what is on disk, catching 'compiled before make css ran'. compare's own D09 (tracked build artefact that make css deletes) makes compare hit exactly the dirty-tree failure mode this gate exists to catch, on every local make css, and nothing enforces it. Correct variant: repo/path sourcehut-tokens/Makefile — bench, coverage, curator, tokens (both targets) and federation (check-version only) all call these from both build() and package(), so the gate runs against the artefact that actually ships. Fix: port check-version/check-embedded-css plus their CHECK_BIN/CHECK_BINS staged-artefact invocations from sourcehut-tokens/Makefile into sourcehut-compare/Makefile and its APKBUILD build()/package(). Audit: D12 (cross-repo audit, 2026-08-17) | open | 2 | bug | NULL | NULL | 2026-08-17T21:36:11Z | bigbes | bigbes@gmail.com | 2026-08-17T21:36:11Z | NULL | NULL | 0 | NULL | NULL | NULL | 0 | 0 | 0 | �{} | 0 | NULL | NULL | NULL | 0 | NULL | 0 | ||||||||||||||||||||||||
| sr-ht-compare-d4m | 9ad11b77c76bb64020f443627f8a476d44a5bcd875cdf25af89c4d87b7fd0c84 | Switch compare's template embed to the all:templates prefix | What is wrong: sourcehut-compare embeds its template tree with a bare glob, 'templates/*.html' (in the //go:embed directive), instead of the 'all:templates' directory-walk prefix that artifacts/bench/coverage/curator/tokens use (each with a comment noting the all: prefix is load-bearing). specs uses the same bare-glob form as compare; dolt uses a two-pattern glob ('templates/*.html templates/icons/*.svg'). Why it matters: nothing is broken today (a glob still picks up _-prefixed partials, unlike a directory walk), but the glob form is fragile going forward: a partial placed in a subdirectory, or any non-.html fragment, is silently NOT embedded and fails at request time as 'no such template' — dolt already had to add a second glob pattern for its icons/ subdirectory to work around exactly this. Correct variant: 'all:templates', e.g. repo/path sourcehut-tokens's //go:embed directive over its templates tree. Fix: change sourcehut-compare's //go:embed directive from 'templates/*.html' to 'all:templates'. Audit: D39 (cross-repo audit, 2026-08-17) | open | 3 | chore | NULL | NULL | 2026-08-17T21:37:46Z | bigbes | bigbes@gmail.com | 2026-08-17T21:37:46Z | NULL | NULL | 0 | NULL | NULL | NULL | 0 | 0 | 0 | �{} | 0 | NULL | NULL | NULL | 0 | NULL | 0 | ||||||||||||||||||||||||
| sr-ht-compare-f6e | c7291faccf05d3d977171de95de133c614db74303c64d102c81d5f59a4d1e764 | Pass *http.Request into compare's template render error log | What is wrong: sourcehut-compare/web/templates.go::(*Server).render logs 'slog.Error("web: render", scribe.Err(err), "page", page, "status", status)' with no *http.Request, so there is no ErrorContext, no method, no path, and no request id. Every other service in the family logs 'slog.ErrorContext(r.Context(), ..., "method", r.Method, "path", r.URL.Path, scribe.Err(err))', the shape pages.Render's own doc-comment shows. Why it matters: chimw.RequestLogger's request id lives in the request context and is dropped here, so a render failure in compare cannot be correlated with the request line that produced it — the one piece of observability every sibling gets for free. Correct variant: the seven siblings, e.g. repo/path sourcehut-tokens/web/templates.go::render (or pages.Render's own doc-comment) for the ErrorContext shape. Fix: thread an *http.Request into sourcehut-compare/web/templates.go::(*Server).render and switch the log call to slog.ErrorContext(r.Context(), ...) including method and path. Audit: D35 (cross-repo audit, 2026-08-17) | open | 3 | chore | NULL | NULL | 2026-08-17T21:37:44Z | bigbes | bigbes@gmail.com | 2026-08-17T21:37:44Z | NULL | NULL | 0 | NULL | NULL | NULL | 0 | 0 | 0 | �{} | 0 | NULL | NULL | NULL | 0 | NULL | 0 | ||||||||||||||||||||||||
| sr-ht-compare-g77 | 9de449836d2118c925ba7fecbe77c2b5528f3b24fcc0d83cbc879606e52a930e | Bump gqlparser/gqlgen off the GO-2024-2920 floor in compare/go.mod | What is wrong: sourcehut-compare/go.mod pins github.com/vektah/gqlparser/v2 v2.5.8 and github.com/99designs/gqlgen v0.17.36. gqlparser v2.5.8 is below the fix for GO-2024-2920 (a DoS in parseDirectives), which landed in v2.5.14. Five modules share this stale pin: sourcehut-specs/go.mod, sourcehut-compare/go.mod, sourcehut-tokens/go.mod, sr-ht-core/go.mod, sr-ht-ecore/go.mod. Why it matters: sr-ht-core and sr-ht-ecore are libraries that compare depends on, so their floor becomes compare's floor regardless of whether compare's own /query path requires a credential first. Correct variant: gqlparser/v2 v2.5.36 + gqlgen v0.17.94, already in use by sourcehut-{artifacts,bench,coverage,curator,dolt}, thistle, sr-ht-api and sourcehut-federation (repo/path: sourcehut-bench/go.mod as a reference). Fix: bump sr-ht-core and sr-ht-ecore to gqlparser/v2@v2.5.36 + gqlgen@v0.17.94 first, then run 'go get github.com/vektah/gqlparser/v2@v2.5.36 github.com/99designs/gqlgen@v0.17.94' in sourcehut-compare/go.mod and re-run go mod tidy. Audit: D06 (cross-repo audit, 2026-08-17) | open | 0 | bug | NULL | NULL | 2026-08-17T21:36:09Z | bigbes | bigbes@gmail.com | 2026-08-17T21:36:09Z | NULL | NULL | 0 | NULL | NULL | NULL | 0 | 0 | 0 | �{} | 0 | NULL | NULL | NULL | 0 | NULL | 0 | ||||||||||||||||||||||||
| sr-ht-compare-jdq | cea9b707c3ee54120545e344272afc44380b8c68685835f8c7aba5ec03e59276 | Untrack the compiled CSS/JS bundle that make css deletes in sourcehut-compare | What is wrong: sourcehut-compare/web/static/main.min.79713f25.css (142 KB) and web/static/bundle.a62c2e63.js (10 MB) are both tracked in git, while sourcehut-compare/.gitignore already has the patterns /web/static/main.css and /web/static/main.min.*.css (with a NOTE that removal from the index 'waits on the first CI run'). A tracked file is unaffected by a later-added ignore pattern, and 'make css' opens with 'rm -f web/static/main.css $(CSS)' — it deletes a tracked file. Why it matters: every developer who runs 'make css' gets a dirty working tree, and Go stamps every binary built afterwards vcs.modified=true, which is exactly what check-version exists to catch — and compare is one of the four repos that has no check-version target (see D12/sr-ht-compare issue for that). Separately, install-files copies web/static/*, so a stale tracked CSS would be staged if make css is skipped. Correct variant: the seven sibling services, all of which gitignore the compiled stylesheet and cannot hit this class of bug. Fix: git rm --cached web/static/main.min.79713f25.css (the ignore entry already exists). Separately decide whether the 10 MB esbuild bundle from frontend/ (web/static/bundle.a62c2e63.js) should be built in CI like the CSS rather than committed, and gitignore it too if so. Audit: D09 (cross-repo audit, 2026-08-17) | open | 1 | bug | NULL | NULL | 2026-08-17T21:36:10Z | bigbes | bigbes@gmail.com | 2026-08-17T21:36:10Z | NULL | NULL | 0 | NULL | NULL | NULL | 0 | 0 | 0 | �{} | 0 | NULL | NULL | NULL | 0 | NULL | 0 | ||||||||||||||||||||||||
| sr-ht-compare-rgh | 6d3d6218b8d59614819770c86a884bf46c93afee836d0a1d72c03b09fc1222f1 | Correct compare's README: no replace directive, no core-go fork exists | What is wrong: sourcehut-compare/README.md's Layout section says 'The core-go dependency is pinned to a private fork (git.srht.bigb.es/~bigbes/core-go) via a replace directive in go.mod.' Neither claim is true against sourcehut-compare/go.mod: 'grep -c replace go.mod' returns 0, and the dependency is a direct require on sourcecraft.dev/bigbes/sr-ht-core, not a replace onto any fork. Why it matters: a reader copying this into a new service would add a replace directive pinning a module that does not exist — and this workspace's own CLAUDE.md specifically warns against a replace onto a local sibling clone. Fix: rewrite the paragraph in sourcehut-compare/README.md to name the two direct requires (sr-ht-core, sr-ht-ecore) and state that no replace directive is used anywhere in the family. The one family exception — dolt's 'github.com/dolthub/gozstd => ./third_party/gozstd-purego' — is a vendored third-party shim, not a local-sibling replace, and should not be cited as a precedent. Note: this finding is marked 'reported' (not independently re-verified by a second pass) in the source register, though the go.mod grep itself was directly checked. Audit: D50 (cross-repo audit, 2026-08-17) | open | 3 | chore | NULL | NULL | 2026-08-17T21:38:41Z | bigbes | bigbes@gmail.com | 2026-08-17T21:38:41Z | NULL | NULL | 0 | NULL | NULL | NULL | 0 | 0 | 0 | �{} | 0 | NULL | NULL | NULL | 0 | NULL | 0 | ||||||||||||||||||||||||
| sr-ht-compare-vos | 6708ad7c99bfd4b1bd2621479d3f656f6fdd32d05874a9fccbd554b3d53ace1c | Mount compare's /static/ with chimw.GetHead instead of r.Handle | What is wrong: sourcehut-compare/web/router.go mounts static assets with 'r.Handle(assets.DefaultPrefix+"*", s.static)', which registers every HTTP method. Two other idioms exist in the family: chimw.GetHead(...) in artifacts/bench/curator/tokens, and r.Mount(...) in specs. compare and dolt both use r.Handle. Why it matters: with r.Handle or r.Mount, a same-origin POST to e.g. /static/main.min.<sha>.css is served the file with a 200 instead of compare's rendered 405 — harmless today, but the routing tree no longer describes what the service actually serves, which is exactly the argument chimw.GetHead's own doc makes for registering the GET/HEAD pair explicitly instead of accepting every method. Correct variant: chimw.GetHead, e.g. repo/path sourcehut-tokens/web/router.go static mount. Fix: sourcehut-compare/web/router.go — replace 'r.Handle(assets.DefaultPrefix+"*", s.static)' with 'chimw.GetHead(r, assets.DefaultPrefix+"*", s.static)' (or the service's existing GetHead wrapper). Audit: D38 (cross-repo audit, 2026-08-17) | open | 3 | chore | NULL | NULL | 2026-08-17T21:37:45Z | bigbes | bigbes@gmail.com | 2026-08-17T21:37:45Z | NULL | NULL | 0 | NULL | NULL | NULL | 0 | 0 | 0 | �{} | 0 | NULL | NULL | NULL | 0 | NULL | 0 |