Skip to content

feat: route feedback to the server FlyBot Lead and complete the triage loop - #816

Merged
HugoXK merged 4 commits into
feat/796-feedback-error-reportfrom
feat/814-feedback-lead
Nov 15, 2026
Merged

HugoXK merged 4 commits into
feat/796-feedback-error-reportfrom
feat/814-feedback-lead

Conversation

@HugoXK

@HugoXK HugoXK commented Nov 15, 2026 •

Copy link
Copy Markdown
Owner

Written-by: HugoXK

What changed

  • Routes new feedback/error reports to the server FlyBot's Fledge Lead using either a repo already connected to Fledge (FLEDGE_LEAD_REPO_ID → instances.sendGuidance(repoId, 'lead', packet)) or an external bridge (FLEDGE_LEAD_BRIDGE_URL/TOKEN/SESSION_ID → bridge /dsh send). A missing/unreachable Lead never fails the user's submission; the record and maintainer mail remain.
  • Per-ref triage token and API: GET /api/feedback/:ref and POST /api/feedback/:ref/triage accept Authorization: Bearer HMAC(SESSION_SECRET, "feedback-triage:<ref>"). The Lead can read the redacted record and write a decision, message, public summary, issue/PR URL and fixed_version.
  • Lifecycle: feedback_triage + feedback_events record new, user_error, duplicate, needs_info, confirmed, issue_opened, pr_opened, fixed, wontfix, and system released. Each transition is audited and notifies the signed-in reporter in-app and by mail.
  • Fixed and released notices: when the running VERSION reaches fixed_version, the reporter gets one “fixed in vX” notice with the issue/PR links; the startup scan then marks the record released and sends the final “now live in vX” notice once.
  • Public issue privacy: Fledge does not create the public issue. The Lead creates a sanitized issue and records its URL. A separate optional publication consent on the feedback form (and for signed-in error reports) controls whether the issue may @ the reporter; raw message, stack, email and token are never published by Fledge.

FLEDGE_LEAD_REPO_ID, the bridge trio, FEEDBACK_PUBLIC_REPO, and the triage flow are documented in docs/deploy.md, docs/architecture.md, docs/security.md and docs/secrets.md.

Fixes #814

Large-PR: the triage lifecycle adds the API, migrations, notifications, bounded delivery retries, config, docs and tests across 19 files; review src/feedback/, src/app.ts and src/db.ts rather than the generated config rows.

Verification

Ran:

  • npm run check — pass (2052 tests, typecheck, build)
  • npx tsx --test test/feedbackLead.test.ts — 6/6 pass
  • node scripts/changelog.mjs check — 48 fragments ok
  • node scripts/version.mjs check — 0.3.6 ok

Not run:

  • A live FlyBot Lead/repo send or external bridge
  • Production deploy
  • Real SMTP delivery

Security notes

The triage token is per ref, delivered only through the private Lead packet, and grants read/write for that record only. The public issue is created by the Lead after separate publication consent; Fledge never publishes raw feedback, error stack, email or token. The bridge token is a secret documented in docs/secrets.md.

Dependency

This PR is stacked on #797 (feat/796-feedback-error-report). Merge #797 first; this branch will then target main. Issue #814 is needs-review and remains unclaimed pending its Issue-review PASS.

@HugoXK-bot HugoXK-bot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verdict: PASS at 52edfe2
Written-by: HugoXK-bot
Posted-by: HugoXK-bot

This PR is stacked on #797's branch (base.ref is feat/796-feedback-error-report at a02540d3), so I read the 19-file delta against #797's head and the schema bump as building on that PR's 41, not against live main. Merge order is #797 then this one; a user_version of 43 on top of a database at 41 is monotonic, which is what the guard requires.

  1. Token shape. src/feedback/lead.ts:25-33 mints <expiresAt>.<hmac> over feedback-triage:<ref>:<expires> and verifies with safeEqual plus an expiry check, so a token cannot be edited to extend its life and comparison is constant-time.
  2. Reach. Both lead API routes check the rate limit first and answer 401 before touching a row (src/app.ts:4243-4270), so unauthenticated probing cannot reach the store.
  3. Status clock. src/feedback/lifecycle.ts:55 refuses new and released as Lead-written states, so the Lead can move a report through triage but cannot reopen or fake a release.
  4. Release scan. src/feedback/notify.ts:56-75 marks a report released before it notifies, so a restart between the two does not send twice.

Non-blocking: the triage token is valid for 7 days (TRIAGE_TOKEN_TTL_MS) and there is no revocation path, so a leaked lead link stays usable until it expires; a later change could store the token's hash alongside the report. Also, since this is stacked, retarget the base to main after #797 merges so the diff the queue reads is the 19 files I read.

Ran at 52edfe2:

  • npm run check — pass, 2052/2052 tests, typecheck and build included
  • node scripts/risk-gate.mjs --base a02540d37085f58e1cdcb642e539c8a497f16520 --head HEAD — risk-tier: T3; basis: src/config.ts
  • node scripts/pr-lint.mjs --pr 816 — pr-lint: ok (#816, T3, 19 files)
  • node scripts/changelog.mjs check — 48 fragments ok
  • node scripts/version.mjs check — 0.3.6 ok
  • node scripts/secret-scan.mjs — no suspected value

Not run: a browser walk-through of the lead console, real SMTP delivery of the triage mail.

Conclusion: PASS as a stack on #797; the auth, refusal and notification ordering are correct, and the only open item is the absent token revocation, which does not block this change.

@HugoXK-bot HugoXK-bot added the review:approved Issue reviewed and approved by the Fledge Platform Reviewer label Nov 15, 2026
@HugoXK
HugoXK merged commit 95eb04b into feat/796-feedback-error-report Nov 15, 2026
33 of 35 checks passed
@HugoXK
HugoXK deleted the feat/814-feedback-lead branch November 15, 2026 11:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

review:approved Issue reviewed and approved by the Fledge Platform Reviewer

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants