MuseHub — Extreme Test Coverage Checklist
Goal: match the standard set by the Muse CLI codebase. Every component below must be covered at all seven layers before we consider MuseHub production-ready. This document is intentionally exhaustive — it is a living checklist, not a planning estimate.
Current baseline: 70 test files, ~29,400 lines of tests. Target: Full coverage at every layer for every component listed here.
Seven test layers (required for every component):
- Unit — isolated function/class, all mocks, no DB, no I/O
- Integration — real DB (test Postgres), real service calls, no HTTP layer
- End-to-End — full HTTP stack via
TestClient, real DB, real storage- Stress — high concurrency, large payloads, sustained load
- Data Integrity — correctness of stored data, constraint enforcement, rollback
- Security — auth bypass, injection, privilege escalation, abuse cases
- Performance — latency budgets, query efficiency, memory/connection bounds
Table of Contents
- Wire Protocol
- Auth — Ed25519 / MSign
- Object Store
- Repository Service
- Snapshot & Symbol Indexer
- Symbol Intelligence (Intel)
- Coordination (muse coord)
- CI — Trigger, Workflow, Gates, Selective
- CI — Runner Protocol
- Issues & Milestones
- Merge Proposals
- Releases & Release Packager
- MCP Protocol Layer
- MCP Read Tools
- MCP Write Tools
- MCP Elicitation
- Search
- Semantic Search (Qdrant)
- Webhooks & Webhook Dispatcher
- Social Graph (Stars, Forks, Follows, Watches)
- Notifications
- Activity Feed & Events
- Agent Context API
- Workspace & Cross-Repo Intelligence
- Domains
- Divergence Engine
- Collaborators & Permissions
- Labels
- Stash
- Sessions
- Wire Tags
- Garbage Collector
- Storage Backends
- Rate Limiting
- Request Signing (MSign)
- Database Migrations (Alembic)
- API Contracts & OpenAPI
- UI / SSR Routes
- Pagination
- Webhook Crypto
- GC & Background Tasks
- Protocol Introspection
- Install Script
1. Wire Protocol
Files: api/routes/wire.py, services/musehub_wire.py, models/wire.py
The push/fetch/presign protocol between the Muse CLI and MuseHub. The highest-traffic and most security-critical surface — a broken push corrupts repos.
- [x] Unit — model validators (DoS limits),
_topological_sort - [x] Integration — push/fetch/push_objects hit real DB; collaborator auth; private repo gating
- [x] End-to-End — full HTTP stack: all wire endpoints exercised via
AsyncClient - [x] Stress — 20-repo push fan-out; 100-object mpack push+fetch; 25-commit BFS chain; 500-ID filter-objects; 30 sustained sequential fetches; 50-object push/objects batch
- [x] Data Integrity — push→fetch round-trip verifies content; CDN content matches; dedup skips correctly
- [x] Security — auth guards on all write endpoints; read-only/unaccepted collaborator rejected; private repo 404
- [x] Performance — single push <500ms; 10-commit fetch <500ms; filter-objects 100 IDs <200ms; GET /refs <100ms; 20 sequential pushes <5s; BFS shallow vs deep both <1s
2. Auth — Ed25519 / MSign
Files: services/musehub_auth.py, auth/dependencies.py, auth/request_signing.py, crypto/keys.py, db/musehub_auth_models.py, api/routes/api/auth.py
Auth is entirely MSign-based (Ed25519 per-request signing):
- Key registration: Ed25519 and ML-DSA-65 public keys stored in
MusehubAuthKey. Multi-key per identity supported. Key fingerprint computed viakey_fingerprint(). - Challenge-response:
create_challenge()issues a short-lived nonce (in-memory, TTL =CHALLENGE_TTL_SECONDS).verify_and_authenticate()verifies the Ed25519/ML-DSA-65 signature over the nonce and issues anMSignContext. - Per-request signing: Every authenticated request carries an
Authorization: MSign ...header.build_canonical_message()hashes method + path + body._verify_msign()checks the signature and enforces a replay window (REPLAY_WINDOW_SECONDS). Stale or replayed requests are rejected with 401. - FastAPI deps:
require_signed_request→MSignContext(raises 401 if missing/invalid).optional_signed_request→MSignContext | None.require_valid_tokenandoptional_tokenare aliases for the MSign variants. - Key revocation:
revoke_key()deletes theMusehubAuthKeyrow. Subsequent requests signed with that key fail_verify_msign.
Test focus areas (all MSign):
build_canonical_messagedeterminism (same inputs → same bytes)_verify_msignhappy path, wrong-key rejection, tampered-body rejection, stale timestamp rejection, replay rejectioncreate_challengeTTL expiry, nonce uniqueness,_purge_expired_challengescleanupverify_and_authenticatecorrect key lookup, bad signature →AuthError, unknown identity →AuthErrorrequire_signed_requestdep: missing header → 401, invalid signature → 401, valid →MSignContextoptional_signed_requestdep: missing header →None, valid →MSignContextMulti-key: two keys registered, one revoked — revoked key rejected, live key still works
get_keys_for_identityreturns all non-revoked keysKey fingerprint stability: same public key bytes → same fingerprint across calls
[x] Unit —
build_canonical_messagedeterminism/format (11 cases);_parse_msign_header(8 cases);KeyAlgorithm,key_fingerprint,fingerprints_equal,b64url_encode/decode,verify_signatureEd25519 (all error paths + bit-flip + size checks);REPLAY_WINDOW_SECONDSsanity; ML-DSA-65 not-yet-implemented guard[x] Integration — challenge-response: nonce single-use, expired nonce, bad fingerprint, key substitution,
last_used_atadvances, handle uniqueness, concurrent registration → 409, 50 sequential logins;verify_and_authenticateall error paths[x] End-to-End —
require_signed_request: missing header, Bearer scheme, malformed, stale ts, future ts, tampered body, wrong key, unknown handle → 401; valid signed request → 200;optional_signed_request: public repo no-auth → 200, private repo with valid MSign → 200, invalid present header → 401[x] Stress — 25 sequential MSign-authenticated requests all accepted under 10s; 50 sequential challenge-response logins under 10s; garbage inputs never 500
[x] Data Integrity —
MSignContext.handlematches registered identity (verified via push authorization);last_used_atadvances monotonically; key revocation deletes row and blocks subsequent requests[x] Security — revoked key → 401; multi-key: revoke one, other still works; tampered body rejected; wrong key rejected; stale/future timestamp rejected; Bearer scheme rejected; forged structured challenge token rejected; key substitution in challenge rejected; re-registration under different handle blocked; handle injection characters rejected
[x] Performance —
build_canonical_messagelatency: 1KB body <1ms, 1MB body <10ms, empty body (GET) <100µs; E2E verification latency: 1-key identity <200ms, 5-key identity <200ms; 5-key/1-key slowdown ratio <5× (validates single SELECT not N queries)
3. Object Store
Files: storage/backends.py (BlobBackend, get_backend), api/routes/musehub/objects.py
Content-addressed object storage via BlobBackend (R2/MinIO): put/get/exists/delete,
presigned URL generation, list_objects, get_object_content, get_blob_meta.
- [x] Unit —
BlobBackend.put/get/exists/deleteasync wrappers;uri_forcontract;_detect_file_type(json/image/xml/other);_content_typehelpers - [x] Integration —
list_objects,get_object_rowwith real DB - [x] End-to-End — list objects, get content, blob meta; public + private visibility on all three endpoints; 404/410/401 error paths
- [x] Stress — 50-object wire push → list round-trip; 20-repo isolation fan-out
- [x] Data Integrity — byte-for-byte content round-trip via HTTP; idempotent push (no duplicate DB rows)
- [x] Security — private-repo auth gate on all three endpoints; cross-repo object isolation
- [x] Performance —
BlobBackend.put1 KB median <50ms;BlobBackend.get1 KB median <10ms;list_objects100-row median <200ms; 1 MB content serve <500ms
4. Repository Service
Files: services/musehub_repository.py, api/routes/api/repos.py, api/routes/musehub/repos.py, db/musehub_models.py (MusehubRepo, MusehubBranch, MusehubCommit, MusehubSnapshot, MusehubSnapshotEntry, MusehubIdentity)
Create/read/update/delete repos and branches, ownership transfer, repo stats, tree listing, snapshot manifest, identity resolution.
Covered by two files: test_musehub_repos.py (85 tests, pre-existing) + test_repository_service.py (64 tests, gap-filling).
- [x] Unit —
_generate_slug(10 edge cases);_guard_visibility/_guard_owneras pure functions;resolve_head_ref(empty/main/alpha fallback);list_branches_with_detailahead/behind computation - [x] Integration —
get_repo_home_stats(counts, 14-day activity, objects);get_recently_pushed_branches; collaborator repos inlist_repos_for_user; private-template copy skipped;transfer_repo_ownershipon soft-deleted → None;create_reposervice persists to DB with correct slug - [x] End-to-End — CRUD via HTTP,
GET /repos/{id}/stats,GET /repos/{id}/branches/detail,GET /api/repos/{id}/snapshots/{snap_id}; private repo gates on branches/commits/stats;CreateRepoRequestowner pattern validation → 422 - [x] Stress — 50 repo HTTP creation + list; cursor pagination over 100 repos (no duplicates); 200-commit history paged via offset (no duplicates, correct total)
- [x] Data Integrity — soft-delete hides repo but preserves row; double delete idempotent; duplicate
(owner, slug)→ 409;create_reposlug derivation; transfer on deleted repo → None - [x] Security — non-owner delete/transfer → 403; private GET/branches/commits/stats → 401; unauthenticated delete/transfer → 401
- [x] Performance —
_generate_slug1000 calls <100ms;list_repos_for_user50 repos <500ms;get_repo_home_stats200 commits <500ms;list_commits200 rows <200ms
5. Snapshot & Symbol Indexer
Files: services/musehub_snapshot.py, services/musehub_symbol_indexer.py, db/musehub_models.py (MusehubSymbolIndex, MusehubFileIntelCache)
Snapshot materialization, symbol index build (triggered async on every push), file intel cache write and invalidation, msgpack blob serialisation.
- [x] Unit —
_extract_ops(empty/flat/PatchOp child_ops/missing address/non-dict),_op_to_muse_op(all 6 keys + unknown + empty), msgpack round-trip schema validation - [x] Integration —
build_symbol_index(no delta → None, creates row, correct symbol_history/hash_occurrence, prunes stale, invalidates FileIntelCache, BFS orphan exclusion),load_symbol_history,load_hash_occurrence,get_snapshot_manifests_batch - [x] End-to-End — full pipeline (commits → build → meta lookup), rebuild updates ref, 3-commit chain all symbols indexed
- [x] Stress — 1000-file manifest upsert, 50-snapshot batch, 100-commit/500-symbol build, file_path filter on large index
- [x] Data Integrity — atomic upsert replace, one row per repo, symbol entry fields present, orphan commit excluded from index
- [x] Security — corrupt msgpack → {} not exception, unknown head commit → None gracefully, invalid op type handled
- [x] Performance —
_extract_ops1000 calls <100 ms, build 100 commits <3 s, upsert 1000 files <500 ms, batch 50 snapshots <300 ms
6. Symbol Intelligence (Intel)
Files: services/musehub_intel.py, api/routes/v2/symbols.py, api/routes/musehub/blame.py, services/musehub_cross_repo.py
compute_intel, hotspot detection, dead code detection, blast risk scoring, health
score formula, file-level intel, symbol blame, symbol history, symbol impact graph,
clone detection, cross-repo impact, workspace blast risk.
- [x] Unit —
_parse_ts(ISO/Unix/Z-suffix/invalid),_health_label/_health_color_class(all 5 bands),compute_intel(empty/hotspot/dead/blast/coupling/breaking/velocity/top-N/invalid-ts),IntelSnapshot.as_dict/from_dictround-trip,_module_prefix/_short_label,_build_real_symbol_blame(path filter, import exclusion, delete skip, intel signals, change_count, empty, unknown commit) - [x] Integration —
load_intel_snapshot(None when absent, populated after build),intel_full_jsonstored/retrievable,intel_summary_jsonfields, blame entries after index build,search_symbol_across_repos(no repos, match, case-insensitive, private excluded),workspace_blast_risk_top_n(empty/populated/sorted),cross_repo_impact(no source, unknown address),build_deps_graph(single repo, missing source → empty) - [x] End-to-End — blame 404/public-200/private-401/entries-present/path-filter, symbol-index-rebuild (authed 200/202, unauthed 401)
- [x] Stress —
compute_intel1000 symbols, 50 co-changing symbols (coupling capped at TOP_N), search across 10 repos each with 20 symbols, workspace blast risk across 5 repos, blame build 500 symbols - [x] Data Integrity —
as_dict/from_dictlossless identity,intel_full_jsonstored and retrievable, velocity always 12 buckets, hotspot fields non-empty, dead days_cold within expected range, blame entry fields complete - [x] Security — private repo blame 401 no token, 404 for deleted repo, private repo not visible to other user, path traversal in blame returns empty (no crash), injected commit IDs safe, XSS in commit message stored verbatim
- [x] Performance —
compute_intel500 symbols <200 ms,as_dict/from_dict1000 entries <50 ms, blame build 1000 symbols <200 ms, search across 5 repos <1 s
7. Coordination (muse coord)
Files: services/musehub_coord.py, services/musehub_coord_server.py, api/routes/coord.py, api/routes/v2/coord.py, db/coord_models.py
coord_push (idempotent, heartbeat upsert), coord_pull (cursor-based), SSE watch
stream, reservation management, task lifecycle (pending → claimed → completed/failed),
conflict forecasting, swarm state query, TTL extension.
- [x] Unit —
CoordRecordInvalidators (all 8 kinds accepted, invalid rejected, UUID4 enforcement/normalization, run_id optional, expires_at optional),CoordPushRequest(empty/1/500/501 records),CoordPollRequest(defaults, negative since_id, invalid kind, limit range),_VALID_KINDScompleteness - [x] Integration —
coord_push(insert, write-once skip, heartbeat upsert, all kinds, materializes reservation/task);coord_pull(empty→cursor=0, all records, cursor pagination, kinds filter, ordered oldest-first, limit respected);conflict_check(no reservations, active found, expired ignored);extend_reservation; task lifecycle (claim→complete, claim→fail, double-claim returns None);list_tasksfilter by status/queue - [x] End-to-End — push 404/401/403/200 with counts; pull public-no-auth/private-404/records-present/kinds-filter; watch invalid kind 400/404 unknown repo
- [x] Stress — push 500 records single call, cursor pagination through 500 (5 pages × 100), 100-task queue with 10 claims, conflict_check 100 reserved symbols
- [x] Data Integrity — UniqueConstraint write-once enforced, heartbeat upsert no duplicate row, coord record fields complete, depends_on preserved, release marks reservation as released
- [x] Security — push requires auth (401), push 403 for non-owner, private pull 404 unauthenticated, invalid kind 422, watch invalid kind 400, complete_task wrong agent returns None
- [x] Performance — push 100 records <500 ms, pull 500 records <200 ms, conflict_check 50 addresses <100 ms, list_tasks 100 <100 ms
8. CI — Trigger, Workflow, Gates, Selective
Files: services/musehub_ci_trigger.py, services/musehub_ci_workflow.py, services/musehub_ci_gates.py, services/musehub_ci_selective.py, services/musehub_ci.py, db/musehub_ci_models.py
Workflow YAML parse and validation, trigger on push/proposal/manual, branch pattern matching,
if: condition evaluation, symbol-targeted gate evaluation (breakage, blast risk, dead
code, test gap), selective test selection, test mapping write/read.
- [x] Unit
- [x] Integration
- [x] End-to-End
- [x] Stress
- [x] Data Integrity
- [x] Security
- [x] Performance
9. CI — Runner Protocol
Files: api/routes/runner.py (created), services/musehub_ci.py (runner endpoints), db/musehub_ci_models.py (MusehubCISecret)
Runner queue, job claim, step progress reporting, job final report, secret delivery
(encrypted at rest, decrypted only to authenticated runners), cancel, test mapping
retrieval. RUNNER_TOKEN auth gating must be stress-tested for bypass.
- [x] Unit
- [x] Integration
- [x] End-to-End
- [x] Stress
- [x] Data Integrity
- [x] Security
- [x] Performance
10. Issues & Milestones
Files: services/musehub_issues.py, api/routes/musehub/issues.py, api/routes/musehub/milestones.py, db/musehub_models.py (MusehubIssue, MusehubIssueComment, MusehubMilestone, MusehubIssueMilestone), api/routes/musehub/labels.py
Issue CRUD, comment threading, state transitions (open/closed), milestone create/assign/ progress, label assignment, issue search, agent-filed issues.
- [x] Unit
- [x] Integration
- [x] End-to-End
- [x] Stress
- [x] Data Integrity
- [x] Security
- [x] Performance
11. Merge Proposals
Files: services/musehub_proposals.py, services/musehub_proposal_risk.py, api/routes/musehub/proposals.py, db/musehub_models.py (MusehubProposal, MusehubProposalReview, MusehubProposalComment)
Proposal create, review (approve/request-changes), merge (with merge commit materialisation), close, comment, domain-diff population, risk scoring, CI gate integration on merge.
- [x] Unit
- [x] Integration
- [x] End-to-End
- [x] Stress
- [x] Data Integrity
- [x] Security
- [x] Performance
12. Releases & Release Packager
Files: services/musehub_releases.py, services/musehub_release_packager.py, services/release_analysis.py, api/routes/musehub/releases.py, db/musehub_models.py (MusehubRelease, MusehubReleaseAsset)
Release create (from tag or dict), semantic release report attach, changelog parse,
asset download URL generation, latest-release resolution, version tag uniqueness,
semantic version bump propagation, SemanticReleaseReportResponse round-trip.
- [x] Unit
- [x] Integration
- [x] End-to-End
- [x] Stress
- [x] Data Integrity
- [x] Security
- [x] Performance
13. MCP Protocol Layer
Files: api/routes/mcp.py, mcp/dispatcher.py, mcp/session.py, mcp/sse.py, mcp/server.py, mcp/stdio_server.py, protocol/events.py, protocol/responses.py
JSON-RPC 2.0 dispatch (single and batch), session lifecycle (create on initialize,
resume on subsequent requests), SSE streaming, ping keepalive, method routing,
Streamable HTTP transport, stdio transport, _validate_origin CORS guard, MSign auth
on write methods.
- [x] Unit
- [x] Integration
- [x] End-to-End
- [x] Stress
- [x] Data Integrity
- [x] Security
- [x] Performance
14. MCP Read Tools
Files: mcp/tools/musehub.py, services/musehub_mcp_executor.py
All read tools: browse_repo, list_branches, list_commits, read_file,
get_analysis, search, get_context, get_commit, and any others. Each tool
must be tested for correct output, repo visibility gating (private repos must be
inaccessible to unauthenticated callers), and graceful error on missing resource.
- [x] Unit
- [x] Integration
- [x] End-to-End
- [x] Stress
- [x] Data Integrity
- [x] Security
- [x] Performance
15. MCP Write Tools
Files: mcp/write_tools/ (issues, proposals, releases, repos, social, ci,
elicitation_tools)
All write tools: create/update/close issues, create/merge proposals, create releases, fork repos, star/unstar, trigger CI, and all elicitation-powered tools. Auth gating — write tools must reject unauthenticated callers. Side-effect correctness — written entities must be retrievable and match input.
- [x] Unit
- [x] Integration
- [x] End-to-End
- [x] Stress
- [x] Data Integrity
- [x] Security
- [x] Performance
16. MCP Elicitation
Files: mcp/elicitation.py, mcp/write_tools/elicitation_tools.py, api/routes/musehub/ui_mcp_elicitation.py, contracts/mcp_types.py (ElicitationRequest, ElicitationResponse, ElicitationAction)
Elicitation request dispatch, form and url mode, schema validation, pending
queue management, response accept/dismiss/cancel, session cleanup on disconnect,
stress test for elicitation queue overflow.
- [x] Unit
- [x] Integration
- [x] End-to-End
- [x] Stress
- [x] Data Integrity
- [x] Security
- [x] Performance
17. Search
Files: services/musehub_search.py, api/routes/musehub/search.py, api/routes/api/search.py, api/routes/musehub/ui_search.py
search_by_property, search_by_ask, search_by_keyword, search_by_pattern,
global search (repo groups + commit matches), full-text search tokenization, score
overlap, pagination. SQL injection via search input must be tested explicitly.
- [x] Unit
- [x] Integration
- [x] End-to-End
- [x] Stress
- [x] Data Integrity
- [x] Security
- [x] Performance
18. Semantic Search (Qdrant)
Files: services/musehub_qdrant.py — DELETED: musehub_qdrant.py no longer exists.
All Qdrant integration was removed. No tests required. Section retired.
19. Webhooks & Webhook Dispatcher
Files: services/musehub_webhook_dispatcher.py, services/musehub_webhook_crypto.py, api/routes/musehub/webhooks.py, db/musehub_models.py (MusehubWebhook, MusehubWebhookDelivery)
Webhook CRUD, HMAC signature generation, delivery dispatch (HTTP POST to subscriber), delivery retry logic with backoff, failed delivery recording, secret rotation, payload size caps, SSRF protection (subscriber URL must not resolve to RFC-1918 ranges).
- [x] Unit
- [x] Integration
- [x] End-to-End
- [x] Stress
- [x] Data Integrity
- [x] Security
- [x] Performance
20. Social Graph (Stars, Forks, Follows, Watches)
Files: api/routes/musehub/social.py, services/musehub_profile.py, db/musehub_models.py (MusehubStar, MusehubFork, MusehubFollow, MusehubWatch)
Star/unstar, fork create and network graph, follow/unfollow, watch/unwatch, public repo visibility checks (private repos must not appear in social feeds), idempotent toggle correctness.
- [x] Unit
- [x] Integration
- [x] End-to-End
- [x] Stress
- [x] Data Integrity
- [x] Security
- [x] Performance
21. Notifications
Files: api/routes/musehub/ui_notifications.py, db/musehub_models.py (MusehubNotification), db/musehub_models.py (MusehubWatch)
Notification fanout on issue/proposal/comment events, read/unread state, mark-all-read, notification count in nav badge, watcher-only delivery (non-watchers must not receive notifications for private repos).
- [x] Unit
- [x] Integration
- [x] End-to-End
- [x] Stress
- [x] Data Integrity
- [x] Security
- [x] Performance
22. Activity Feed & Events
Files: services/musehub_events.py, api/routes/musehub/feeds.py, db/musehub_models.py (MusehubEvent, MusehubViewEvent, MusehubDownloadEvent)
record_event, list_events, list_user_activity, debounced view event (one row per
visitor per day), download event, repo activity event stream, pagination, private repo
filtering.
- [x] Unit
- [x] Integration
- [x] End-to-End
- [x] Stress
- [x] Data Integrity
- [x] Security
- [x] Performance
23. Agent Context API
Files: services/musehub_context.py, api/routes/musehub/repos.py (context endpoint), models/musehub_context.py
AgentContextResponse construction at all three ContextDepth levels, ref
resolution (branch name → commit_id), history build, open proposals/issues inclusion,
suggestion generation, graceful null handling for Storpheus-pending fields.
- [x] Unit
- [x] Integration
- [x] End-to-End
- [x] Stress
- [x] Data Integrity
- [x] Security
- [x] Performance
24. Workspace & Cross-Repo Intelligence
Files: services/musehub_cross_repo.py, api/routes/v2/workspace.py
search_symbol_across_repos, cross_repo_impact, workspace_blast_risk_top_n,
build_deps_graph, workspace intel aggregate, workspace coord forecast,
multi-repo symbol resolution, visibility gating (private repos invisible to
non-members in cross-repo results).
- [x] Unit
- [x] Integration
- [x] End-to-End
- [x] Stress
- [x] Data Integrity
- [x] Security
- [x] Performance
25. Domains
Files: services/musehub_domains.py, api/routes/musehub/domains.py, db/musehub_domain_models.py (MusehubDomain, MusehubDomainInstall)
Domain create, manifest hash computation, domain-by-scoped-id and by-id lookup, repo-for-domain listing, domain install lifecycle. Domain manifest tampering must be detected via hash mismatch.
- [x] Unit
- [x] Integration
- [x] End-to-End
- [x] Stress
- [x] Data Integrity
- [x] Security
- [x] Performance
26. Divergence Engine
Files: services/musehub_divergence.py, api/routes/musehub/repos.py (compare endpoint)
compute_hub_divergence, compute_hub_dimension_divergence, branch commit retrieval,
common ancestor find, commits-since, message classification, score-to-level, affected
section extraction. Must correctly handle repos with no common ancestor (fresh forks).
- [x] Unit
- [x] Integration
- [x] End-to-End
- [x] Stress
- [x] Data Integrity
- [x] Security
- [x] Performance
27. Collaborators & Permissions
Files: api/routes/musehub/collaborators.py, api/routes/musehub/ui_collaborators.py, db/musehub_collaborator_models.py
Add/remove collaborator, access level check (read vs write vs admin), owner-only operations (transfer, delete), collaborator list, private repo access gating across all protected endpoints.
- [x] Unit
- [x] Integration
- [x] End-to-End
- [x] Stress
- [x] Data Integrity
- [x] Security
- [x] Performance
28. Labels
Files: services/musehub_labels.py (if exists), api/routes/musehub/labels.py, db/musehub_label_models.py (MusehubLabel, MusehubIssueLabel, MusehubProposalLabel)
Label CRUD, color validation, issue/proposal label assign and unassign, label filter on issue/proposal list, label uniqueness per repo.
- [x] Unit
- [x] Integration
- [x] End-to-End
- [x] Stress
- [x] Data Integrity
- [x] Security
- [x] Performance
29. Stash
REMOVED — Source files deleted from codebase. Only stale
.pyccaches remained; those have been purged. No tests needed.
- [N/A] Unit
- [N/A] Integration
- [N/A] End-to-End
- [N/A] Stress
- [N/A] Data Integrity
- [N/A] Security
- [N/A] Performance
30. Sessions
Files: services/musehub_sessions.py, api/routes/musehub/sessions.py (if present), db/musehub_models.py (MusehubSession)
Recording session create, stop, list, retrieval, active-session SSE stream, session metadata correctness, ownership check.
- [x] Unit
- [x] Integration
- [x] End-to-End
- [x] Stress
- [x] Data Integrity
- [x] Security
- [x] Performance
31. Wire Tags
Files: services/musehub_wire_tags.py, api/routes/wire.py (wire_push_tags), db/musehub_models.py (MusehubWireTag)
Wire tag push (upsert semantics — duplicate push is no-op), tag list, tag delete,
(repo_id, tag) uniqueness constraint, max tag length enforcement, tag query
by label pattern.
- [x] Unit
- [x] Integration
- [x] End-to-End
- [x] Stress
- [x] Data Integrity
- [x] Security
- [x] Performance
32. Garbage Collector
Files: services/musehub_gc.py, api/routes/wire.py (_run_gc_async)
run_gc — unreferenced object detection and deletion, GC triggered on push,
GC must not delete objects referenced by any live snapshot, GC atomicity (partial
GC must not leave repo in inconsistent state).
- [x] Unit
- [x] Integration
- [x] End-to-End
- [x] Stress
- [x] Data Integrity
- [x] Security
- [x] Performance
33. Storage Backends
Files: storage/backends.py (BlobBackend, get_backend)
BlobBackend: write/read/exists/delete, presigned URL generation, get/put/delete,
credential failure handling, concurrent write correctness. Backend selection via config
(R2_BUCKET for R2/MinIO, AWS_S3_ASSET_BUCKET for AWS S3).
- [x] Unit
- [x] Integration
- [x] End-to-End
- [x] Stress
- [x] Data Integrity
- [x] Security
- [x] Performance
34. Rate Limiting
Files: rate_limits.py, all route files that apply limiters
Per-route limit enforcement (WIRE_PUSH_LIMIT, WIRE_FETCH_LIMIT, MCP_LIMIT,
AUTH_LIMIT, SEARCH_LIMIT, MCP_PUSH_LIMIT), 429 response format with
Retry-After, limit reset after window expiry, per-IP isolation (one IP hitting
the limit must not affect others), limit bypass attempts.
- [x] Unit
- [x] Integration
- [x] End-to-End
- [x] Stress
- [x] Data Integrity
- [x] Security
- [x] Performance
35. Request Signing (MSign)
Files: auth/request_signing.py, auth/dependencies.py
build_canonical_message, _verify_msign, require_signed_request,
optional_signed_request. Signature over method + path + body hash + timestamp,
replay attack prevention via timestamp window, wrong-key rejection, tampered-body
rejection.
- [x] Unit
- [x] Integration
- [x] End-to-End
- [x] Stress
- [x] Data Integrity
- [x] Security
- [x] Performance
36. Database Migrations (Alembic)
Files: alembic/versions/ (19 migrations)
Each migration must be tested forward and in rollback. Full migration chain from empty DB to HEAD must complete without errors. Production-sized data snapshot must survive the full chain. No orphaned columns, no missing indexes, no FK constraint violations post-migration.
- [x] Unit
- [x] Integration
- [x] End-to-End
- [x] Stress
- [x] Data Integrity
- [x] Security
- [x] Performance
37. API Contracts & OpenAPI
Files: api/, models/, contracts/
OpenAPI schema generation must succeed with zero warnings. Every route must have a
documented response type. Every Pydantic model must round-trip through JSON serialisation
without data loss. type-contracts.md must match what muse code symbols reports.
Additions to models/musehub.py must appear in the OpenAPI spec.
- [x] Unit
- [x] Integration
- [x] End-to-End
- [x] Stress
- [x] Data Integrity
- [x] Security
- [x] Performance
38. UI / SSR Routes
Files: api/routes/musehub/ui*.py, api/routes/musehub/ui.py, templates/musehub/
Server-side rendered Jinja2 pages: repo home, code browser, blame, symbols, symbol detail, issues (list + detail), proposals, releases, profiles, settings, explore, search results, notifications, stash, sessions, milestones, labels, topics, forks, collaborators, new repo, agent fleet. Each page must render without 500s for both populated and empty state. HTMX partial fragments must return correct HTML fragments.
- [x] Unit
- [x] Integration
- [x] End-to-End
- [x] Stress
- [x] Data Integrity
- [x] Security
- [x] Performance
39. Pagination
Files: All list endpoints across the API
Cursor-based and page-based pagination: correct total, page, total_pages
values, no off-by-one on boundaries, last page contains the remainder, empty
results return empty list not 404, page > total_pages returns empty gracefully,
sort stability across pages.
- [x] Unit
- [x] Integration
- [x] End-to-End
- [x] Stress
- [x] Data Integrity
- [x] Security
- [x] Performance
40. Webhook Crypto
Files: services/musehub_webhook_crypto.py
HMAC-SHA256 signature generation and verification, Fernet encryption/decryption
(for CI secrets via the same key), key rotation correctness (old payloads must fail
after rotation), hmac.compare_digest constant-time comparison.
- [x] Unit
- [x] Integration
- [x] End-to-End
- [x] Stress
- [x] Data Integrity
- [x] Security
- [x] Performance
41. GC & Background Tasks
Files: api/routes/wire.py (_build_symbol_index_async, _run_gc_async, _embed_push_async, _trigger_ci_push_async), services/musehub_gc.py
Background task scheduling on push, task failure isolation (a failed background task must not affect the push response), task idempotency (same push triggered twice must not double-index or double-trigger CI), concurrent background task correctness under high push volume.
- [x] Unit
- [x] Integration
- [x] End-to-End
- [x] Stress
- [x] Data Integrity
- [x] Security
- [x] Performance
42. Protocol Introspection
Files: protocol/responses.py, protocol/events.py, api/routes/ (protocol endpoints)
GET /protocol info response, GET /protocol/events.json, GET /protocol/tools.json,
GET /protocol/schema.json, compute_protocol_hash stability (same schema → same hash),
EVENT_REGISTRY completeness.
- [x] Unit
- [x] Integration
- [x] End-to-End
- [x] Stress
- [x] Data Integrity
- [x] Security
- [x] Performance
43. Install Script
Files: api/routes/musehub/install.py
Install script generation, MUSEHUB_URL substitution, uninstall script does NOT
delete ~/.muse, install script idempotency (running twice leaves a clean state),
archive URL construction, shell safety (no injection via user-controlled vars).
- [x] Unit
- [x] Integration
- [x] End-to-End
- [x] Stress
- [x] Data Integrity
- [x] Security
- [x] Performance
Progress Summary
| Component | Unit | Integration | E2E | Stress | Integrity | Security | Perf |
|---|---|---|---|---|---|---|---|
| 1. Wire Protocol | [x] | [x] | [x] | [x] | [x] | [x] | [x] |
| 2. Auth / MSign | [x] | [x] | [x] | [x] | [x] | [x] | [x] |
| 3. Object Store | [x] | [x] | [x] | [x] | [x] | [x] | [x] |
| 4. Repository Service | [x] | [x] | [x] | [x] | [x] | [x] | [x] |
| 5. Snapshot / Indexer | [x] | [x] | [x] | [x] | [x] | [x] | [x] |
| 6. Symbol Intelligence | [x] | [x] | [x] | [x] | [x] | [x] | [x] |
| 7. Coordination | [x] | [x] | [x] | [x] | [x] | [x] | [x] |
| 8. CI Trigger/Workflow/Gates | [x] | [x] | [x] | [x] | [x] | [x] | [x] |
| 9. CI Runner Protocol | [x] | [x] | [x] | [x] | [x] | [x] | [x] |
| 10. Issues & Milestones | [x] | [x] | [x] | [x] | [x] | [x] | [x] |
| 11. Merge Proposals | [x] | [x] | [x] | [x] | [x] | [x] | [x] |
| 12. Releases | [x] | [x] | [x] | [x] | [x] | [x] | [x] |
| 13. MCP Protocol Layer | [x] | [x] | [x] | [x] | [x] | [x] | [x] |
| 14. MCP Read Tools | [x] | [x] | [x] | [x] | [x] | [x] | [x] |
| 15. MCP Write Tools | [x] | [x] | [x] | [x] | [x] | [x] | [x] |
| 16. MCP Elicitation | [x] | [x] | [x] | [x] | [x] | [x] | [x] |
| 17. Search | [x] | [x] | [x] | [x] | [x] | [x] | [x] |
| 18. Semantic Search (Qdrant) | N/A | N/A | N/A | N/A | N/A | N/A | N/A |
| 19. Webhooks | [x] | [x] | [x] | [x] | [x] | [x] | [x] |
| 20. Social Graph | [x] | [x] | [x] | [x] | [x] | [x] | [x] |
| 21. Notifications | [x] | [x] | [x] | [x] | [x] | [x] | [x] |
| 22. Activity Feed | [x] | [x] | [x] | [x] | [x] | [x] | [x] |
| 23. Agent Context | [x] | [x] | [x] | [x] | [x] | [x] | [x] |
| 24. Workspace Intel | [x] | [x] | [x] | [x] | [x] | [x] | [x] |
| 25. Domains | [x] | [x] | [x] | [x] | [x] | [x] | [x] |
| 26. Divergence Engine | [x] | [x] | [x] | [x] | [x] | [x] | [x] |
| 27. Collaborators | [x] | [x] | [x] | [x] | [x] | [x] | [x] |
| 28. Labels | [x] | [x] | [x] | [x] | [x] | [x] | [x] |
| 29. Stash | N/A | N/A | N/A | N/A | N/A | N/A | N/A |
| 30. Sessions | [x] | [x] | [x] | [x] | [x] | [x] | [x] |
| 31. Wire Tags | [x] | [x] | [x] | [x] | [x] | [x] | [x] |
| 32. Garbage Collector | [x] | [x] | [x] | [x] | [x] | [x] | [x] |
| 33. Storage Backends | [x] | [x] | [x] | [x] | [x] | [x] | [x] |
| 34. Rate Limiting | [x] | [x] | [x] | [x] | [x] | [x] | [x] |
| 35. Request Signing | [x] | [x] | [x] | [x] | [x] | [x] | [x] |
| 36. Migrations | [x] | [x] | [x] | [x] | [x] | [x] | [x] |
| 37. API Contracts | [x] | [x] | [x] | [x] | [x] | [x] | [x] |
| 38. UI / SSR | [x] | [x] | [x] | [x] | [x] | [x] | [x] |
| 39. Pagination | [x] | [x] | [x] | [x] | [x] | [x] | [x] |
| 40. Webhook Crypto | [x] | [x] | [x] | [x] | [x] | [x] | [x] |
| 41. Background Tasks | [x] | [x] | [x] | [x] | [x] | [x] | [x] |
| 42. Protocol Introspection | [x] | [x] | [x] | [x] | [x] | [x] | [x] |
| 43. Install Script | [x] | [x] | [x] | [x] | [x] | [x] | [x] |
301 checkboxes total. Launch gate: all 301 checked.