~bigbes/sr-ht-ecore · issues

5jsltamh0v2kle3b02836hjurfddcng9 · 14 rows

idcontent_hashtitledescriptiondesignacceptance_criterianotesstatuspriorityissue_typeassigneeestimated_minutescreated_atcreated_byownerupdated_atclosed_atclosed_by_sessionexternal_refspec_idcompaction_levelcompacted_atcompacted_at_commitoriginal_sizesenderephemeralwisp_typepinnedis_templatemol_typework_typesource_systemmetadatasource_repoclose_reasonevent_kindactortargetpayloadawait_typeawait_idtimeout_nswaitershook_beadrole_beadagent_statelast_activityrole_typerigdue_atdefer_untilno_historystarted_atis_blocked
sr-ht-ecore-1ajc4c2ac5328e8bff0f19885800e9d66e8ee4425f78a823059b40864a4b17cec0dchrome: remove the deprecated ExtraNav seamchrome.Service.ExtraNav has no users left across the six services: bench and cov dropped it when the instance deployed a tokens.sr.ht and 'tokens' appeared in the navbar twice, and artifacts moved its three sections to Sections (ecore 514838a, artifacts 7584106). Both historical uses were the same mistake - a page of one service in the row that lists the instance's services - so there is no correct use to preserve. Removing it touches Service, Page and the srht-nav partial's second range block.open3taskNULLNULL2026-08-15T19:37:00ZEugene Blikhbigbes@gmail.com2026-08-15T19:37:00ZNULLNULL0NULLNULLNULL000�{}0NULLNULLNULL0NULL0
sr-ht-ecore-3sa215f333df6ff16c8b5689438a7ddeb225dd529efd8e3f1b66d3f3de31a9bc980Bump gqlparser to v2.5.36 and gqlgen to v0.17.94 in go.modWhat is wrong: sr-ht-ecore/go.mod pins github.com/vektah/gqlparser/v2 v2.5.8 and github.com/99designs/gqlgen v0.17.36, below the GO-2024-2920 security floor (a DoS in gqlparser's parseDirectives, fixed in v2.5.14). gqlgen v0.17.36 also pins golang.org/x/tools v0.9.3, which does not compile under the current toolchain, breaking 'go generate ./graph' in downstream consumers (observed in sourcehut-specs). Why it matters: sr-ht-ecore is a shared library, so its floor becomes every consumer's floor. sourcehut-specs, sourcehut-compare and sourcehut-tokens all inherit this pin transitively via sr-ht-ecore/sr-ht-core. This must land before those consumers can be bumped (sr-ht-core needs the same bump first). Correct variant, already in use by: sourcehut-artifacts, sourcehut-bench, sourcehut-coverage, sourcehut-curator, sourcehut-dolt, sourcehut-federation, sr-ht-api and thistle, all on gqlparser v2.5.36 + gqlgen v0.17.94. Fix: go get github.com/vektah/gqlparser/v2@v2.5.36 github.com/99designs/gqlgen@v0.17.94 in sr-ht-ecore/go.mod. Confidence: verified (version strings read directly out of all nine services' go.mod plus sr-ht-core and sr-ht-ecore; split is exactly 5/5). Audit: D06 (cross-repo audit, 2026-08-17)open0bugNULLNULL2026-08-17T20:35:28ZEugene Blikhbigbes@gmail.com2026-08-17T20:35:28ZNULLNULL0NULLNULLNULL000�{}0NULLNULLNULL0NULL0
sr-ht-ecore-6r25a67ac288a1f220cf4ef8e7674c6a12e4b32044d52cf9db6af99a2055527cab6Parameterize the hardcoded Vary header in mcphttp.PrivateCache so dolt can adopt mcphttpWhat is wrong: sr-ht-ecore/mcphttp/cache.go's PrivateCache hardcodes vary = "Cookie, Authorization". This is the one stated blocker preventing sourcehut-dolt from importing mcphttp instead of carrying its own private copy, since dolt deliberately uses Vary: Authorization alone. Why it matters: mcphttp was extracted precisely because the Host guard, the commit-time cache wrapper and the two transport options are byte-identical across six services (artifacts, bench, coverage, curator, dolt, specs) — yet nothing imports it (grep across all nine service trees returns zero real imports, only two doc-comment mentions in bench and specs falsely claiming the swap is blocked because the ecore commit adding mcphttp is unpublished/unpinned — verifiably false, both pinned ecore revisions already contain the package). Because each service kept its own private copy, the identical cacheWriter.Flush bug was independently discovered and fixed twice (ecore 3bd158f/00d7582, artifacts 6c44e03), and two other defects in this same audit (a service missing Stateless: true, two services missing Flush on their cacheWriter) are direct consequences of copy-don't-import continuing instead of the package being adopted. Correct variant: mcphttp itself, once this one blocker is removed. Fix: make vary a parameter/field on mcphttp.PrivateCache (or on StreamableOptions), defaulting to "Cookie, Authorization" but overridable so dolt can pass "Authorization" alone. This unblocks each of the six services deleting their private privateCache/cacheWriter/allowHosts/hostAllowed copies and importing mcphttp directly — that consumer-side work is separate follow-up work per repo, not part of this issue. Confidence: verified (two doc-comment mentions found, zero real imports; both services' pinned sr-ht-ecore revisions confirmed to already contain mcphttp). Audit: D10 (cross-repo audit, 2026-08-17)open2bugNULLNULL2026-08-17T20:36:07ZEugene Blikhbigbes@gmail.com2026-08-17T20:36:07ZNULLNULL0NULLNULLNULL000�{}0NULLNULLNULL0NULL0
sr-ht-ecore-aq4f954467082a25557b0733c65f491debb17722b0e2545335c944d95137b9272b9Fill in sr-ht-ecore/CLAUDE.md — it is still the 77-line unedited stubWhat is wrong: sr-ht-ecore/CLAUDE.md is one of eight family CLAUDE.md files that are all exactly 77 lines and still contain both placeholder strings (_Add your build and test commands here_, _Add your project-specific conventions here_). sourcehut-tokens/CLAUDE.md (107 lines, zero placeholders) is the one real file in the family and 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 'never default to the widest answer'. Why it matters: an agent working in sr-ht-ecore currently gets none of this context, which is exactly how several other defects in this same audit (hardcoded sha256sum in Makefiles, missing check-version/check-embedded-css gates, CI silently skipping DB tests) get re-introduced by a future donor copy that has nowhere to read the family's own rules from. Correct variant: sourcehut-tokens/CLAUDE.md. Fix: promote the four generalisable sections of sourcehut-tokens/CLAUDE.md into sr-ht-ecore/CLAUDE.md, adjusting the env-var name and the layering diagram to ecore's own shape — it is a shared library, not a standalone service, so the service layering diagram needs adapting rather than copying verbatim. Confidence: verified (line count and both placeholder strings confirmed directly in sr-ht-ecore/CLAUDE.md). Audit: D44 (cross-repo audit, 2026-08-17)open3taskNULLNULL2026-08-17T20:37:54ZEugene Blikhbigbes@gmail.com2026-08-17T20:37:54ZNULLNULL0NULLNULLNULL000�{}0NULLNULLNULL0NULL0
sr-ht-ecore-c6h98b5db48f712ccd79a818a6e116c2e791c80fb936da39eacb3e1c3efa743705eAdd Flush and a stamping ReadFrom to assets.writer; fix its stale Unwrap commentWhat is wrong: two defects in sr-ht-ecore/assets/assets.go::writer. (a) writer stamps the asset cache policy at commit time but hooks only WriteHeader and Write, not Flush — the exact shape fixed once in mcphttp (3bd158f) and once independently in artifacts (6c44e03). A response committed through a flush would leave without the asset's cache-control headers. (b) middleware.startTracker.ReadFrom exists specifically so static assets aren't a buffered copy loop, but in the documented wiring assets.writer sits inside startTracker directly under ServeContent, so the copy sees *assets.writer, finds no io.ReaderFrom on it, and startTracker.ReadFrom is never reached — a real performance regression against its own doc-comment's stated reason for existing. Why it matters: (a) fails safe today (unreachable because http.FileServer/ServeContent never flush before writing) but is worth closing before it becomes a live bug a third time, as it already has twice elsewhere. Also, assets.writer.Unwrap's doc comment carries the same sentence 00d7582 retracted in mcphttp, and it is only true here because of this same missing Flush — so fixing (a) makes the comment wrong too and both must move together. (b) is a pure, currently-live performance regression. Correct variant: sr-ht-ecore/mcphttp/cache.go::cacheWriter (all three commit hooks plus the corrected Unwrap wording) and sr-ht-ecore/middleware/middleware.go::startTracker (which additionally has Hijack and ReadFrom). Fix: add func (w *writer) Flush() { w.stamp(); _ = http.NewResponseController(w.ResponseWriter).Flush() } and a ReadFrom that calls w.stamp() first; rewrite the Unwrap doc comment to mcphttp's corrected wording. Confidence: verified (method sets tabulated across all three ecore wrappers). Audit: D15 (cross-repo audit, 2026-08-17)open2bugNULLNULL2026-08-17T20:36:19ZEugene Blikhbigbes@gmail.com2026-08-17T20:36:19ZNULLNULL0NULLNULLNULL000�{}0NULLNULLNULL0NULL0
sr-ht-ecore-dwxe03c8cd9f2eef3a2b9f20f5bc86647e04a5052c117eca710f3fb9fcff1bdf3a3Reconcile bearer vs metapat expired-entry handling on cache read (or document the difference)What is wrong: sr-ht-ecore/bearer/bearer.go::(*Validator).cached returns a miss on an expired cache entry and leaves deletion to the sweep in remember, while sr-ht-ecore/metapat's (*Validator).cached deletes an expired entry as it reads it. Every other difference between these two deliberately-parallel packages has a written rationale in the code; this one does not. Why it matters: an unexplained divergence between two packages built to be parallel is exactly the kind of drift the family's copy-with-rationale convention is meant to prevent — the next reader (or the next donor copy) cannot tell whether this is a considered choice or an oversight. Correct variant: sr-ht-ecore/metapat (delete-on-read). Fix: make bearer's cached delete-on-read to match metapat, or add a comment in bearer.go explaining why it is deliberately different. Confidence: verified (part of a bundle of five minor divergences, all verified by the source reports; this is item 3 of that bundle, D46). Audit: D46 item 3 (cross-repo audit, 2026-08-17)open3taskNULLNULL2026-08-17T20:38:08ZEugene Blikhbigbes@gmail.com2026-08-17T20:38:08ZNULLNULL0NULLNULLNULL000�{}0NULLNULLNULL0NULL0
sr-ht-ecore-g3r7bc634f8ff5276c0d7ed0606d98065dcab336835eeeb84293e5d62817317aa68Unify the GraphQL bearer plane: meta PAT beside the working tokenFour services (cov, bench, spec, artifacts) accept only a tokens.sr.ht working token on /query, and publish an empty scope list in api-meta.json, so meta.sr.ht cannot mint a PAT for them at all. dolt already accepts both and publishes a scope. api.sr.ht forwards ONE client Authorization header to every service a federated query touches, so a GraphQL plane that refuses meta PATs cannot federate. Bring the four to dolt's shape: /query accepts meta PAT + working token; MCP and REST stay on tokens.sr.ht alone.Shared half lands in a new sr-ht-ecore package, metapat, beside bearer: ClientID routing, the meta PAT resolve path (decode, username check, LookupUser, LookupTokenRevocation, positive cache) and the OAuth scope check. Each service keeps its own Principal, MetaBackend and error classification. dolt is not migrated in this epic: its PAT plane is entangled with the Basic clone path. Scopes are spelled upstream-style, upper case: cov.sr.ht/REPORTS, bench.sr.ht/RESULTS, spec.sr.ht/SPECS, artifacts.sr.ht/REPOS.open1epicNULLNULL2026-08-16T18:27:30ZEugene Blikhbigbes@gmail.com2026-08-16T18:27:30ZNULLNULL0NULLNULLNULL000�{}0NULLNULLNULL0NULL0
sr-ht-ecore-g3r.16690b3b79f16709676dae3a6f0b93b38828402c0c8cd1e1e8ecca20c54419d2becore/metapat: the shared meta.sr.ht PAT planeA validator for meta.sr.ht personal access tokens beside bearer's working-token one: PlaneOf routing, decode/lookup/revocation with a bounded positive cache, and Allows for the OAuth scope gate.closed1featureNULLNULL2026-08-16T18:37:37ZEugene Blikhbigbes@gmail.com2026-08-16T18:59:50Z2026-08-16T18:59:50ZNULL0NULLNULLNULL000�{}Closed0NULLNULLNULL0NULL0
sr-ht-ecore-g3r.25997c4e1476c5bf13968d86af31e1de96d4d785cd472868cf297aa31d77a69eccov.sr.ht accepts a meta PAT on /query (scope REPORTS)Adopt ecore/metapat on the GraphQL endpoint: route by PlaneOf, keep the working-token arm, gate the meta PAT arm on the service's OAuth scope, and publish that scope in api-meta.json so meta.sr.ht can mint a token for it. MCP and REST stay on tokens.sr.ht alone. Rewrite the doc comments that currently state the opposite.closed1taskEugene BlikhNULL2026-08-16T18:37:49ZEugene Blikhbigbes@gmail.com2026-08-16T19:13:39Z2026-08-16T19:13:39ZNULL0NULLNULLNULL000�{}Deployed as cov.sr.ht 0.9.1_git30 and verified end-to-end: api-meta.json publishes REPORTS, and hut reads /query with the ordinary meta PAT already in its config.0NULLNULLNULL02026-08-16T18:59:58Z0
sr-ht-ecore-g3r.366c7751f414cf0b90abe4ea13425406b477a790ecbe973c19d832d94e54f2f00bench.sr.ht accepts a meta PAT on /query (scope RESULTS)Adopt ecore/metapat on the GraphQL endpoint: route by PlaneOf, keep the working-token arm, gate the meta PAT arm on the service's OAuth scope, and publish that scope in api-meta.json so meta.sr.ht can mint a token for it. MCP and REST stay on tokens.sr.ht alone. Rewrite the doc comments that currently state the opposite.closed1taskEugene BlikhNULL2026-08-16T18:37:49ZEugene Blikhbigbes@gmail.com2026-08-16T19:34:12Z2026-08-16T19:34:12ZNULL0NULLNULLNULL000�{}Implemented, green, pushed; awaiting CI and deploy.0NULLNULLNULL02026-08-16T19:13:46Z0
sr-ht-ecore-g3r.4dbd2c9916707cdf650d8a40a3ef2bd558062d3ea79934d7f3a7ea10b1e556b60spec.sr.ht accepts a meta PAT on /query (scope SPECS)Adopt ecore/metapat on the GraphQL endpoint: route by PlaneOf, keep the working-token arm, gate the meta PAT arm on the service's OAuth scope, and publish that scope in api-meta.json so meta.sr.ht can mint a token for it. MCP and REST stay on tokens.sr.ht alone. Rewrite the doc comments that currently state the opposite.closed1taskNULLNULL2026-08-16T18:37:50ZEugene Blikhbigbes@gmail.com2026-08-17T06:03:09Z2026-08-17T06:03:09ZNULL0NULLNULLNULL000�{}Implemented by parallel agents, verified independently (gates re-run + mutation tests), pushed and deployed; all four services answer a meta PAT on /query.0NULLNULLNULL0NULL0
sr-ht-ecore-g3r.52903cfd195123a383a6bcea6a4232f6eb4439e1ae5b45dd2b4549ae2d5056838artifacts.sr.ht accepts a meta PAT on /query (scope REPOS)Adopt ecore/metapat on the GraphQL endpoint: route by PlaneOf, keep the working-token arm, gate the meta PAT arm on the service's OAuth scope, and publish that scope in api-meta.json so meta.sr.ht can mint a token for it. MCP and REST stay on tokens.sr.ht alone. Rewrite the doc comments that currently state the opposite.closed1taskNULLNULL2026-08-16T18:37:51ZEugene Blikhbigbes@gmail.com2026-08-17T06:03:10Z2026-08-17T06:03:10ZNULL0NULLNULLNULL000�{}Implemented by parallel agents, verified independently (gates re-run + mutation tests), pushed and deployed; all four services answer a meta PAT on /query.0NULLNULLNULL0NULL0
sr-ht-ecore-g3r.699ae2263684e417f3db49e4563c52d5d011ad36811f4692b4bd5604d8a2672ecapi.sr.ht is not deployed on the instance, so nothing is federated yetThe stack on phoebe runs 23 srht-* containers and api.sr.ht is not among them: POST https://api.srht.bigb.es/query does not resolve. So the federation the meta-PAT work unblocks is potential, not current — what it buys today is that hut and any other meta-PAT client can read /query directly. Deploying the gateway means a Dockerfile.api in phoebe-lab/srht, an [api.sr.ht] section, and api-origin= lines for the services to federate. Upstream builds the service list from every config section whose name ends in .sr.ht, so our six custom services would be picked up automatically once they are in its config.open2taskNULLNULL2026-08-16T19:35:26ZEugene Blikhbigbes@gmail.com2026-08-16T19:35:26ZNULLNULL0NULLNULLNULL000�{}0NULLNULLNULL0NULL0
sr-ht-ecore-n3ud2d6482ab7bda4ccd731bac37ca96f8b241666d6991211ad7a6df42ba67e3736Add a shared pager partial and inc/dec/agotime/shorttime helpers to chromeWhat is wrong: four services (bench, coverage, curator, dolt) each hand-roll their own pagination markup — four different HTML shapes, one of them a <button> instead of a link — plus byte-equivalent inc/dec arithmetic copied three times, plus two incompatible ago time-formatting helpers (coverage: short units, forward-facing, reads time.Since directly; dolt: long units, past-facing, clamps the future, swappable timeNow) — while sr-ht-ecore/chrome.Funcs already provides a third phrasing, reltime. sr-ht-ecore/chrome ships none of a pager, inc/dec or ago, so there is nowhere for a new service to import these from and every donor copy re-derives its own. Why it matters: this is the most visible inconsistency to a user hopping between services on the same instance. Upstream SourceHut ships a shared core.sr.ht/srht/templates/pagination.html and ecore currently has no equivalent. RelTime's own doc-comment names exactly this class of drift as the reason it was hoisted into chrome in the first place ('the copies disagreed about the future... for the same instant'). Correct variant: none of the four existing copies alone — dolt's clock-swappable, past-facing ago is judged the better implementation; coverage's short units serve a legitimately different, valid need, so the fix may need two ago variants rather than one. Fix: add srht-pager to sr-ht-ecore/chrome/templates/chrome.tmpl over a chrome.Pager{PrevHref, NextHref, Page, TotalPages} dot, plus inc/dec and agotime/shorttime to chrome.Funcs(). Converting bench/coverage/curator/dolt to use it and deleting their private copies is separate follow-up work per consumer repo, not part of this issue. Confidence: verified. Audit: D40 (cross-repo audit, 2026-08-17)open3taskNULLNULL2026-08-17T20:36:52ZEugene Blikhbigbes@gmail.com2026-08-17T20:36:52ZNULLNULL0NULLNULLNULL000�{}0NULLNULLNULL0NULL0