Issues Reimagined — MuseHub Design Plan
Date: 2026-04-09 Status: Draft
The Problem With the Current Page
The current issue detail page is a GitHub clone with a markdown body, a comment textarea, and a sidebar. That model was designed for humans writing prose to other humans. It has three fundamental problems on MuseHub:
The comment box is a lie. There is no unauthenticated form submission. Every write operation on MuseHub is an MSign-signed API call. A textarea with a submit button implies a cookie session that doesn't exist here. Agents don't type in textboxes. Humans using the CLI don't either.
It ignores what makes muse different. An issue in the git world is a prose description of a problem and a thread of replies. An issue in the muse world can be anchored to specific symbols, commits, blast radii, churn trends, and dead code — because the VCS tracks named things, not line numbers. The current page doesn't surface any of this.
It treats agents as second-class citizens. An agent that files an issue knows exactly which symbol it was operating on, which commit introduced the regression, and what the blast radius of a fix would be. That provenance is structurally available. The current page throws it away.
The Reimagined Model
An issue is not a support ticket. It is a named coordination point in the codebase's evolution. It can be:
- Filed by a human or an agent
- Anchored to zero or more symbols (not just files — named things)
- Anchored to zero or more commits
- Associated with live code intelligence: churn, blast risk, dead code, impact
- Observed by agents who subscribe to it and act on it
- Resolved not by closing with a comment, but by a linked proposal that merges
The core mental model shift: an issue is a living document that knows about the code it describes. It isn't a conversation — it's a coordination artifact.
What replaces the comment box
There is no comment textarea. Write operations on MuseHub are CLI-first:
muse hub issue comment <number> --body "..." --repo owner/slug
muse hub issue close <number> --repo owner/slug
muse hub issue label add <number> bug performance
muse hub issue assign <number> --to gabriel
The page surfaces the results of those commands. It does not simulate them. This is not a limitation — it is the correct UX for a system where the terminal and the agent loop are the primary interfaces, and the web is the observation layer.
For humans who want to interact via the browser, the MCP panel is the interface: an agent is always available to take a natural language instruction and execute the signed API call on their behalf.
Phase 1 — Issue Detail: Symbol-Anchored Intelligence View
Layout
┌─────────────────────────────────────────────────────────────────────────────┐
│ HERO (full-bleed, dark, glow on accent) │
│ │
│ ● OPEN #42 [bug] [performance] filed by agentception-w03 │
│ ───────────────────────────────────────────────────────────────────────── │
│ Memory leak in snapshot diffing on large repos │
│ │
│ ┌────────────┐ ┌────────────┐ ┌────────────┐ ┌────────────┐ │
│ │ 3 anchors │ │ blast: 47 │ │ churn: 12× │ │ 0 linked │ │
│ │ symbols │ │ dependents │ │ last 30d │ │ proposals │ │
│ └────────────┘ └────────────┘ └────────────┘ └────────────┘ │
└─────────────────────────────────────────────────────────────────────────────┘
┌────────────────────────────────────┬────────────────────────────────────────┐
│ MAIN (left, ~65%) │ SIDEBAR (right, ~35%) │
│ │ │
│ ╔══════════════════════════════╗ │ ┌──────────────────────────────────┐ │
│ ║ SYMBOL ANCHORS ║ │ │ STATUS │ │
│ ║ ║ │ │ ● Open · 2 days ago │ │
│ ║ ◈ muse/core/snapshot.py ║ │ │ filed by agentception-w03 │ │
│ ║ ::compute_snapshot_id ║ │ │ [agent] │ │
│ ║ blast: 47 churn: 8× ║ │ └──────────────────────────────────┘ │
│ ║ [ view impact ] ║ │ │
│ ║ ║ │ ┌──────────────────────────────────┐ │
│ ║ ◈ muse/core/store.py ║ │ │ ASSIGNEE │ │
│ ║ ::get_head_snapshot_id ║ │ │ ○ unassigned │ │
│ ║ blast: 23 stable: 180d ║ │ └──────────────────────────────────┘ │
│ ║ ║ │ │
│ ║ + anchor a symbol ║ │ ┌──────────────────────────────────┐ │
│ ╚══════════════════════════════╝ │ │ LINKED COMMITS │ │
│ │ │ a3f2c9 "fix: snapshot hashing" │ │
│ ╔══════════════════════════════╗ │ │ 2026-04-07 gabriel │ │
│ ║ COMMIT ANCHORS ║ │ └──────────────────────────────────┘ │
│ ║ ║ │ │
│ ║ c34861ef feat: add venv ║ │ ┌──────────────────────────────────┐ │
│ ║ 2026-04-08 gabriel ║ │ │ LINKED PROPOSALS │ │
│ ║ snapshot.py +14 −3 ║ │ │ ○ #38 fix snapshot memory leak │ │
│ ╚══════════════════════════════╝ │ │ ● #39 refactor store layer │ │
│ │ └──────────────────────────────────┘ │
│ ╔══════════════════════════════╗ │ │
│ ║ DESCRIPTION ║ │ ┌──────────────────────────────────┐ │
│ ║ (provenance metadata if ║ │ │ LABELS │ │
│ ║ agent-filed: model_id, ║ │ │ [bug] [performance] │ │
│ ║ agent_id, commit anchor) ║ │ └──────────────────────────────────┘ │
│ ║ ║ │ │
│ ║ markdown body rendered ║ │ ┌──────────────────────────────────┐ │
│ ╚══════════════════════════════╝ │ │ MILESTONE │ │
│ │ │ v0.3.0 ████████░░ 80% │ │
│ ╔══════════════════════════════╗ │ └──────────────────────────────────┘ │
│ ║ ACTIVITY TIMELINE ║ │ │
│ ║ ║ │ ┌──────────────────────────────────┐ │
│ ║ ● opened agentception-w03 ║ │ │ ACT VIA CLI │ │
│ ║ 2026-04-07 14:32 ║ │ │ │ │
│ ║ ║ │ │ muse hub issue comment 42 \ │ │
│ ║ ◈ symbol anchored ║ │ │ --body "..." │ │
│ ║ gabriel 2026-04-07 14:45 ║ │ │ │ │
│ ║ snapshot.py::compute_... ║ │ │ muse hub issue close 42 │ │
│ ║ ║ │ │ │ │
│ ║ ○ comment gabriel ║ │ │ [ open in MCP ] │ │
│ ║ 2026-04-08 09:12 ║ │ └──────────────────────────────────┘ │
│ ║ "confirmed — rss spikes ║ │ │
│ ║ on repos > 50k objects" ║ │ ┌──────────────────────────────────┐ │
│ ║ ║ │ │ NAVIGATION │ │
│ ║ ⊕ proposal linked #38 ║ │ │ ← #41 → #43 │ │
│ ║ gabriel 2026-04-08 11:00 ║ │ └──────────────────────────────────┘ │
│ ╚══════════════════════════════╝ │ │
└────────────────────────────────────┴────────────────────────────────────────┘
Key Design Decisions
Symbol Anchors panel — the most important new element. An issue can be anchored to one or more named symbols (file.py::Symbol). For each anchor, the page fetches live code intelligence: blast radius (how many dependents), churn rate (how often it changed in the last 30 days), and stability (days since last modification). This data comes from the MCP code intelligence tools already in musehub/mcp/tools/musehub.py. "View impact" links to the intel page filtered to that symbol.
No comment textarea. The "Activity Timeline" is read-only — it shows opens, comments, anchor events, label changes, proposal links, and closures in chronological order. The "Act via CLI" card in the sidebar shows the exact commands to interact. A [ open in MCP ] link opens the MCP panel with the issue context pre-loaded.
Commit Anchors panel — issues can reference commits directly (not just via #commit in prose). The diff stat is shown inline.
Agent provenance in the description header — if the issue was filed by an agent (agent_id, model_id from the identity record), that metadata is displayed before the body: which agent, which model, which toolchain, which commit the agent was operating on when it filed. This makes agent-filed issues first-class, not indistinguishable from human-filed ones.
Activity Timeline instead of a comment thread — a flat chronological list of all events: opens, closes, reopens, comments, label additions, anchor events, proposal links. Each event has a distinct icon and color:
●open/close (green/purple)◈symbol anchor (blue accent)○comment (muted)⊕proposal linked (orange)⊘proposal merged (green)✕proposal closed without merge (muted)
Phase 2 — Issue Detail: Live Intelligence Panel
Adds a collapsible intelligence panel below the symbol anchors — server-rendered on page load from the code intel index, no JavaScript required for initial render.
┌──────────────────────────────────────────────────────────────────────────────┐
│ INTELLIGENCE (for anchored symbols) [ collapse ] │
│ │
│ compute_snapshot_id │
│ ┌────────────────────────────────────────────────────────────────────────┐ │
│ │ BLAST RADIUS │ │
│ │ 47 direct dependents · 128 transitive │ │
│ │ ████████████████████████████████░░░░░ gravity: 4.8% of codebase │ │
│ │ top callers: snapshot.py store.py merge_engine.py wire.py +43 │ │
│ └────────────────────────────────────────────────────────────────────────┘ │
│ ┌────────────────────────────────────────────────────────────────────────┐ │
│ │ CHURN (last 90 days) │ │
│ │ 12 modifications · 3 authors · last touched 2026-04-07 gabriel │ │
│ │ ▂▃▅▇▅▃▂▃▇▅▃▂ (sparkline — one bar per week) │ │
│ └────────────────────────────────────────────────────────────────────────┘ │
│ ┌────────────────────────────────────────────────────────────────────────┐ │
│ │ OPEN ISSUES TOUCHING THIS SYMBOL │ │
│ │ #42 (this) #38 #31 │ │
│ └────────────────────────────────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────────────────────────────────┘
This panel is rendered server-side by querying the symbol intel index. If the index is empty (repo never indexed), it shows a placeholder:
Intelligence index not built for this repo.
Run: muse -C /path/to/repo push local main (triggers indexing on push)
Phase 3 — Issue List: Beyond the Table
The current issue list is a filtered table. The reimagined list surfaces health signals across the open issue set.
┌─────────────────────────────────────────────────────────────────────────────┐
│ STAT STRIP │
│ 47 open · 203 closed · 12 unassigned · 3 agent-filed · 8 anchored │
└─────────────────────────────────────────────────────────────────────────────┘
┌────────────────────────────────────────┬────────────────────────────────────┐
│ ISSUE LIST (main) │ SIDEBAR │
│ │ │
│ [open] [closed] sort▾ label▾ by▾ │ ┌──────────────────────────────┐ │
│ │ │ HOTSPOT ISSUES │ │
│ ┌────────────────────────────────┐ │ │ Issues anchored to the │ │
│ │ ● #47 Memory leak in snap.. │ │ │ highest-churn symbols: │ │
│ │ [bug] [perf] agentception │ │ │ │ │
│ │ ◈ 2 anchors blast:47 2d │ │ │ #42 compute_snapshot_id │ │
│ ├────────────────────────────────┤ │ │ churn 12× │ │
│ │ ● #46 Proposal merge fails.. │ │ │ #38 wire_push │ │
│ │ [bug] gabriel │ │ │ churn 8× │ │
│ │ no anchors 3d │ │ └──────────────────────────────┘ │
│ ├────────────────────────────────┤ │ │
│ │ ● #45 Add --json to branch │ │ ┌──────────────────────────────┐ │
│ │ [feat] gabriel │ │ │ BLAST RISK │ │
│ │ ◈ 1 anchor blast:12 5d │ │ │ Issues touching high-risk │ │
│ └────────────────────────────────┘ │ │ symbols: │ │
│ │ │ │ │
│ ← prev 1 / 5 next → │ │ #42 risk: 82 │ │
│ │ │ #45 risk: 34 │ │
│ │ └──────────────────────────────┘ │
│ │ │
│ │ ┌──────────────────────────────┐ │
│ │ │ AGENT ACTIVITY │ │
│ │ │ 3 issues filed by agents │ │
│ │ │ this week │ │
│ │ │ │ │
│ │ │ agentception-w03 2 issues │ │
│ │ │ agentception-w07 1 issue │ │
│ │ └──────────────────────────────┘ │
│ │ │
│ │ ┌──────────────────────────────┐ │
│ │ │ MILESTONES │ │
│ │ │ v0.3.0 ████████░░ 80% │ │
│ │ │ 12 open · 47 closed │ │
│ │ └──────────────────────────────┘ │
└────────────────────────────────────────┴────────────────────────────────────┘
Each issue row shows:
◈ N anchorsif symbol anchors exist — a visual signal that this issue has structural groundingblast:N— highest blast radius of any anchored symbol (from intel index)- Agent-filed issues have
[agent]badge instead of avatar
The sidebar sidebar surfaces Hotspot Issues (issues anchored to high-churn symbols), Blast Risk (issues touching structurally dangerous symbols), and Agent Activity (which agents have been filing issues). All of this is derived from the intel index — no new data model required.
Phase 4 — New Issue: Structured, Not Freeform
The current "new issue" flow is a blank title + body textarea — a GitHub clone. The reimagined flow is a structured form that the CLI or an agent fills out, with the web page acting as a read-only preview. But for humans in the browser, the creation flow becomes:
┌─────────────────────────────────────────────────────────────────────────────┐
│ NEW ISSUE │
│ │
│ This page is a preview. Issues are created via CLI or agent: │
│ │
│ muse hub issue create \ │
│ --title "Memory leak in snapshot diffing" \ │
│ --body "..." \ │
│ --label bug --label performance \ │
│ --anchor "muse/core/snapshot.py::compute_snapshot_id" \ │
│ --repo gabriel/muse │
│ │
│ Or: [ open MCP panel ] — talk to an agent, it will create the issue │
│ on your behalf with a signed request. │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
We're not removing the ability to create issues from the browser — we're making the interface honest. The MCP panel button opens the global MCP panel pre-seeded with context (owner/repo, action: create_issue). The agent handles the signed request. No hidden form submission, no fake session auth.
For the MCP protocol itself, create_issue already exists in musehub/mcp/write_tools/issues.py. This is wiring, not new work.
Data Model Changes (Phase 1)
New field: symbol_anchors on MusehubIssue
symbol_anchors: list[str] # stored as JSON, e.g. ["muse/core/snapshot.py::compute_snapshot_id"]
This is a JSON column — no foreign key into the symbol graph (which is per-commit and changes). The anchor is a string address; the live intelligence is fetched at render time from the intel index.
New field: commit_anchors on MusehubIssue
commit_anchors: list[str] # stored as JSON, e.g. ["c34861efbf33..."]
Commit IDs. The page resolves them to commit messages and diff stats at render time.
New model: MusehubIssueEvent (replaces flat comments for the timeline)
Instead of treating comments as the only activity type, the timeline is built from an event log:
class MusehubIssueEvent(Base):
event_id: str # UUID
issue_id: str # FK
repo_id: str # FK
actor: str # handle of human or agent
event_type: str # "opened" | "closed" | "reopened" | "commented" |
# "labeled" | "unlabeled" | "assigned" | "unassigned" |
# "symbol_anchored" | "commit_anchored" |
# "proposal_linked" | "proposal_merged" | "milestone_set"
payload: dict # event-type-specific JSON
created_at: datetime
Comments become events with event_type="commented" and payload={"body": "..."}. This is backwards-compatible — existing comments can be migrated to events. The Alembic migration creates the new table; existing MusehubIssueComment rows are left in place and the timeline query unions both.
Implementation Order
| Phase | Scope | Complexity | New Data | New Routes |
|---|---|---|---|---|
| 1A | Symbol anchors on issue detail — display only, no new data. Read symbol_anchors from existing labels as a convention: label symbol:muse/core/snapshot.py::compute_snapshot_id |
Low | None | None |
| 1B | Activity timeline (read-only, replaces comment section) | Medium | None (union existing comments + state changes) | None |
| 1C | "Act via CLI" sidebar card + MCP panel link | Low | None | None |
| 2A | Add symbol_anchors JSON column to MusehubIssue. Alembic migration. |
Low | 1 column | PATCH /{owner}/{slug}/issues/{n} add anchors |
| 2B | Live intelligence panel (blast radius, churn) — requires intel index. Server-rendered. | Medium | None | None (uses existing intel query layer) |
| 2C | Agent provenance block in description header | Low | None (uses identity lookup already in route) | None |
| 3A | Issue list: ◈ N anchors + blast badge per row |
Low | None | None |
| 3B | Sidebar panels: Hotspot Issues, Blast Risk, Agent Activity | Medium | None | None |
| 4A | commit_anchors JSON column. Alembic migration. |
Low | 1 column | PATCH add anchors |
| 4B | MusehubIssueEvent table and timeline query |
High | 1 table + migration | GET timeline endpoint |
| 4C | New issue page: CLI instructions + MCP panel integration | Low | None | Redirect existing /issues/new |
Visual Language
Follows the existing design system exactly:
- Hero pattern:
.ph-herofull-bleed with glow, same asdomain_detail.htmlandproposal_detail.html - Stats strip:
.ph-stats-stripwith 4 stat blocks - Two-column layout: 65/35 split,
.id-main/.id-sidebar, responsive collapse at 900px - Symbol anchor card: new
.id-anchorspanel using--color-accent(#4f8ef7) with◈icon - Activity timeline: new
.id-timelinewith event-type icons and colors matching the token palette - Agent badge:
--agent-accent(#a78bfa) consistently, same as elsewhere - CLI snippet card:
--bg-overlaybackground, JetBrains Mono, no syntax highlighting needed - Intelligence panel: uses existing
.id-intel-*class namespace,--dim-athrough--dim-cfor blast/churn/risk
No new colors. No new fonts. The new elements are compositions of existing tokens.
What We Are NOT Building
- No comment textarea. Not a form, not a rich text editor, not a mention system.
- No @mention autocomplete. Mentions happen in the CLI where the shell can complete them.
- No real-time updates. The page is server-rendered. Reload to see new activity. Streaming can come later via SSE if needed.
- No emoji reactions. Not a social platform.
- No attachments. Binary assets belong in object storage, referenced by OID in the issue body.
- No issue templates picker modal. Templates live in
.muse/issue_templates/and are rendered bymuse hub issue create --template bugin the CLI.