feat(docs): v0 static host (Vite, nginx, crawl files, stub routes) #3
Labels
No labels
agent:implement
agent:research
docs
feature
ready
research
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
code/cl8y-docs#3
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Gated v0 implement for https://docs.cl8y.com in this repo: one Coolify-deployable TypeScript static site (Vite + React + TS → nginx non-root) with honest crawl files, unique prerendered titles/canonicals, stub indexable routes, and DEX CTAs.
Do not start until #1 architecture is on
mainand #2 has RECOMMEND: ACCEPT (or FIX items landed and re-reviewed). Do not applyready/agent:implementuntil those gates pass.Parent spec: PlasticDigits/cl8y-marketing#3. Follow
docs/ARCHITECTURE.mdfrom #1; do not invent product policy.Bundle (do not split):
VITE_*only.GET /robots.txtistext/plainrobots syntax;GET /sitemap.xmlisapplication/xmlurlset. No SPA catch-all for those paths (missing file → 404, notindex.html).<title>and canonical:/,/methodology+ one child,/markets,/contracts,/guides+ one child.https://dex.cl8y.comwith campaign query params viaURLSearchParams. No unverified fee, volume, or “best DEX” claims.docs.cl8y.com. Do not pick SKU/snapshot/hypervisor. Rollback = previous image tag. DEXSitemap:pointer is not this PR (marketing#2).Current codebase
Until #1/#2 complete, this tree is README + architecture docs only. Implement against the merged architecture, not this paragraph alone.
This repo (expected at gate open)
README.md,docs/ARCHITECTURE.md,AGENTS.mdfrom #1.Dockerfile, or nginx until this issue. If those already exist and contradict #1, stop and comment on #2.Parent / siblings (do not merge into this PR)
code/cl8y-docshalf; marketing AC12 strategy file stays in marketing.git).docker/frontend/nginx.conf/og-image.png; do not copylocation / { try_files ... /index.html; }for unknown docs paths or crawl files.vite.config.ts,src/blog/SEO.tsx,src/lib/siteOrigin.ts). Do not copy wagmi, WalletConnect, or three.js.src/content/invariants.tsDEX originhttps://dex.cl8y.com. Token addresses only fromsrc/data/tokenDirectory.ts/ DEXVITE_CL8Y_TOKEN_ADDRESSif/contractslists any..woodpecker.yaml— gitleaks + tests; this repo has no Postgres.Duplicates / already implemented
https://docs.cl8y.comIf a PR already shipped v0 and AC1–AC12 below pass on production, close this as implemented — do not duplicate.
Why the new implementation is needed
Phase 1 needs a crawlable content host. Architecture (#1) and program review (#2) only decide; they do not emit HTML, robots, or an image. Without this ship:
Sitemap: https://docs.cl8y.com/sitemap.xml.v0 may stub copy. The platform (repo app, image, TLS hostname, robots/sitemap, unique titles, CTA helper, CI) must be real.
Constraints and guardrails
Follow
docs/ARCHITECTURE.md. In addition:ready, until #2 ACCEPT.cl8y-marketing. Do not adddocs.cl8y.comroutes toCL8Y-webor the DEX SPA./robots.txtor/sitemap.xml. Exactlocation =+try_files $uri =404. Sibling paths (/robots.txt/,/sitemap_index.xmlunless shipped) must not return HTML 200.text/plain; sitemapapplication/xml.VITE_*only. Fail the image build ifVITE_SITE_ORIGIN/VITE_DEX_ORIGINmissing or nothttps://. Optional indexer origin must behttps://indexer.dex.cl8y.comif present — nohttp://, no internal hostnames.link rel=canonicalfor that path. Unknown paths 404 (not home HTML 200).dexHrefusesURL+URLSearchParams. Default pair may useuluna+ checksummed Terra Classic CL8Y CW20 already documented first-party. Campaignutm_source=docs&utm_medium=web&utm_campaign=<page-or-stub-id>. Never concatenate visitor query; neverjavascript:/data:/ protocol-relative /?url=redirectors; do not readwindow.locationto build product origins.content/guides/from marketing.git.X-Frame-Options: DENY,frame-ancestors 'none',X-Content-Type-Options: nosniffon HTML and crawl files.Sitemap:must not be changed in this PR.https://docs.cl8y.com(no trailing slash).Relevant files
docs/ARCHITECTURE.mdAGENTS.mdpackage.json, lockfile,vite.config.ts,tsconfig.json,Dockerfile,nginx.confpublic/robots.txt,public/sitemap.xmldexHref+ unit tests.woodpecker.yaml(gitleaks, typecheck, unit, Playwright 5 workers)cl8y-dex-terraclassic/docker/frontend/nginx.conf(exact-location 404; not SPA/)CL8Y-web/vite.config.ts,src/blog/SEO.tsx,src/lib/siteOrigin.tsCL8Y-web/src/content/invariants.ts,src/data/tokenDirectory.tscl8y-dex-terraclassic/frontend-dapp/src/utils/swapQueryParams.tspublic/robots.txtSitemap line; marketingstrategy/static-content-architecture.mdRecommended direction
npmVite + React + TypeScript (strict). Small dependency set: no wagmi, WalletConnect, three.js.VITE_SITE_ORIGINin absolute canonicals/OG URLs.public/robots.txt:User-agent: *+Allow: /.Sitemap: https://docs.cl8y.com/sitemap.xml. No marketing claims in comments.public/sitemap.xml: urlset of only prerenderedhttps://docs.cl8y.com/...URLs. No DEX/bridge/third-party loc. No unbounded parameters.USER+ writable pid/temp; exact robots/sitemap locations; HTML maytry_filesprerendered files — never fall through to a single rootindex.htmlfor unknown URLs. Prefer 404. Security headers as in Constraints.FROM node:24-*-slim AS builder→npm ci→npm run buildwith publicARG/ENV→ copydistinto nginx html. HealthcheckGET /as non-root./— what this host is; links to methodology, markets, contracts, guides; CTA to DEX./methodologyand one child./markets— no fabricated protocol-fee numbers; “see DEX / public indexer” without inventing numbers./contracts— first-party addresses only if already in CL8Y-web token directory / DEX env; else “see DEX” stub./guidesand one child.dexHref({ from, to, campaign }).npm test; Playwright 5 workers (content-type + body sniff, titles/canonicals, CTA hrefs). Add averify-*script that curls a local nginx container.docs.cl8y.comwith TLS to this service. Rollback = previous tag. After live, a separate DEX PR may setSitemap:only if marketing#2 files exist and production curl of this sitemap isapplication/xml+<urlset.Acceptance criteria
mainand #2RECOMMEND: ACCEPT(or completed FIX cycle) before implement labels.code/cl8y-docs; marketing.git has no app server.GET https://docs.cl8y.com/→ 200,text/html, TLS valid, documentation chrome (not empty nginx default, not DEX SPA, notcl8y.comhomepage).GET https://docs.cl8y.com/robots.txt→text/plain, containsUser-agent, not<!doctype/ Vite shell.GET https://docs.cl8y.com/sitemap.xml→application/xml(or+xml), XMLurlsetofhttps://docs.cl8y.comURLs only./,/methodology(+ child),/markets,/contracts,/guides(+ child) each have a distinct title and canonical in prerendered HTML (curl the path).https://dex.cl8y.comwith campaign params fromURLSearchParams; no secrets in the image or repo.docs.cl8y.comserves this service.Sitemap:at docs.Test plan (functional paths)
GET /https://docs.cl8y.com/GET /robots.txttext/plain;User-agent;Sitemap:to this hostGET /sitemap.xmlapplication/xml;<urlset>; loc = docs origin onlyGET /methodologyand a child/and each otherGET /marketsGET /contractsGET /guidesand a childGET /no-such-pageGET /robots.txt/and/sitemap_index.xmlhttps://dex.cl8y.com+utm_*(optionalfrom/toids)VITE_SITE_ORIGIN/ DEX origindocker runhealthcheckGET /200 as non-rootdexHrefURLSearchParams; rejectsjavascript:/ foreign hostsTest plan (attack, hack, and abuse)
text/plain)User-agent/<urlsetjavascript:https://docs.cl8y.comwindow.location.searchutm_*orfrom/towithjavascript:,data:,//evilVITE_*or gitnosniffon crawl filescontent/guides/Sitemap:to docs in this PRhttp://or internal hostnameVerification criteria
-sIand body on local nginx image and onhttps://docs.cl8y.comfor/,/robots.txt,/sitemap.xml, one methodology URL, one guide URL (status +Content-Type+ sniff).index.htmlOG shell.Sitemap:pointer only after production curl of this host’s sitemap succeeds.mainif implement started from a gated label.Out of scope
cl8y.commissing robots/sitemap (CL8Y-web).strategy/static-content-architecture.mdin marketing.git.First-pass model recommendation
Recommendation: grok-high. New deployable, nginx crawl-file security, prerender canonicals, CTA URL construction, Docker non-root. Cross-cutting vs DEX/CL8Y-web. Not a three-file Composer edit.
Gate
Blocked on #1 and #2. Labels at filing:
featureonly. A human appliesready+agent:implementonly after #2 ACCEPT.Gitleaks + nonempty-tree Woodpecker lands in #6 without waiting on this issue. AC12 Node 24 unit tests and Playwright 5 workers remain here after #2 ACCEPT.
#2 recorded RECOMMEND: ACCEPT. Implement is in #7 (
issue/3-v0-static-host).This work did not apply
ready/agent:implement.Local verify (re-run after nginx MIME + no-slash path fixes):
npm test13 passednpm run typecheckgreennpm run build+npm run test:dist4 passednpm run verify: non-root uid, robotstext/plain+User-agent, sitemapapplication/xml+<urlset, unknown path 404, missing crawl files 404, hashed asset 404, Playwright 5 workers 11 passedscripts/check-origins.mjswithoutVITE_SITE_ORIGINexits 1Not in this PR: Coolify hostname attach / production curl of
https://docs.cl8y.com(AC2/T13 live host; rollback remains image/tag). DEXSitemap:still gated on marketing#2.