Updated after each phase. Newest entries at top of the changelog.
Phase progress
| # | Phase | Status |
|---|---|---|
| 1 | Repo, docs, design system, schema | ✅ complete |
| 2 | Public landing page + seeded public registry | ✅ complete (2.1 polish items below) |
| 3 | Auth, registration wizard, verification workflows | ✅ live-verified (2026-07-12); evidence uploads live — migration 0005 applied to production 2026-07-14, bucket/policies/function verified |
| 4 | Land/Tree/Farm passport pages + relationships | ✅ shipped early with Phase 2 (pages live; deepen with Phase 3 data) |
| 5 | Smart contract + Amoy integration | ✅ COMPLETE: contract live on Amoy (0xf1b7…d6c0), two real certificates (CG-FRM-0001 → #1, CG-TRE-0017 → #2); issue AND revoke paths live-verified — full certificate lifecycle on-chain |
| 6 | Founding Forest checkout + payment abstraction | ✅ mock mode end-to-end (catalogue → disclosures → checkout → receipt certificate → passport attribution) |
| 7 | Institutional data room | ✅ sample data room over CG-FRM-0001 + request-demo queue in admin |
| 8 | Grow gated shell | ✅ waitlist questionnaire (no-offer acknowledgement enforced), fictional sample data room, admin review queue |
| 9 | Security, tests, accessibility, demo resilience | ✅ core: 16 vitest unit tests + 18 contract tests in CI; a11y/e2e polish continues in 9.1 |
| 10 | Deployment + founder instructions | ✅ live on Vercel; runbook, demo script, content entry + readiness checklists written |
Definition-of-done tracker
- [x] Visitor understands Corngate within 30 seconds (hero + proof strip)
- [x] Inspect real proof (23 seeded passports, open disputes/revocations included)
- [x] Open a passport via stable link (QR-ready URLs; printed QR images pending Phase 2.1)
- [x] Start understanding registration (flows documented; interactive wizard Phase 3)
- [x] Register an asset self-service (land/tree/farm wizards; GPS capture; demo mode live, Supabase pending live pass)
- [x] Sponsor a tree in demo payment mode (mock provider; disclosures at selection, checkout and passport; receipt certificate)
- [x] Join Grow without being offered an unapproved investment (waitlist via contact; no investment path exists)
- [x] Verifier approves records (queue + review + noted decisions; approval publishes the passport)
- [x] Admin issues/revokes a certificate (real Amoy issuance AND revocation live — contract deployed, two real certificates on-chain, revoke path live-verified on a disposable test token)
- [x] Institutional sample data room (aggregated CG-FRM-0001 with risk view + printable report)
- [x] Sensitive data protected by design (no precise geometry or PII exists client-side; RLS posture written)
- [x] Tests pass (16 unit + 18 contract; wired into GitHub Actions CI)
- [x] Deployment documented and live (Vercel; DEPLOYMENT.md; GitHub/CI pending founder push)
Phase 2.1 polish backlog
- ~~QR code images on passport pages~~ ✅ shipped (server-rendered SVG, printable)
- ~~Self-hosted display font upgrade (ADR-012)~~ ✅ shipped (Fraunces + Inter, ADR-016)
- ~~Interactive map~~ ✅ shipped keyless — MapLibre GL v5 + OpenFreeMap, schematic SVG stays as fallback (ADR-018; no Mapbox token needed after all)
- ~~Printable certificate sheet~~ ✅ shipped (
/certificate/[id], A4, SIMULATED/REVOKED watermarks) - ~~Whitepaper PDF download; docs web versions~~ ✅ shipped (versioned PDF + all six repo docs at
/docs/[slug]) - ~~On-chain revocation live pass~~ ✅ done (revoke path live on Amoy; tx recorded on the certificate row)
- Real field photographs via content entry workflow (blocks public launch — ADR-013; GROUND_TRUTH_INTAKE.md still awaiting founder input)
Changelog
2026-07-14 — corngate.co is the official domain 🌐
- corngate.co live (founder-purchased on Namecheap): attached to the Vercel project (apex +
wwwwith 308 redirect to apex), Namecheap DNS cut over from parking to Vercel's recommended records (A216.198.79.1+64.29.17.1, CNAMEwww→ project DNS target). Vercel reports the domain correctly configured; SSL automatic. - Google Workspace email on the domain: Custom MX →
smtp.google.com(priority 1, Google's modern single-record setup), SPF (v=spf1 include:_spf.google.com ~all), Google site-verification TXT, DKIM (2048-bit,google._domainkey) and DMARC in monitor mode (p=none, reports to marcel@corngate.co — tighten to quarantine once DKIM is confirmed). - App repointed:
NEXT_PUBLIC_SITE_URL=https://corngate.coin Vercel (QR codes + certificate sheets now emit corngate.co URLs), hardcoded vercel.app references replaced, whitepaper PDF regenerated with the new domain, redeployed. - Supabase Auth site_url updated to
https://corngate.co(verified on reload) — magic-link emails now land on the official domain. - Migration
0005applied to production (founder ran it; verified by query: privateevidencebucket with 10 MB cap ✓, all threeevidence_*object policies ✓,register_assetownership gate ✓). Evidence uploads are live end-to-end.
2026-07-14 — ADR-020: institutional identity + storytelling homepage 🏛️
- Design system re-anchored to the master crest: navy
#0f1f3b(authority — display, primary actions) + harvest gold#d9ad45(accent), both sampled from the official logo; forest stays as the field/verification colour; status scale untouched. Type: Fraunces/Inter → Libre Franklin (display) + Public Sans (text — the U.S. Web Design System typeface), self-hosted, token names kept so components were untouched. - Homepage rebuilt as a What/How/Why story (Apple-style pacing, ~⅓ of the previous copy): full-bleed hero on the real tractor shot (provenance-linked to CG-FRM-0002) → logo strip → WHAT (compact passport rows + interactive map + count-up live stats) → HOW as a full-bleed photo chapter ("Verified by walking the land") with a 4-step lifecycle → WHY with the honesty pull-quote + three openable proof records → "Corngate is a farm first" founder photo section → navy applications band → close. All depth moved to /docs and the whitepaper.
- Motion system: scroll-reveal + stagger (IntersectionObserver), count-up numerals, CSS scroll-driven Ken-Burns drift on full-bleed imagery — everything gated on
.jsandprefers-reduced-motion, so no-JS and reduced-motion visitors get the complete static page. Live-pass note: the first deploy revealed nothing above the fold (threshold too strict for in-view-at-mount elements); fixed by revealing anything already within 92% of the viewport at mount. - Photo pass from the real media library: hero tractor wide (1920w + 960w), parcel-walk wide, plus the existing face-free set. EXIF stripped throughout. Correction (same day): a maize-field selfie was initially published captioned as the founder; the founder flagged that the person is not him. The photo was removed from the site and the repo entirely (unconfirmed-consent face, ADR-019), the feature image replaced with the grain-drying shot, and the caption corrected. Rule reaffirmed: no photo gets a naming caption without the founder confirming who is in it.
- Verified: tsc clean, 28 tests, remote production build; visual QA via browser screenshots at 1440px (hero, WHAT/map/stats, HOW chapter). Deployed to production.
2026-07-13 — Revocation live, evidence uploads, docs centre, certificate sheets 🧾
- On-chain revocation is live (Phase 5 complete):
revokeCertificateActionnow sends the realrevoke(tokenId, reason)transaction for non-simulated certificates and recordsrevoke_tx_hash; the honest gate message is gone. Chain calls were extracted tosrc/lib/certificates/chain.ts(noserver-only) so live passes exercise the app's own code. Live-verified on Amoy: disposable token #3 (CG-TST-REVOKE-…, never in the DB) minted0xa5de2b0f…→ revoked0xbda0084a…→ double-revoke reverts → real certs #1/#2 confirmed untouched. Runner:test/live-revocation.test.ts(gated byLIVE_CHAIN_PASS=1); a mirror exists atcontracts/scripts/live-revocation-pass.cjs. A real cert can no longer be DB-revoked without chain credentials — the site cannot disagree with the chain. - Evidence file uploads (last live-mode gap): migration
0005creates the privateevidencebucket (10 MB cap; JPEG/PNG/WebP/PDF) with owner-prefix-only object RLS, and hardensregister_assetto refuse storage paths outside the caller's ownpending/{uid}/prefix. Land wizard evidence items get an optional file attach (sha256 computed server-side, honest demo-mode message); the verifier review shows submitted files via 5-minute signed URLs with hashes for integrity checks. Uploads go through the user-scoped client so storage RLS is the authority, never the service key. ⚠ Apply migration 0005 to the live project (DEPLOYMENT.md §B.2) before relying on uploads. - Documentation centre published: all six repository docs render as web pages at
/docs/[slug](architecture, data-classification, regulatory-boundaries, threat-model, decisions, status) — rendered at build fromdocs/*.mdvia a deliberately-minimal project-owned markdown subset (src/lib/docs/render-markdown.ts, contract locked bytest/docs-render.test.tsover the real corpus; mermaid fences render as labelled source blocks). - Whitepaper v0.1 PDF: branded, versioned artefact at
/docs/corngate-whitepaper-v0.1.pdf(Fraunces/Inter from the repo's own fonts, crest cover, page-numbered footers, no-offer disclosure on the cover); generator kept atscripts/build-whitepaper-pdf.py. Download button replaces the "PDF on request" note on/whitepaper. - Printable certificate sheet (
/certificate/[id]): A4 print sheet with ink-stamp crest, registry ref, verification + certificate details, passport QR and the not-title disclaimer; SIMULATED and REVOKED states get unmissable watermarks; linked from every certificate panel. Records without certificates get an honest "nothing to print" page. - Verified:
tscclean, 28 unit tests passing (4 live-gated skipped), production build 56/56 pages, new routes smoke-tested against a running server (docs pages render tables/diagrams with no raw markdown leakage; revoked/simulated sheets watermark correctly; PDF serves at 96 kB). ROUTES.md, DATA_CLASSIFICATION.md and DEPLOYMENT.md updated. - Public track record shipped: homepage "Presented publicly at" strip (NFT.NYC 2023 speaker · Harvard African Development Conference 2023 panelist) above the stats, linking to the recordings; full entries on the About page; noted as founder evidence in YC_READINESS.md. Per founder direction the strip carries the official marks (
public/brand/mentions/): NFT.NYC's logo (from nft.nyc) and the Harvard University wordmark — used nominatively for events actually presented at, muted press-strip styling, exact roles stated underneath. The VERITAS shield was deliberately not used: it is reserved by the university (even student orgs may not use it) and would imply an affiliation that doesn't exist. If HADC organisers grant use of the conference's own mark, swap it in. - Deployed to production (Vercel API, founder-provided token; 147 source files, remote build clean). Verified live: docs pages, whitepaper PDF download, revoked certificate sheet rendering against the live DB. Repo housekeeping: stale git-lock debris removed. ⚠ Still pending: migration
0005on the live Supabase project (evidence uploads inert until then); founder GitHub push for CI auto-deploys.
2026-07-13 — Official logo + brand variants
- Corngate Farms crest is the site-wide mark: header (40px), footer and receipt via the shared
CorngateMarkcomponent, plus favicon and apple touch icon. The site renders the forest two-tone variant (navy hues remapped to the forest palette; gold kept as harvest accent — founder-approved); the navy+gold original remains the official master.public/brand/: original,-forest(site),-ink(single-colour stamp for print/QR tags),-ink-paper(reverse, for dark surfaces).
2026-07-13 — First real records + real field media (ADR-019) 🌽
- CG-FRM-0002 (Aperade) and CG-FRM-0003 (Kubenta) — Corngate Farms' actual maize operations — registered in the live DB and fixtures as founder-entered
unverified_claimrecords with explicit no-shortcuts disclosures. Locations locality-level (Kubenta at district centroid pending GPS; it has no OSM entry). - Homepage "From the field": four real, face-free photographs (maize rows, land prep, cleared parcel walk, grain drying) — EXIF stripped, pillarboxes cropped, honest captions; links to both real records. Full media library (66 photos + 26 videos incl. drone) catalogued in
media/for future use. - GROUND_TRUTH_INTAKE.md placed in the client folder: farm facts, photo→parcel mapping, consent tracking; records update in one pass when filled.
- YC_READINESS.md: honest assessment against YC criteria + the leverage-ordered gap list (short version: product ready, traction absent — 10 real registrations and one institutional signal before applying).
- Seed test updated (23 → 25 passports). Verified: tsc, 17 tests, clean build, gallery + record screenshots. Note for future sessions:
rm -rf .nextafter adding new Tailwind utility classes — stale CSS cache silently drops them.
2026-07-13 — Interactive map, keyless (ADR-018) 🗺️
- The registry map is real: MapLibre GL JS v5.24 over OpenFreeMap Positron vector tiles — no API key, no usage limits, production-permitted. Researched current practice first: MapLibre v5 (globe-era, community-governed), OpenFreeMap (keyless OSM hosting), cadastral-viewer interaction patterns (feature-state hover), react-map-gl v8 (skipped — one component doesn't need a wrapper library).
- Progressive enhancement preserved: the server-rendered schematic SVG is still the first paint, the no-JS/offline/demo experience, and the fallback on tile failure (verified: SVG present in SSR HTML; MapLibre loads as a lazy client chunk so First Load JS is unchanged).
- Interaction: status-coloured parcels + points (design-token colours), per-feature hover highlight with a hover card (name, ref, facts, status), click-through to passports, dashed disputed boundaries, parcel labels, cooperative gestures, reduced-motion respected, satellite toggle available via
NEXT_PUBLIC_SATELLITE_STYLE_URL(licensed source required — nothing bundled). - Privacy in the camera: only the public read model renders (generalised centroids/simplified boundaries) and
maxZoomis capped at 16 so the map can't imply survey precision (ADR-018). - Passport pages get a real locator map for free (same component, non-interactive mode). Mapbox token flag removed from flags/env/docs.
- Verified: tsc clean, 17 unit tests, production build, Playwright screenshots (registry overview, hover card on CG-FRM-0001, passport locator).
2026-07-13 — Amoy is real + design pass (Fraunces/Inter) ⛓️
- CorngatePassportRegistry deployed to Polygon Amoy:
0xf1b7a49A4EB1D35c161b941B85c9dD4A903dd6c0(deploy tx0x26e4aebe…4ea0c9dd, block 42112902, 18/18 contract tests green pre-deploy). Deployer = the funded burner incontracts/.env. - First real certificates minted and recorded in the live DB: CG-FRM-0001 → token #1 (tx
0xcf568b88…9ed3d0), CG-TRE-0017 → token #2 (tx0x5cbca0c7…95bab7). Both rowsissued,simulated=false— the DB honesty constraints (real ⇒ tx hash) held. - Chain-mode fix:
issueCertificatenow writes the certificates row after a successful mint (previously the mint was invisible to the site); failures surface the tx hash for manual reconciliation. Issuance fees pinned to Amoy's 25 gwei floor — the RPC's suggested ~90 gwei would have tripled gas spend (ADR-017). - Vercel production env:
AMOY_RPC_URL,NEXT_PUBLIC_REGISTRY_CONTRACT_ADDRESS(all targets) andDEPLOYER_PRIVATE_KEY(sensitive, production only — previews cannot spend gas). Wallet balance after deploy + 2 mints: ~0.034 POL. - Design pass (ADR-016): self-hosted variable Fraunces (display) + Inter (text) via
next/font/local, OFL licences vendored; editorial eyebrow rules on section headings; active nav states (newNavLinksclient component highlights the current section,/passport/*maps to Registry); button hover/press micro-interactions;text-balance/text-prettyon display headings and ledes; certificate-panel and proof-strip copy updated now real issuance exists. - Verified: 17 unit tests,
tsc --noEmitclean, production build clean; homepage/registry/passport/founding-forest screenshotted at 1440px in demo mode.
2026-07-12 — PRODUCTION IS LIVE MODE 🎉
- The public registry now reads from Supabase in production.
supabase/seed.sql(generated from the fixtures bytest/generate-seed.test.ts) seeded the DB with the full pilot: 23 passports, 29 claims, 55 evidence items, 42 inspections, 45 versions, 16 certificates, the DSP-2026-004 dispute and 2 consented sponsorships. - Migration
0004: rebuiltregistry_public(GeoJSON boundaries, numeric centroids, full public-safe columns), addedfarm_parcels_public+sponsorships_public, and lockedpartiesto column-level access — anon can never selectlegal_name/contact. - Data layer is now an async dual-mode dispatcher: live reads via the anon-key read model (structurally incapable of returning precise geometry); demo mode (no env) still works fully from fixtures for offline demos.
- Live wiring completed: verifier queue + review read real unverified claims and decide via RPC; dashboard lists the signed-in user's registrations; sponsorship checkout persists payments + sponsorships rows; admin certificate issue/revoke writes the certificates table; receipts resolve from the DB.
- Verified locally against the live DB (registry filters, disputed detail incl. dispute row, DB sponsorships, simulated cert labels, magic-link login) and re-verified on production after the flip. 17 unit tests passing.
- Auth: sign in at /login with marcelkojogyan@gmail.com (magic link) — the account already holds registry_admin + verifier.
- Note: demo personas no longer appear in production (real auth now); run
npm run devwithout env vars for the persona-based offline demo.
2026-07-12 — Supabase live-mode verification pass ✅
Project hkacpjhbcfrsdljbprah (eu-west-2) created; migrations 0001–0003 applied clean (0003 adds the auth→profiles trigger). All 10 live checks passed: anon blocked from register_asset · password sign-in · register_asset created CG-LND-0001 with claims/evidence/v1 · server-side declaration enforcement · non-verifier blocked from deciding · decision note required · verifier decision → document_verified + v2 · anon public read reflects status · anon receives zero rows of precise geometry (RLS) · version history correct. Test data and test users fully removed (audit-log FK correctly resisted user deletion until test audit rows were cleared — append-only design working). Founder admin account created (marcelkojogyan@gmail.com, registry_admin + verifier). Supabase auth site_url → production domain. Env vars set in Vercel for PREVIEW/DEVELOPMENT only — production intentionally stays in demo mode until the queues/dashboard read Supabase (next build item); flipping is: add the same 4 vars to the production scope. Local production build + server verified in live mode: magic-link login active, guards intact.
Remaining for full live cutover: wire /verify, /dashboard and the public registry reads to Supabase behind the existing data-layer seam; evidence file uploads to private storage.
2026-07-12 — Phases 5–9: contract, checkout, data rooms, Grow shell, tests
- Smart contract (Phase 5):
CorngatePassportRegistry— ERC-721 + AccessControl + Pausable; registry-ref duplicate prevention; transfers and approvals disabled (admin migration with reasons is the only move path); revocation with public reasons; versioned token URIs; zero payment/sale/fractional logic. 18 Hardhat tests passing (compile target cancun, solc 0.8.28). Amoy deploy script refuses non-testnet networks. - Certificate ops: dual-mode issuance service (viem for real Amoy behind env keys; honest SIMULATED records otherwise) + admin console with issue/revoke, eligibility policy (verified + dispute-free + no active cert) and a sponsorships ledger.
- Founding Forest (Phase 6): payment provider abstraction with mock mode (no provider hard-coded; Ghana adapter interface documented); checkout with naming, privacy consent and DB-style disclosure acceptance recorded with a version tag; receipt + printable sponsorship certificate; attribution flows onto the Tree Passport.
- Institutional (Phase 7):
/institutionalwith request-demo intake into the admin queue; sample data room aggregating CG-FRM-0001 (summary, holdings & verification, evidence index, monitoring, risk view incl. the open dispute and revoked tree, print/PDF export). - Grow (Phase 8): in-page waitlist with jurisdiction + non-scoring suitability questions and a mandatory no-offer acknowledgement; clearly-FICTIONAL sample data room (Demo Farm Alpha) with risk-first ordering; admin review queue. Investment code paths remain nonexistent by design.
- Tests & CI (Phase 9): 16 vitest unit tests (schemas incl. declaration enforcement, area math ±3%, full registration→verification cycle, sponsorship/cert/waitlist store behaviour); CI now runs typecheck + unit tests + build + the contract suite.
- Docs: DEMO_SCRIPT, CONTENT_ENTRY, MAINNET_READINESS, GROW_REGULATORY_READINESS.
- Live-mode (Supabase/Amoy-real) paths remain marked "needs live pass" — one session against real credentials.
2026-07-12 — Deployed to production (demo mode)
- Live at https://corngate-platform.vercel.app (Vercel, via API deploy; 77 source files, remote build clean). Verified live: homepage, registry filters, passport pages, login personas.
- No env vars set — the site runs in demo mode. Note: on serverless, demo-cycle submissions are ephemeral and per-instance; use
npm run devlocally for reliable full-cycle demos, or connect Supabase (DEPLOYMENT.md §B) for real persistence. - GitHub repo + CI still pending (deployed direct-to-Vercel); do DEPLOYMENT.md §A when ready so pushes auto-deploy.
2026-07-12 — Phase 3: auth, registration wizards, verification workflows
- Dual-mode auth (ADR-014): Supabase SSR magic-link auth when configured; labelled demo personas (registrant / verifier / admin) otherwise. Middleware guards
/dashboard,/verify,/admin; roles re-checked server-side on every page and action. - Registration wizards for land (boundary GPS walk with live area estimate, claimant roles, evidence declarations, encumbrance disclosure, mandatory declarations), tree (phone-first: GPS trunk fix, species picker, health/measurements, parcel link) and farm (parcel linking, operator, cycles, infrastructure, monitoring, buyers, insurance). Zod schemas validated client-side for UX and server-side for authority.
- Verifier workspace: queue of open applications, full review detail, decisions (verify documents / request changes / reject) requiring a written note; complete decision trail rendered. Approval creates the passport and publishes it to the registry (ADR-015).
- Registrant dashboard: submissions with statuses, verifier notes on change requests, links to resulting passports.
- Live-mode plumbing:
0002_registration_rpc.sql— atomicregister_asset+decide_registrationsecurity-definer RPCs with declaration enforcement and audit rows. ⚠ Needs the live verification pass against a real Supabase project before production reliance. - Deployment readiness: git history initialised (commit 65d7d8a),
vercel.jsonwith security headers, GitHub Actions CI (typecheck + build),docs/DEPLOYMENT.mdrunbook. Deployment itself requires founder GitHub/Vercel accounts (~5 min) — this sandbox has no credentials, by design. - Verification:
tsc --noEmitclean; production build 43/43 pages; smoke-tested running server — middleware redirect, persona login, role blocking (registrant denied verifier queue), wizard rendering, public site intact. The click-through of submit→approve→passport should be exercised once locally (npm run dev→ demo personas); code paths are typechecked and the store logic is deterministic.
2026-07-12 — Phases 1 & 2: foundation + first vertical slice
- Repo scaffolded: Next.js 15 App Router, TypeScript strict, Tailwind v4 token-based design system (institutional/nature-forward, no crypto clichés).
- Passport Engine schema written with RLS: core passports, land/tree/farm extensions, claims (9 roles), evidence with visibility classes + hashes, inspections, append-only versions, disputes, certificates with honesty constraints (simulated ⇒ no tx hash; Amoy-only check), sponsorships with DB-enforced disclosure acceptance, Grow waitlist with mandatory no-offer acknowledgement, institutional grants, audit log.
- Seeded pilot registry: CG-LND-0001 (field verified, cocoa, customary tenure), CG-LND-0002 (disputed — boundary overlap DSP-2026-004), CG-FRM-0001 (farm linking both parcels), 20 trees across 6 species incl. superseded CG-TRE-0005 and revoked CG-TRE-0013. All certificates honestly labelled Simulated; all imagery labelled illustrative placeholder.
- Public site: full homepage sequence (12 sections), registry with search/filter + schematic survey-style map, complete passport detail pages (facts, claims, evidence index, inspection timeline, versions, certificate panel, relationships, disclosures), Founding Forest catalogue, Grow concept page, applications, whitepaper web rendition, about/contact/docs, gated-shell previews for dashboard/verify/admin, QR-aware 404.
- Docs: ARCHITECTURE (+ Mermaid system/ERD/workflow diagrams), DECISIONS (13 ADRs), ROUTES, DATA_CLASSIFICATION, REGULATORY_BOUNDARIES, THREAT_MODEL, founder README.
- Build verified:
next buildpasses clean (TypeScript strict, 42/42 pages generated, 23 passport pages SSG'd, ~106 kB first-load JS). Smoke-tested against a running production server: homepage hero + real stats render; simulated-certificate labels present; revoked (CG-TRE-0013) and disputed (DSP-2026-004) records render with notices; registry search and type/status filters return correct records; unknown passport refs return 404.package-lock.jsoncommitted for reproducible installs.
