Reading copy of lichen.page.review: one PR per unit, product changes only

OCTOBER-REVIEW-REVISIONS 5c: SiteOwner is one plain type, and a handle is used only when verified both ways #48

targeting base/october-review-revisions-u5c from view/october-review-revisions-u5c
Closed opened by and assigned to notplants-bot.bsky.social
targeting base/october-review-revisions-u5c from view/october-review-revisions-u5c

SiteOwner becomes one plain type, SiteOwner { atproto_did, deploy_key_public } in lichen-site/src/owner.rs (where OwnerFacts was). The SiteOwner trait, LinkOwner, lichen-site's AuthProvider (it stays in lichen-server's users.rs), link::owner_facts, has_remote, should_push and start_iroh_side are gone, and the handle is dropped from the launch, LaunchIroh and the lent session, so the main runtime holds no handle.

A handle is derived from the DID only when it is verified both ways. The identity resolver moves to lichen-site/src/atproto/identity.rs with its SSRF guard, and gains names_both_ways, verified_handle and a TCP-only DNS resolver at 127.0.0.1:53 (a confined site with iroh off has no /etc/resolv.conf); the admin thread's fetches go through the site's egress. An old pds://<handle>/<domain> remote is pushed only when its handle verifies both ways to the owner's DID, and git is given the DID form per push.


OCTOBER-REVIEW-REVISIONS, subunit 5c. Plan: https://tangled.org/notplants-bot.bsky.social/lichen-orchestrator/blob/main/machine-docs/plans/OCTOBER-REVIEW-REVISIONS-2026-10-28.md

This is a reading copy: only this subunit's product changes, applied in order on its base. Nothing here is to be merged.

Source PRs on lichen.page.review (product), in order, with their original descriptions #

  • #3410 s/778-orr-u5c-site-owner-did — ORR 5c: SiteOwner is one plain type; a handle only verified both ways; DID-form remotes

    OCTOBER-REVIEW-REVISIONS unit 5c, product: SiteOwner is one plain type, and a handle comes from the DID only when it is verified both ways (C3, R6).

    • SiteOwner { atproto_did, deploy_key_public } in lichen-site/src/owner.rs, where OwnerFacts was; unit 6 moves it to ipc/site_owner.rs. Gone:

      • the SiteOwner trait and LinkOwner;
      • AuthProvider from lichen-site (it stays in lichen-server's users.rs);
      • link::owner_facts, has_remote, should_push, start_iroh_side;
      • the handle in the launch, in LaunchIroh and in the lent session.

      The main runtime holds no handle.

    • The resolver moves to lichen-site/src/atproto/identity.rs, with its SSRF guard. Its commit is a move: the AST check matched all 20 moved items, and its one difference is a // comment above client.rs's use lines rewritten inside that commit.

    • New in identity.rs: names_both_ways, verified_handle, and a TCP-only DNS resolver at 127.0.0.1:53, since a confined site with iroh off has no /etc/resolv.conf. The admin thread's fetches go through the site's egress.

    • Remotes:

      • An old pds://<handle>/<domain> remote is pushed only when its handle verifies both ways to the owner's DID. Git is given the DID form per push (-c url.pds://<did>/….insteadOf=…), and the owner's URL is never rewritten.
      • A handle that names another DID becomes a proposal: "not pushed: this handle no longer names your account".
      • A check that fails on the network is not a refusal and not a proposal: "not pushed: the handle could not be checked (network); it is tried again on the next push".
      • New remotes and PDS site records are written in DID form; an import reads either.
    • iroh: collaborator entries stay handles; the site's own entry is recorded by the admin thread.

    • The git-remote-pds pin moves to the fork's 6e0847f2 (notplants.net/git-remote-pds #14: the helper takes a DID-form URL). It changes in Cargo.toml, Cargo.lock, the flake hash and the submodule link.

Commits #

  • 6bbbe5447 ORR 5c: orr-u5c-site-owner-did (#3410)

Count and shas #

count-product-code-lines 1a17a5513d0a..6bbbe5447b29: NET +272 · counted +739 -467 · moved out of the counted set +0 · comment-only deletions flagged 40 · macros flagged 0 · tests-folder code flagged 0

Base 1a17a5513d0af3957f19527a355d242346791c75 (tip of s/777-orr-u5b-no-seams-tests). Head 6bbbe5447b290ff799c86b0c057d5b29ee37e0c6. 48 files changed.

Check #

Every changed file is a file one of the product PRs changed, and each is identical at the head to the same file at the last product branch s/778-orr-u5c-site-owner-did. Files that differ from the subunit's top branch s/779-orr-u5c-site-owner-did-tests: crates/lichen-site/src/atproto/tests/identity.rs.

Commits 0