UCCA Gear-Up — Session 13 March 2026¶
Tim Rignold + Claude — Brisbane¶
To pick up from here¶
- Read this file top to bottom
- Check Alex's current status (contact form module — hosting + wiring in progress)
- Check pending briefs section at the bottom
- Ask Tim what's next
What shipped today¶
| Item | Status |
|---|---|
| trust.ucca.online | ✅ Live — 4 open legal docs, hero home page |
| Legal rename | ✅ Complete — "United Community Colleges of America Inc" gone from entire stack |
| Footer links + popup | ✅ Complete — all ucca.online namespace surfaces |
| trust.ucca.online compliance record | ✅ Updated — UCCA Inc / Universal Capability Certification Authority |
| Unified contact form module | 🔄 Alex building — hosting + wiring in progress |
Legal entity (LOCKED)¶
UCCA Inc Universal Capability Certification Authority (DBA) 1207 Delaware Ave #1678, Wilmington DE 19806 Delaware C-Corp · DE File No. 7824354 EIN 84-4522608 · D-U-N-S 119-199-377 USPTO Reg. No. 7,619,705 · Int. Cl. 41 First Use in Commerce: Sep. 25, 2017
"United Community Colleges of America Inc" is legally dead. Never use it again.
Surfaces (ucca.online namespace only — rtopacks.com.au is separate)¶
| Surface | Worker | Status |
|---|---|---|
| ucca.online | ucca-site | Live |
| ir.ucca.online | ucca-ir | Live |
| vcc.ucca.online | ucca-vcc + ucca-keys | Live |
| trust.ucca.online | Cloudflare Pages (ucca-trust) | Live |
| t.ucca.online | ucca-track | Live |
| ops console | ucca-ops | Live |
| api.ucca.online | ucca-api | Live (stub, infra endpoint pending) |
Unified Contact Form Module¶
File: ucca-contact-form.js
Hosted at: https://api.ucca.online/components/ucca-contact-form.js
Mount: UCCAContactForm.mount('#el', { mode: 'modal'|'page', endpoint: '...' })
CONFIG object (all tuneable in one place)¶
const CONFIG = {
STEP_DELAY: 400,
STANDBY_HOLD: 3000,
FADE_TO_BLACK: 1200,
CHAR_SPEED: 20, // ms per character — start here, tune after seeing live
POLL_INTERVAL: 5000,
POLL_TIMEOUT: 600000,
CHAIN_PREVIEW_COUNT: 5, // events shown in tractor feed on first load
// ... all copy strings, dial codes, enquiry types
}
Fields (canonical order)¶
- Name (required)
- Organisation
- Email (required)
- Mobile with dial code (18 countries, AU default)
- Enquiry type (Investor / Enterprise Partner / Technical / Other)
- Message
- Honeypot (hidden)
- Turnstile (conditional — loads if Turnstile script present on host page)
Post-submit sequence¶
- Phase 1: STAND BY receipt card (3s)
- Phase 2: Fade to black (1.2s) — in modal mode breaks out of modal, full page takeover
- Phase 3: Full-page teletype — character by character, QR (bundled ~4KB generator), masked email/mobile
- Phase 4: MESSAGE ENDS
- Phase 5: Chain tractor feed (see below)
Tractor feed — THE canonical description¶
The 5 most recent chain events type in as delivery — character by character, line by line, you're watching the chain being printed in real time.
─────────────────────
YOUR CHAIN
─────────────────────
13 Mar 2026 05:14:22 hash_generated ✓
13 Mar 2026 05:14:23 email_confirmed ✓
13 Mar 2026 05:14:31 sms_confirmed ✓
13 Mar 2026 05:14:31 k2_delivered ✓
13 Mar 2026 05:14:31 record_verified ✓
↑ scroll for full history
─────────────────────
Scroll up = pulling the paper back through the printer. Fast. Pre-rendered. Not retyping. AJAX fetches older events from GET /api/chain/:hash as user scrolls up. Infinite scroll upward, most recent at bottom, oldest at top.
This pattern is identical on web and native iOS app.
Approved footer copy¶
"Your contact details are used to create a verified UCCA record. We respond directly by email."
Modal behaviour¶
- Close button + backdrop + ESC close when not mid-sequence
- After submit: close button hidden, modal uncloseable, submitting flag blocks all close handlers
- Full-page takeover breaks out of modal for teletype + tractor feed
Surfaces wired¶
- ucca.online — modal mode (replaces existing /api/contact email handler)
- ir.ucca.online — page mode (reskin only, endpoint unchanged)
The Onboarding Insight¶
UCCA invented a new onboarding category. Not "create an account." Not "sign up."
You contacted us. We verified you. You're onboarded.
The chain starts the moment someone fills in the contact form. There is no separate signup step. There is no password. The teletype sequence isn't decoration — it's the moment the person realises they didn't sign up for a SaaS tool. They entered a verified record.
Pitch language: "They contact us. We verify them. They're onboarded. There's no login page because there's no account to create. There's a chain record. It starts the moment they reach out."
Auth Model (brief not yet written — pending)¶
No email/password anywhere in the stack. Ever.
| Context | Method |
|---|---|
| Mobile | UCCA Authenticator + Face ID |
| Web browser | Passkey — WebAuthn, local biometrics |
| No smartphone | SMS OTP via Twilio |
| Landline / no mobile | Voice OTP via Twilio (reads code aloud) |
| Third party verifying | QR scan → keys.ucca.online → chain confirmed |
Passkey sync¶
- Apple ecosystem: iCloud Keychain syncs passkey across iPhone, Mac, iPad automatically
- Google ecosystem: Google Password Manager syncs across Android + Chrome on any OS
- Cross-platform: iPhone passkey works on Windows via QR code + Bluetooth proximity — phone is the key
- Windows only: Windows Hello, passkey stays local
Login button¶
Copy: "My record →" — not "Log in", not "Sign in" Placement: Nav on ucca.online, ir, vcc — lock screens on trust Current state: Placeholder only — shows "Verification coming soon. If you're already registered your record is safe." Wired: When auth brief is built and deployed — one pass across all surfaces
Endpoints needed (not yet built)¶
POST /api/auth/register-passkey
POST /api/auth/verify-passkey
POST /api/auth/otp/send — 'sms' or 'voice'
POST /api/auth/otp/verify
POST /api/push/register
POST /api/push/send
DB tables needed (not yet in engine-db)¶
CREATE TABLE passkey_credentials (
id TEXT PRIMARY KEY,
contact_hash TEXT NOT NULL,
credential_id TEXT NOT NULL,
public_key TEXT NOT NULL,
sign_count INTEGER DEFAULT 0,
created_at INTEGER NOT NULL,
last_used INTEGER
);
CREATE TABLE otp_codes (
id TEXT PRIMARY KEY,
contact_hash TEXT NOT NULL,
code TEXT NOT NULL, -- hashed, never stored plain
method TEXT NOT NULL, -- 'sms' or 'voice'
expires_at INTEGER NOT NULL,
used INTEGER DEFAULT 0
);
CREATE TABLE device_tokens (
id TEXT PRIMARY KEY,
contact_hash TEXT NOT NULL,
platform TEXT NOT NULL, -- 'ios' or 'android'
token TEXT NOT NULL,
created_at INTEGER NOT NULL,
last_seen INTEGER
);
Push Notifications (brief not yet written — pending)¶
What needs to exist¶
- APNs .p8 key — Tim generates in Apple Developer portal (Keys → +). Download once, gone if missed.
- APNs Key ID — 10-char string shown at creation
- Bundle ID — e.g.
online.ucca.authenticator - Firebase project + google-services.json + FCM server key (Android)
device_tokenstable in engine-db (schema above)POST /api/push/registerandPOST /api/push/sendon ucca-api
Chain events that trigger push¶
email_confirmed→ "Email verified ✓"k2_delivered→ "Your key has been delivered"record_verified→ "Your record was just verified"document_viewed→ "Your compliance record was accessed" (Level 3+ only)access_requested→ ops console alert
Tractor feed + push (native app)¶
Push notification arrives → new chain event row types in at bottom of tractor feed, character by character. Pull up → older events load instantly, pre-rendered. Same teletype language as web.
Cloudflare note¶
APNs requires HTTP/2. Cloudflare Workers support fetch() to api.push.apple.com natively. FCM is standard REST. Both work from Workers without special setup.
Twilio voice OTP note¶
Check if existing Twilio number has voice capability enabled. If not — quick upgrade in Twilio console, same number.
iOS Authenticator¶
Repo: uccaonline/ucca-authenticator (private)
Team ID: B29TSCBPHD
Entity: UCCA Inc (formerly United Community Colleges of America Inc) — name change may need updating with Apple
Nav structure (pending brief)¶
- Tab 1: Chains — dark cards per chain (name, short hash, trust level, last event)
- Tab 2: Scan — QR scanner for third-party verification
- Tab 3: Notifications — list
- Tab 4: Settings — display toggle, biometrics, K2 management, about
Chain view = tractor feed¶
Last 5 events on load. Pull up = tractor feed scrolling back through history, fast, pre-rendered. New events type in at bottom when push notification arrives.
trust.ucca.online Step 2 (brief written, not started)¶
See: Brief-trust.ucca.online-Step2.md
Covers: - ucca-trust Worker — access control, document hash verification - Document hashing — SHA-256 per doc, stored in engine-db, QR on every page - Chain events — document_viewed, document_downloaded, document_printed, document_verified, access_requested - Print CSS — legal block, hash, QR, tractor feed disclaimer on every printed doc - Intent declaration — Level 1 → 2 gate - Trust levels 1–4 — 13 data governance docs (stubs, awaiting lawyer review before public)
Blocked on: Lawyer review of Level 0 legal docs before opening data governance to real users.
Infrastructure Map (brief written, pending)¶
See: Brief-infra-map-ops.md
- New endpoint on ucca-api:
GET /api/infra/map - Uses existing MCP credentials — no new CF token needed
- Ops console Infrastructure world block — live map, clickable nodes, detail drawer
- PAT warning banner: GitHub PAT
ucca-engine-push— CHECK EXPIRY (was March 26 2026)
Style Manual¶
File: STYLE_MANUAL.md at repo root (Alex to create as part of contact form build)
Contact Form (canonical)¶
One component. One appearance. One function. - Appearance: ucca.online dark treatment - Function: VCC chain generation via POST /api/ir/register - No lite version. No email-only submission. No anonymous enquiry. - Post-submit: always the full teletype + tractor feed sequence
Pending Briefs (in priority order)¶
| Brief | Status | Blocker |
|---|---|---|
| Contact form — add tractor feed to module | Add to current Alex build | None — tell Alex now |
| "My record →" button placeholders | Tell Alex after contact form ships | None |
| Auth — passkey + SMS OTP + voice OTP | Write brief | None |
| Push notifications — APNs + FCM | Write brief | Tim must generate APNs .p8 key first |
| Infra map ops console | Brief written | None — Alex picks up after contact form |
| trust Step 2 — Worker + hashing + chain events | Brief written | Lawyer review for data governance docs |
| iOS Authenticator nav + tractor feed | Write brief | None |
Key Credentials & Infrastructure¶
- Engine-db:
0efa8970-0053-4623-8436-4e877af10887 - Ops-db:
00daba3d-2d65-4ae2-b85a-e56d25ec2b02 - RTOpacks-db:
334ac8fb-9850-48c0-9da0-b56c55640e98 - R2: ucca-ir-assets (photos/{hash}.enc), rtopacks-media, rtopacks-output, ucca-terraform-state
- CF Account:
e5a9830215a8d88961dc6c80a8c7442a - Apple Team ID:
B29TSCBPHD - GitHub PAT:
ucca-engine-push— CHECK EXPIRY - Twilio: in stack for SMS K2 delivery — check voice capability on existing number
- Cloudflare Turnstile: needs site key + secret key from CF dashboard for ucca.online
Three Primes (UCCA interaction primitives)¶
- We don't lie to make a sale
- We know our shape
- No means no. But we remember yes.