~bigbes/sourcehut-root

ref: d7794447714c1c1c761ed19943db832c731e2c88 sourcehut-root/CLAUDE.md -rw-r--r-- 9.1 KiB
d7794447 — Eugene Blikh init: superproject for SourceHut documentation mirror 8 days ago

#CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

#Purpose

This directory is a read-only documentation mirror, not a development workspace. It exists to let Claude inspect the current state of every SourceHut service in one place when answering questions about how SourceHut works.

The set of repos is discovered by scraping the upstream source listing pages:

  • https://sr.ht/~sircmpwn/sourcehut/sources
  • https://sr.ht/~sircmpwn/sourcehut/sources?page=2 (and additional pages if they exist)

This workspace is itself a git superproject: every cloned subproject is a submodule pinned to a specific commit (typically the latest upstream tag), tracked in .gitmodules. Use the sourcehut-refresh skill to re-discover upstream and bump submodules; use sourcehut-lookup for fast cross-repo documentation traversal. A refresh leaves submodule pointer bumps uncommitted so the user can review and commit one snapshot at a time.

Submodules' .git directories are absorbed into .git/modules/<name>/ of the superproject. Each clone's worktree contains a .git file (gitlink), not a directory — do not be confused by this.

A pre-built inventory lives at .claude/INDEX.md — per-service GraphQL types, SQL tables, Python blueprints, Go packages, plus a cross-repo type map. Regenerated automatically by sourcehut-refresh; the sourcehut-lookup skill reads it first to skip a lot of grepping.

#Production deviations (phoebe-lab)

The user runs a patched SourceHut in production under ~/data/home/phoebe-lab/srht/. Fixes not yet upstreamed are mirrored here in patches/ for reference — they are not applied to the clones in this workspace. When answering questions about behavior that might diverge from upstream, check patches/README.md first. Currently tracked:

  • patches/core-go-checksum.patch — disables AWS SDK v2 default request/response checksum calculation in core-go/objects/middleware.go NewClient. Upstream defaults break streaming PutObject (pages publish, builds artifact upload) on non-AWS S3 backends.

Do not commit, push, or develop in these clones — they will be wiped/replaced by the next refresh. If you need to make changes, clone the upstream repo separately.

#Repository layout

