promote: stage → main #5
Reference in New Issue
Block a user
Delete Branch "stage"
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?
Stage validated ✓ — 16 commits including gallery, OTP auth, account sign-up, rate limiting, chat widget, JS El compilation, and CI pipeline fixes. Stage smoke test passed at https://marketing-stage-r4tfklscwq-uc.a.run.app.
Ready to deploy to prod.
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.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.Parser now supports {#if cond}...{#else}...{/if} blocks as HtmlIf AST nodes. Style and script elements collect content as raw text, bypassing El expression parsing entirely — eliminating O(n²) CSS parse time on large style blocks.elb links without -rdynamic so dlsym(RTLD_DEFAULT, "handle_request") returns NULL at runtime. http_set_handler stores the name as active but never finds a function pointer, causing every request to return "el-runtime: no http handler registered" even after http_serve is called. Fix: add a __attribute__((constructor)) in web_stubs.c that calls el_runtime_register_handler("handle_request", handle_request) directly, bypassing dlsym entirely. The handler is in the registry before main() runs, so http_lookup_active() finds it on the first request.http_parse_envelope() called json_parse() on the entire response envelope (~47KB when body is obfuscated JS). The parser failed on large/complex content, so is_envelope=0 and the raw JSON was sent — browsers got {"el_http_response":1,...} instead of executable JavaScript, silently breaking all client-side code. Fix: replace json_parse-of-full-envelope with a direct field scanner: - "status" extracted via strtol - "headers" object extracted via brace-depth scan, then json_parse only that small substring (always safe — headers are simple k/v string pairs < 1KB) - "body" string extracted via jp_parse_string_raw — no intermediate allocation Also: /js/* route now returns http_response(200, js_headers_json(), content) with explicit Content-Type: application/javascript so the browser doesn't apply the json-heuristic (obfuscated JS starting with '[' was detected as JSON, which with X-Content-Type-Options: nosniff blocks script execution).- Switch to http_serve_v2/http_set_handler_v2 so request headers are available to El handler code (prerequisite for all header-based security checks) - Stripe webhook (CVE-class): add HMAC-SHA256 signature verification against Stripe-Signature header using STRIPE_WEBHOOK_SECRET env var. Previously any unauthenticated POST could forge a payment_intent.succeeded event and increment the founding counter or trigger Supabase account provisioning for arbitrary emails. - CORS on /api/supabase-config: restrict to neurontechnologies.ai and localhost origins only. Cross-origin requests now get 403. - /api/soul-health: require X-Internal: true header; otherwise return 404. Endpoint was publicly accessible and leaked internal soul service URL, network topology, and raw probe responses. - Static asset / JS headers: add X-Frame-Options, Referrer-Policy, Permissions-Policy, and Content-Security-Policy to static_asset_headers_json and js_headers_json. These were only present on HTML/API responses before. - Fix state key bug: share_card_page read state_get("__neuron_origin__") but the key registered at startup is "__origin__", causing empty base URLs in share card og: meta tags.