Issue pipeline — from the Report an Issue dialog to a human-gated fix, including the credibility pipeline, the report skill, the report agent, and the session-start hook

Issue

The issue pipeline connects user-reported bugs to fixes. Anyone clicks "Report an Issue" in the UI, a GitHub issue is created, a human takes or rejects it, and the report agent fixes what was taken.

Report an Issue (User-Facing)

Every page in hogwarts, mkan and kun carries a "Report an issue" link or icon. It opens one canonical component (src/components/report-issue/dialog.tsx, source of truth in kun, copied verbatim to the other repos):

  • ≥ 768px — a centred dialog: title, textarea, hint, captcha (anonymous only), Submit.
  • < 768px — a full-height bottom sheet shaped like the iOS Books search sheet: the title on top, a quiet state area in the middle, and a pill composer pinned right above the on-screen keyboard with a round send button inside it and a round ✕ beside it. The pill follows the keyboard through window.visualViewport. The page address, viewport, direction and browser are attached automatically; the user only types what went wrong.

Language comes from the [lang] route param (never from document at render time), and direction is set on the portal explicitly so the Arabic sheet renders RTL.

Where It Appears

RepoLocationVariant
kunSite footer, every pagetext
hogwartsDashboard footer, marketing pages, auth, onboarding, exam wizardtext
hogwartsApplication form wizard footericon
mkanSite footer, hosting/travel/auth layoutstext / icon

Intake limits

The dialog and the server read the same numbers from src/lib/report/limits.ts:

Reportermin charsmin unique words
anonymous305
signed-in103

Max 2000 chars. The send button enables exactly when the server will accept the text. (Before 2026-09-13 hogwarts enabled submit on any text while the server demanded 30 chars — short team reports drew a success toast and created nothing.)

Server Action

src/actions/report-issue.ts          # kun
src/lib/actions/report-issue.ts      # hogwarts, mkan

A thin wrapper around runReportPipeline() (src/lib/report/pipeline.ts):

schema → reporter → pure filters (junk stops here, zero network)
  → rate limit → [captcha ‖ recent-self ‖ banned] → context filters
  → [GitHub dedup search ‖ AI triage] → score → bucket → GitHub issue

The client always receives the same "Submitted. Thank you!" — silent rejects are indistinguishable from real submissions, so spammers cannot probe the filter.

Issue Body Format

<user's description>
 
---
 
**Page**: `https://demo.balqalam.com/en/students/enroll`
**Reporter**: team · ADMIN (id:cmrkybll…)
**Time**: 2026-09-13T01:20:00.000Z
**Category**: other
**Viewport**: 390x844
**Direction**: ltr
**Browser**: Mozilla/5.0 (iPhone; …)
 
<!-- score-block
{ "score": 58, "bucket": "needs-human", "team": true, "reporterKind": "authenticated",
  "classification": "unknown", "severity": "medium", "language": "other",
  "scores": { "R": 30, "Q": 8, "C": 10, "A": 0, "P": 0 }, "rationale": "" }
-->

Title is the description, truncated to 80 characters. classification: "unknown" with A: 0 is the normal case: AI triage only runs when ANTHROPIC_API_KEY is set, and under the subscription-only billing posture it is not.

Labels the pipeline sets

