gitea.authenticate(name, password) was the door on the old instance. Teahub prod signs people in with GitHub (nostr next) and has no local passwords, so Persimmons cannot run against https://teahub.xyz until sign-in is an OAuth flow against Gitea — the same shape the Green Tea MCP uses (register an OAuth2 app on Gitea, redirect to /login/oauth/authorize, exchange, then act with the user's token; teahubxyz/teahubmcp/ is the reference). Vault/juice calls already take a per-user token, so only the front door changes.
Then: a Fly app (persimmons-app, volume at /data for sessions + human vault db), PERSIMMONS_GITEA_ORIGIN=https://teahub.xyz, and persimmons.app's holding page in persimmons/site links to it (or the app takes the apex and the site moves to www).
DONE: sign in on persimmons.app with a Teahub (GitHub) login, create a vault, see it as a repo on teahub.xyz.
`gitea.authenticate(name, password)` was the door on the old instance. Teahub prod signs people in with GitHub (nostr next) and has no local passwords, so Persimmons cannot run against `https://teahub.xyz` until sign-in is an OAuth flow against Gitea — the same shape the Green Tea MCP uses (register an OAuth2 app on Gitea, redirect to `/login/oauth/authorize`, exchange, then act with the user's token; `teahubxyz/teahub` `mcp/` is the reference). Vault/juice calls already take a per-user token, so only the front door changes.
Then: a Fly app (`persimmons-app`, volume at `/data` for sessions + human vault db), `PERSIMMONS_GITEA_ORIGIN=https://teahub.xyz`, and persimmons.app's holding page in `persimmons/site` links to it (or the app takes the apex and the site moves to `www`).
DONE: sign in on persimmons.app with a Teahub (GitHub) login, create a vault, see it as a repo on teahub.xyz.
Layout update (2026-10-14): main is now the canonical matcha/persims@97f4a73 merged in with its history (749dac3). The website is at the root, with extension/, backend/ and docs/ beside it. The port had taken an older backend-only copy. persimmons.app is served from this repo's root by Teahub pages (pages/page.conf says source=.). That's the real site; its vault reads "Service unavailable" because /api/* isn't running anywhere.
When this card is picked up:
The app has to answer /api/* on the persimmons.app origin, because the session cookie is __Host- and the handlers check Origin exactly. The simplest shape is for persimmons-app to take the apex and serve the root files too, since backend/server.py already serves /, /signin and /assets.
backend/gitea.py uses an admin-scoped PERSIMMONS_GITEA_TOKEN for more than sign-up. It creates vault repos under users (/admin/users/{u}/repos) and reads and writes their Actions variables and secrets (juice). Whether a product backend may hold that on prod is an operator decision. The alternative is to do those calls with the signed-in user's OAuth token.
Old data on hb-5: the human vault has 0 items and 1 capability (matcha). Nothing needs migrating.
Layout update (2026-10-14): `main` is now the canonical `matcha/persims@97f4a73` merged in with its history (749dac3). The website is at the root, with `extension/`, `backend/` and `docs/` beside it. The port had taken an older backend-only copy. persimmons.app is served from this repo's root by Teahub pages (`pages/page.conf` says `source=.`). That's the real site; its vault reads "Service unavailable" because `/api/*` isn't running anywhere.
When this card is picked up:
- The app has to answer `/api/*` on the persimmons.app origin, because the session cookie is `__Host-` and the handlers check `Origin` exactly. The simplest shape is for `persimmons-app` to take the apex and serve the root files too, since `backend/server.py` already serves `/`, `/signin` and `/assets`.
- `backend/gitea.py` uses an admin-scoped `PERSIMMONS_GITEA_TOKEN` for more than sign-up. It creates vault repos under users (`/admin/users/{u}/repos`) and reads and writes their Actions variables and secrets (juice). Whether a product backend may hold that on prod is an operator decision. The alternative is to do those calls with the signed-in user's OAuth token.
- Old data on hb-5: the human vault has 0 items and 1 capability (matcha). Nothing needs migrating.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
gitea.authenticate(name, password)was the door on the old instance. Teahub prod signs people in with GitHub (nostr next) and has no local passwords, so Persimmons cannot run againsthttps://teahub.xyzuntil sign-in is an OAuth flow against Gitea — the same shape the Green Tea MCP uses (register an OAuth2 app on Gitea, redirect to/login/oauth/authorize, exchange, then act with the user's token;teahubxyz/teahubmcp/is the reference). Vault/juice calls already take a per-user token, so only the front door changes.Then: a Fly app (
persimmons-app, volume at/datafor sessions + human vault db),PERSIMMONS_GITEA_ORIGIN=https://teahub.xyz, and persimmons.app's holding page inpersimmons/sitelinks to it (or the app takes the apex and the site moves towww).DONE: sign in on persimmons.app with a Teahub (GitHub) login, create a vault, see it as a repo on teahub.xyz.
Layout update (2026-10-14):
mainis now the canonicalmatcha/persims@97f4a73merged in with its history (749dac3). The website is at the root, withextension/,backend/anddocs/beside it. The port had taken an older backend-only copy. persimmons.app is served from this repo's root by Teahub pages (pages/page.confsayssource=.). That's the real site; its vault reads "Service unavailable" because/api/*isn't running anywhere.When this card is picked up:
/api/*on the persimmons.app origin, because the session cookie is__Host-and the handlers checkOriginexactly. The simplest shape is forpersimmons-appto take the apex and serve the root files too, sincebackend/server.pyalready serves/,/signinand/assets.backend/gitea.pyuses an admin-scopedPERSIMMONS_GITEA_TOKENfor more than sign-up. It creates vault repos under users (/admin/users/{u}/repos) and reads and writes their Actions variables and secrets (juice). Whether a product backend may hold that on prod is an operator decision. The alternative is to do those calls with the signed-in user's OAuth token.