Commit Graph

126 Commits

Author SHA1 Message Date
will.anderson 067c83f8ff ci: retrigger — ci-base:latest rebuilt with fresh El SDK
Dev — Build & local smoke test / build-smoke (pull_request) Failing after 24s
2026-05-07 09:32:47 -05:00
will.anderson 5f35ddde39 feat(demo): header countdown switches to reset timer when questions exhausted
Dev — Build & local smoke test / build-smoke (pull_request) Failing after 8s
When a user hits the 10-question limit, the header countdown flips from
'0 questions left' to a live 'resets in HH:MM:SS' ticker counting to
midnight UTC. Clears automatically when the session resets.
2026-05-07 02:49:11 -05:00
will.anderson e6d10fc3d5 fix(demo): remove 'launch night' from opening greeting — no longer accurate
Dev — Build & local smoke test / build-smoke (pull_request) Failing after 44s
2026-05-07 02:36:10 -05:00
will.anderson 7c4c0d9963 feat(demo): server-side 8000-char (~2000 token) input limit on /api/demo
Dev — Build & local smoke test / build-smoke (pull_request) Failing after 45s
2026-05-07 02:35:29 -05:00
will.anderson aedb14f86c ci: commit dev.yaml with elb + ci-base approach (was written but not staged)
Dev — Build & local smoke test / build-smoke (pull_request) Failing after 45s
2026-05-07 02:35:02 -05:00
will.anderson c24b9b179b feat(demo): cap chat input at 8000 chars (~2000 tokens) 2026-05-07 02:33:36 -05:00
will.anderson 3e377e2bb6 ci: replace build-stage.sh concatenation with elb build from ci-base
- stage.yaml and deploy.yaml now extract El SDK from ci-base (docker cp /opt/el) and run elb build to produce dist/neuron-landing
- JS El sources compiled via elc --target=js in a dedicated step, matching dev.yaml exactly
- build-stage.sh replaced with thin elb wrapper for local dev use
- Removes the broken "Set up El SDK" stub (echo EL_HOME) and old build-stage.sh invocation from both workflows
2026-05-07 01:55:08 -05:00
will.anderson 9e77c3cbf0 Merge pull request 'Enforce dev-only source on stage' (#12) from fix/stage-source-enforcement into dev
Dev — Build & local smoke test / build-smoke (push) Failing after 17m6s
2026-05-07 06:09:40 +00:00
will.anderson 042b9b2b2f Enforce dev-only source on stage — reject PRs from non-dev branches 2026-05-07 01:07:20 -05:00
will.anderson fef846e6f5 Merge pull request 'Sync stage fixes into dev' (#11) from sync/dev-stage into dev
Dev — Build & local smoke test / build-smoke (push) Waiting to run
2026-05-07 06:05:52 +00:00
will.anderson 494f4ef585 Merge stage fixes into dev — HAVE_CURL, free-tier checkout, Stripe dedup, escaped styles 2026-05-07 01:05:36 -05:00
will.anderson e68de7892f Merge pull request 'Fix free tier checkout and Stripe duplicate customers' (#10) from fix/have-curl-define into stage
Stage — Build, push & deploy to marketing-stage / deploy-stage (push) Successful in 3m41s
2026-05-07 06:01:02 +00:00
will.anderson 00e62bb010 Fix free tier checkout and Stripe duplicate customers
Free tier:
- checkout-stripe.el bails out immediately for plan=free (no Stripe init)
- checkout-auth.el skips payment section reveal and initStripe for free plan
- checkout-free.el shows #free-success panel after auth (no card ever shown)
- /api/payment-intent returns early for free plan — no Stripe call

Stripe dedup (all paid plans):
- Stripe init now deferred to window.initStripe(email, name), called by
  checkout-auth.el after sign-in — email is known before intent is created
- /api/payment-intent finds-or-creates Stripe Customer by email before
  creating the PaymentIntent/SetupIntent and attaches customer upfront
- Eliminates the window between intent creation and /api/link-customer
  that was producing duplicate guest customers
2026-05-07 01:00:51 -05:00
will.anderson 1cf2ef8835 Merge pull request 'fix: -DHAVE_CURL for el_runtime OTLP — resolves emit_metric linker error' (#8) from fix/have-curl-define into stage
Stage — Build, push & deploy to marketing-stage / deploy-stage (push) Successful in 3m12s
2026-05-07 02:35:32 +00:00
will.anderson f0a6b55a13 fix: add -DHAVE_CURL to el_runtime.c compilation, restore el_runtime.o for soul-demo
Root cause: the staged el_runtime.c (from el.git) wraps the entire OTLP
observability section (emit_metric, emit_log, trace_span_start/end) in
#ifdef HAVE_CURL. Without -DHAVE_CURL, those symbols are compiled out,
causing the undefined reference linker errors.

libcurl IS available (installed via libcurl4-openssl-dev), so -DHAVE_CURL
correctly enables the OTLP code path.

Also reverts the soul-demo compile to use el_runtime.o (the pre-compiled
cached object) now that the object will contain the correct symbols.
2026-05-06 21:35:16 -05:00
will.anderson 843b6e07a7 Merge pull request 'fix: soul-demo emit_metric linker error — rebuild from source, compile with el_runtime.c' (#7) from fix/soul-demo-emit-metric into stage
Stage — Build, push & deploy to marketing-stage / deploy-stage (push) Failing after 2m26s
2026-05-07 02:30:46 +00:00
will.anderson 0202b09d37 fix: rebuild soul-demo.c from source, compile against el_runtime.c directly
soul-demo.c was previously an older compiled artifact that triggered an
undefined reference to emit_metric/emit_log/trace_span_* at link time in CI.

Two fixes:
1. Rebuild soul-demo.c from soul-demo.el using current elc — cleaner
   codegen (no double-wrapped el_from_float), same logic, unix_timestamp
   collision with el_runtime.c removed.
2. Dockerfile.stage: compile soul-demo against el_runtime.c directly
   (not el_runtime.o) so all runtime symbols are always resolved from the
   staged source, bypassing any Docker layer cache divergence on el_runtime.o.
2026-05-06 21:30:25 -05:00
will.anderson f19403ba68 Merge pull request 'fix: security hardening from pentest findings' (#6) from fix/pentest-security-hardening into stage
Stage — Build, push & deploy to marketing-stage / deploy-stage (push) Failing after 2m37s
2026-05-07 02:02:50 +00:00
will.anderson 8d741fac20 Fix pentest security findings
- Turnstile server-side verification: reject requests with no cf_token;
  read secret from TURNSTILE_SECRET_KEY env (no longer hardcoded); fix
  siteverify URL from v0 to v1
- Security headers: wrap all responses via http_response() with HSTS,
  X-Content-Type-Options, X-Frame-Options, Referrer-Policy,
  Permissions-Policy, and Content-Security-Policy
- GCS error info leak: guard /share/<id> response — only return content
  that starts with '<' (valid HTML); GCS error JSON is silently 404d
- robots.txt: remove Sitemap reference to sitemap.xml that returns 404
- SRI hash: add integrity + crossorigin attributes to marked.min.js CDN tag
- Attestations bucket: write /api/attest records to GCS_ATTEST_BUCKET
  (dedicated private bucket) instead of the share bucket; falls back to
  GCS_SHARE_BUCKET if GCS_ATTEST_BUCKET is not set (legacy deploys)
2026-05-06 20:58:29 -05:00
will.anderson d546c9563e ci: pass --elc path explicitly to elb (elc not in container PATH) 2026-05-05 14:52:56 -05:00
will.anderson 486eda8bc5 ci: trigger rebuild with fixed elb/elc (O(n2) memory fix + stderr surface) 2026-05-05 14:46:49 -05:00
will.anderson 92676731cc elb: pass --runtime to locate el_runtime.c in ci-base 2026-05-05 14:08:28 -05:00
will.anderson 83555f5f32 Switch CI from build-stage.sh to elb — no OOM
elb compiles each .el source independently (per-file codegen),
avoiding the exponential memory growth from concatenating all sources
into main-combined.el and feeding it to elc in one shot.

- dev.yaml: replace build-stage.sh with elb build + per-file JS elc
- Dockerfile.stage: COPY dist/neuron-landing (elb binary) directly
  instead of compiling from pre-generated main.c. soul-demo stays as
  cc compilation (small file, no risk).
2026-05-05 13:59:06 -05:00
will.anderson 33fa14935b ci: use pre-installed El SDK from ci-base image
Remove fallback download logic in dev.yaml — El SDK v1.2.1 is now baked
into the ci-base image at /opt/el, so EL_HOME just needs to be pointed there.
2026-05-05 13:13:19 -05:00
will.anderson d2c5370f55 ci: fallback El SDK download if not pre-installed in runner image 2026-05-05 13:05:02 -05:00
will.anderson 3509dda67c ci: use pre-installed El SDK from ci-base image 2026-05-05 12:48:54 -05:00
will.anderson 2854b89e35 ci: restore El SDK v1.2.1 release download (repo clone uses incompatible elc) 2026-05-05 11:33:04 -05:00
will.anderson b5eecc94ff ci: use elc-linux-amd64 from El repo, fix EL_HOME to lang/ across all workflows 2026-05-05 09:45:20 -05:00
will.anderson 46f4be83fd ci: add sudo to apt-get (runner is non-root) 2026-05-05 09:13:18 -05:00
will.anderson aa6c354d58 ci: fix elc link flags (libcurl install + gcc ordering) 2026-05-05 09:09:55 -05:00
will.anderson 14cae0dcb5 ci: compile elc.c from El repo source for linux/amd64 support
The El repo only has a darwin arm64 elc binary. The v1.2.1 linux
binary predates native HTML template syntax. Compile elc.c (the
committed C source of the El compiler) on linux/amd64 in CI to
get a native binary that supports the new syntax.
2026-05-05 09:07:45 -05:00
will.anderson 62f0fc054f ci: clone El repo for native HTML template support
v1.2.1 elc (282KB) cannot compile native HTML template syntax
introduced in feat/native-el-templates. Clone El repo depth=1
to get the latest elc (486KB) that supports it. Set EL_HOME
to lang/ subdir.
2026-05-05 06:45:07 -05:00
will.anderson 6cfd6e4b56 feat: native El HTML templates — remove all HTML string literals
Converts all El source files in src/ from HTML string literals to native
El template syntax. Part of the el rewrite tracked in PR #4.
2026-05-05 11:11:04 +00:00
will.anderson 28c47c11c9 ci: fix EL_HOME to use lang/ subdirectory for El repo clone
El repo is organized under lang/ — runtime and dist/platform binaries
are at lang/el-compiler/runtime/ and lang/dist/platform/, not at root.
Setting EL_HOME=$DEST/lang makes RUNTIME_SRC resolve correctly so
build-stage.sh can cp el_runtime.{c,h,js} from the right location.
2026-05-05 11:01:47 +00:00
will.anderson 9d264cb506 ci: download el_runtime.js from El SDK v1.2.1 release 2026-05-05 10:49:56 +00:00
Will Anderson 5cb13d67f7 feat: convert web El source to native HTML template syntax
Replace all return "..." HTML string literals with native El templates —
removes all \" escapes, converts + interpolations to {expr}/{raw(expr)},
and replaces conditional string concatenation with {#if}/{#else}/{/if}.
No functional changes; output is identical.
2026-05-05 05:21:19 -05:00
will.anderson 1127dcd278 fix(ci): download El SDK from release assets instead of cloning repo 2026-05-05 09:52:51 +00:00
will.anderson 7c8bf444ca fix(ci): ensure dist/platform dir exists before elc download 2026-05-05 09:49:20 +00:00
Will Anderson 8a8762ad4f ci: trigger stage CI after API merge 2026-05-05 04:46:30 -05:00
Will Anderson a936d2ebb7 ci: trigger stage build after API merge 2026-05-05 04:45:07 -05:00
will.anderson c49a838aad Merge pull request 'promote: dev → stage' (#2) from dev into stage
promote: dev to stage
2026-05-05 09:40:51 +00:00
will.anderson 7e72bdd083 Merge pull request 'fix: gallery layout, OTP auth, account sign-up, rate limiting, Google Ads, web demo key' (#1) from fix/gallery-layout-account-otp into dev
fix: gallery layout, OTP auth, rate limiting, Google Ads, web demo key
2026-05-05 09:37:46 +00:00
Will Anderson 70820cf078 feat(chat): IP-keyed daily rate limit (10/day), live reset countdown, web_demo Anthropic key 2026-05-05 04:10:22 -05:00
Will Anderson 9b69783306 Ignore all emitted HTML files via wildcard 2026-05-05 03:52:56 -05:00
Will Anderson 7a3dc94dec Ignore .elh emitted files 2026-05-05 03:52:11 -05:00
Will Anderson 260ea4edaa Remove letter.html 2026-05-05 03:51:30 -05:00
Will Anderson 566cd568b7 Add Google Ads conversion tracking (AW-18140150015) 2026-05-05 03:49:14 -05:00
Will Anderson 94f6e749a0 Add El source files for all client-side JS
Recovers original JS from git history and ports it into proper El source
files under src/js/. Each file wraps the original JS in a native_js call
inside a main() function, making it valid El that compiles to a
self-contained IIFE via elc --target=js --bundle.

Files added:
  src/js/account-auth.el       - Supabase OTP magic-link (sendMagicLink)
  src/js/account-dashboard.el  - Account dashboard: session, plan card, family
  src/js/chat-widget.el        - Demo chat widget (neuronDemoToggle/Send/Reset)
  src/js/checkout-auth.el      - Checkout auth: OAuth, email sign-in/up
  src/js/checkout-free.el      - Free plan: auth-badge watch -> payment reveal
  src/js/checkout-stripe.el    - Stripe Payment Element (reads NEURON_CFG)
  src/js/enterprise.el         - Enterprise inquiry form + headcount filter
  src/js/environmental.el      - Efficiency calculator slider
  src/js/gallery.el            - Gallery nav, search/sort, Supabase voting
  src/js/main.el               - Share page voting + copyForPlatform
  src/js/marketplace.el        - Developer interest form
  src/js/nav.el                - Nav hamburger + Mission dropdown
  src/js/styles.el             - Landing: nav scroll, reveal, founding counter
2026-05-04 11:23:21 -05:00
Will Anderson 246a5f0967 Fix gallery HTML structure bug and replace email auth with OTP flow
Gallery: remove <a> from share allowlist. Gallery cards wrap content in
<a class="gal-link">; allowing <a> in sanitized answer HTML causes nested
anchors that the HTML5 adoption agency algorithm resolves by restructuring
the DOM, producing mismatched </div> tags that leave gallery-grid open and
pull sibling elements into the grid as spurious grid columns.

Account: replace email+password sign-up/sign-in with magic-link OTP.
supabase.auth.signInWithOtp handles both new and existing users in one
flow. Existing onAuthStateChange listener (dadeb8ddb9a8.js) retained for
post-redirect dashboard display. sendMagicLink added to extract-js
RESERVED_GLOBALS so the obfuscator does not mangle the onclick reference.
2026-05-04 10:04:22 -05:00
will.anderson 6075f49e8a Merge pull request 'feat(account): email/password sign-up on account page' (#2) from dev into stage
Stage — Build, push & deploy to marketing-stage / deploy-stage (push) Successful in 2m47s
2026-05-04 14:05:04 +00:00