From c5e57f3211d760f9608b05f13fa6fad3de3593e2 Mon Sep 17 00:00:00 2001 From: drjones Date: Thu, 1 Oct 2026 20:14:05 -0700 Subject: [PATCH] HOARD tier: $50/mo unlimited (30-day entitlement), bolder provable claims, idempotent DB migrations --- config.example.json | 18 ++++++++++++++---- draco_core.py | 26 ++++++++++++++++++++------ pages.py | 20 +++++++++++--------- pages2.py | 12 +++++++++--- 4 files changed, 54 insertions(+), 22 deletions(-) diff --git a/config.example.json b/config.example.json index ac808fc..8722d59 100644 --- a/config.example.json +++ b/config.example.json @@ -11,9 +11,19 @@ "free_monthly": 30, "admin_key": "sk-draco-admin-CHANGE_ME", "plans": { - "satchel": {"usd": 3, "credits": 60}, - "crate": {"usd": 10, "credits": 250}, - "hoard": {"usd": 25, "credits": 750} + "satchel": { + "usd": 3, + "credits": 60 + }, + "crate": { + "usd": 10, + "credits": 250 + }, + "hoard": { + "usd": 50, + "credits": 1000000, + "label": "UNLIMITED 30 DAYS" + } }, "btcpay": { "url": "https://btcpay.thetempleofdoom.com", @@ -21,4 +31,4 @@ "api_key": "SET_ME", "webhook_secret": "SET_ME" } -} +} \ No newline at end of file diff --git a/draco_core.py b/draco_core.py index cb51a8a..451d15e 100644 --- a/draco_core.py +++ b/draco_core.py @@ -21,6 +21,7 @@ CREATE TABLE IF NOT EXISTS users ( credits INTEGER DEFAULT 0, free_used INTEGER DEFAULT 0, total_calls INTEGER DEFAULT 0, + unlimited_until VARCHAR(32), is_admin INTEGER DEFAULT 0, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, last_used_at TIMESTAMP @@ -59,10 +60,16 @@ def db(): def init_db(): c = db() c.executescript(SCHEMA) - try: # in-place migration for DBs created before total_calls existed - c.execute("SELECT total_calls FROM users LIMIT 1") - except sqlite3.OperationalError: - c.execute("ALTER TABLE users ADD COLUMN total_calls INTEGER DEFAULT 0") + for col, decl in (("total_calls", "INTEGER DEFAULT 0"), # idempotent migrations: + ("unlimited_until", "VARCHAR(32)")): # gunicorn workers race at boot + try: + c.execute(f"SELECT {col} FROM users LIMIT 1") + except sqlite3.OperationalError: + try: + c.execute(f"ALTER TABLE users ADD COLUMN {col} {decl}") + except sqlite3.OperationalError as e: # another worker won the race + if "duplicate column" not in str(e).lower(): + raise c.commit() c.execute("INSERT OR IGNORE INTO users (email, api_key, credits, is_admin) VALUES (?,?,?,1)", ("admin@draco.local", CFG["admin_key"], 999999)) @@ -417,7 +424,9 @@ def consume(user, kind, detail="", ip=""): cur = c.execute("SELECT credits, free_used FROM users WHERE id=?", (user["id"],)).fetchone() row = c.execute("SELECT * FROM users WHERE id=?", (user["id"],)).fetchone() month = time.strftime("%Y-%m") - if row["free_used"] < CFG["free_monthly"]: + if row["unlimited_until"] and row["unlimited_until"] > time.strftime("%Y-%m-%d"): + pass # HOARD subscriber: unlimited, no decrement + elif row["free_used"] < CFG["free_monthly"]: c.execute("UPDATE users SET free_used=free_used+1, last_used_at=CURRENT_TIMESTAMP WHERE id=?", (user["id"],)) elif row["credits"] > 0: c.execute("UPDATE users SET credits=credits-1, last_used_at=CURRENT_TIMESTAMP WHERE id=?", (user["id"],)) @@ -580,7 +589,12 @@ def handle_webhook(body, header_sig_ok): return True if etype == "InvoiceSettled": c.execute("UPDATE payments SET status='settled', settled_at=CURRENT_TIMESTAMP WHERE invoice_id=?", (invoice_id,)) - c.execute("UPDATE users SET credits=credits+? WHERE id=?", (p["credits"], p["user_id"])) + if p["amount_usd"] >= 50: # HOARD = $50/mo unlimited: 30 days from settle + import datetime + until = (datetime.date.today() + datetime.timedelta(days=30)).isoformat() + c.execute("UPDATE users SET unlimited_until=? WHERE id=?", (until, p["user_id"])) + else: + c.execute("UPDATE users SET credits=credits+? WHERE id=?", (p["credits"], p["user_id"])) else: c.execute("UPDATE payments SET status='processing' WHERE invoice_id=?", (invoice_id,)) c.commit() diff --git a/pages.py b/pages.py index a7d082e..54b636e 100644 --- a/pages.py +++ b/pages.py @@ -75,16 +75,18 @@ NAV = """ PAGE_HOME = """
- ◈ Grounded in real books — not vibes -

The smartest coding AI you can prove.

-

Most AI assistants guess. DRACO retrieves from __STATS__ — - languages, kernels, networks, exploitation, red-team tradecraft — and shows you the exact - books behind every answer. Check the citations. That's the proof.

+ ◈ THE LARGEST PROVABLE BOOK-GROUNDED AI ON THE INTERNET +

Other AIs guess.
DRACO knows — and proves it.

+

Generic chatbots hallucinate from compressed training data. DRACO retrieves + live from __STATS__ of actual expert books — languages, kernels, networks, + exploitation, red-team tradecraft — and stamps the exact source on every claim. + No cutoff. No hallucination. Receipts attached.

{{ books }}real books indexed
{{ chunks }}retrievable passages
{{ mb }}Mchars of expert text
-
<2sretrieval + answer start
+
<2sretrieval + answer start
+
100%cited or flagged — never silent
@@ -111,10 +113,10 @@ PAGE_HOME = """ -

◈ Why "book-forged" is different

+

◈ Why DRACO embarrasses generic chatbots

-
Every claim has a receiptanswers cite [n] — click through to the source book in /library
-
No 2021 knowledge cutofffundamentals from the canon: K&R, Tanenbaum, the shellcoders' handbook
+
Every claim has a receiptanswers cite [n] with the source book attached — verify in one click, unlike any chatbot's 'trust me'
+
Knowledge cutoff: NEVERthe canon is resident — K&R, Tanenbaum, the shellcoders' handbook — not compressed away in training
Agentic by designMCP server + REST API — summon DRACO from Claude, GPT, or any agent
Self-hosted, no telemetryruns on bare metal; questions never leave the house
diff --git a/pages2.py b/pages2.py index db6f583..e57c34e 100644 --- a/pages2.py +++ b/pages2.py @@ -53,11 +53,17 @@ self-hosted BTCPay — no card processor ever sees you or us.

FREE{{ free_monthly }} API credits / month + {{ free_day }} web questions / day
1 credit= 1 ask (RAG + citations) or 1 search
-

◈ Credit packs — one-time, never expire

+

◈ Pricing — the honest kind

+

$50/mo HOARD = unlimited: every ask, every search, the whole +{{ mb }}M-char library, as hard as you want to run it. Or pay-per-use with packs. Bitcoin only, +no subscription trap — HOARD simply expires in 30 days unless you renew.

- + {% for name, p in plans.items() %} - += 50 %} style='border:1px solid var(--gold)'{% endif %}> + + + {% endfor %}
PackPriceCredits$/credit
TierPriceWhat you get
{{ name }}${{ '%.2f'|format(p.usd) }}{{ p.credits }}${{ '%.3f'|format(p.usd / p.credits) }}{{ name }}{% if p.usd >= 50 %} BEST{% endif %}${{ '%.0f'|format(p.usd) }}{% if p.usd >= 50 %}/mo{% endif %}{% if p.usd >= 50 %}UNLIMITED asks + searches for 30 days. The whole library, unmetered.{% else %}{{ p.credits }} credits (1 = 1 ask or search), never expire.{% endif %}