QALS Wiki · the qalarc network⌂ qalarc.com/projects/qals
generated 2026-09-16 · qalcode autonomous research

The character-rig as a QALS compute provider (1c = 10cr) · 07_compute_marketplace/GOETICA_RUNPOD_INTEGRATION.md

GOETICA ↔ QALS — RunPod / Credits Integration Map

Authored 2026-09-10. Study target: ~/projects/goetica (read-only). Anchor: this corpus (crypto_currency/). Every claim cites path:line. Goetica's own credits doc (docs/architecture/GOETICA_CREDITS.md) already cites this corpus as its "source of truth for the money model" — this map closes the loop and makes it concrete as a build plan.

1. What goetica is

Goetica (goetica.ai, private repo qalarc/goetica) is the character-truth workshop + product site: a character is conceived through long midwife-agent interviews ("sittings"), distilled into structured TRUTH documents (philosophy, perspectives, interaction, voice, biography), synthesized into an audited prompt/response corpus, then raised as a character LoRA on GLM-4.7-Flash and served live (README.md:3-11, pipeline diagram README.md:15-30). The pipeline is: conversations/ → truth/ → corpus/ → LoRA → tulpas/<slug>/ platform record, with hard rules that conversations/corpus never leave the machine via git and every truth line traces to something the founder said (README.md:47-61). As a product it was repositioned (sitting 03) into a product site for the character-creation studio plus a downloadable all-in-one media tool, with Stolas as the flagship demo (PROJECT_PLAN.md:108-115).

Where compute happens — three planes (INFRA_REVIEW.md:44-62): (1) a Cloudflare control plane (Worker + KV + Workers AI; wrangler.jsonc:14-19 binds AI and GOETICA_SESSIONS, route goetica.ai at wrangler.jsonc:20-22); (2) a demo plane on RunPod — serverless endpoints for the weighted Stolas LLM (RTX 4090 @ $1.10/hr), STT (L4 @ $0.69), TTS Kokoro (INFRA_REVIEW.md:64-75); and (3) training, which runs on RunPod A100 pods (~$2–3.30/run) via the battle-tested runpod_train.py v3 automation (METHOD.md:58-59, INFRA_REVIEW.md:31, COMPUTE_LEDGER.md:11-13: 165 min A100 = $3.30). The Stolas LoRA (glm-4.7-flash:stolas-t1) is already trained and serving locally; RunPod serverless serving is designed but not built (INFRA_REVIEW.md:11-15).

2. Current credits system

GOETICA_CREDITS.md is DESIGN only, 2026-09-09 — no billing implemented (GOETICA_CREDITS.md:3-4). Locked founder canon: 1,000 goetica credits = AU$1 (1 credit = 1 milli-qAUD), creators keep 80% of credits their characters earn (:20-22). Unit ladder: display = credits; pre-chain ledger = integer credits in D1; chain phase = doofs (1 credit = 1,000 doofs, assuming the 10⁻⁶ exponent — the doc flags a stale 10⁻⁹ figure in CREDIT_PLATFORM.md §4 as [verify], :56-80); underlying asset B-QALS (:61). Ledger mirrors QALS qal_credit: lazy CreditAccount, Hold with expires_at auto-release, settle-at-actual, refunds as reversal rows, four SQL tables drafted at :96-121. Flow: top-up mints 1:1,000 against the reserve invariant AUD_held ≥ credits_outstanding × AU$0.001 (:125-130); chat settle burns user credits, mints creator +0.8N / platform +0.2N born-backed (:131-141); free tier drips 50 cr/day (proposal, born backed, :198-202). Rate cards: creator-set flat 10–500 credits/message server-band-enforced, or metered base + per-1k-output-tokens (:163-172). The chat billing sequence is fully specified — auth → price → hold (120 s expiry) → proxy → settle/release → message_id idempotency (:174-189). Enforced vs manual: nothing is enforced yet. The deployed worker has only a toy KV credits stub — pseudonymous hashed-session accounts, unauthenticated grant labelled "top-up (pre-payment)", spend with 402 on insufficient (worker.js:123-161) — no holds, no settlement, no real payment. Agents get DIDs + capability credentials with hard daily caps enforced by the ledger, not prompts (:231-258); compliance is Phase-1 closed-loop prepaid — non-transferable, no cash-out, creator payouts are revenue share (:262-290).

3. The RunPod rig

RUNPOD_SETUP.md describes a deployed-and-waiting state: "The Worker proxy is deployed and waiting. When the Stolas weights (or any OpenAI-compatible endpoint) are up," flip two secrets — RUNPOD_CHAT_URL + RUNPOD_API_KEY — and the site chat goes live automatically (:1-12). The worker's /api/chat/completions proxies verbatim to the RunPod OpenAI-compatible endpoint with a Bearer secret and tags the response x-goetica-backend: runpod (worker.js:56-73); /api/ping reports chat: !!env.RUNPOD_CHAT_URL (worker.js:41-42). TTS routes ?engine=kokoro to a RUNPOD_TTS_URL sidecar (port 8880 FastAPI) with edge-melo fallback — a five-voice ladder from local kokoro to captions (RUNPOD_SETUP.md:39-53). Cost guard for stealth phase: STOP pods between sessions, per-request Workers AI pennies, free-tier KV (:28-33); fallback chain site → Worker → RunPod, offline canon banks on 503 (:34-37). Target serving architecture (INFRA_REVIEW.md:64-75): load-balancing serverless endpoints (not queue-based), weights baked into the Docker image to kill 19 GB cold-start downloads, FlashBoot + min_workers=1 during demo hours ≈ $26/mo floor. Pricing (RunPod, 2026-07-27): L4 $0.69, 4090 $1.10, A100 $2.72, RTX Pro 6000 $3.49, H100 $4.79/hr (:144). Training stays pod-based: runpod_train.py v3 already speaks RunPod REST v2 (catalog → order → monitor) with encrypted kit delivery and budget guard (INFRA_REVIEW.md:31); tulpa_studio's FOUNDRY TRAIN step is a "RUNPOD A100 honest stub ~$2/run" (tulpa_studio/README.md:44). Status today: worker deployed; chat secrets unset; serverless workers unbuilt; training battle-tested.

4. COMPUTE_LEDGER.md — usage tracking now

Created 2026-09-09 from a $20 campaign post-mortem. The ledger is a JSONL file — logs/compute_ledger.jsonl, 14 entries itemizing the whole campaign — with one row per compute event: purpose, gpu, cloud, duration_min, cost_usd, outcome, category (productive · bug-loss · environment · saved · future inference/render/eval), artifact, note (COMPUTE_LEDGER.md:3-16). Campaign 1's productive-compute ratio was 10% (target >85%) — the exemplar row is "outcome": "trained-adapter-lost", a $3.30 A100 run destroyed by cleanup-before-verify (:11-14, :28). Four planned concierge-panel views: IN/OUT balance sheet (pulling RunPod billing API /v2 actuals), WHERE-IT-WENT (cost by category/stage — "points directly at what to harden next"), DEMAND SIGNALS (per-character compute, "most expensive soul" leaderboard), TRUST (publicly auditable per-user outcome+artifact trail, "lost-adapter events = 0 since the contract") (:20-43). Critically, the writer is still a TODO: "runpod_train.py/fetch_adapter at pod events (one line each — TODO next session)" (:53); the reader is the concierge panel + RunPod billing API with creds in ~/.config/tulpa (:54-55). The ledger is also framed as the demand-research instrument for "the compute marketplace's pricing" (:45-50) — i.e., goetica already expects a marketplace to sit on this data.

5. THE INTEGRATION MAP