LabelMeaning
reportEvery dialog-created issue
teamThe reporter is a databayt team member (kun contributor session; hogwarts DEVELOPER, team account, or demo-tenant admin) — listed first, never below needs-human
verified-reportScore ≥ 75 with an AI-confirmed bug, or three corroborating reporters
needs-human / low-confidenceScore bands — hints that order the list
severity/*, lang/*Only when AI triage ran

The human gate

The queue is listed. Abdout chooses. Nothing is auto-processed.

report                # list the whole org queue, then take / reject
report hogwarts       # one repo
report hogwarts#382   # skip the list — treat as accepted and fix it
report --status       # the table only

Passive triggers, no slash needed: "list the reports", "what did the team report", "fix reports", "البلاغات", "بلاغات الفريق".

  1. LIST — one gh search issues --owner databayt --label report --state open call renders a numbered table ordered accepted → verified → team → needs-human → low-confidence → legacy, oldest first within a lane, with reporter, score and page.
  2. CHOOSE — "take 1,3 reject 2 — not a bug". Up to four rows the skill asks with a multi-select; more than four it asks in prose.
  3. APPLY — taken → accepted label + a one-line comment; rejected → closed as not planned with the reason; unmentioned rows stay untouched.
  4. FIX — the report agent runs on every accepted (or verified-report) issue, oldest first.

Report Agent (the fix lane)

READ → LOCATE → CONTEXT → VALIDATE → SEE → DEBUG → IDENTIFY → FIX → BUILD → PUSH → VERIFY → CLOSE
StepWhat It Does
READgh issue view — description, page URL, reporter, score-block
LOCATEMap URL to route directory (src/app/) and component directory (src/components/)
CONTEXTRead CLAUDE.md, README.md, ISSUE.md in the component directory
VALIDATEAccepted means "fix it if it is a bug the QA scope allows" — no schema/auth/middleware; data gaps and feature requests go back to the human with a comment
SEE / DEBUGScreenshot, console, network
FIXMinimum diff, documented patterns
BUILDpnpm tsc --noEmit + pnpm build (hogwarts ignores type errors in the build)
PUSHfix: commit with Closes #N, straight to main — no branches, no PRs
VERIFYkun redeploys itself on push (Vercel); hogwarts and mkan need /deploy (Cloudflare)
CLOSEgh issue close with root cause, fix, files, verification — and which platform has it

Escalation

SituationAction
Build error after fixHand off to build agent
Server-side exceptionHand off to sse agent
Performance issueHand off to performance agent
Security concernHand off to guardian agent
Needs schema / auth / architecture changeComment, leave open for Abdout
Cannot reproduceComment + cannot-reproduce label

Agent Definition

.claude/agents/report.md

Session-Start Hook

Every Claude Code session in a databayt repo runs ~/.claude/hooks/session-start-reports.sh (canonical copy kun/.claude/hooks/, wired in .claude/settings.json). One search call, one compact table:

📋 Open reports: 5 (0 accepted, 0 from the team). Say "report" to take or reject them.
   kun#108        needs-human     111d  i got stuck in 4/8 step, also read whole terminal…
   hogwarts#382   low-confidence   59d  in the student drop down list not all the students appears

It lists; it never starts the agent. The policy lives in ~/.claude/rules/session-start.md.

Why a human gate (since 2026-09-13). The buckets used to be verdicts. But AI triage never ran in production — there is no API-key spend under the subscription-only billing posture — so every real report was scored on reporter and content signals alone, and the "auto-fix" bucket was unreachable. The pipeline still scores every submission and kills junk before an issue exists, but the score now only orders the list; Abdout takes or rejects each row.

Scheduled Trigger (Paused)

A remote trigger exists that runs the report agent every 2 hours in Anthropic's cloud. Currently paused — the human gate makes an unattended run pointless until reports are accepted.

FieldValue
NameReport Auto-Fix (Every 2h)
IDtrig_01MFLRtUTfMMNTDGBBGQtZLq
Schedule0 */2 * * * (every 2 hours)
StatusDisabled
Repodatabayt/hogwarts
Managehttps://claude.ai/code/scheduled

Full Pipeline Flow

User taps "Report an issue" (dialog on desktop, sheet above the keyboard on mobile)
    ↓
Server action → credibility pipeline (junk dies, the rest is scored)
    ↓
GitHub issue (report + lane label, `team` when a teammate filed it)
    ↓
Next Claude Code session → hook lists the queue
    ↓
Abdout says "report" → table → take / reject → `accepted` label / closed not planned
    ↓
Agent: READ → LOCATE → CONTEXT → VALIDATE → FIX → BUILD → PUSH
    ↓
Issue closed with structured comment; kun live on push, hogwarts/mkan after /deploy

Files

Product repos (hogwarts, mkan, kun)

FileRole
src/components/report-issue/dialog.tsxThe canonical dialog + mobile sheet (copied from kun)
src/components/report-issue/index.tsxPer-repo wrapper: session, server action, language
src/components/report-issue/dictionary.tsBuilt-in bilingual strings (mkan overrides through strings)
src/lib/report/The credibility pipeline (copied from kun; only adapter.ts differs)
src/lib/report/limits.tsIntake floors — the one place both sides read from
src/actions/report-issue.ts or src/lib/actions/report-issue.tsServer action

Kun (Engine)

FileRole
.claude/skills/report/SKILL.mdList → choose → apply → fix
.claude/agents/report.mdThe fix lane (12 steps)
.claude/hooks/session-start-reports.shSession hook, canonical copy
.claude/rules-global/session-start.mdThe hook lists, the human chooses
content/docs/issue.mdxThis documentation

Issue Creation (CLI)

Issues can also be created from Claude Code or Slack, not just the dialog.

Usage

# From Claude Code
/issue "Login crashes on Safari mobile" --repo hogwarts
 
# From keyword
issue "Add dark mode to dashboard"

Repo Mapping

RepoScope
databayt/kunEngine: agents, skills, MCP, hooks, rules, memory
databayt/hogwartsEducation: features, bugs, LMS, SIS, billing
databayt/souqE-commerce: vendors, cart, checkout
databayt/mkanRentals: listings, booking, search
databayt/shifaMedical: appointments, patient records
databayt/codebaseShared: patterns, components, templates
databayt/shadcnUI: component library
databayt/ios-appMobile: iOS app
databayt/android-appMobile: Android app
databayt/marketingMarketing: landing pages

Labels

Priority

LabelWhen
P0-criticalProduction down, data loss, security
P1-highBlocks current sprint, customer-facing bug
P2-mediumImportant but not blocking
P3-lowNice to have, cleanup

Type

LabelWhen
reportUser-reported via dialog — listed for the human gate
teamReported by a databayt team member
acceptedA human took it — the report agent may fix it
bugSomething is broken
enhancementImprove existing feature
needs-humanScore band; undecided until listed
cannot-reproduceAgent couldn't reproduce the reported issue

Issue Body Template (CLI)

## Context
Why this matters — user impact, business context, or technical debt.
 
## Action
- [ ] Step 1
- [ ] Step 2
- [ ] Step 3
 
## Verification
How to confirm it's done — test commands, URLs to check, expected behavior.