feat(phase6d): GitHub action loop — issue creation, webhook, validation cron, patterns view
Schema:
- Insight.+githubIssueNumber (user-visible #N, separate from id BigInt)
GitHub integration (apps/web/src/lib/github.ts):
- repoFor(projectKey): env-based GITHUB_REPO_<KEY>=owner/repo mapping
- createIssue / getIssue REST wrappers
- verifyWebhookSignature (HMAC-SHA256 timing-safe)
- buildIssueBody: renders structured markdown from insight + LLM body
(hypothesis, reproduce steps, affected route/provider, quick/long fixes,
suggested investigation, evidence links to panel, DoD checklist)
Server action createGithubIssueForInsight:
- Auth-gated, audited; idempotent (refuses if issue already exists)
- Labels: insight-driven, severity-<P>, type-<T>, <project>-pilot
- Sets status=in_backlog, stores githubIssueUrl/Id/Number/State
Webhook /api/webhooks/github:
- Signature verify with GITHUB_WEBHOOK_SECRET
- issues.closed → status=shipped + shippedAt + validationStartedAt
- issues.reopened → status=in_progress + clear validation state
- issues.opened → status=in_backlog
- PR linking placeholder (passthrough only for now)
Validation cron (worker, daily 5:00 UTC):
- For each insight in 'shipped' state:
- Count sessions with same fingerprint after shippedAt
- >= INSIGHT_REGRESSION_THRESHOLD (default 3) → status=regressed + regressionDetected=true
- validationPeriodDays elapsed with no regression → status=validated + validatedAt
UI:
- Insight detail: GithubActions card — Create button (when no issue),
external link + issue # + state (when present)
- New /insights/patterns page: clusters insights by type + affected_route/provider,
shows ≥2-insight or ≥5-occurrence groups sorted by max severity
- Inbox header link to Patterns
- Cmd+K palette: Patterns entry
Env needed: GITHUB_TOKEN, GITHUB_REPO_SASE, GITHUB_WEBHOOK_SECRET.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>