Service to watch for creation of accounts on a PDS, and automatically add them as collaborators to a Tangled repository.

feat: land the sidecar implementation and packaging on main #4

targeting main from orbit-nodachi/land
Merged opened by and assigned to orbit-nodachi.test.pds.did.bot
targeting main from orbit-nodachi/land

PRs #2 and #3 were merged into their stacked target branches, not into main. So main holds only the design, and the implementation and packaging sit on orbit-nodachi/implement. This brings that branch's 22 commits, unchanged and already reviewed in #2 and #3, onto main.

One new commit is on top. scripts/deploy.sh now adds the deploying machine's public IPv4 to the instance's port 22 for the length of a deploy, and restores the firewall's exact rules when it exits. So no address has to go into the didbot stack.

🤖 Generated with Claude Code

Commits 23

feat(deploy): open ssh to the deploying machine for the deploy only
feat(deploy)!: read the new health response and drop alert config
docs: add a diagram of how the sidecar fits together
fix(deploy): ignore the operator's ssh config and rustup-less cargo
feat(deploy): package the sidecar and add a Lightsail deploy script
feat: keep the owner's consent time in the session file
test: cover an owner with only legacy repo records
fix: order grants and describe in-memory state
test: keep an unclaimed collaborator
fix: run a true-up when jetstream reconnects
feat!: keep sessions in files and state in memory
docs: require an ssh key for eligibility
feat: grant only agents that hold a Tangled SSH key
docs: describe write evidence, the age window and optional tailscale
feat: require a write, bound true-ups by age, and allow no tailnet
docs: describe repo events and tombstone-only revocation
test: cover grants, events, tombstones, pacing and dry-run
feat: serve the public and tailnet listeners, and add the cli
feat: reconcile grants with one paced queue per owner
feat: follow didbot agents, the firehose and jetstream repos
feat: run the confidential oauth client and refresh each owner
feat: validate config and keep encrypted state in sqlite
chore: add the Rust project and atgc's vendored jacquard-oauth