From 137d2cdd534d868db6278d8a2363edee68a905bf Mon Sep 17 00:00:00 2001 From: Nirav Patel Date: Sat, 22 Aug 2026 17:16:16 -0400 Subject: [PATCH] docs: invited-user quickstart + re-probe token mechanics on Gitea 1.27.2 The client is downloadable from central now, but no document took an invited user from clone to working state. Quickstart covers link -> list -> get/add -> watch, plus the two things people get wrong: an expired device code creates nothing (just re-run link), and merging is deliberately a forge action because watch refuses to merge or force. Also re-probed the token-minting mechanics the README pinned to 1.27.1, since both forges now run 1.27.2. All three results still hold: token-auth + Sudo header -> 401 token-auth + ?sudo= -> 401 admin basic auth + Sudo -> 201 Probe minted a token on the granthi-sync-e2e machine user and deleted it (204 under basic auth). /v1/link's mint path is unaffected by the bump. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01LTARYHX7GPepi3CH3tp5pg --- README.md | 46 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index b92b09e..b080ced 100644 --- a/README.md +++ b/README.md @@ -26,6 +26,47 @@ git CLI only — same portability heritage as the estate's `gitea_sync.py` mesh. └───────────────────────────────┘ ``` +## Quickstart (invited user) + +You need a shre-id account — an operator creates it; there is no open signup +(see "Invite-only story"). You also need to be on the tailnet: the +provisioning service is not publicly exposed yet. + +```sh +git clone https://granthi.shre.ai/nirpa/granthi-sync.git +cd granthi-sync + +# 1. Link this device. Prints a URL + code; approve it in a browser within +# 5 minutes. Creates your forge account and stores a scoped token in +# ~/.granthi-sync/config.json (0600). You never see a forge password. +./bin/granthi-sync link + +# 2. See what is already yours on the forge. +./bin/granthi-sync list + +# 3. Either pull an existing repo down... +./bin/granthi-sync get # or /, --into DIR + +# 3b. ...or push a local folder up. It becomes a private repo. +./bin/granthi-sync add ~/work/notes + +# 4. Keep everything synced. Autocommits, ff-pulls, pushes; skips anything +# that has diverged rather than merging or forcing. +./bin/granthi-sync watch # --once for a single pass +./bin/granthi-sync status # what is linked, last sync, divergence +``` + +Run `watch` as a background daemon on macOS with +`client/launchd/ai.granthi.sync.plist` (edit the script path, then +`launchctl bootstrap gui/$UID `). + +**If the device code expires** (5 minutes, unapproved), nothing is created — +no account, no token, no partial state. Just run `link` again. + +**Merging is a forge action, not a client one.** `watch` deliberately refuses +to merge; when a folder shows `DIVERGED` in `status`, resolve it in git or on +the forge web UI. The client will never force or auto-merge your work. + ## Components ### `server/granthi_link.py` — provisioning service (granthi VPS) @@ -84,7 +125,10 @@ this change must be seeded into `state.json` once, as machine user `granthi-sync-e2e` (seeded); the forge's human admin `nirpa` is never provisioned through `/v1/link`, so nothing else needed seeding. -Empirically verified mechanics on Gitea **1.27.1** (beta forge): +Empirically verified mechanics on Gitea **1.27.1**, re-probed and still +holding on **1.27.2** (beta forge, 2026-08-22 — all three results below +matched; the probe minted a token on the `granthi-sync-e2e` machine user and +deleted it again, `DELETE …/tokens/{id}` returning 204 under basic auth): * Token minting: `POST /api/v1/users/{login}/tokens` returns **401 for token-authenticated sudo** (both `Sudo:` header and `?sudo=`); it only works