docs(plan-c): re-scope to universal isomorphic-git receive-pack push
Mini-spike (isomorphic-git) proved the universal write path end-to-end with no
live creds: Tier 1 commit({onSign}) embeds our SSHSIG -> git verify-commit +
verify-org-commit both PASS; Tier 2 push over git-receive-pack to a bare repo
running the real org pre-receive hook ACCEPTS a member-signed commit and
REJECTS a non-member one.
- Spike doc: + Addendum recording the isomorphic-git Tier 1/2 results + Task 2
implications (in-memory fs only, http/web, onAuth Basic, no new WASM export).
- Plan doc: architecture re-scoped (Gitea has no write Git Data API at any
version -> single universal receive-pack path for both hosts); Task 1 marked
DONE/GO; Task 2 rewritten as the universal commitSigned; Dev-A OrgManifest
contract + Tasks 3-5 HELD-on-A/B recorded.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LKBbrAjmpVXMEK15pNi3Ha
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
# Spike: Org signed-commit push via host APIs — GO/NO-GO
|
||||
|
||||
- **Date run:** 2026-06-25 (Dev-C, v0.9.0 Plan C / org write)
|
||||
- **Status:** **COMPLETE — GO** (signature mechanism proven; transport is host-specific, see below)
|
||||
- **Status:** **COMPLETE — GO** (signature mechanism proven; universal isomorphic-git packfile-push transport proven 2026-06-25 — see **Addendum**)
|
||||
- **Plan:** `docs/superpowers/plans/2026-06-20-v0.9.0-org-c-write.md` Task 1
|
||||
- **Spec:** `docs/superpowers/specs/2026-06-20-extension-org-gui-design.md` § "The org-write signing gate"
|
||||
|
||||
@@ -136,3 +136,20 @@ curl -s https://git.adlee.work/swagger.v1.json | jq '.paths|keys[]|select(test("
|
||||
curl -s -o /dev/null -w '%{http_code}' \
|
||||
'https://git.adlee.work/alee/relicario.git/info/refs?service=git-receive-pack' # 401 (exists)
|
||||
```
|
||||
|
||||
## Addendum (2026-06-25): universal isomorphic-git packfile push — PROVEN end-to-end
|
||||
|
||||
**Decision (user):** build org write NOW in v0.9.0 as a **single universal write path for both Gitea and GitHub** — a native `git-receive-pack` smart-HTTP packfile push driven by **isomorphic-git** in the service worker. The GitHub Git Data API + `signature` approach is retired (one path, not two). Rationale: Gitea has no write Git Data API at any version (§ above), and receive-pack is host-agnostic, so it also covers GitHub.
|
||||
|
||||
A follow-on mini-spike validated the isomorphic-git integration, again with **no live-host credentials**:
|
||||
|
||||
- **Tier 1 — signature survives isomorphic-git serialization.** `git.commit({ onSign })` hands the callback the exact serialized commit payload; the callback returns our SSHSIG armor (raw ed25519 over `SSHSIG‖git‖sha512‖H(payload)`, the framing proven above), and isomorphic-git embeds it as `gpgsig`. Result: real `git verify-commit` **PASS** and `relicario-server verify-org-commit` **PASS**. Because `onSign` signs isomorphic-git's *own* payload, the byte-canonicalization hazard (timestamps, header folding) is eliminated by construction.
|
||||
- **Tier 2 — push through the real hook.** `git.push({ http })` over git smart-HTTP `git-receive-pack` to a local `git-http-backend` bare repo carrying the real `relicario-server generate-org-hook` pre-receive hook: an owner-signed commit was **ACCEPTED** (`refs/heads/main ok`), a commit signed by a non-member was **REJECTED** ("pre-receive hook declined"). The hook gates the push exactly as in production.
|
||||
|
||||
**Implications for Task 2 (now "universal `commitSigned`"):**
|
||||
- One `commitSigned` for both hosts: in-memory fs + isomorphic-git shallow `clone` → stage files → `commit({ onSign: sshsig })` → `push` over receive-pack. Host difference is only auth + URL.
|
||||
- SW uses `isomorphic-git/http/web`; the extension's `host_permissions` exempt SW `fetch()` from page CORS (no proxy). Auth via `onAuth → { username, password: token }` (Basic) — Gitea PAT-as-password; a GitHub token works as Basic over HTTPS.
|
||||
- SSHSIG framing is SW/TypeScript (`sshsig.ts`), calling the existing WASM `sign_for_git` for the one secret operation. Still **no new WASM export**.
|
||||
- Residual unchanged: one live push to git.adlee.work + github.com with real tokens (transport-only confirmation).
|
||||
|
||||
Mini-spike harness: `iso-spike/spike1.mjs` (commit+verify) and `spike2.mjs` (push through the real hook) in the Dev-C scratchpad.
|
||||
|
||||
Reference in New Issue
Block a user