solid-pod-rs-forge 0.5.0-alpha.18

Clean-room Rust Git forge (Gogs/Gitea slice) composed on solid-pod-rs primitives: pod-native issues/PRs, forge push tokens, hosted did:nostr bodies, and Blocktrails anchoring. Cites JavaScriptSolidServer `forge` behaviour by function name only; all code original.
Documentation
# solid-pod-rs-forge

A clean-room Rust reimplementation of the JavaScriptSolidServer `forge`
plugin: a zero-build, server-rendered Git forge (a Gogs/Gitea slice)
composed almost entirely from primitives `solid-pod-rs` already ships.

## Design

The forge is ~90% composition of existing solid-pod-rs primitives and
~10% new glue. It reuses:

- **git smart-HTTP** (clone/fetch/push, auto-init) — `solid-pod-rs-git`
- **repo browse porcelain** (log/diff/branches/commit) — `solid-pod-rs-git::api`
- **write-as-commit provenance + Bitcoin anchoring** — `solid-pod-rs::provenance` / `mrc20` / `bitcoin_tx`
- **NIP-98 auth** — `solid-pod-rs::auth::nip98`
- **`did:nostr` identity** — `solid-pod-rs::did_nostr_types`
- **WAC gating** — enforced by the embedding server before `handle`

New in this crate: the spine index (issue/PR/label pointers), the
two-phase pod-write coordinator, hosted storage for podless `did:nostr`
agents, the forge push token, NIP-34 emission (feature `announce`, below), the
marks manager, and fork/PR/browse porcelain that extends the git API.

**NIP-34 emission (feature `announce`).** The forge builds and signs a kind
30617 repository announcement and a kind 30618 repository state for each
repository (`GET /api/repos/<o>/<n>/nostr`), with the anchor tags
(`r`, `anchor`, `chain`, `txo`, `commit`) for anchored repositories, signed by
a forge-instance key (config `announce_key`, else a `0600` `announce-key`
file in the plugin directory). Publication is opt-in: with `announce_relays`
set (`ws://` and `wss://` only, each host passing the SSRF check) the owner
can `POST /api/repos/<o>/<n>/announce`, and other tiers can call
`ForgeService::announce_repo` or `announce_repo_in_background`. With no relays
nothing is sent. Not included: ephemeral previews (kind 21617) and the
web-edit tier that would trigger an announce.

## Architecture rule

**"Words in pods, metadata in the forge."** Issue/PR/comment bodies live
in the author's own pod (WAC-governed, author-owned); the forge keeps only
a spine of pointers and re-fetches bodies at read time (bounded). Podless
`did:nostr` agents store bodies in forge-hosted storage instead.

## IP posture

Everything is derived from the forge plugin's published *behaviour* and
expressed as fresh Rust on solid-pod-rs's own primitives. JSS is cited by
function/section name only — no upstream JavaScript is transcribed.

## Native-only

The forge shells to `git`/`git-http-backend`, touches the filesystem, and
runs a loopback HTTP client. It is never part of a `core`/wasm build and
adds zero dependencies to the core crate.

## Features

| Feature | Effect |
|---|---|
| `anchoring` | Tier 3.5 Blocktrails anchoring (pulls `solid-pod-rs/mrc20` + `k256`) |
| `announce` | NIP-34 30617/30618 builders, announce key, relay publisher, `GET /nostr`, `POST /announce` (pulls `solid-pod-rs-nostr`, `k256`, `tokio-tungstenite`) |

## Entry point

Framework-agnostic: `ForgeService::handle(ForgeRequest, ForgeAgent) ->
Result<ForgeResponse, ForgeError>`. The embedding server translates its
native types at the edge and WAC-gates the forge scope before dispatch.

## Licence

AGPL-3.0-only.