This is not a single repo — it is a workspace of ~28 sibling clones of upstream SourceHut subprojects (https://git.sr.ht/~sircmpwn/<name>). Each subdirectory is an independent git repo with its own LICENSE, build, and history. Always cd into the specific subproject before running per-repo commands.

#Service topology

SourceHut is a federation of services that share a common architecture. Categorize a repo by inspecting its top level:

  • Hybrid Python+Go service (api/, *srht/, Makefile, run.py, schema.sql, migrations/, pyproject.toml, go.mod): builds.sr.ht, git.sr.ht, hub.sr.ht, lists.sr.ht, meta.sr.ht, paste.sr.ht, todo.sr.ht, man.sr.ht, pages.sr.ht. Python Flask app (<name>srht/app.py) serves the user-facing web UI; Go binary (cmd/api<service>-api) serves the GraphQL API. builds.sr.ht additionally has cmd/workerbuilds.sr.ht-worker (job runner using Celery via gocelery, Redis, and builds.sr.ht-shell).
  • Pure Go service: api.sr.ht (the federated GraphQL gateway built on git.sr.ht/~adnano/thistle), sourcehut-ssh (SSH dispatch for git/hg shells), pages.sr.ht (newer version, Go-only).
  • Shared libraries: core.sr.ht (Python — srht package: ORM, OAuth, GraphQL helpers, templates, SCSS/Bootstrap assets) and core-go (Go equivalent: auth, client, config, database, redis, server, webhooks, crypto).
  • Static sites / docs: sourcehut.org and srht.site (Hugo), sr.ht-docs (man.sr.ht content), git-am.io, git-rebase.io, git-send-email.io.
  • Ops / infra: gensokyo (Kubernetes YAML for the production cluster), sr.ht-nginx (nginx configs), sr.ht-apkbuilds / sr.ht-pkgbuilds (Alpine/Arch packaging), sourcehut-migrate (data migration tooling), status.sr.ht, go-away-config.
  • Misc Go clients/tools: sourcehut-go (Go client library and CLI examples), forgeperf (forge performance benchmark harness using Chromium+Lighthouse).

#Build commands

Each service that builds has a top-level Makefile. The hybrid Python+Go services follow a uniform pattern (driven by core.sr.ht's Makefile conventions):

make                      # default: all-bin all-share all-python
make all-bin              # Go binaries: <service>-api, <service>-worker (if present)
make all-share            # compile SCSS via sassc → static/main.min.css
make all-python           # generate buildsrht/graphql/__init__.py via ariadne-codegen
make install              # install to $(PREFIX)=/usr/local
make clean

Toolchain prerequisites (vary by service):

  • Go: project go.mod versions range from 1.16 (older repos like api.sr.ht) to 1.22+ with toolchain go1.24.0 (newer repos like builds.sr.ht).
  • Python: needs the srht package from core.sr.ht installed (editable or via system package). Production uses pip install -e . after pip install -e ../core.sr.ht.
  • sassc (or set SASSC), minify, ariadne-codegen (Python package, used to generate GraphQL client stubs from *.graphql queries).
  • GraphQL server code is generated by gqlgen (Go) — cd api && go generate ./graph (uses gqlgen.yml, reads api/graph/schema.graphqls, writes api/graph/api/generated.go).
  • DataLoader code is generated by dataloadencd api && go generate ./loaders (the api/loaders/gen shell helper + directives in generate.go).
  • Build-time version strings come from sourcehut-buildver / sourcehut-builddate (installed from core.sr.ht) and are injected via -ldflags into core-go/server.BuildVersion/BuildDate.

#Running a service locally

For Python web tier: python3 run.py (calls srht.debug.run_service(app)). For the Go API: ./<service>-api after make. Both read config.ini (copy from config.example.ini).

#Database / migrations

Each service ships its full schema.sql plus incremental migrations/*.sql. Tests/dev use Postgres; Redis is required for job queues, GraphQL pubsub, and webhooks. lists.sr.ht additionally has an ingress/ (LMTP) component; todo.sr.ht has todo.sr.ht-lmtp.

#Tests

builds.sr.ht/api/manifest_test.go shows the Go test convention — standard go test ./... from inside each service's repo. There is no top-level "run all tests" target across the workspace; each repo is tested independently.

#Architecture notes that span files

  • GraphQL is the API contract. Each service publishes api/graph/schema.graphqls; clients (the Python web tier of the same service, the federated gateway api.sr.ht, and the Python web tiers of other services) consume it. Python clients are generated under <svc>srht/graphql/ and <svc>srht/meta/ via ariadne-codegen. Go resolvers live under api/graph/, with batched lookups in api/loaders/.
  • api.sr.ht is the federation layer. It uses thistle to merge per-service schemas into one endpoint and forwards requests to each <service>-api based on the type. InternalAuthTransport in api.sr.ht/auth.go is how it elevates calls when needed.
  • Authentication paths: OAuth 2.0 with meta.sr.ht as the IdP. core-go/auth and core.sr.ht/srht/oauth are the canonical client implementations — every other service depends on one of them. Internal service-to-service calls use the "internal user" with HMAC-signed headers (core-go/auth/internal.go).
  • Webhooks (legacy HTTP and new GraphQL-native): core-go/webhooks defines the worker; each service registers concrete event subscriptions in api/webhooks/.
  • SCSS / static assets: core.sr.ht/scss/ provides the shared bootstrap-derived theme; each service has its own scss/main.scss that imports it. The Makefile compiles to a hashed main.min.<sha>.css for cache busting.
  • CI manifests for the project itself live in each repo's .builds/ directory (if present) and run on builds.sr.ht — see the sourcehut-ci skill for authoring rules.

#Upstream and contributions

Upstream is hosted at git.sr.ht/~sircmpwn/<name>. Patches go to the sr.ht-dev mailing list via git send-email. This workspace is a read-only mirror — do not commit, push, or develop here. To contribute, clone the upstream repo independently outside this workspace.

#Gotchas

  • make from the workspace root does nothing useful — there is no top-level Makefile. Always work inside a single subproject.
  • The Go modules use git.sr.ht/~sircmpwn/core-go from upstream tags; do not add a replace directive to point at the local ./core-go clone unless explicitly working on a coordinated change, since the local clone is pinned to a tag that may not match what the service expects.
  • Several repos still target Go 1.16 (api.sr.ht, possibly older clones). Use the toolchain declared in each go.mod.
  • gensokyo uses the Go-based yq (github.com/mikefarah/yq), not the Python one — they are not interchangeable.
  • forgeperf is an offline benchmark harness, not a service — it needs Chromium, an X server, and lighthouse via npm to run.