smoke-handler's celiloGet returns "key = value", so every post-deploy smoke URL is malformed #58
Labels
No labels
area/auth
area/backend
area/ci
area/deploy
area/e2e
area/frontend
area/shared
blocked
good-first-issue
needs-info
priority/high
priority/low
priority/medium
type/bug
type/chore
type/docs
type/feature
type/tech-debt
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
celilo/lunacycle#58
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
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?
celiloGet()incelilo/scripts/smoke-handler.ts:146-162shells out tocelilo module config get <module> <key>and treats stdout as the bare value. It is not.celilo module config getreturns`${key} = ${formatted}`(apps/celilo/src/cli/commands/module-config.ts:365in the celilo repo), and it never setsrawOutput: true.Verified against the live fleet just now:
So every value the handler reads carries a
key =prefix, and every URL built from one is garbage:domain→"domain = lunacycle.net"wwwHost=`www.${domain}`→"www.domain = lunacycle.net"authentikUrl→"idp_base_url = https://auth.lunacycle.net"The first
fetch()—mintAccessToken— then fails withfetch() URL is invalid, which is the error recorded against thelunacycle.smoke-after-deploybus subscriber.Two things that hide it
The guard is defeated by the format it was meant to catch.
if (!domain) throw new Error('lunacycle smoke: domain not configured …')exists to fail loudly on missing config — but"domain = lunacycle.net"is truthy, so it passes and the failure surfaces much later as an unrelated-looking fetch error.stripCliDecorationdoes not help and its comment says why it should. It only strips ANSI escapes (if (!raw.includes('\x1b')) return raw;) and does nothing about thekey =prefix. Its comment reasons: "As a child ofbun /path/handler.ts, stdout is a pipe → rawOutput-mode commands write the raw value." Two problems —module config getis not a rawOutput command, and per celilo'scli/index.ts:2568,rawOutput"no longer selects a different destination" anyway.Blast radius: the post-deploy smoke has never run
celilo events list-failedshows 8 failed deliveries forlunacycle.smoke-after-deploy, most recent from tonight's 1.4.0+1 deploy. It only fires ondeploy.completed.lunacycle, so 8 failures is plausibly every deploy it has ever seen.Critically, this is invisible from the health side: the 15-minute
health_checkhook is a different code path that receives config through injected deps rather than shelling out, and it passes (smoke_spa: SPA fetched data and rendered (tRPC 200, 6 /api requests, 5404ms)). So the fleet looks healthy while the post-deploy smoke has silently never executed — the failure lives only in the event bus's failed-delivery table.Scope
celilo/scripts/smoke-handler.ts:146-162—celiloGet().:164-171—stripCliDecoration(); its stated premise about rawOutput is wrong and the comment should go with the fix.:58(domain),:81(idp_base_url), and thebotPasswordsecret read — check whethercelilo module secret gethas the same shape.wwwHost,authentikUrl,redirectUri, and the API/WS smoke targets.Acceptance
celiloGetreturns the value only, parsing the documentedkey = valueshape (or uses a machine-readable mode if celilo grows one) — and does not silently accept a value it failed to parse.!domainguard actually catches malformed config.celilo module secret get's output shape is confirmed rather than assumed.celiloGet's parser the real"idp_base_url = https://auth.lunacycle.net"string and asserting it yieldshttps://auth.lunacycle.net. Prove it fails against the current implementation first — it currently returns the whole line.lunacycle.smoke-after-deployrecords a success, not a failed delivery.Related
module config get— that would remove the parsing entirely rather than making this handler better at guessing.