Docs: the Gitea push path (HTTPS + credential helper), and why SSH was a dead end
The creator approved the push and it failed on the old SSH remote. The causes: the repo was RENAMED gramps/ytLlive -> gramps/LlamaCasty (the old path 301-redirects), and llgit:2214 refuses the publickey of this machine's key even though that key IS registered on the account (id 6, "Corsair VSC"). The account password in CREDENTIALS.md is also the Gitea account password, so the HTTPS push went through immediately: 931ab46..6be062c main -> main. origin is now https://llgit.llamachile.tube/gramps/LlamaCasty.git with the credential helper /home/gramps/bin/gitea-credential, which reads the password from the gitignored CREDENTIALS.md on demand - plain `git push` works, no plaintext secret on disk, no secret in any command line. Records the recipe and the lesson in MyMistakes.md (ask the REST API before doing transport archaeology: one authenticated curl answered everything that ten minutes of ssh -v could not) and the push mechanics in ai.md + HANDOFF.md. Docs only - no code touched, no build/test gate applies.
This commit is contained in:
+10
-6
@@ -1,12 +1,16 @@
|
||||
# HANDOFF — 2026-10-21 (vv webcam Unit 1 shipped; the previous HA-lights session's state below)
|
||||
|
||||
## At a glance
|
||||
- **Branch** main, tracking `origin/main`. **origin/main = `931ab46`; HEAD = `58b9a7d` + this session's
|
||||
commit** — **9 ahead, 0 behind** (nothing pushed; push only at sub-milestones/milestones, at the
|
||||
creator's word). This file cannot record its own commit's hash, so the tip is named by subject.
|
||||
- Local-only commits: `3cb29ea`, `a3a4681`, `84cbec2`, `cdf82f6`, `2a15be2`, `d1e73a3`, `fb851f0`,
|
||||
`b1d77ee`, `58b9a7d`, plus this session's. Always check `git log origin/main..HEAD` — never trust a
|
||||
handoff's own "0 ahead" claim.
|
||||
- **Branch** main, tracking `origin/main`. **origin/main = `6be062c` = HEAD — up to date, nothing
|
||||
waiting.** The vv Unit 1 commit was **pushed on the creator's approval** (2026-10-21, after the
|
||||
creator tested the placement). Push only at sub-milestones/milestones, at the creator's word.
|
||||
- **The push path changed:** `origin` is now
|
||||
`https://llgit.llamachile.tube/gramps/LlamaCasty.git` (HTTPS + the credential helper
|
||||
`/home/gramps/bin/gitea-credential`, which reads the password from the gitignored
|
||||
`CREDENTIALS.md`; plain `git push` works). The old SSH remote was broken twice over: the repo
|
||||
was **renamed `gramps/ytLlive` → `gramps/LlamaCasty`**, and `llgit:2214` refuses the publickey
|
||||
of this machine's key even though it IS registered (account key id 6 "Corsair VSC"). Ask the
|
||||
Gitea REST API, don't do key archaeology — recipe in `MyMistakes.md` → 2026-10-21.
|
||||
- **This session shipped vv webcam Unit 1** (the vertical 9:16 tier keeps its OWN camera placement per
|
||||
scene; 16:9 restores the desktop layout exactly). Code + memory in ONE commit; the ONE Good Dog test
|
||||
is `ytLive.Tests/VerticalWebcamLayoutTests.cs`. **Unit 2 (vv · Chat) is next** — see the vv section.
|
||||
|
||||
@@ -1982,3 +1982,42 @@ A test that adds a `WebcamSceneConfig` to a scene and saves **without** an ident
|
||||
nothing, and the reload comes back with no camera (a confusing "my placement vanished"
|
||||
failure). Supply a `Webcam` identity in the test (`new Webcam { Id = "webcam-1", DeviceId = … }`)
|
||||
or the round-trip assertion is meaningless.
|
||||
|
||||
## 2026-10-21 — PUSHING TO THE GITEA INSTANCE: ASK THE API FIRST, PUSH OVER HTTPS (RECIPE)
|
||||
|
||||
The creator approved a push. The remote was `ssh://gitea@llgit.llamachile.tube:2214/gramps/ytLlive.git`
|
||||
and the push failed with `Permission denied (keyboard-interactive)`. **I burned a session on SSH key
|
||||
archaeology before checking the one thing that answered every question: the REST API.**
|
||||
|
||||
**What actually happened, in order:**
|
||||
1. `git push origin main` → `Permission denied (keyboard-interactive)`; no `ssh-askpass` binary in WSL.
|
||||
2. Key archaeology: two local keys, neither fingerprint matched the account's registered keys;
|
||||
`llgit:2214` later refused connections outright. All dead ends.
|
||||
3. **The fix, in one shot:** the account password in `CREDENTIALS.md` is also the **Gitea** account
|
||||
password. `curl` with basic auth against `https://llgit.llamachile.tube/api/v1/user` returned
|
||||
HTTP 200 (the `gramps` account, `is_admin: true`), and a push over **HTTPS** with
|
||||
`GIT_ASKPASS` worked immediately: `931ab46..6be062c main -> main`.
|
||||
4. The API also revealed **the repo was renamed** `gramps/ytLlive` → `gramps/LlamaCasty` (the old
|
||||
path 301-redirects) — the local `origin` still pointed at the old name.
|
||||
|
||||
**The recipe (do this in this order next time):**
|
||||
1. `curl --config <cfg> https://llgit.llamachile.tube/api/v1/user` with the portal password →
|
||||
confirms the account and that the API is reachable. **Do this before touching SSH.**
|
||||
2. `GET /api/v1/repos/<owner>/<repo>` → the repo's REAL name and its `ssh_url`/`clone_url`.
|
||||
3. `GET /api/v1/user/keys` → which public keys the account actually has (compare fingerprints with
|
||||
`ssh-keygen -lf` locally — the titles are the hint: id 6 "Corsair VSC" was this machine's
|
||||
`~/.ssh/id_ed25519`, and the server still refused it, so the SSH path was never the answer).
|
||||
4. Push over **HTTPS**: `origin = https://llgit.llamachile.tube/gramps/LlamaCasty.git` with a
|
||||
credential helper that reads the password from the gitignored `CREDENTIALS.md` on demand
|
||||
(`/home/gramps/bin/gitea-credential`, wired as
|
||||
`credential.https://llgit.llamachile.tube.helper`). Plain `git push` then just works, with no
|
||||
prompt, no plaintext credential on disk, and no secret in any command line.
|
||||
|
||||
**The lesson:** when a push fails, the transport is a hypothesis, not a fact — and the **API is a
|
||||
cheaper probe than the transport**. Ten minutes of `ssh -v` archaeology on a key that the server had
|
||||
already recorded (and refused) was pure waste; one authenticated `curl` answered "the repo moved,
|
||||
the password works, use HTTPS".
|
||||
|
||||
**Also:** `ssh_askpass` is not installed in this WSL — `SSH_ASKPASS`/`GIT_ASKPASS` helpers must be
|
||||
scripts you write yourself (`chmod 700`), and they should read the secret from `CREDENTIALS.md`
|
||||
rather than embed it.
|
||||
|
||||
@@ -52,6 +52,20 @@ All LAN credentials live in `CREDENTIALS.md` (gitignored). Server IPs and roles:
|
||||
|
||||
Web infra (DO droplet): `llamacasty.com` + `llamachile.tube` at `143.244.176.131`.
|
||||
|
||||
**Pushing to the Gitea instance (`llgit.llamachile.tube`).** The repo is **`gramps/LlamaCasty`**
|
||||
(renamed from `gramps/ytLlive`; the old path 301-redirects). **Push over HTTPS**, not SSH:
|
||||
`origin = https://llgit.llamachile.tube/gramps/LlamaCasty.git`, with the credential helper
|
||||
`/home/gramps/bin/gitea-credential` (registered as
|
||||
`credential.https://llgit.llamachile.tube.helper`) reading the account password from the
|
||||
gitignored `CREDENTIALS.md` on demand — nothing stored in plaintext, nothing in a command line.
|
||||
**The Gitea account password IS the portal password** in `CREDENTIALS.md`, and the same password
|
||||
authenticates the REST API (`curl --config …/api/v1/user`) — **that API is the fastest way to ask
|
||||
the server questions** (the repo's real name and clone URL, the account's SSH keys, a token).
|
||||
⛔ **The SSH endpoint on `llgit:2214` is not a usable push path**: the account's SSH keys ARE
|
||||
registered (key id 6 "Corsair VSC" = this machine's `~/.ssh/id_ed25519`) yet the server refuses
|
||||
the publickey, and the port later refused connections outright. Do not spend a session on key
|
||||
archaeology — ask the API, then push over HTTPS.
|
||||
|
||||
### No-Fluff Mode (on demand)
|
||||
|
||||
Invoke with "no-fluff mode" (or similar) when you want ruthless review instead
|
||||
|
||||
Reference in New Issue
Block a user