-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathrender.yaml
More file actions
146 lines (145 loc) · 7.76 KB
/
Copy pathrender.yaml
File metadata and controls
146 lines (145 loc) · 7.76 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
# Agent Guild — one-click deploy blueprint for Render (render.com).
# Push this repo to GitHub, then in Render: New + > Blueprint > pick this repo.
# Render builds the Docker image and mounts a 1 GB persistent disk at /data so
# the reputation graph, accounts and credit ledger survive restarts.
services:
- type: web
name: agent-guild
runtime: docker
dockerfilePath: ./live/guild/Dockerfile
# REPO ROOT context (2026-08-01). With ./live/guild the build could not see
# docs/, so the committed checkpoint pin was absent from the image and the
# disk-independent half of the canonical floor did not exist in production.
dockerContext: .
plan: starter # smallest paid plan supports a persistent disk
healthCheckPath: /health
envVars:
- key: GUILD_DATA
value: /data/guild.json
# --- ACTIVATED 2026-07-13 (production-truth hardening) ----------------
# SQLite write-through backend. First boot auto-backs-up guild.json to
# guild.json.pre-sqlite-<ts> and migrates; the JSON file is never written
# again under sqlite, so ROLLBACK = revert this block (deploy_canary.py
# rollback <commit>). SINGLE instance + ONE uvicorn worker ONLY (see
# Store._guard_single_writer — scaling out requires Postgres first).
- key: GUILD_STORE
value: sqlite
- key: GUILD_STORE_PATH
value: /data/guild.sqlite3
# Hashed credentials: new keys store a salted-PBKDF2 verifier only; the
# existing plaintext keys migrate in place on first load (raw keys keep
# authenticating). Full production KDF cost — GUILD_ALLOW_WEAK_KDF unset.
- key: GUILD_HASH_KEYS
value: "1"
# Abuse controls: registration flooding / trial farming / unfunded read
# bursts / storage exhaustion (app/abuse.py; limits tunable via GUILD_RL_*).
- key: GUILD_ABUSE_CONTROLS
value: "1"
- key: GUILD_ADMIN_TOKEN # protects seed-agent registration
generateValue: true
- key: GUILD_BILLING_DEV_TOKEN # mint credits without Stripe (pilot)
generateValue: true
- key: GUILD_BILLING_ENFORCED # require sandbox credits or x402 on paid reads
value: "1"
- key: GUILD_BOOTSTRAP_EVAL # "1" self-seeds a labelled, first-party
value: "1" # bootstrap /evaluation cohort on boot
# Strict first-party tagging (Pilot A instrumentation audit, 2026-07-10):
# when set, ONLY X-Guild-Source headers matching this exact token are
# treated as our own traffic — a third party sending a random header can
# no longer self-tag as first-party, and our jobs are DETERMINISTICALLY
# classified (never by UA/IP/naming). sync:false = set the value in the
# Render dashboard, then distribute it to all first-party tooling BEFORE
# saving (activation runbook: docs/discovery-swarm/FIRST_PARTY_TOKEN.md —
# setting it here without updating tooling makes our own traffic read as
# external-unknown).
- key: GUILD_FIRST_PARTY_TOKEN
sync: false
# Public Base payer addresses used by Guild-operated canaries. Read-time
# classification ensures they can never count as external adoption or
# revenue, even when a canary omits the token-gated source header.
- key: GUILD_X402_FIRST_PARTY_PAYERS
value: "0x6904b3E1a5007C94b195d054CF2ca06B43a5C45c"
# --- autonomous discovery scout (2026-07-15) ---------------------------
# GUILD_SCOUT_AUTORUN=1 runs the demand-driven scout on a jittered,
# lease-guarded schedule inside the service (app/swarm/runner.py) and
# publishes GET /swarm/status. The release gate REQUIRES one completed
# production cycle (a zero-demand cycle counts), so this must be "1"
# for the gate to go green. Outbound contact is a SEPARATE switch and
# stays OFF: GUILD_SCOUT_CONTACT is deliberately not set (default 0).
- key: GUILD_SCOUT_AUTORUN
value: "1"
# --- autonomous trust index (product-led pivot 2026-07-31) ------------
# GUILD_INDEX_AUTORUN=1 lets the SAME lease-guarded, jittered scout loop
# also maintain the public index: ingest, recheck the stalest entries,
# run due customer watches and evaluate experiments. One loop, one lease,
# one deadline, one kill switch — set this to "0" to stop all index
# upkeep without touching the scout or taking the service down.
- key: GUILD_INDEX_AUTORUN
value: "1"
# Remote public-registry ingest is a SEPARATE switch and stays OFF until
# the local loop is proven in production. Outbound traffic to third-party
# infrastructure should never start because a container restarted.
# Adapters read documented public read-only APIs with a truthful,
# contactable User-Agent; no scraping, no auth bypass, no ToS evasion.
# Cleared for the documented, capped MCP Registry adapter only after a
# bounded local-only cycle ran clean in production. Set to "0" to stop
# all remote ingest in one config change, with no deploy. Excluded
# sources and their exact gates: GET /admin/index/cycle -> bounds, and
# app/indexsources.UNAVAILABLE_SOURCES.
- key: GUILD_INDEX_INGEST
value: "1"
# How long an observation stays "fresh" before the index reports it as
# stale and the loop re-probes it.
- key: GUILD_INDEX_FRESH_TTL_S
value: "86400"
# Hard cap on endpoints probed per cycle. This is the bound that keeps an
# autonomous loop from becoming a crawler of other people's servers.
- key: GUILD_INDEX_RECHECK_BATCH
value: "8"
# --- experiment engine bounds ----------------------------------------
# Minimum GENUINE-EXTERNAL actors before any verdict other than
# insufficient_evidence may be reached. Crawlers and first-party traffic
# are excluded structurally and can never reach this threshold.
- key: GUILD_EXP_MIN_QUALIFIED
value: "10"
- key: GUILD_EXP_WINDOW_DAYS
value: "14"
# --- paid index layer: prices are CONFIG, not doctrine ----------------
# Every price is env-overridable within a hard ceiling enforced in
# app/pricing.py, so a price change is a config change and a rollback
# rather than a deploy and a revert. Unset = the documented default
# (deep_preflight 20cr/$0.02, evidence_bundle 100cr/$0.10,
# watch_cycle 5cr/$0.005, watch_provision free). GET /pricing publishes
# the live value, the ceiling and the stated basis for each.
# - key: GUILD_PRICE_DEEP_PREFLIGHT
# value: "20"
# --- set these only when you go live with real card payments -----------
# - key: STRIPE_SECRET_KEY
# sync: false
# - key: STRIPE_WEBHOOK_SECRET
# sync: false
disk:
name: guild-data
mountPath: /data
sizeGB: 1
# --- market demo WORKER (first-party demo supply; never counted external) --
# The FastAPI half of the machine-only market loop (the buyer is Node.js and
# discovers this worker exclusively through the Guild's public /check routing
# gate). Free instance: sleeps when idle; the Guild's probe/invoke wakes it.
- type: web
name: agent-guild-market-worker
runtime: python
rootDir: live/market_clients/worker
buildCommand: pip install -r requirements.txt
startCommand: uvicorn worker:app --host 0.0.0.0 --port $PORT
plan: free
healthCheckPath: /
envVars:
- key: PYTHON_VERSION
value: 3.11.9
- key: GUILD_URL
value: https://agent-guild-5d5r.onrender.com
- key: WORKER_PUBLIC_URL
value: https://agent-guild-market-worker.onrender.com/a2a
- key: GUILD_FIRST_PARTY_TOKEN # classification only; set with the main
sync: false # service's token when Ross activates it