# Goetica concept (evidence) QALS component Proposed mapping / rate
1 Goetica credit = AU$0.001; 1,000 cr = AU$1 (GOETICA_CREDITS.md:20-22,54-80) loopd paper ledger, cents-denominated (qmarket/README.md:3 — all prices *_cents) 1 loopd cent = 10 goetica credits. Keep the milli-unit as goetica's display layer; mirror into loopd as integer cents. Chain phase: 1 credit = 1,000 doofs (10⁻⁶) = 0.001 B-QALS, born backed exactly as :28-30,131-141 already specifies. Do not re-rate to 1 credit = 1c — that would break their locked 1,000:1 canon and the 10–500 cr/message band (:63-65).
2 RunPod A100 training pods, ~$2–3.30/run (METHOD.md:58-59; COMPUTE_LEDGER.md:12) qmarket job, kind="lora-training" (qmarket/test_market_v2.sh:80 shows register --kind render --price 12) Price per unit = GPU-hour in cents: A100 272c, 4090 110c, L4 69c, H100 479c (INFRA_REVIEW.md:144). bench.py target-margin logic sets the floor; the escrowed Hold → attested metrics → settle-at-metered × price → 0% platform fee flow (founder policy 2026-09-12 — the buy-spread is the margin) (qmarket/README.md:3) replaces the ad-hoc RunPod billing pull.
3 Midwife + agent customers with hard caps (GOETICA_CREDITS.md:231-258) loopd agents with daily caps — cap-refusal already proven live on Qalnet (:151-153, :250-253) Agent capability token goetica:chat, spend-cap:N cr/day maps 1:1 to the loopd/qal_credit cap field; a capped hold is refused by the ledger, never prompt-enforced. Training agents get their own spend-cap in cents.
4 truth/ → corpus/ provenance, audit bar "unaudited data never trains" (METHOD.md:74-79) qalpipe anchors (qmarket/README.md:3 — output hash anchored on-chain) Anchor corpus/audit_report.json sha256 and the dataset sha256 before any training job is accepted; the qmarket gateway refuses lora-training jobs whose spec lacks an dataset_anchor. This makes the audit bar machine-checkable instead of honour-system.
5 Character LoRA outputs, "trained-adapter-lost" disaster (COMPUTE_LEDGER.md:13) ComputeReceipt-style anchored artifact qmarket already writes {tx, object_id, sha256} + receipt per job (qmarket/data/jobs.jsonl:1). The LoRA adapter fetched by fetch_adapter.py becomes the job output whose sha256 is anchored at settle — the ledger's TRUST view "artifact + verification trail" (COMPUTE_LEDGER.md:41-43) falls out for free.
6 Users' credit balance (KV stub today, D1 design tomorrow) (worker.js:123-161; GOETICA_CREDITS.md:87-121) loopd account, dual issuance Paid top-ups: direct loopd account issued against the reserve (transferred from the pre-endowed issuer supply) (GOETICA_CREDITS.md:125-130). Free-tier drips + promo grants: qalclaim-issued rewards, born backed per the QALS rewards rule (:136-141,198-202). daily_cap_credits ↔ loopd cap field.
7 The goetica Worker / runpod_train.py automation qmarket remote provider adapter (qmarket/provider.py pattern: gateway POSTs {job_id, kind, spec} to :8850 — provider.py:11,24) Wrap runpod_train.py (REST v2: catalog→order→monitor, INFRA_REVIEW.md:31,82) in provider.py as provider goetica-runpod; register kinds lora-training and inference (the chat proxy worker.js:56-73 is a ready inference provider). Stake sized above max job value (e.g. 1,000c for A100 work).

6. What's needed to make it real (ordered)

  1. Fix the ledger seam first — implement GOETICA_CREDITS.md:304-317 step 1–2 (D1 binding + Ledger {getAccount, placeHold, settle, release, reverse}) but with a second thin impl: LoopdLedger POSTing to loopd. The interface is already specified; estimate: days.
  2. COMPUTE_LEDGER writer → qmarket job records — the "one line each" TODO (COMPUTE_LEDGER.md:53) becomes: emit the qmarket job event and the JSONL row; categories map to qmarket outcomes. Hours.
  3. RunPod provider adapterrunpod_train.py already exposes everything; wrap it in the provider.py POST /execute pattern (register --kind lora-training --price 272), artifact pull from R2 not LAN. Days.
  4. Anchor-before-train gate — qalpipe anchor of audit_report + dataset sha256 in the gateway job validator (§5 row 4). Hours–a day.
  5. Adapter ComputeReceipt — wire fetch_adapter.py output into qmarket settle so the receipt carries the anchored adapter hash (§5 row 5). Days (mostly retrieval-hardening, which campaign 1 says is the real friction, COMPUTE_LEDGER.md:49-50).
  6. Rate cards + wallet UIGOETICA_CREDITS.md:318-324 (price badges, creator dashboard, Resend receipts). Days.
  7. Agent credential issuer — Ed25519 capability tokens + KV revocation (:325-326); loopd caps enforce spend. Days.
  8. Swap-to-Qalnet (:330-337) — later, gated on the VASP phase (:282-288).

Fastest end-to-end win: #2+#3 together — a qmarket-registered RunPod provider that prices A100 training in cents and anchors the adapter it produces. It makes campaign 2 the first metered, escrowed, anchored training run in the ecosystem.

7. Honest gaps / risks