🔄 Synced from the AI-Factory monorepo (append-only history). Pull requests are welcome — merged PRs are imported back and re-synced here. Issues · Pull requests
CITE DESKS — independent evidence desks on AIMarket rails
Part of the alexar76 AI agent economy · not an AIMarket brand surface
Evidence you can cite — not perimeters, forecasts, or scores we invent. — family landing → · Emberline demo →
Family landing · Emberline · Use-cases · ATLAS · GAIA
One parent satellite (alexar76/cite-desks): shared kernel/ plus six nested desks, each with its own origin, legal strip, and claim class. Still excluded from the trimmed factory alexar76/aicom — nested desks are not separate top-level GitHub repos.
![]() Emberline — fire · live |
![]() Tideline — flood · live |
![]() Solrecord — PV · live |
![]() Seamark — Nordic AIS · live |
![]() Plinth — site · live |
![]() Smokeproof — smoke · intended |
| Kernel — shared rail (no live origin) | |
| Desk | Claim | Live / intended | README |
|---|---|---|---|
| Emberline — Fire | FIRMS/EFFIS points + bounded weather. Not a perimeter. | emberlinedesk.com | emberline/README.md |
| Tideline — Flood | CAP warning and in-situ gauge, two lists. Not a flood model. | tideline.modelmarket.dev · tidelinedesk.com (intended) | tideline/README.md |
| Solrecord — PV | Retrospective irradiance at a plant pin. Not a yield forecast. | solrecord.modelmarket.dev · solrecorddesk.com (intended) | solrecord/README.md |
| Seamark — Nordic AIS | Fintraffic + Kystverket, two lists. Not global AIS. | seamark.modelmarket.dev · seamarkdesk.com (intended) | seamark/README.md |
| Plinth — Site | Named campus/colo nowcast; weather, air, water as separate lists. Not a BMS. | plinth.modelmarket.dev · plinthdesk.com | plinth/README.md |
| Smokeproof — Smoke | HMS containment at a pin + colocated air, two lists. Not a risk score. | smokeproof.modelmarket.dev · smokeproofdesk.com (intended) | smokeproof/README.md |
| Kernel — shared rail | Hub custody, USDC salt invoices + settlement, cite packs, webhooks, FastAPI runtime | — | kernel/README.md |
Sibling kernel desks share kernel/web (/sample /press /legal /status). Emberline keeps its own React globe. Smokeproof is a peer desk for the HMS question (Emberline may still offer smoke as an optional fire-watch layer). Locale ≠ licence expansion: docs/LOCALES-AND-PLACEMENT.md.
Emberline’s brand and outreach are fire-specific. Putting flood, AIS or smoke under Emberline would mix claim classes and fail intake. The kernel is shared. The origin is not.
One parent satellite. Emberline is a full product tree. The other five desks are brand + compose + DESK_ID; runnable code lives in the shared kernel.
flowchart TB
ROOT["alexar76/cite-desks"]
ROOT --> KER["kernel"]
ROOT --> EMB["emberline"]
ROOT --> SIBS["tideline · solrecord · seamark · plinth · smokeproof"]
KER --> WEB["kernel/web"]
KER --> DK["kernel/desk_kernel"]
EMB --> EF["emberline/frontend"]
EMB --> EB["emberline/backend"]
WEB --> SIBS
DK --> SIBS
- Emberline — own site and API:
emberline/frontend/andemberline/backend/. Compose builds those trees (emberline/docker-compose.yml). - Tideline / Solrecord / Seamark / Plinth / Smokeproof — brand, docs, compose, and
DESK_IDonly. Compose builds API fromkernel/Dockerfileand serveskernel/web/; Python iskernel/desk_kernel/(uvicorn desk_kernel.service.main:app). Example:plinth/docker-compose.ymlsetsDESK_ID=plinth. */backendand*/frontendunder those five desks — pointer READMEs to the kernel paths above, not copies of Emberline (e.g.plinth/backend/,plinth/frontend/).
Cite desks are Hub clients, not a second Hub. They buy attested atlas.* / gaia.* SKUs, file a cite pack, and settle customer access in USDC on Base when operated for real.
flowchart TB
subgraph factory["Factory · alexar76/aicom"]
AICOM["AI-Factory pipeline"]
end
subgraph sensors["Physical rails"]
GAIA["GAIA"]
ATLAS["ATLAS"]
GAIA --> ATLAS
end
subgraph market["Market + cognition"]
HUB["AIMarket Hub"]
METIS["Metis"]
SORTES["Sortes"]
end
subgraph desks["Satellite · cite-desks"]
K["desk_kernel"]
E["Emberline"]
T["Tideline"]
S["Solrecord"]
M["Seamark"]
P["Plinth"]
SP["Smokeproof"]
K --> E & T & S & M & P & SP
end
ATLAS -->|"atlas.* prepaid"| desks
HUB -->|"gaia.* federated"| desks
factory -.->|"does NOT fold cite-desks"| desks
Metis is an optional analyst elsewhere in the economy; Sortes is a verifiable-randomness oracle class — neither is desk supply.
| Project | Relation to desks |
|---|---|
| AICOM factory | Ships the ecosystem; does not embed cite-desks/ in the public factory tree |
| GAIA | Sensor relays / gaia.* capabilities desks purchase |
| ATLAS | Watchbox / situation / fire / PV map products (atlas.*) |
| Hub | Federated catalog; desks use it when buying federated gaia.* |
| Metis | Cognitive layer elsewhere in the economy — not the desk checkout |
| Sortes | Verifiable-randomness oracle class — not desk supply |
Honest split: customers pay the desk; the desk pays ATLAS/GAIA for evidence. Mixing them is how you sell a plan that dies after five anonymous Hub calls.
Self-serve checkout, nobody in the loop (kernel checkout):
- Buyer
POST /api/public/pay/invoices→ unique micro-amount quote - Wallet sends USDC on Base to
PAY_BASE_ADDRESS - Desk poll (
scan_payments/ optional tx-hash confirm) →settle()mints exactly one desk key - Web shell redeems the key (
POST /api/auth/redeem)
Plans (from desk_kernel / Emberline plans.py):
| Plan | USD | Watches | Runs | Retention |
|---|---|---|---|---|
| Solo | 49 | 2 | 200 | 30d |
| Team | 149 | 10 | 1000 | 90d |
| Desk | 499 | 50 | 5000 | 365d |
Fail-closed: no real treasury / placeholder PAY_BASE_ADDRESS → checkout closed (503); production refuses to boot. Family demo host (desk.modelmarket.dev) is explicitly not for sale — checkout closed, live Hub invokes capped.
| Upstream | Env | What it buys |
|---|---|---|
| ATLAS | HUB_URL + HUB_API_KEY |
atlas.* (watchbox, fire weather, situation, PV record, …) |
| Federated GAIA | GAIA_HUB_URL + GAIA_HUB_API_KEY |
gaia.* (e.g. public AIS) — ATLAS answers 404 for those |
Prepaid ATLAS account (X-API-Key); credited calls are not on the anonymous 5/hour IP allowance. Both GAIA URL and key or neither — no silent fall-back to free tier. Supply exhaustion fails honestly: customer told the desk cannot buy evidence; the run does not burn plan quota; refusals are never billed.
Health surfaces: /api/public/health → checkout.*, supply.credit, supply.last_failure.
cite-desks/ ← GitHub satellite root (alexar76/cite-desks)
kernel/ desk_kernel + shared web shell
emberline/ fire desk (React UI)
tideline/ solrecord/ seamark/ plinth/ smokeproof/
deploy.sh family entry (rsync + compose)
docs/landing/ family landing (desk.modelmarket.dev)
.github/workflows/ci.yml family CI (kernel · emberline api · web)
Rooted here on purpose: every desk imports desk_kernel via ../../kernel. A repo rooted at emberline/ leaves the kernel outside the checkout.
Any desk on your own computer, with fixture payments and sample data (Docker; about a minute on the first build):
git clone https://github.com/alexar76/cite-desks.git && cd cite-desks
./deploy.sh tideline # prints the address, e.g. http://127.0.0.1:8091/Tests:
cd kernel && python -m pip install -e ".[dev]" && python -m pytest
cd emberline && make test-api
./deploy.sh --list
./deploy.sh --testFamily entry: deploy.sh. Flags that exist: --list, --test, --build, --prod. Compose stays per desk. Optional host-only docker-compose.host.yml (loopback behind nginx) is picked up automatically when present — keep it off repo syncs. Never bare rsync --delete over a desk folder. After --prod, require checkout.open + settlement: scheduled and a fresh checkout.last_scan.age_seconds.
Own frontend + backend trees.
./deploy.sh emberline
# or: cd emberline && docker compose -f docker-compose.yml up --build -d- Compose:
emberline/docker-compose.yml(buildsemberline/backend,emberline/frontend) - Merchant overlay:
./deploy.sh emberline --prod→ alsoemberline/docker-compose.prod.yml - Metis public demo (no
--prod): auto-addsemberline/docker-compose.metis.ymlwhen that file exists and the host has themetisnetnetwork (DESK_MODE=demo); elsewhere the bare compose runs
Example — only Tideline: that desk’s compose + shared kernel images + DESK_ID + host.
./deploy.sh tideline --build
# or: cd tideline && docker compose -f docker-compose.yml up --build -d- Compose:
tideline/docker-compose.yml(DESK_ID=tideline; API fromkernel/Dockerfile, web fromkernel/web/Dockerfile) - Same pattern for
solrecord/,seamark/,plinth/,smokeproof/ - Merchant:
./deploy.sh tideline --prod→tideline/docker-compose.prod.yml - Metis demo (no
--prod): autotideline/docker-compose.metis.yml
Shared kernel source; each desk is its own compose project (own DB, DESK_ID, ports/host).
./deploy.sh tideline --build
./deploy.sh solrecord --build
./deploy.sh seamark --build
./deploy.sh plinth --build
./deploy.sh smokeproof --buildOn Metis, each metis overlay joins external metisnet; edge routing is deploy/nginx.desks.conf (append into host metis-nginx, do not replace the Metis conf).
Static catalog only — no desk API.
- Sources:
docs/landing/(index.html,sw.js) - Host docroot (Metis):
/var/www/metis-landing/cite-desks→ nginxrootfordesk.modelmarket.devindeploy/nginx.desks.conf - Sync the landing tree to that path; reload
metis-nginx. No./deploy.sh <desk>required.
- Sync
docs/landing/→/var/www/metis-landing/cite-desks - Ensure
deploy/nginx.desks.confis appended on the host nginx (desk + emberline + sibling vhosts) - Bring up each desk without
--prodsodocker-compose.metis.ymlapplies:
./deploy.sh emberline --build
./deploy.sh tideline --build
./deploy.sh solrecord --build
./deploy.sh seamark --build
./deploy.sh plinth --build
./deploy.sh smokeproof --buildDemo overlays set DESK_MODE=demo (checkout closed), fixture Hub/pay, and loopback web ports; metis-nginx proxies via *-web on metisnet.
Satellite id cite-desks → https://github.com/alexar76/cite-desks. Mirror via ./scripts/publish_all_repos.sh --satellite cite-desks (alexar76 + GH_PAT). First push of .github/workflows/ci.yml needs a PAT with workflow scope; repo + write:packages alone is enough for satellites whose workflows already exist on GitHub and did not change in that run.





