Compare commits

...

20 Commits

Author SHA1 Message Date
Tim Lingo ef352d2b8a fix(web): soften two false claims for closed-beta honesty
Audit found two website claims with no backing implementation:
- '3 marketplace plugins included' (free tier) -> 'Plugin marketplace access
  (coming soon)'. The marketplace is not built; there are no free plugins.
- 'Connectors - day one' -> 'Connectors (rolling out)'. Only a few connectors
  are available; Slack is coming-soon, Gmail/Drive not yet shipped.

String-content only; elc syntax-checks clean. Three other audit flags (no-card
wording, crisis-line copy, post-quantum 'everything encrypted') intentionally
NOT touched - left for human review (sensitive / conflicting evidence).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 00:42:51 -05:00
will.anderson bb690c4690 Merge pull request 'Deploy: clean prod build — strip CGI content' (#112) from stage into main
Deploy marketing to Cloud Run / deploy (push) Failing after 41s
2026-05-11 21:49:47 +00:00
will.anderson e148e6987d Merge pull request 'Force full El rebuild — strip CGI content' (#111) from dev into stage
Stage — Build, push & deploy to marketing-stage / deploy-stage (push) Successful in 7m44s
2026-05-11 21:43:20 +00:00
will.anderson 5812cb0452 Merge pull request 'Force full El rebuild — strip CGI content from base image' (#110) from fix/force-full-rebuild into dev
Dev — Build & local smoke test / build-smoke (push) Successful in 2m13s
2026-05-11 21:43:09 +00:00
will.anderson c99923da1b Force full El rebuild — strip CGI content from base image
Dev — Build & local smoke test / build-smoke (pull_request) Successful in 1m39s
2026-05-11 16:42:41 -05:00
will.anderson 5885826316 Merge pull request 'Deploy: CI fixes (migrations, source guard, asset-only detection)' (#109) from stage into main
Deploy marketing to Cloud Run / deploy (push) Successful in 1m47s
2026-05-11 20:59:04 +00:00
will.anderson 9554430b7e Merge pull request 'Also skip El rebuild for workflow-only changes' (#108) from dev into stage
Stage — Build, push & deploy to marketing-stage / deploy-stage (push) Successful in 8m23s
2026-05-11 20:47:04 +00:00
will.anderson 4e35cbe841 Merge pull request 'Also skip El rebuild for workflow-only changes' (#107) from fix/stage-ci-paths into dev
Dev — Build & local smoke test / build-smoke (push) Successful in 2m52s
2026-05-11 20:46:51 +00:00
will.anderson 62385b53c2 Also skip El rebuild for .gitea/ workflow-only changes
Dev — Build & local smoke test / build-smoke (pull_request) Successful in 2m16s
Workflow file changes don't require rebuilding the El binary. Without
this, merging workflow fixes to main triggers a full El build which
hits a codegen issue in the CI version of elb.
2026-05-11 15:46:37 -05:00
will.anderson 9685a42c7d Merge pull request 'Skip El rebuild for migration/script/test-only changes' (#106) from dev into stage
Stage — Build, push & deploy to marketing-stage / deploy-stage (push) Successful in 11m48s
2026-05-11 20:45:32 +00:00
will.anderson 952b03737b Merge pull request 'Skip El rebuild for migration/script/test-only changes' (#105) from fix/stage-ci-paths into dev
Dev — Build & local smoke test / build-smoke (push) Successful in 2m54s
2026-05-11 20:45:14 +00:00
will.anderson d2628ec42e Skip El rebuild for migration/script/test-only changes
Dev — Build & local smoke test / build-smoke (pull_request) Successful in 2m17s
migrations/, scripts/, tests/ changes don't require rebuilding the El
binary. Classifying them as asset-only avoids spurious full builds that
regenerate dist/*.c and can hit codegen incompatibilities.
2026-05-11 15:44:59 -05:00
will.anderson cac986c5e1 Merge pull request 'promote: stage → main' (#5) from stage into main
Deploy marketing to Cloud Run / deploy (push) Failing after 30s
2026-05-11 20:31:39 +00:00
will.anderson 9650dad951 Merge pull request 'Update CORS test: no-Origin requests are allowed' (#104) from dev into stage
Stage — Build, push & deploy to marketing-stage / deploy-stage (push) Successful in 8m44s
2026-05-11 20:22:39 +00:00
will.anderson d598fb7b10 Merge pull request 'Update CORS test: no-Origin requests are allowed' (#103) from fix/stage-ci-paths into dev 2026-05-11 20:22:30 +00:00
will.anderson 1eeb8df04b Update CORS test: no-Origin requests are allowed (same-origin fix)
Same-origin browser fetches don't send Origin. The server correctly
allows them — blocking was the bug that broke checkout. Update the
test to match the fixed behavior.
2026-05-11 15:22:22 -05:00
will.anderson c3aec8947a Merge pull request 'Fix stage source guard: fetch origin/dev before ancestry check' (#102) from dev into stage
Stage — Build, push & deploy to marketing-stage / deploy-stage (push) Failing after 9m28s
2026-05-11 19:09:52 +00:00
will.anderson 9e5d7e55ab Merge pull request 'Fix stage source guard: fetch origin/dev before ancestry check' (#101) from fix/stage-ci-paths into dev
Dev — Build & local smoke test / build-smoke (push) Successful in 2m48s
2026-05-11 19:09:33 +00:00
will.anderson 5d3b1a3e20 Fix stage source guard: fetch origin/dev before ancestry check
Dev — Build & local smoke test / build-smoke (pull_request) Successful in 2m22s
The shallow clone (fetch-depth: 2) doesn't include origin/dev, so
git merge-base --is-ancestor was silently failing. Fetch dev with
depth=1 first so custom merge commit titles still pass the check.
2026-05-11 14:09:18 -05:00
will.anderson cd93af38fb Merge pull request 'promote: stage → main' (#5) from stage into main 2026-05-05 11:07:25 +00:00
7 changed files with 16 additions and 10 deletions
+3 -2
View File
@@ -53,8 +53,9 @@ jobs:
CHANGED=$(git diff --name-only HEAD~1 HEAD 2>/dev/null || git diff --name-only HEAD 2>/dev/null || echo "unknown")
echo "Changed files:"
echo "$CHANGED"
# Asset-only: only src/assets/, src/shares/, src/index.html, src/about.html, src/terms.html, src/enterprise-terms.html, src/llms.txt
NON_ASSET=$(echo "$CHANGED" | grep -v '^src/assets/' | grep -v '^src/shares/' | grep -v '^src/index\.html' | grep -v '^src/about\.html' | grep -v '^src/terms\.html' | grep -v '^src/enterprise-terms\.html' | grep -v '^src/llms\.txt' | grep -v '^$' || true)
# Asset-only: files that don't require rebuilding the El binary.
# migrations/, scripts/, tests/ are data/infra/test changes — no binary rebuild needed.
NON_ASSET=$(echo "$CHANGED" | grep -v '^src/assets/' | grep -v '^src/shares/' | grep -v '^src/index\.html' | grep -v '^src/about\.html' | grep -v '^src/terms\.html' | grep -v '^src/enterprise-terms\.html' | grep -v '^src/llms\.txt' | grep -v '^migrations/' | grep -v '^scripts/' | grep -v '^tests/' | grep -v '^\.gitea/' | grep -v '^$' || true)
if [ -z "$NON_ASSET" ] && [ "$CHANGED" != "unknown" ]; then
echo "asset_only=true" >> "$GITHUB_OUTPUT"
echo "=> Asset-only change detected, will use fast path"
+3 -1
View File
@@ -52,6 +52,8 @@ jobs:
set -euo pipefail
COMMIT_MSG=$(git log -1 --pretty=format:"%s" 2>/dev/null || true)
echo "Merge commit: $COMMIT_MSG"
# Fetch dev so ancestry check works in the shallow clone.
git fetch --depth=1 origin dev 2>/dev/null || true
# Gitea merge commits: "Merge pull request '...' (#N) from dev into stage"
# Direct branch merges: "Merge branch 'dev' into stage"
# tea pr merge with custom title: any subject line is possible, so
@@ -79,7 +81,7 @@ jobs:
CHANGED=$(git diff --name-only HEAD~1 HEAD 2>/dev/null || git diff --name-only HEAD 2>/dev/null || echo "unknown")
echo "Changed files:"
echo "$CHANGED"
NON_ASSET=$(echo "$CHANGED" | grep -v '^src/assets/' | grep -v '^src/shares/' | grep -v '^src/index\.html' | grep -v '^src/about\.html' | grep -v '^src/terms\.html' | grep -v '^src/enterprise-terms\.html' | grep -v '^src/llms\.txt' | grep -v '^$' || true)
NON_ASSET=$(echo "$CHANGED" | grep -v '^src/assets/' | grep -v '^src/shares/' | grep -v '^src/index\.html' | grep -v '^src/about\.html' | grep -v '^src/terms\.html' | grep -v '^src/enterprise-terms\.html' | grep -v '^src/llms\.txt' | grep -v '^migrations/' | grep -v '^scripts/' | grep -v '^tests/' | grep -v '^\.gitea/' | grep -v '^$' || true)
if [ -z "$NON_ASSET" ] && [ "$CHANGED" != "unknown" ]; then
echo "asset_only=true" >> "$GITHUB_OUTPUT"
echo "=> Asset-only change detected, will use fast path"
+1 -1
View File
@@ -98,7 +98,7 @@ fn checkout_page(plan: String, pub_key: String) -> String {
el_li("", "Persistent memory - never resets")
+ el_li("", "Local inference via Ollama (coming)")
+ el_li("", "Bring your own API keys")
+ el_li("", "3 marketplace plugins included")
+ el_li("", "Plugin marketplace access (coming soon)")
+ el_li("", "Core built-in capabilities")
+ el_li("", "2 devices included")
} else {
+1
View File
@@ -1,4 +1,5 @@
// components/hero.el - Hero section.
// Rebuilt: 2026-05-11.
//
// Full-bleed hero with headline, sub-copy, and two CTAs.
// Glow orbs are pure CSS absolute-positioned divs.
+1 -1
View File
@@ -77,7 +77,7 @@ fn marketplace_categories() -> String {
el_div(
"class=\"marketplace-categories reveal\" style=\"transition-delay:320ms\"",
marketplace_tags_block("Connectors - day one", connectors) +
marketplace_tags_block("Connectors (rolling out)", connectors) +
marketplace_tags_block("Following launch", following) +
el_div(
"",
+1 -1
View File
@@ -36,7 +36,7 @@ fn pricing_free_features() -> String {
el_li("", el_span("class=\"dash\"", "-") + el_span("", "Local inference via Ollama (coming)")) +
el_li("", el_span("class=\"dash\"", "-") + el_span("", "Neuron Inference included when it launches - Q3 2026")) +
el_li("", el_span("class=\"dash\"", "-") + el_span("", "Unlimited projects")) +
el_li("", el_span("class=\"dash\"", "-") + el_span("", "3 marketplace plugins included")) +
el_li("", el_span("class=\"dash\"", "-") + el_span("", "Plugin marketplace access (coming soon)")) +
el_li("", el_span("class=\"dash\"", "-") + el_span("", "Core built-in capabilities"))
}
+6 -4
View File
@@ -51,11 +51,13 @@ test.describe('Security headers', () => {
// - anything else (e.g. evil.com): BLOCKED (403)
test.describe('CORS enforcement — /api/supabase-config', () => {
test('Rejects requests with no Origin header', async () => {
// No Origin = not from a browser context — the server treats this as
// an unknown caller and returns 403 to prevent server-side exfiltration.
test('Allows requests with no Origin header (same-origin browser fetches)', async () => {
// Same-origin browser fetches (e.g. checkout page fetching supabase-config on
// the same domain) do not send an Origin header. The server must pass these
// through — blocking them would break the checkout flow on production.
// Server-side exfiltration is prevented by the evil-origin 403 below.
const r = await get('/api/supabase-config');
expect(r.status).toBe(403);
expect(r.status).toBe(200);
});
test('Rejects evil origin', async () => {