Pre-launch — Gluecron is in final validation. Public signups and git hosting for non-owner users open after launch review.
Commite64c368

docs(audit): 2026-07-09 verified audit + session work log

docs(audit): 2026-07-09 verified audit + session work log

Consolidates code+live-verified status (MDs were stale): self-sufficiency
cutover, 23 pre-existing test failures triaged, 5 07-07 security findings
re-verified (2 fixed this session), MCP/onboarding/OAuth facts, design root
cause, and the next-decade strategic read.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
ccanty labs committed on July 8, 2026Parent: 889e0c5
1 file changed+1190e64c3688bab97b921f596bb125720f6587d9def4
1 changed file+119−0
AddedAUDIT-2026-07-09.md+119−0View fileUnifiedSplit
1# Gluecron Audit & Work Log — 2026-07-09
2
3Verified against **code and the live site**, not the older markdown docs
4(several of which were stale — noted inline). Supersedes the 2026-07-07 audit
5where they disagree.
6
7## TL;DR
8
9- Last week's deploy **did** ship: gluecron.com runs current `main` (light
10 landing, login with password form + lockout throttle, the 07-07 security
11 fixes). The "still looks like the old site" feeling is the **logged-in app
12 shell**, not the landing — and it was mostly a **stale `theme=dark` cookie**
13 plus indigo buttons / dark-only code highlighting. Fixed (see Design).
14- Biggest strategic gap remains: **CI does not run on push.**
15- New priority this session: **cut the GitHub mirror, go fully self-sufficient.**
16 Architecture was ready; the durability gap (no offsite repo backup) is now
17 closed in code and sequenced in a runbook.
18
19## What shipped this session (local commits on `main`, not yet deployed)
20
21Push to `main`/deploy is pending owner authorization + a `GLUECRON_PAT`
22(the auto-classifier blocked the push; deploy needs the canonical remote).
23
24| Area | Commits | Summary |
25|---|---|---|
26| Self-sufficiency | offsite backup, LF attr, bootstrap, docs, runbook | See Track C below |
27| Security | api-v2 IDOR/leak, GitHub OAuth takeover | 2 of 3 open HIGHs fixed |
28| Design | QI light foundation | tokens + ink buttons + light code highlighting + theme default |
29| Docs | MCP `.mcp.json` fix | docs.tsx + connect.tsx corrected |
30
31## Track C — Self-sufficiency (GitHub mirror removal)
32
33Findings: **no automatic self-mirror to GitHub exists** (safe to cut); the
34`post-receive.ts``self-deploy.sh` pipeline (health-check + auto-rollback) is
35fully built and GitHub-independent in steady state. Two gaps handled:
36
37- **Durability (the real risk):** bare git repos under `GIT_REPOS_PATH` had
38 **no off-box copy** — GitHub was the de-facto backup. Added
39 `scripts/backup-offsite.sh` (tar repos + `pg_dump` Neon → rclone, fail-loud,
40 retention, dead-man's-switch) and `scripts/restore.sh` (DR restore, never
41 clobbers prod by default). `.gitattributes` forces LF so the scripts run on Linux.
42- **Bootstrap tie:** fresh-host bootstrap seeded from GitHub. `DEFAULT_SOURCE`
43 is now empty (`self-bootstrap.ts`, `self-host-bootstrap.ts`, `index.ts`);
44 a fresh host re-seeds from a restored backup, not GitHub.
45- **Docs/marketing:** `CLAUDE.md` + `SELF_HOST.md` now declare Gluecron
46 self-canonical; corrected the false "two-way GitHub mirror" product claim.
47- **Runbook:** `docs/CUTOVER_RUNBOOK.md` — owner-executed, backup-first, then
48 freeze GitHub → 7 green days → delete in 30. **Decision:** offsite rclone
49 backup, freeze-then-delete GitHub, owner runs the VPS steps.
50
51The one fact I can't verify off-box (in the runbook): the VPS `/opt/gluecron`
52working-tree `origin` must point at the **local bare repo**, not GitHub.
53
54## Track A — Verification results
55
56**Test suite:** 2910 pass / 122 skip / **23 fail** (pre-existing). Triage:
579 stale skills-bundle assertions, 3 "2030 reboot" landing-hero (DB-mock
58`innerJoin` unsupported), 1 stale login-shell assertion (signin-v2 redesign),
59several playground/env tests needing `DATABASE_URL`, and **1 real minor bug**:
60`GET /:owner/:repo/wiki` on a missing repo returns 200 instead of 404
61(`wikis.test.ts`). None are regressions; none block this work.
62
63**Security re-verification** (the 5 still-open 07-07 HIGHs):
64
65| # | Finding | Verdict | Action |
66|---|---|---|---|
67| 1 | git-grep arg injection | **FIXED** (array argv) | none |
68| 2 | X-Forwarded-For spoofing (`rate-limit.ts:89`) | **OPEN** | follow-up (infra-dependent trusted-proxy config) |
69| 3 | GitHub OAuth unverified-email takeover | **FIXED this session** | `sso.ts` + `github-oauth.tsx` verified-email gate |
70| 4 | SSRF DNS-rebinding | **FIXED** (`assertPublicUrl` in webhook+mirror) | none |
71| 5 | api-v2 workflow-dispatch IDOR | **FIXED this session** | write-access gate; also closed an unauth private-repo runs-list leak |
72
73**Broader follow-up:** the api-v2 write surface (issues/PR/label/topic/webhook
74POSTs under `requireScope("repo")`) needs a per-endpoint authorization audit —
75access level varies, so no blanket rule.
76
77**MCP:** 60 real tools (15 `mcp-tools.ts` + 45 `mcp-tools-expanded.ts`),
78`.mcp.json` correct. Fixed `/docs/mcp-server` + `/connect` teaching the wrong
79config file. Live 60-tool matrix needs a running instance + PAT (deferred).
80
81**Onboarding:** all landing "Migrate from GitHub" CTAs point to `/import`
82(`import.tsx`) — that's the blessed flow; the other 4 route files are
83secondary/overlapping. Live import test needs creds (deferred to runbook).
84
85**OAuth login (owner-reported broken):** not a bug — Google/GitHub OAuth was
86never configured (`getGoogleOauthConfig` reads an empty `sso_config`). Fix:
87owner sets client id/secret at `/admin/google-oauth` + `/admin/github-oauth`;
88and the login page should hide unconfigured providers instead of erroring
89(small follow-up). GitHub login is now safe to enable after the #3 fix.
90
91## Track B — Design (Quiet Intelligence)
92
93Root cause corrected: the app is **already light-by-default at runtime**; the
94"old dark site" was a stale `theme=dark` cookie + a `readTheme()` dark default
95(fixed). Shipped B0–B2: QI light tokens (page `#fcfcfd`, ink `#16181d`, ink
96primary buttons, green `#1e7f5c`, amber `#b45309`), a light syntax-highlighting
97palette (code blocks were dark-only on light pages), theme-color meta — all
98scoped to `:root[data-theme='light']` so the locked dark-theme tests stay green.
99
100Remaining (next session): B3 shell chrome + shared `.qi-*` utilities; B4
101high-traffic view conversions (dashboard → RepoHeader/RepoNav → repo page → PR
102→ issues → auth); B5 long-tail hex sweep (717 `#5b6ee8` + 24 `#58a6ff`) + emails
103+ pwa manifest; B6 a hex-count ratchet test. Then a Playwright screenshot sweep.
104
105## Strategic answer — "the platform for the next decade?"
106
107The AI-native/MCP layer is genuinely differentiated (60 MCP tools, agent
108sessions, ship-spec — a shape GitHub doesn't have). Four table-stakes gaps keep
109it at "impressive demo" rather than "platform you'd bet a company on":
110
1111. **CI doesn't run on push** — every GitHub refugee notices day one.
1122. **CI runner has no real sandbox** (env-allowlist only; gVisor/Firecracker/
113 nsjail still TODO).
1143. **"Verified" commit badge does no real crypto verification.**
1154. **Org/team permissions aren't enforced** for repo access.
116
117Next-decade bet: double down on the AI layer while closing those four, and —
118now — nail self-sufficiency + durable backups so it can be trusted to run on
119its own. The self-sufficiency work this session is the first plank of that.
0120