Skip to content

Add beta feedback capture: "Send feedback" + /feedback -> capture worker#153

Merged
dannon merged 7 commits into
galaxyproject:mainfrom
dannon:feedback-beta-capture
Jun 2, 2026
Merged

Add beta feedback capture: "Send feedback" + /feedback -> capture worker#153
dannon merged 7 commits into
galaxyproject:mainfrom
dannon:feedback-beta-capture

Conversation

@dannon
Copy link
Copy Markdown
Member

@dannon dannon commented Jun 2, 2026

What this does

For the beta we want to actually capture feedback into a store we own, instead of leaning on the high-friction public-GitHub-issue path. This reworks the existing "Report an issue" flow and adds a brain command:

  • Orbit "Send feedback" modal (was "Report an issue"): posts a structured payload to a private capture endpoint. Both "include system info" and "include logs" now default ON -- the destination is a private store, not a public issue. If the POST fails it falls back to the old pre-filled GitHub issue, but text-only, never the auto-collected diagnostics, so default-on logs can't land on a public issue.
  • /feedback in the Loom brain: an always-on command that captures a title + body inline via ctx.ui (Orbit and the CLI alike), guarded on hasUI. On a failed POST it appends the payload to a local outbox so nothing is lost.
  • Shared feedback-contract: one payload type + validator + wire constants that the brain, Orbit main, and the worker all bind to.

The endpoint is a small companion Cloudflare Worker + D1 (separate repo: https://github.com/dannon/orbit-feedback): POST /feedback validates, caps body size, rate-limits per hashed IP, and stores a row; GET /admin/feedback is Basic-auth'd.

Notable details

  • Fixes a latent bug in the old report code: it read llm.provider/llm.model, which don't exist on the masked config shape, so sysinfo always showed (none)/(none). Now reads llm.active + providers[active].model.
  • The activity tail is summarized to one line per event (timestamp/kind/source) -- never raw payloads. Sysinfo carries no API keys, credentials, or cwd. The endpoint URL and any key live in Orbit's main process only; the renderer just calls submitFeedback.

Deployment

The companion worker is deployed (Cloudflare Worker + D1) and FEEDBACK_ENDPOINT_URL is wired to it; a live POST round-trips and lands a row in D1. Local dev still overrides the base via LOOM_FEEDBACK_URL against wrangler dev.

Testing

Root suite green (new contract/helper/command tests); brain and Orbit typecheck clean; the worker has its own tests (payload validation, size cap, rate-limit 429, admin auth, bad JSON).

dannon added 7 commits June 2, 2026 01:07
…worker all bind to.

Dual-file (.js + .d.ts) like team-dispatch-contract so the brain resolves a real
runtime file. Holds the payload shape, the validator, and the wire constants
(route, key header, schema version, endpoint base).
POSTs a FeedbackPayload to the capture worker with global fetch, plus an activity
summarizer (timestamp+kind+source only -- never raw payloads) and a brain sysinfo
builder (node/platform/arch + active llm + galaxy-configured, no secrets).
Gathers a title + body inline via ctx.ui and POSTs through the submit helper,
cross-shell in Orbit and the CLI. Guards on ctx.hasUI so it never sends an empty
payload in non-interactive mode, and offers an opt-in to attach diagnostics. The
brain can't open Orbit's HTML modal, so this is its own capture path.
Main posts the payload to the orbit-feedback worker with Electron net.fetch
(endpoint URL + any secret live in main only, like the existing hard-coded
GitHub/releases URLs), and preload bridges it as window.orbit.submitFeedback so
the renderer never holds the endpoint.
Submit now POSTs the structured payload to the private capture store and only
falls back to a public GitHub issue (text-only, no diagnostics) when that POST
fails. Both include boxes default on for the beta. Drops the buggy flat llm
provider/model read -- the masked config exposes llm.active + providers[active]
-- and fixes the disclosure copy that claimed 30/150 lines when the code sends
15 events / 80 lines.
/feedback now stamps the app version on every loom-cli row (so beta triage can
filter by build even when diagnostics are declined), and on a failed POST it
appends the payload to a local feedback-outbox.jsonl instead of dropping it --
the brain had no fallback where Orbit falls back to a GitHub issue. The brain
fetch also gets the same 10s timeout the Orbit side already had. Adds the missing
tests: the outbox/error-notify branch, the appVersion-on-decline path, and the
contract's schemaVersion/body/clientTs rejection cases.
orbit-feedback is live at orbit-feedback.dannon-baker.workers.dev (CF Worker +
D1); this swaps the placeholder so production posts land in the store. Local dev
still overrides via LOOM_FEEDBACK_URL.
@dannon dannon merged commit ded1b58 into galaxyproject:main Jun 2, 2026
3 checks passed
@dannon dannon deleted the feedback-beta-capture branch June 2, 2026 12:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant