# 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//` 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/`). 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 (`srht/app.py`) serves the user-facing web UI; Go binary (`cmd/api` → `-api`) serves the GraphQL API. `builds.sr.ht` additionally has `cmd/worker` → `builds.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), `hut` (third-party CLI client for SourceHut from `~xenrox` — *not* part of the `~sircmpwn` umbrella but the de-facto CLI users reach for; covers builds/git/lists/meta/paste/pages/todo/hub via the GraphQL APIs). ## 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: -api, -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 `dataloaden` — `cd 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: `./-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 `srht/graphql/` and `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 `-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..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/`. 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.