# Musehub — Type Contracts Reference > Auto-generated: 2026-04-12 > Source: `tools/gen_type_contracts.py (repo: musehub)` > Check for drift: `python tools/gen_type_contracts.py --check` > > **Do not edit this file manually.** It is regenerated from source on every > commit. To update, change the source types and re-run the generator. --- ## Table of Contents - [Enums](#enums) (5) - [TypedDicts](#typeddicts) (47) - [Pydantic Models](#pydantic-models) (215) - [SQLAlchemy ORM Models](#sqlalchemy-orm-models) (43) - [Protocols](#protocols) (4) --- ## Enums ### `Permission` — [`musehub/api/routes/musehub/collaborators.py`](musehub/api/routes/musehub/collaborators.py) Collaborator permission levels in ascending order of authority. **Bases:** `StrEnum` | Member | Value | |--------|-------| | `read` | `'read'` | | `write` | `'write'` | | `admin` | `'admin'` | | `owner` | `'owner'` | ### `KeyAlgorithm` — [`musehub/crypto/keys.py`](musehub/crypto/keys.py) Supported key algorithm identifiers (wire strings). **Bases:** `str`, `Enum` | Member | Value | |--------|-------| | `ED25519` | `'ed25519'` | | `ML_DSA_65` | `'ml-dsa-65'` | ### `ContextDepth` — [`musehub/models/musehub_context.py`](musehub/models/musehub_context.py) Depth level controlling how much data the context endpoint returns. **Bases:** `StrEnum` | Member | Value | |--------|-------| | `brief` | `'brief'` | | `standard` | `'standard'` | | `verbose` | `'verbose'` | ### `ContextFormat` — [`musehub/models/musehub_context.py`](musehub/models/musehub_context.py) Wire format for the context response. **Bases:** `StrEnum` | Member | Value | |--------|-------| | `json` | `'json'` | | `yaml` | `'yaml'` | ### `MuseHubDivergenceLevel` — [`musehub/services/musehub_divergence.py`](musehub/services/musehub_divergence.py) Qualitative label for a per-dimension or overall divergence score. **Bases:** `StrEnum` | Member | Value | |--------|-------| | `NONE` | `'NONE'` | | `LOW` | `'LOW'` | | `MED` | `'MED'` | | `HIGH` | `'HIGH'` | ## TypedDicts ### `_IdentityDict` — [`musehub/api/routes/api/identities.py`](musehub/api/routes/api/identities.py) **Bases:** `TypedDict` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `id` | `str` | ✓ | `—` | | `handle` | `str` | ✓ | `—` | | `identity_type` | `str` | ✓ | `—` | | `display_name` | `str | None` | ✓ | `—` | | `bio` | `str | None` | ✓ | `—` | | `avatar_url` | `str | None` | ✓ | `—` | | `website_url` | `str | None` | ✓ | `—` | | `email` | `str | None` | ✓ | `—` | | `agent_model` | `str | None` | ✓ | `—` | | `agent_capabilities` | `list[str]` | ✓ | `—` | | `spawned_by` | `str | None` | ✓ | `—` | | `scope` | `str | None` | ✓ | `—` | | `expires_at` | `str | None` | ✓ | `—` | | `created_at` | `str | None` | ✓ | `—` | | `updated_at` | `str | None` | ✓ | `—` | ### `MCPPromptArgument` — [`musehub/mcp/prompts.py`](musehub/mcp/prompts.py) A single named argument for an MCP prompt. **Bases:** `TypedDict` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `name` | `Required[str]` | ✓ | `—` | | `description` | `str` | ✓ | `—` | | `required` | `bool` | ✓ | `—` | ### `MCPPromptDef` — [`musehub/mcp/prompts.py`](musehub/mcp/prompts.py) Definition of a single MCP prompt exposed to agents. **Bases:** `TypedDict` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `name` | `Required[str]` | ✓ | `—` | | `description` | `Required[str]` | ✓ | `—` | | `arguments` | `list[MCPPromptArgument]` | ✓ | `—` | ### `MCPPromptMessage` — [`musehub/mcp/prompts.py`](musehub/mcp/prompts.py) A single message in an MCP prompt response. **Bases:** `TypedDict` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `role` | `str` | ✓ | `—` | | `content` | `MCPPromptMessageContent` | ✓ | `—` | ### `MCPPromptMessageContent` — [`musehub/mcp/prompts.py`](musehub/mcp/prompts.py) The content of a single prompt message. **Bases:** `TypedDict` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `type` | `str` | ✓ | `—` | | `text` | `str` | ✓ | `—` | ### `MCPPromptResult` — [`musehub/mcp/prompts.py`](musehub/mcp/prompts.py) The result returned by ``prompts/get``. **Bases:** `TypedDict` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `description` | `str` | ✓ | `—` | | `messages` | `list[MCPPromptMessage]` | ✓ | `—` | ### `MCPResource` — [`musehub/mcp/resources.py`](musehub/mcp/resources.py) A concrete MCP resource (static URI). **Bases:** `TypedDict` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `uri` | `Required[str]` | ✓ | `—` | | `name` | `Required[str]` | ✓ | `—` | | `description` | `str` | ✓ | `—` | | `mimeType` | `str` | ✓ | `—` | ### `MCPResourceContent` — [`musehub/mcp/resources.py`](musehub/mcp/resources.py) The content object returned inside a ``resources/read`` response. **Bases:** `TypedDict` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `uri` | `str` | ✓ | `—` | | `mimeType` | `str` | ✓ | `—` | | `text` | `str` | ✓ | `—` | ### `MCPResourceTemplate` — [`musehub/mcp/resources.py`](musehub/mcp/resources.py) An MCP resource template (RFC 6570 URI template). **Bases:** `TypedDict` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `uriTemplate` | `Required[str]` | ✓ | `—` | | `name` | `Required[str]` | ✓ | `—` | | `description` | `str` | ✓ | `—` | | `mimeType` | `str` | ✓ | `—` | ### `IssueEventPayload` — [`musehub/models/musehub.py`](musehub/models/musehub.py) Payload emitted when an issue is opened or closed. **Bases:** `TypedDict` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `repoId` | `str` | ✓ | `—` | | `action` | `str` | ✓ | `—` | | `issueId` | `str` | ✓ | `—` | | `number` | `int` | ✓ | `—` | | `title` | `str` | ✓ | `—` | | `state` | `str` | ✓ | `—` | ### `ProposalEventPayload` — [`musehub/models/musehub.py`](musehub/models/musehub.py) Payload emitted when a merge proposal is opened or merged. **Bases:** `TypedDict` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `repoId` | `str` | ✓ | `—` | | `action` | `str` | ✓ | `—` | | `proposalId` | `str` | ✓ | `—` | | `title` | `str` | ✓ | `—` | | `fromBranch` | `str` | ✓ | `—` | | `toBranch` | `str` | ✓ | `—` | | `state` | `str` | ✓ | `—` | | `mergeCommitId` | `NotRequired[str]` | ✓ | `—` | ### `PushEventPayload` — [`musehub/models/musehub.py`](musehub/models/musehub.py) Payload emitted when commits are pushed to a MuseHub repo. **Bases:** `TypedDict` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `repoId` | `str` | ✓ | `—` | | `branch` | `str` | ✓ | `—` | | `headCommitId` | `str` | ✓ | `—` | | `pushedBy` | `str` | ✓ | `—` | | `commitCount` | `int` | ✓ | `—` | ### `DAWToolCallMessage` — [`musehub/muse_contracts/mcp_types.py`](musehub/muse_contracts/mcp_types.py) Message sent from the MCP server to the connected DAW over WebSocket. **Bases:** `TypedDict` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `type` | `Literal['toolCall']` | ✓ | `—` | | `requestId` | `str` | ✓ | `—` | | `tool` | `str` | ✓ | `—` | | `arguments` | `JSONObject` | ✓ | `—` | ### `DAWToolResponse` — [`musehub/muse_contracts/mcp_types.py`](musehub/muse_contracts/mcp_types.py) Response sent from the DAW back to the MCP server after tool execution. **Bases:** `TypedDict` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `success` | `Required[bool]` | ✓ | `—` | | `content` | `list[MCPContentBlock]` | ✓ | `—` | | `isError` | `bool` | ✓ | `—` | ### `ElicitationAction` — [`musehub/muse_contracts/mcp_types.py`](musehub/muse_contracts/mcp_types.py) The action taken by the user in response to an elicitation request. **Bases:** `TypedDict` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `action` | `Required[str]` | ✓ | `—` | | `content` | `NotRequired[JSONObject]` | ✓ | `—` | ### `ElicitationRequest` — [`musehub/muse_contracts/mcp_types.py`](musehub/muse_contracts/mcp_types.py) An ``elicitation/create`` request sent from the server to the client. **Bases:** `TypedDict` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `mode` | `Required[str]` | ✓ | `—` | | `message` | `Required[str]` | ✓ | `—` | | `requestedSchema` | `NotRequired[JSONObject]` | ✓ | `—` | | `url` | `NotRequired[str]` | ✓ | `—` | | `elicitationId` | `NotRequired[str]` | ✓ | `—` | ### `ElicitationResponse` — [`musehub/muse_contracts/mcp_types.py`](musehub/muse_contracts/mcp_types.py) A JSON-RPC 2.0 response from the client to an ``elicitation/create`` request. **Bases:** `TypedDict` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `action` | `Required[str]` | ✓ | `—` | | `content` | `NotRequired[JSONObject]` | ✓ | `—` | ### `MCPCallResponse` — [`musehub/muse_contracts/mcp_types.py`](musehub/muse_contracts/mcp_types.py) Full JSON-RPC response for the ``tools/call`` method. **Bases:** `TypedDict` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `jsonrpc` | `str` | ✓ | `—` | | `id` | `str | int | None` | ✓ | `—` | | `result` | `MCPCallResult` | ✓ | `—` | ### `MCPCallResult` — [`musehub/muse_contracts/mcp_types.py`](musehub/muse_contracts/mcp_types.py) Result body for the ``tools/call`` JSON-RPC method. **Bases:** `TypedDict` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `content` | `Required[list[MCPContentBlock]]` | ✓ | `—` | | `isError` | `bool` | ✓ | `—` | ### `MCPCapabilities` — [`musehub/muse_contracts/mcp_types.py`](musehub/muse_contracts/mcp_types.py) MCP server capabilities advertised during the ``initialize`` handshake. **Bases:** `TypedDict` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `tools` | `MCPToolsCapability` | ✓ | `—` | | `resources` | `MCPResourcesCapability` | ✓ | `—` | ### `MCPCapabilitiesResult` — [`musehub/muse_contracts/mcp_types.py`](musehub/muse_contracts/mcp_types.py) Result body for ``initialize`` — capability block. **Bases:** `TypedDict` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `tools` | `MCPToolsCapability` | ✓ | `—` | ### `MCPContentBlock` — [`musehub/muse_contracts/mcp_types.py`](musehub/muse_contracts/mcp_types.py) A content block in an MCP tool result (currently always text). **Bases:** `TypedDict` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `type` | `str` | ✓ | `—` | | `text` | `str` | ✓ | `—` | ### `MCPErrorDetail` — [`musehub/muse_contracts/mcp_types.py`](musehub/muse_contracts/mcp_types.py) The ``error`` object inside a JSON-RPC 2.0 error response. **Bases:** `TypedDict` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `code` | `Required[int]` | ✓ | `—` | | `message` | `Required[str]` | ✓ | `—` | | `data` | `JSONValue` | ✓ | `—` | ### `MCPErrorResponse` — [`musehub/muse_contracts/mcp_types.py`](musehub/muse_contracts/mcp_types.py) A JSON-RPC 2.0 error response. **Bases:** `TypedDict` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `jsonrpc` | `str` | ✓ | `—` | | `id` | `str | int | None` | ✓ | `—` | | `error` | `MCPErrorDetail` | ✓ | `—` | ### `MCPInitializeParams` — [`musehub/muse_contracts/mcp_types.py`](musehub/muse_contracts/mcp_types.py) Params for the ``initialize`` JSON-RPC method. **Bases:** `TypedDict` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `protocolVersion` | `Required[str]` | ✓ | `—` | | `clientInfo` | `StrDict` | ✓ | `—` | | `capabilities` | `JSONObject` | ✓ | `—` | ### `MCPInitializeResponse` — [`musehub/muse_contracts/mcp_types.py`](musehub/muse_contracts/mcp_types.py) Full JSON-RPC response for the ``initialize`` method. **Bases:** `TypedDict` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `jsonrpc` | `str` | ✓ | `—` | | `id` | `str | int | None` | ✓ | `—` | | `result` | `MCPInitializeResult` | ✓ | `—` | ### `MCPInitializeResult` — [`musehub/muse_contracts/mcp_types.py`](musehub/muse_contracts/mcp_types.py) Result body for the ``initialize`` JSON-RPC method. **Bases:** `TypedDict` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `protocolVersion` | `str` | ✓ | `—` | | `serverInfo` | `MCPServerInfo` | ✓ | `—` | | `capabilities` | `MCPCapabilitiesResult` | ✓ | `—` | ### `MCPInputSchema` — [`musehub/muse_contracts/mcp_types.py`](musehub/muse_contracts/mcp_types.py) JSON Schema describing an MCP tool's accepted arguments. **Bases:** `TypedDict` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `type` | `Required[str]` | ✓ | `—` | | `properties` | `Required[_PropInputMap]` | ✓ | `—` | | `required` | `list[str]` | ✓ | `—` | ### `MCPPropertyDef` — [`musehub/muse_contracts/mcp_types.py`](musehub/muse_contracts/mcp_types.py) JSON Schema definition for a single MCP tool property. **Bases:** `TypedDict` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `type` | `Required[str]` | ✓ | `—` | | `description` | `str` | ✓ | `—` | | `enum` | `list[str | int | float]` | ✓ | `—` | | `minimum` | `float` | ✓ | `—` | | `maximum` | `float` | ✓ | `—` | | `default` | `JSONValue` | ✓ | `—` | | `items` | `JSONObject` | ✓ | `—` | | `properties` | `_PropDefMap` | ✓ | `—` | ### `MCPRequest` — [`musehub/muse_contracts/mcp_types.py`](musehub/muse_contracts/mcp_types.py) An incoming JSON-RPC 2.0 message from an MCP client. **Bases:** `TypedDict` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `jsonrpc` | `Required[str]` | ✓ | `—` | | `method` | `Required[str]` | ✓ | `—` | | `id` | `str | int | None` | ✓ | `—` | | `params` | `JSONObject` | ✓ | `—` | ### `MCPResourcesCapability` — [`musehub/muse_contracts/mcp_types.py`](musehub/muse_contracts/mcp_types.py) The ``resources`` entry in ``MCPCapabilities``. **Bases:** `TypedDict` _No annotated fields._ ### `MCPServerInfo` — [`musehub/muse_contracts/mcp_types.py`](musehub/muse_contracts/mcp_types.py) MCP server info returned in ``initialize`` responses and ``get_server_info()``. **Bases:** `TypedDict` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `name` | `str` | ✓ | `—` | | `version` | `str` | ✓ | `—` | | `protocolVersion` | `str` | ✓ | `—` | | `capabilities` | `MCPCapabilities` | ✓ | `—` | ### `MCPSuccessResponse` — [`musehub/muse_contracts/mcp_types.py`](musehub/muse_contracts/mcp_types.py) A JSON-RPC 2.0 success response. **Bases:** `TypedDict` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `jsonrpc` | `str` | ✓ | `—` | | `id` | `str | int | None` | ✓ | `—` | | `result` | `JSONObject` | ✓ | `—` | ### `MCPToolAnnotations` — [`musehub/muse_contracts/mcp_types.py`](musehub/muse_contracts/mcp_types.py) MCP 2025-11-25 tool annotations — behavioural hints for LLM clients. **Bases:** `TypedDict` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `readOnlyHint` | `bool` | ✓ | `—` | | `destructiveHint` | `bool` | ✓ | `—` | | `idempotentHint` | `bool` | ✓ | `—` | | `openWorldHint` | `bool` | ✓ | `—` | ### `MCPToolCallParams` — [`musehub/muse_contracts/mcp_types.py`](musehub/muse_contracts/mcp_types.py) Params for the ``tools/call`` JSON-RPC method. **Bases:** `TypedDict` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `name` | `str` | ✓ | `—` | | `arguments` | `JSONObject` | ✓ | `—` | ### `MCPToolDef` — [`musehub/muse_contracts/mcp_types.py`](musehub/muse_contracts/mcp_types.py) Definition of a single MCP tool exposed to LLM clients. **Bases:** `TypedDict` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `name` | `Required[str]` | ✓ | `—` | | `description` | `Required[str]` | ✓ | `—` | | `inputSchema` | `Required[MCPInputSchema]` | ✓ | `—` | | `annotations` | `MCPToolAnnotations` | ✓ | `—` | | `server_side` | `bool` | ✓ | `—` | ### `MCPToolsCapability` — [`musehub/muse_contracts/mcp_types.py`](musehub/muse_contracts/mcp_types.py) The ``tools`` entry in ``MCPCapabilities``. **Bases:** `TypedDict` _No annotated fields._ ### `MCPToolsListResponse` — [`musehub/muse_contracts/mcp_types.py`](musehub/muse_contracts/mcp_types.py) Full JSON-RPC response for the ``tools/list`` method. **Bases:** `TypedDict` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `jsonrpc` | `str` | ✓ | `—` | | `id` | `str | int | None` | ✓ | `—` | | `result` | `MCPToolsListResult` | ✓ | `—` | ### `MCPToolsListResult` — [`musehub/muse_contracts/mcp_types.py`](musehub/muse_contracts/mcp_types.py) Result body for the ``tools/list`` JSON-RPC method. **Bases:** `TypedDict` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `tools` | `list[MCPToolDef]` | ✓ | `—` | ### `SessionInfo` — [`musehub/muse_contracts/mcp_types.py`](musehub/muse_contracts/mcp_types.py) Summary of an active MCP session — returned in server metadata endpoints. **Bases:** `TypedDict` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `session_id` | `Required[str]` | ✓ | `—` | | `user_id` | `Required[str | None]` | ✓ | `—` | | `client_capabilities` | `NotRequired[JSONObject]` | ✓ | `—` | | `pending_count` | `NotRequired[int]` | ✓ | `—` | | `sse_queue_count` | `NotRequired[int]` | ✓ | `—` | | `created_at` | `NotRequired[float]` | ✓ | `—` | | `last_active` | `NotRequired[float]` | ✓ | `—` | | `supports_form_elicitation` | `NotRequired[bool]` | ✓ | `—` | | `supports_url_elicitation` | `NotRequired[bool]` | ✓ | `—` | ### `_ChildOp` — [`tests/test_musehub_proposals_touched_symbols.py`](tests/test_musehub_proposals_touched_symbols.py) **Bases:** `TypedDict` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `op` | `str` | ✓ | `—` | | `address` | `str` | ✓ | `—` | | `content_summary` | `str` | ✓ | `—` | ### `_Delta` — [`tests/test_musehub_proposals_touched_symbols.py`](tests/test_musehub_proposals_touched_symbols.py) **Bases:** `TypedDict` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `ops` | `list[_DeltaOp]` | ✓ | `—` | ### `_DeltaOp` — [`tests/test_musehub_proposals_touched_symbols.py`](tests/test_musehub_proposals_touched_symbols.py) **Bases:** `TypedDict` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `address` | `str` | ✓ | `—` | | `child_ops` | `list[_ChildOp]` | ✓ | `—` | ### `_S3GetResponse` — [`tests/test_storage_backends_section33.py`](tests/test_storage_backends_section33.py) **Bases:** `TypedDict` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `Body` | `MagicMock` | ✓ | `—` | ### `_DeltaObjectPayload` — [`tests/test_wire_compression.py`](tests/test_wire_compression.py) **Bases:** `TypedDict` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `object_id` | `str` | ✓ | `—` | | `content` | `bytes` | ✓ | `—` | | `path` | `str` | ✓ | `—` | | `encoding` | `str` | ✓ | `—` | | `base_id` | `str` | ✓ | `—` | ### `_RawObjectPayload` — [`tests/test_wire_compression.py`](tests/test_wire_compression.py) **Bases:** `TypedDict` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `object_id` | `str` | ✓ | `—` | | `content` | `bytes` | ✓ | `—` | | `path` | `str` | ✓ | `—` | | `encoding` | `str` | ✓ | `—` | ### `_ZlibObjectPayload` — [`tests/test_wire_compression.py`](tests/test_wire_compression.py) **Bases:** `TypedDict` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `object_id` | `str` | ✓ | `—` | | `content` | `bytes` | ✓ | `—` | | `path` | `str` | ✓ | `—` | | `encoding` | `str` | ✓ | `—` | ## Pydantic Models ### `CreateIdentityRequest` — [`musehub/api/routes/api/identities.py`](musehub/api/routes/api/identities.py) **Bases:** `BaseModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `handle` | `str` | ✓ | `—` | | `identity_type` | `str` | | `'human'` | | `display_name` | `str | None` | | `None` | | `bio` | `str | None` | | `None` | | `avatar_url` | `str | None` | | `None` | | `website_url` | `str | None` | | `None` | | `email` | `str | None` | | `None` | | `agent_model` | `str | None` | | `None` | | `agent_capabilities` | `list[str]` | | `[]` | ### `UpdateIdentityRequest` — [`musehub/api/routes/api/identities.py`](musehub/api/routes/api/identities.py) **Bases:** `BaseModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `display_name` | `str | None` | | `None` | | `bio` | `str | None` | | `None` | | `avatar_url` | `str | None` | | `None` | | `website_url` | `str | None` | | `None` | | `email` | `str | None` | | `None` | | `agent_model` | `str | None` | | `None` | | `agent_capabilities` | `list[str] | None` | | `None` | ### `CollaboratorInviteRequest` — [`musehub/api/routes/musehub/collaborators.py`](musehub/api/routes/musehub/collaborators.py) Body for POST /collaborators — invite a new collaborator. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `handle` | `str` | ✓ | `—` | | `permission` | `Permission` | ✓ | `Field(Permission.write, description='Initial permission level (read | write | admin)')` | ### `CollaboratorListResponse` — [`musehub/api/routes/musehub/collaborators.py`](musehub/api/routes/musehub/collaborators.py) Paginated list of repository collaborators. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `collaborators` | `list[CollaboratorResponse]` | ✓ | `—` | | `total` | `int` | ✓ | `—` | ### `CollaboratorPermissionUpdate` — [`musehub/api/routes/musehub/collaborators.py`](musehub/api/routes/musehub/collaborators.py) Body for PUT /collaborators/{handle}/permission — update permission. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `permission` | `Permission` | ✓ | `—` | ### `CollaboratorResponse` — [`musehub/api/routes/musehub/collaborators.py`](musehub/api/routes/musehub/collaborators.py) A single collaborator entry. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `collaborator_id` | `str` | ✓ | `—` | | `repo_id` | `str` | ✓ | `—` | | `handle` | `str` | ✓ | `—` | | `permission` | `str` | ✓ | `—` | | `invited_by` | `str | None` | | `Field(None, description='Handle of the inviter (null if added programmatically)')` | ### `RegisterDomainRequest` — [`musehub/api/routes/musehub/domains.py`](musehub/api/routes/musehub/domains.py) Body for registering a new domain plugin. **Bases:** `BaseModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `author_slug` | `str` | ✓ | `—` | | `slug` | `str` | ✓ | `—` | | `display_name` | `str` | ✓ | `—` | | `description` | `str` | | `''` | | `capabilities` | `dict[str, PydanticJson]` | ✓ | `—` | | `viewer_type` | `str` | | `'generic'` | | `version` | `str` | | `'1.0.0'` | ### `AssignLabelsRequest` — [`musehub/api/routes/musehub/labels.py`](musehub/api/routes/musehub/labels.py) Body for bulk-assigning labels to an issue or proposal. **Bases:** `BaseModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `label_ids` | `list[str]` | ✓ | `—` | ### `LabelCreate` — [`musehub/api/routes/musehub/labels.py`](musehub/api/routes/musehub/labels.py) Payload for creating a new label. **Bases:** `BaseModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `name` | `str` | ✓ | `—` | | `color` | `str` | ✓ | `—` | | `description` | `str | None` | | `Field(None, max_length=200, description='Optional human-readable description')` | ### `LabelListResponse` — [`musehub/api/routes/musehub/labels.py`](musehub/api/routes/musehub/labels.py) Paginated list of labels. **Bases:** `BaseModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `items` | `list[LabelResponse]` | ✓ | `—` | | `total` | `int` | ✓ | `—` | ### `LabelResponse` — [`musehub/api/routes/musehub/labels.py`](musehub/api/routes/musehub/labels.py) Public representation of a label. **Bases:** `BaseModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `label_id` | `str` | ✓ | `—` | | `repo_id` | `str` | ✓ | `—` | | `name` | `str` | ✓ | `—` | | `color` | `str` | ✓ | `—` | | `description` | `str | None` | | `None` | ### `LabelUpdate` — [`musehub/api/routes/musehub/labels.py`](musehub/api/routes/musehub/labels.py) Payload for updating an existing label (all fields optional). **Bases:** `BaseModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `name` | `str | None` | | `Field(None, min_length=1, max_length=50)` | | `color` | `str | None` | | `Field(None, pattern='^#[0-9a-fA-F]{6}$')` | | `description` | `str | None` | | `Field(None, max_length=200)` | ### `SetTopicsRequest` — [`musehub/api/routes/musehub/topics.py`](musehub/api/routes/musehub/topics.py) Body for POST /repos/{repo_id}/topics. **Bases:** `BaseModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `topics` | `list[str]` | ✓ | `—` | ### `SetTopicsResponse` — [`musehub/api/routes/musehub/topics.py`](musehub/api/routes/musehub/topics.py) Result of POST /repos/{repo_id}/topics. **Bases:** `BaseModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `repo_id` | `str` | ✓ | `—` | | `topics` | `list[str]` | ✓ | `—` | ### `TopicItem` — [`musehub/api/routes/musehub/topics.py`](musehub/api/routes/musehub/topics.py) A single topic entry returned by GET /topics. **Bases:** `BaseModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `name` | `str` | ✓ | `—` | | `repo_count` | `int` | ✓ | `—` | ### `TopicListResponse` — [`musehub/api/routes/musehub/topics.py`](musehub/api/routes/musehub/topics.py) Response for GET /musehub/topics. **Bases:** `BaseModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `topics` | `list[TopicItem]` | ✓ | `—` | ### `TopicReposResponse` — [`musehub/api/routes/musehub/topics.py`](musehub/api/routes/musehub/topics.py) Cursor-paginated repo list for GET /musehub/topics/{tag}/repos. **Bases:** `BaseModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `tag` | `str` | ✓ | `—` | | `repos` | `list[ExploreRepoResult]` | ✓ | `—` | | `total` | `int` | ✓ | `—` | | `next_cursor` | `str | None` | | `Field(None, alias='nextCursor')` | ### `CuratedGroup` — [`musehub/api/routes/musehub/ui_topics.py`](musehub/api/routes/musehub/ui_topics.py) A labelled set of topic items surfaced on the topics index page. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `label` | `str` | ✓ | `—` | | `topics` | `list[TopicItem]` | ✓ | `—` | ### `TopicsIndexResponse` — [`musehub/api/routes/musehub/ui_topics.py`](musehub/api/routes/musehub/ui_topics.py) JSON response for GET /topics. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `all_topics` | `list[TopicItem]` | ✓ | `—` | | `curated_groups` | `list[CuratedGroup]` | ✓ | `—` | | `total` | `int` | ✓ | `—` | ### `CreateProfileBody` — [`musehub/api/routes/musehub/users.py`](musehub/api/routes/musehub/users.py) Body for POST /api/musehub/users — create a public profile for the authenticated user. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `username` | `str` | ✓ | `—` | | `bio` | `str | None` | | `Field(None, max_length=500, description='Short bio (Markdown supported)')` | | `avatar_url` | `str | None` | | `Field(None, max_length=2048, description='Avatar image URL')` | ### `UserCardResponse` — [`musehub/api/routes/musehub/users.py`](musehub/api/routes/musehub/users.py) Compact user card returned by followers-list and following-list endpoints. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `username` | `str` | ✓ | `—` | | `bio` | `str | None` | | `None` | | `avatar_url` | `str | None` | | `None` | ### `_WorkerObjectEntry` — [`musehub/api/routes/wire.py`](musehub/api/routes/wire.py) One object stored by the Cloudflare Worker. **Bases:** `BaseModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `object_id` | `str` | ✓ | `—` | | `path` | `str` | | `''` | | `size` | `int` | | `0` | ### `_WorkerRegisterRequest` — [`musehub/api/routes/wire.py`](musehub/api/routes/wire.py) Body sent by the Cloudflare mpack-receiver Worker. **Bases:** `BaseModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `owner` | `str` | ✓ | `—` | | `slug` | `str` | ✓ | `—` | | `objects` | `list[_WorkerObjectEntry]` | ✓ | `—` | ### `Settings` — [`musehub/config.py`](musehub/config.py) Application settings loaded from environment variables. **Bases:** `BaseSettings` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `app_name` | `str` | | `'Muse'` | | `app_version` | `str` | | `_app_version_from_package()` | | `debug` | `bool` | | `False` | | `muse_env` | `str` | | `'production'` | | `public_url` | `str` | | `'https://musehub.ai'` | | `allowed_hosts` | `list[str]` | | `['musehub.ai', 'staging.musehub.ai', 'localhost:1337']` | | `host` | `str` | | `'0.0.0.0'` | | `port` | `int` | | `10001` | | `database_url` | `str | None` | | `None` | | `db_password` | `str | None` | | `None` | | `cors_origins` | `list[str]` | | `[]` | | `aws_region` | `str` | | `'eu-west-1'` | | `aws_s3_asset_bucket` | `str | None` | | `None` | | `aws_cloudfront_domain` | `str | None` | | `None` | | `presign_expiry_seconds` | `int` | | `1800` | | `r2_bucket` | `str | None` | | `None` | | `r2_endpoint` | `str | None` | | `None` | | `r2_access_key_id` | `str | None` | | `None` | | `r2_secret_access_key` | `str | None` | | `None` | | `r2_region` | `str` | | `'auto'` | | `asset_rate_limit_per_device` | `str` | | `'30/minute'` | | `asset_rate_limit_per_ip` | `str` | | `'120/minute'` | | `mcp_rate_limit_human` | `str` | | `'60/minute'` | | `mcp_rate_limit_agent` | `str` | | `'600/minute'` | | `mcp_rate_limit_anonymous` | `str` | | `'20/minute'` | | `db_pool_timeout` | `int` | | `30` | | `slow_query_threshold_ms` | `int` | | `100` | | `mcp_push_per_user_quota_bytes` | `int` | | `10 * 1024 * 1024 * 1024` | | `per_repo_quota_bytes` | `int` | | `5 * 1024 * 1024 * 1024` | | `object_retention_days` | `int` | | `30` | | `muse_mcp_url` | `str | None` | | `None` | | `mcp_token` | `str | None` | | `None` | | `musehub_objects_dir` | `str` | | `'/data/musehub/objects'` | | `musehub_releases_dir` | `str` | | `'/data/releases'` | | `webhook_secret_key` | `str | None` | | `None` | | `require_signed_commits` | `bool` | | `False` | | `trusted_agent_ids` | `list[str]` | | `[]` | | `worker_internal_key` | `str | None` | | `None` | | `pack_worker_url` | `str | None` | | `None` | ### `CamelModel` — [`musehub/models/base.py`](musehub/models/base.py) Base model that serializes to camelCase on the wire. **Bases:** `BaseModel` _No annotated fields._ ### `CoordPollRequest` — [`musehub/models/coord.py`](musehub/models/coord.py) Request body for ``POST /{owner}/{slug}/coord/pull``. **Bases:** `BaseModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `since_id` | `int` | | `0` | | `kinds` | `list[str]` | | `(factory)` | | `limit` | `int` | | `500` | ### `CoordPullResponse` — [`musehub/models/coord.py`](musehub/models/coord.py) Response for ``POST /{owner}/{slug}/coord/pull``. **Bases:** `BaseModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `records` | `list[CoordRecordOut]` | ✓ | `—` | | `cursor` | `int` | ✓ | `—` | ### `CoordPushRequest` — [`musehub/models/coord.py`](musehub/models/coord.py) Request body for ``POST /{owner}/{slug}/coord/push``. **Bases:** `BaseModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `records` | `list[CoordRecordIn]` | ✓ | `—` | ### `CoordPushResponse` — [`musehub/models/coord.py`](musehub/models/coord.py) Response for ``POST /{owner}/{slug}/coord/push``. **Bases:** `BaseModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `inserted` | `int` | ✓ | `—` | | `skipped` | `int` | ✓ | `—` | ### `CoordRecordIn` — [`musehub/models/coord.py`](musehub/models/coord.py) A single coordination record to be pushed to MuseHub. **Bases:** `BaseModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `kind` | `str` | ✓ | `—` | | `record_uuid` | `str` | ✓ | `—` | | `run_id` | `str` | | `''` | | `payload` | `PydanticJson` | ✓ | `—` | | `expires_at` | `datetime | None` | | `None` | ### `CoordRecordOut` — [`musehub/models/coord.py`](musehub/models/coord.py) A coordination record returned from MuseHub (pull or watch). **Bases:** `BaseModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `id` | `int` | ✓ | `—` | | `repo_id` | `str` | ✓ | `—` | | `kind` | `str` | ✓ | `—` | | `record_uuid` | `str` | ✓ | `—` | | `run_id` | `str` | ✓ | `—` | | `payload` | `PydanticJson` | ✓ | `—` | | `created_at` | `datetime` | ✓ | `—` | | `expires_at` | `datetime | None` | | `None` | ### `ActivityEventResponse` — [`musehub/models/musehub.py`](musehub/models/musehub.py) Wire representation of a single repo-level activity event. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `event_id` | `str` | ✓ | `—` | | `repo_id` | `str` | ✓ | `—` | | `event_type` | `str` | ✓ | `—` | | `actor` | `str` | ✓ | `—` | | `description` | `str` | ✓ | `—` | | `metadata` | `dict[str, PydanticJson]` | | `(factory)` | | `created_at` | `datetime` | ✓ | `—` | ### `AgentCardEntry` — [`musehub/models/musehub.py`](musehub/models/musehub.py) A single agent that has committed to repos owned by a human identity. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `agent_id` | `str` | ✓ | `—` | | `model_id` | `str | None` | | `None` | | `model_label` | `str` | ✓ | `—` | | `commit_count` | `int` | ✓ | `—` | | `repo_count` | `int` | ✓ | `—` | | `last_seen` | `datetime` | ✓ | `—` | ### `AgentFleetResponse` — [`musehub/models/musehub.py`](musehub/models/musehub.py) All agents deployed by a given handle, sorted by commit volume. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `handle` | `str` | ✓ | `—` | | `agents` | `list[AgentCardEntry]` | ✓ | `—` | | `total` | `int` | ✓ | `—` | ### `ApiChangeSummaryResponse` — [`musehub/models/musehub.py`](musehub/models/musehub.py) A public-API symbol that was added, removed, or modified. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `address` | `str` | ✓ | `—` | | `language` | `str` | | `''` | | `kind` | `str` | | `''` | | `change` | `str` | | `''` | ### `BlobMetaResponse` — [`musehub/models/musehub.py`](musehub/models/musehub.py) Wire representation of a single file (blob) in the Muse tree browser. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `object_id` | `str` | ✓ | `—` | | `path` | `str` | ✓ | `—` | | `filename` | `str` | ✓ | `—` | | `size_bytes` | `int` | ✓ | `—` | | `sha` | `str` | ✓ | `—` | | `created_at` | `datetime` | ✓ | `—` | | `raw_url` | `str` | ✓ | `—` | | `file_type` | `str` | ✓ | `—` | | `content_text` | `str | None` | | `Field(None, description='UTF-8 content for JSON/XML files up to 256 KB; None for binary or oversized files')` | ### `BranchDetailListResponse` — [`musehub/models/musehub.py`](musehub/models/musehub.py) List of branches with detail — used by the branch list page and its JSON variant. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `branches` | `list[BranchDetailResponse]` | ✓ | `—` | | `default_branch` | `str` | | `Field('main', description="Name of the repo's default branch")` | ### `BranchDetailResponse` — [`musehub/models/musehub.py`](musehub/models/musehub.py) Branch pointer enriched with ahead/behind counts and musical divergence. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `branch_id` | `str` | ✓ | `—` | | `name` | `str` | ✓ | `—` | | `head_commit_id` | `str | None` | | `Field(None, description='HEAD commit ID; null for an empty branch')` | | `is_default` | `bool` | | `Field(False, description="True when this is the repo's default branch")` | | `ahead_count` | `int` | | `Field(0, ge=0, description='Commits on this branch not yet on the default branch')` | | `behind_count` | `int` | | `Field(0, ge=0, description='Commits on the default branch not yet on this branch')` | | `divergence` | `BranchDivergenceScores` | | `(factory)` | ### `BranchDivergenceScores` — [`musehub/models/musehub.py`](musehub/models/musehub.py) Placeholder musical divergence scores between a branch and the default branch. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `melodic` | `float | None` | | `Field(None, description='Melodic divergence (0–1)')` | | `harmonic` | `float | None` | | `Field(None, description='Harmonic divergence (0–1)')` | | `rhythmic` | `float | None` | | `Field(None, description='Rhythmic divergence (0–1)')` | | `structural` | `float | None` | | `Field(None, description='Structural divergence (0–1)')` | | `dynamic` | `float | None` | | `Field(None, description='Dynamic divergence (0–1)')` | ### `BranchListResponse` — [`musehub/models/musehub.py`](musehub/models/musehub.py) Paginated list of branches. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `branches` | `list[BranchResponse]` | ✓ | `—` | ### `BranchResponse` — [`musehub/models/musehub.py`](musehub/models/musehub.py) Wire representation of a branch pointer. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `branch_id` | `str` | ✓ | `—` | | `name` | `str` | ✓ | `—` | | `head_commit_id` | `str | None` | | `Field(None, description='HEAD commit ID; null for an empty branch', examples=['a3f8c1d2e4b5'])` | ### `ChangelogEntryResponse` — [`musehub/models/musehub.py`](musehub/models/musehub.py) A single changelog entry auto-generated from commit metadata. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `commit_id` | `str` | ✓ | `—` | | `message` | `str` | ✓ | `—` | | `sem_ver_bump` | `str` | | `''` | | `breaking_changes` | `list[str]` | | `(factory)` | | `author` | `str` | | `''` | | `timestamp` | `str` | | `''` | ### `CollaboratorAccessResponse` — [`musehub/models/musehub.py`](musehub/models/musehub.py) Response for the collaborator access-check endpoint. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `username` | `str` | ✓ | `—` | | `permission` | `str` | ✓ | `—` | | `accepted_at` | `datetime | None` | | `Field(None, description='UTC timestamp when the collaborator accepted the invitation; null for owners')` | ### `CommitDiffDimensionScore` — [`musehub/models/musehub.py`](musehub/models/musehub.py) Per-dimension change score between a commit and its parent. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `dimension` | `str` | ✓ | `—` | | `score` | `float` | ✓ | `—` | | `label` | `str` | ✓ | `—` | | `color` | `str` | ✓ | `—` | ### `CommitDiffSummaryResponse` — [`musehub/models/musehub.py`](musehub/models/musehub.py) Multi-dimensional diff summary between a commit and its parent. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `commit_id` | `str` | ✓ | `—` | | `parent_id` | `str | None` | | `Field(None, description='Parent commit ID; None for root commits')` | | `dimensions` | `list[CommitDiffDimensionScore]` | ✓ | `—` | | `overall_score` | `float` | ✓ | `—` | ### `CommitInput` — [`musehub/models/musehub.py`](musehub/models/musehub.py) A single commit record transferred in a push payload. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `commit_id` | `str` | ✓ | `—` | | `parent_ids` | `list[str]` | | `(factory)` | | `message` | `str` | ✓ | `—` | | `snapshot_id` | `str | None` | | `None` | | `timestamp` | `datetime` | ✓ | `—` | | `author` | `str | None` | | `None` | ### `CommitListResponse` — [`musehub/models/musehub.py`](musehub/models/musehub.py) Cursor-paginated list of commits (newest first). **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `commits` | `list[CommitResponse]` | ✓ | `—` | | `total` | `int` | ✓ | `—` | | `next_cursor` | `str | None` | | `Field(None, description='Opaque cursor for the next page. Pass verbatim as ?cursor= to advance. Null when this is the last page.')` | ### `CommitResponse` — [`musehub/models/musehub.py`](musehub/models/musehub.py) Wire representation of a pushed commit. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `commit_id` | `str` | ✓ | `—` | | `branch` | `str` | ✓ | `—` | | `parent_ids` | `list[str]` | ✓ | `—` | | `message` | `str` | ✓ | `—` | | `author` | `str` | ✓ | `—` | | `timestamp` | `datetime` | ✓ | `—` | | `snapshot_id` | `str | None` | | `None` | ### `CompareResponse` — [`musehub/models/musehub.py`](musehub/models/musehub.py) Multi-dimensional musical comparison between two refs in a MuseHub repo. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `repo_id` | `str` | ✓ | `—` | | `base_ref` | `str` | ✓ | `—` | | `head_ref` | `str` | ✓ | `—` | | `common_ancestor` | `str | None` | | `None` | | `dimensions` | `list[DivergenceDimensionResponse]` | ✓ | `—` | | `overall_score` | `float` | ✓ | `—` | | `commits` | `list[CommitResponse]` | ✓ | `—` | | `emotion_diff` | `EmotionDiffResponse` | ✓ | `—` | | `create_proposal_url` | `str` | ✓ | `—` | ### `ContributionDay` — [`musehub/models/musehub.py`](musehub/models/musehub.py) A single day in the contribution heatmap. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `date` | `str` | ✓ | `—` | | `count` | `int` | ✓ | `—` | ### `ContributorCredits` — [`musehub/models/musehub.py`](musehub/models/musehub.py) Wire representation of a single contributor's credit record. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `author` | `str` | ✓ | `—` | | `session_count` | `int` | ✓ | `—` | | `contribution_types` | `list[str]` | ✓ | `—` | | `first_active` | `datetime` | ✓ | `—` | | `last_active` | `datetime` | ✓ | `—` | ### `CreateRepoRequest` — [`musehub/models/musehub.py`](musehub/models/musehub.py) Body for POST /musehub/repos — creation wizard. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `name` | `str` | ✓ | `—` | | `owner` | `str` | ✓ | `—` | | `visibility` | `str` | | `Field('public')` | | `description` | `str` | | `Field('', description='Short description shown on the explore page')` | | `tags` | `list[str]` | | `(factory)` | | `license` | `str | None` | | `Field(None, max_length=100, description="License identifier (e.g. 'CC BY 4.0', 'MIT')")` | | `topics` | `list[str]` | | `(factory)` | | `initialize` | `bool` | | `Field(True, description='When true, create an initial empty commit + default branch so the repo is immediately browsable')` | | `default_branch` | `str` | | `Field('main', min_length=1, max_length=255, description='Name of the default branch created when initialize=true')` | | `template_repo_id` | `str | None` | | `Field(None, description='UUID of a public repo to copy topics/description/labels from; must be public')` | | `domain_scoped_id` | `str | None` | | `Field(None, description="Scoped domain ID (e.g. '@gabriel/midi') — always set when created via /domains/@author/slug/new")` | ### `CreditsResponse` — [`musehub/models/musehub.py`](musehub/models/musehub.py) Wire representation of the full credits roll for a repo. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `repo_id` | `str` | ✓ | `—` | | `contributors` | `list[ContributorCredits]` | ✓ | `—` | | `sort` | `str` | ✓ | `—` | | `total_contributors` | `int` | ✓ | `—` | ### `DagEdge` — [`musehub/models/musehub.py`](musehub/models/musehub.py) A directed edge in the commit DAG. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `source` | `str` | ✓ | `—` | | `target` | `str` | ✓ | `—` | ### `DagGraphResponse` — [`musehub/models/musehub.py`](musehub/models/musehub.py) Topologically sorted commit graph for a MuseHub repo. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `nodes` | `list[DagNode]` | ✓ | `—` | | `edges` | `list[DagEdge]` | ✓ | `—` | | `head_commit_id` | `str | None` | | `None` | ### `DagNode` — [`musehub/models/musehub.py`](musehub/models/musehub.py) A single commit node in the repo's directed acyclic graph. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `commit_id` | `str` | ✓ | `—` | | `message` | `str` | ✓ | `—` | | `author` | `str` | ✓ | `—` | | `timestamp` | `datetime` | ✓ | `—` | | `branch` | `str` | ✓ | `—` | | `parent_ids` | `list[str]` | ✓ | `—` | | `is_head` | `bool` | | `False` | | `branch_labels` | `list[str]` | | `(factory)` | | `tag_labels` | `list[str]` | | `(factory)` | | `commit_type` | `str` | | `''` | | `sem_ver_bump` | `str` | | `'none'` | | `is_breaking` | `bool` | | `False` | | `is_agent` | `bool` | | `False` | | `sym_added` | `int` | | `0` | | `sym_removed` | `int` | | `0` | ### `DivergenceDimensionResponse` — [`musehub/models/musehub.py`](musehub/models/musehub.py) Wire representation of divergence scores for a single musical dimension. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `dimension` | `str` | ✓ | `—` | | `level` | `str` | ✓ | `—` | | `score` | `float` | ✓ | `—` | | `description` | `str` | ✓ | `—` | | `branch_a_commits` | `int` | ✓ | `—` | | `branch_b_commits` | `int` | ✓ | `—` | ### `DivergenceResponse` — [`musehub/models/musehub.py`](musehub/models/musehub.py) Full musical divergence report between two MuseHub branches. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `repo_id` | `str` | ✓ | `—` | | `branch_a` | `str` | ✓ | `—` | | `branch_b` | `str` | ✓ | `—` | | `common_ancestor` | `str | None` | ✓ | `—` | | `dimensions` | `list[DivergenceDimensionResponse]` | ✓ | `—` | | `overall_score` | `float` | ✓ | `—` | ### `EmotionDiffResponse` — [`musehub/models/musehub.py`](musehub/models/musehub.py) Delta between the emotional character of base and head refs. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `energy_delta` | `float` | ✓ | `—` | | `valence_delta` | `float` | ✓ | `—` | | `tension_delta` | `float` | ✓ | `—` | | `darkness_delta` | `float` | ✓ | `—` | | `base_energy` | `float` | ✓ | `—` | | `base_valence` | `float` | ✓ | `—` | | `base_tension` | `float` | ✓ | `—` | | `base_darkness` | `float` | ✓ | `—` | | `head_energy` | `float` | ✓ | `—` | | `head_valence` | `float` | ✓ | `—` | | `head_tension` | `float` | ✓ | `—` | | `head_darkness` | `float` | ✓ | `—` | ### `ExploreRepoResult` — [`musehub/models/musehub.py`](musehub/models/musehub.py) A public repo card shown on the explore/discover page. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `repo_id` | `str` | ✓ | `—` | | `name` | `str` | ✓ | `—` | | `owner` | `str` | ✓ | `—` | | `slug` | `str` | ✓ | `—` | | `owner_user_id` | `str` | ✓ | `—` | | `description` | `str` | ✓ | `—` | | `tags` | `list[str]` | ✓ | `—` | | `star_count` | `int` | ✓ | `—` | | `commit_count` | `int` | ✓ | `—` | | `created_at` | `datetime` | ✓ | `—` | ### `ExploreResponse` — [`musehub/models/musehub.py`](musehub/models/musehub.py) Cursor-paginated response from GET /api/discover/repos. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `repos` | `list[ExploreRepoResult]` | ✓ | `—` | | `total` | `int` | ✓ | `—` | | `next_cursor` | `str | None` | | `None` | ### `FileHotspotResponse` — [`musehub/models/musehub.py`](musehub/models/musehub.py) A file and how many times it was touched across the release's commits. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `file_path` | `str` | ✓ | `—` | | `change_count` | `int` | | `0` | | `language` | `str` | | `''` | ### `ForkNetworkNode` — [`musehub/models/musehub.py`](musehub/models/musehub.py) A single node in the fork network tree. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `owner` | `str` | ✓ | `—` | | `repo_slug` | `str` | ✓ | `—` | | `repo_id` | `str` | ✓ | `—` | | `divergence_commits` | `int` | ✓ | `—` | | `forked_by` | `str` | ✓ | `—` | | `forked_at` | `datetime | None` | | `Field(None, description='Timestamp when the fork was created (None for root repo)')` | | `children` | `list['ForkNetworkNode']` | | `(factory)` | ### `ForkNetworkResponse` — [`musehub/models/musehub.py`](musehub/models/musehub.py) Fork network graph for a repo — root with recursive children. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `root` | `ForkNetworkNode` | ✓ | `—` | | `total_forks` | `int` | ✓ | `—` | ### `ForkRepoRequest` — [`musehub/models/musehub.py`](musehub/models/musehub.py) Request body for ``POST /api/repos/{repo_id}/fork``. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `name` | `str | None` | | `Field(None, description="Name for the new fork repo. Defaults to the source repo's name. A unique slug is auto-generated; use this to disambiguate when you already own a repo with the same slug as the source.")` | | `description` | `str | None` | | `Field(None, description="Description for the fork. Defaults to the source repo's description prefixed with 'Fork of {owner}/{slug}: '.")` | | `visibility` | `Literal['public', 'private'] | None` | | `Field(None, description="Visibility for the fork repo. Defaults to 'public'.")` | ### `GlobalSearchCommitMatch` — [`musehub/models/musehub.py`](musehub/models/musehub.py) A single commit that matched the search query in a cross-repo search. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `commit_id` | `str` | ✓ | `—` | | `message` | `str` | ✓ | `—` | | `author` | `str` | ✓ | `—` | | `branch` | `str` | ✓ | `—` | | `timestamp` | `datetime` | ✓ | `—` | | `repo_id` | `str` | ✓ | `—` | | `repo_name` | `str` | ✓ | `—` | | `repo_owner` | `str` | ✓ | `—` | | `repo_visibility` | `str` | ✓ | `—` | | `audio_object_id` | `str | None` | | `None` | ### `GlobalSearchRepoGroup` — [`musehub/models/musehub.py`](musehub/models/musehub.py) All matching commits for a single repo, with repo-level metadata. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `repo_id` | `str` | ✓ | `—` | | `repo_name` | `str` | ✓ | `—` | | `repo_owner` | `str` | ✓ | `—` | | `repo_slug` | `str` | ✓ | `—` | | `repo_visibility` | `str` | ✓ | `—` | | `matches` | `list[GlobalSearchCommitMatch]` | ✓ | `—` | | `total_matches` | `int` | ✓ | `—` | ### `GlobalSearchResult` — [`musehub/models/musehub.py`](musehub/models/musehub.py) Top-level response for GET /search?q={query}. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `query` | `str` | ✓ | `—` | | `mode` | `str` | ✓ | `—` | | `groups` | `list[GlobalSearchRepoGroup]` | ✓ | `—` | | `total_repos_searched` | `int` | ✓ | `—` | | `next_cursor` | `str | None` | | `None` | ### `GrooveCheckResponse` — [`musehub/models/musehub.py`](musehub/models/musehub.py) Rhythmic consistency dashboard data for a commit range in a MuseHub repo. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `commit_range` | `str` | ✓ | `—` | | `threshold` | `float` | ✓ | `—` | | `total_commits` | `int` | ✓ | `—` | | `flagged_commits` | `int` | ✓ | `—` | | `worst_commit` | `str` | ✓ | `—` | | `entries` | `list[GrooveCommitEntry]` | | `(factory)` | ### `GrooveCommitEntry` — [`musehub/models/musehub.py`](musehub/models/musehub.py) Per-commit groove metrics within a groove-check analysis window. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `commit` | `str` | ✓ | `—` | | `groove_score` | `float` | ✓ | `—` | | `drift_delta` | `float` | ✓ | `—` | | `status` | `str` | ✓ | `—` | | `track` | `str` | ✓ | `—` | | `section` | `str` | ✓ | `—` | | `midi_files` | `int` | ✓ | `—` | ### `IssueAssignRequest` — [`musehub/models/musehub.py`](musehub/models/musehub.py) Body for POST /musehub/repos/{repo_id}/issues/{number}/assign. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `assignee` | `str | None` | | `Field(None, description='Display name or user ID to assign; null to unassign', examples=['miles_davis'])` | ### `IssueCommentCreate` — [`musehub/models/musehub.py`](musehub/models/musehub.py) Body for POST /musehub/repos/{repo_id}/issues/{number}/comments. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `body` | `str` | ✓ | `—` | | `parent_id` | `str | None` | | `Field(None, description='Parent comment UUID for threaded replies; omit for top-level comments')` | ### `IssueCommentListResponse` — [`musehub/models/musehub.py`](musehub/models/musehub.py) Cursor-paginated discussion on a single issue. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `comments` | `list[IssueCommentResponse]` | ✓ | `—` | | `total` | `int` | ✓ | `—` | | `next_cursor` | `str | None` | | `Field(None, description='Opaque cursor for the next page. Pass verbatim as ?cursor= to advance. Null when this is the last page.')` | ### `IssueCommentResponse` — [`musehub/models/musehub.py`](musehub/models/musehub.py) Wire representation of a single issue comment. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `comment_id` | `str` | ✓ | `—` | | `issue_id` | `str` | ✓ | `—` | | `author` | `str` | ✓ | `—` | | `body` | `str` | ✓ | `—` | | `parent_id` | `str | None` | | `Field(None, description='Parent comment UUID; null for top-level comments')` | | `is_deleted` | `bool` | | `Field(False, description='True when the comment has been soft-deleted')` | | `created_at` | `datetime` | ✓ | `—` | | `updated_at` | `datetime` | ✓ | `—` | ### `IssueCreate` — [`musehub/models/musehub.py`](musehub/models/musehub.py) Body for POST /musehub/repos/{repo_id}/issues. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `title` | `str` | ✓ | `—` | | `body` | `str` | | `Field('', max_length=50000, description='Issue description (Markdown)', examples=["The Dm→Am→E7→Am progression in the verse doesn't resolve — suggest Dm→G7→CMaj7."])` | | `labels` | `list[_Label]` | | `(factory)` | | `symbol_anchors` | `list[_SymbolAnchor]` | | `(factory)` | | `commit_anchors` | `list[_CommitAnchor]` | | `(factory)` | | `agent_id` | `str` | | `Field('', max_length=255, description="Agent identifier when filed by an AI agent (e.g. 'agentception-worker-42')")` | | `model_id` | `str` | | `Field('', max_length=255, description="Model identifier when filed by an AI agent (e.g. 'claude-sonnet-4-6')")` | ### `IssueLabelAssignRequest` — [`musehub/models/musehub.py`](musehub/models/musehub.py) Body for POST /musehub/repos/{repo_id}/issues/{number}/labels. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `labels` | `list[_Label]` | ✓ | `—` | ### `IssueListResponse` — [`musehub/models/musehub.py`](musehub/models/musehub.py) Cursor-paginated list of issues for a repo. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `issues` | `list[IssueResponse]` | ✓ | `—` | | `total` | `int` | | `Field(0, ge=0, description='Total matching issues across all pages')` | | `next_cursor` | `str | None` | | `Field(None, description='Opaque cursor for the next page. Pass verbatim as ?cursor= to advance. Null when this is the last page.')` | ### `IssueResponse` — [`musehub/models/musehub.py`](musehub/models/musehub.py) Wire representation of a MuseHub issue. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `issue_id` | `str` | ✓ | `—` | | `number` | `int` | ✓ | `—` | | `title` | `str` | ✓ | `—` | | `body` | `str` | ✓ | `—` | | `state` | `str` | ✓ | `—` | | `labels` | `list[str]` | ✓ | `—` | | `symbol_anchors` | `list[str]` | | `(factory)` | | `commit_anchors` | `list[str]` | | `(factory)` | | `author` | `str` | | `''` | | `assignee` | `str | None` | | `Field(None, description='Display name of the assigned collaborator')` | | `agent_id` | `str` | | `Field('', description='Agent identifier if filed by an AI agent')` | | `model_id` | `str` | | `Field('', description='Model identifier if filed by an AI agent')` | | `created_at` | `datetime` | ✓ | `—` | | `updated_at` | `datetime | None` | | `Field(None, description='Last update timestamp (ISO-8601 UTC)')` | | `comment_count` | `int` | | `Field(0, description='Number of non-deleted comments on this issue')` | ### `IssueUpdate` — [`musehub/models/musehub.py`](musehub/models/musehub.py) Body for PATCH /musehub/repos/{repo_id}/issues/{number} — partial update. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `title` | `str | None` | | `Field(None, min_length=1, max_length=500, description='Updated issue title')` | | `body` | `str | None` | | `Field(None, max_length=50000, description='Updated issue body (Markdown)')` | | `labels` | `list[_Label] | None` | | `Field(None, max_length=20, description='Replacement label list (max 20, each max 100 chars)')` | | `symbol_anchors` | `list[_SymbolAnchor] | None` | | `Field(None, max_length=50, description='Replacement symbol anchor list (max 50, each max 500 chars)')` | | `commit_anchors` | `list[_CommitAnchor] | None` | | `Field(None, max_length=50, description='Replacement commit anchor list (max 50, each max 64 chars)')` | | `agent_id` | `str | None` | | `Field(None, max_length=255, description='Agent identifier (set when agent-filed)')` | | `model_id` | `str | None` | | `Field(None, max_length=255, description='Model identifier (set when agent-filed)')` | ### `LanguageStatResponse` — [`musehub/models/musehub.py`](musehub/models/musehub.py) File and symbol counts for a single programming language. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `language` | `str` | ✓ | `—` | | `files` | `int` | | `0` | | `symbols` | `int` | | `0` | ### `MuseHubContextCommitInfo` — [`musehub/models/musehub.py`](musehub/models/musehub.py) Minimal commit metadata included in a MuseHub context document. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `commit_id` | `str` | ✓ | `—` | | `message` | `str` | ✓ | `—` | | `author` | `str` | ✓ | `—` | | `branch` | `str` | ✓ | `—` | | `timestamp` | `datetime` | ✓ | `—` | ### `MuseHubContextHistoryEntry` — [`musehub/models/musehub.py`](musehub/models/musehub.py) A single ancestor commit in the evolutionary history of the composition. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `commit_id` | `str` | ✓ | `—` | | `message` | `str` | ✓ | `—` | | `author` | `str` | ✓ | `—` | | `timestamp` | `datetime` | ✓ | `—` | | `active_tracks` | `list[str]` | ✓ | `—` | ### `MuseHubContextMusicalState` — [`musehub/models/musehub.py`](musehub/models/musehub.py) State at the target commit, derived from stored artifact paths. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `active_tracks` | `list[str]` | ✓ | `—` | ### `MuseHubContextResponse` — [`musehub/models/musehub.py`](musehub/models/musehub.py) Human-readable and agent-consumable musical context document for a commit. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `repo_id` | `str` | ✓ | `—` | | `current_branch` | `str` | ✓ | `—` | | `head_commit` | `MuseHubContextCommitInfo` | ✓ | `—` | | `musical_state` | `MuseHubContextMusicalState` | ✓ | `—` | | `history` | `list[MuseHubContextHistoryEntry]` | ✓ | `—` | | `missing_elements` | `list[str]` | ✓ | `—` | | `suggestions` | `StrDict` | ✓ | `—` | ### `ObjectInput` — [`musehub/models/musehub.py`](musehub/models/musehub.py) A binary object transferred in a push payload. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `object_id` | `str` | ✓ | `—` | | `path` | `str` | ✓ | `—` | | `content_b64` | `str` | ✓ | `—` | ### `ObjectMetaListResponse` — [`musehub/models/musehub.py`](musehub/models/musehub.py) List of artifact metadata for a repo. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `objects` | `list[ObjectMetaResponse]` | ✓ | `—` | ### `ObjectMetaResponse` — [`musehub/models/musehub.py`](musehub/models/musehub.py) Wire representation of a stored artifact -- metadata only, no content bytes. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `object_id` | `str` | ✓ | `—` | | `path` | `str` | ✓ | `—` | | `size_bytes` | `int` | ✓ | `—` | | `created_at` | `datetime` | ✓ | `—` | ### `ObjectResponse` — [`musehub/models/musehub.py`](musehub/models/musehub.py) A binary object returned in a pull response. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `object_id` | `str` | ✓ | `—` | | `path` | `str` | ✓ | `—` | | `content_b64` | `str` | ✓ | `—` | ### `ProfileRepoSummary` — [`musehub/models/musehub.py`](musehub/models/musehub.py) Compact repo summary shown on a user's profile page. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `repo_id` | `str` | ✓ | `—` | | `name` | `str` | ✓ | `—` | | `owner` | `str` | ✓ | `—` | | `slug` | `str` | ✓ | `—` | | `visibility` | `str` | ✓ | `—` | | `star_count` | `int` | ✓ | `—` | | `last_activity_at` | `datetime | None` | ✓ | `—` | | `created_at` | `datetime` | ✓ | `—` | ### `ProfileResponse` — [`musehub/models/musehub.py`](musehub/models/musehub.py) Full wire representation of a MuseHub user profile. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `user_id` | `str` | ✓ | `—` | | `username` | `str` | ✓ | `—` | | `display_name` | `str | None` | | `None` | | `bio` | `str | None` | | `None` | | `avatar_url` | `str | None` | | `None` | | `location` | `str | None` | | `None` | | `website_url` | `str | None` | | `None` | | `social_url` | `str | None` | | `None` | | `is_verified` | `bool` | | `False` | | `cc_license` | `str | None` | | `None` | | `pinned_repo_ids` | `list[str]` | ✓ | `—` | | `repos` | `list[ProfileRepoSummary]` | ✓ | `—` | | `contribution_graph` | `list[ContributionDay]` | ✓ | `—` | | `session_credits` | `int` | ✓ | `—` | | `created_at` | `datetime` | ✓ | `—` | | `updated_at` | `datetime` | ✓ | `—` | ### `ProfileUpdateRequest` — [`musehub/models/musehub.py`](musehub/models/musehub.py) Body for PUT /api/users/{username}. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `display_name` | `str | None` | | `Field(None, max_length=255, description='Human-readable display name')` | | `bio` | `str | None` | | `Field(None, max_length=500, description='Short bio (Markdown supported)')` | | `avatar_url` | `str | None` | | `Field(None, max_length=2048, description='Avatar image URL')` | | `location` | `str | None` | | `Field(None, max_length=255, description='City or region')` | | `website_url` | `str | None` | | `Field(None, max_length=2048, description='Personal website or project URL')` | | `social_url` | `str | None` | | `Field(None, max_length=2048, description='Full URL to a social profile')` | | `pinned_repo_ids` | `list[str] | None` | | `Field(None, max_length=6, description='Up to 6 repo_ids to pin on the profile page')` | ### `ProposalCommentCreate` — [`musehub/models/musehub.py`](musehub/models/musehub.py) Body for POST /musehub/repos/{repo_id}/proposals/{proposal_id}/comments. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `body` | `str` | ✓ | `—` | | `target_type` | `str` | | `Field('general', pattern='^(general|track|region|note)$', description='Comment target granularity', examples=['region'])` | | `target_track` | `str | None` | | `Field(None, max_length=255, description='Instrument track name for track/region/note targets', examples=['bass'])` | | `target_beat_start` | `float | None` | | `Field(None, ge=0, description='First beat of the targeted region (inclusive)', examples=[16.0])` | | `target_beat_end` | `float | None` | | `Field(None, ge=0, description='Last beat of the targeted region (exclusive)', examples=[24.0])` | | `target_note_pitch` | `int | None` | | `Field(None, ge=0, le=127, description='MIDI pitch (0-127) for note-level targets', examples=[46])` | | `parent_comment_id` | `str | None` | | `Field(None, description='ID of the parent comment when creating a threaded reply', examples=['a1b2c3d4-e5f6-7890-abcd-ef1234567890'])` | | `symbol_address` | `str | None` | | `Field(None, max_length=512, description="Symbol address to anchor this comment to (e.g. 'auth.py::AuthService.login'). Binds the comment to a specific named symbol in the Symbol Delta. Takes precedence over target_type for code-domain proposals.", examples=['core/engine.py::Engine.process'])` | ### `ProposalCommentListResponse` — [`musehub/models/musehub.py`](musehub/models/musehub.py) Cursor-paginated list of review comments for a merge proposal. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `comments` | `list[ProposalCommentResponse]` | | `(factory)` | | `total` | `int` | | `Field(0, ge=0, description='Total number of comments (all levels)')` | | `next_cursor` | `str | None` | | `Field(None, description='Opaque cursor for the next page. Pass verbatim as ?cursor= to advance. Null when this is the last page.')` | ### `ProposalCommentResponse` — [`musehub/models/musehub.py`](musehub/models/musehub.py) Wire representation of a single proposal review comment. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `comment_id` | `str` | ✓ | `—` | | `proposal_id` | `str` | ✓ | `—` | | `author` | `str` | ✓ | `—` | | `body` | `str` | ✓ | `—` | | `target_type` | `str` | ✓ | `—` | | `target_track` | `str | None` | | `Field(None, description='Instrument track name when targeted')` | | `target_beat_start` | `float | None` | | `Field(None, description='Region start beat (inclusive)')` | | `target_beat_end` | `float | None` | | `Field(None, description='Region end beat (exclusive)')` | | `target_note_pitch` | `int | None` | | `Field(None, description='MIDI pitch for note-level targets')` | | `parent_comment_id` | `str | None` | | `Field(None, description='Parent comment ID for threaded replies')` | | `symbol_address` | `str | None` | | `Field(None, description='Symbol address anchor, if set')` | | `created_at` | `datetime` | ✓ | `—` | | `replies` | `list[ProposalCommentResponse]` | | `(factory)` | ### `ProposalCreate` — [`musehub/models/musehub.py`](musehub/models/musehub.py) Body for POST /musehub/repos/{repo_id}/proposals. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `title` | `str` | ✓ | `—` | | `from_branch` | `str` | ✓ | `—` | | `to_branch` | `str` | ✓ | `—` | | `body` | `str` | | `Field('', max_length=10000, description='Merge proposal description (Markdown)', examples=['This branch adds an 8-bar bossa nova bridge in 5/4 with guitar and upright bass.'])` | ### `ProposalDiffDimensionScore` — [`musehub/models/musehub.py`](musehub/models/musehub.py) Per-dimension musical change score between the from_branch and to_branch of a merge proposal. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `dimension` | `str` | ✓ | `—` | | `score` | `float` | ✓ | `—` | | `level` | `str` | ✓ | `—` | | `delta_label` | `str` | ✓ | `—` | | `description` | `str` | ✓ | `—` | | `from_branch_commits` | `int` | ✓ | `—` | | `to_branch_commits` | `int` | ✓ | `—` | ### `ProposalDiffResponse` — [`musehub/models/musehub.py`](musehub/models/musehub.py) Musical diff between the from_branch and to_branch of a merge proposal. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `proposal_id` | `str` | ✓ | `—` | | `repo_id` | `str` | ✓ | `—` | | `from_branch` | `str` | ✓ | `—` | | `to_branch` | `str` | ✓ | `—` | | `dimensions` | `list[ProposalDiffDimensionScore]` | ✓ | `—` | | `overall_score` | `float | None` | | `Field(None, ge=0.0, le=1.0, description='Mean of all five dimension scores; None for code-domain proposals')` | | `common_ancestor` | `str | None` | | `Field(None, description='Merge-base commit ID; None if no common ancestor')` | | `affected_sections` | `list[str]` | | `(factory)` | ### `ProposalListResponse` — [`musehub/models/musehub.py`](musehub/models/musehub.py) Cursor-paginated list of merge proposals for a repo. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `proposals` | `list[ProposalResponse]` | ✓ | `—` | | `total` | `int` | | `Field(0, ge=0, description='Total matching merge proposals across all pages')` | | `next_cursor` | `str | None` | | `Field(None, description='Opaque cursor for the next page. Pass verbatim as ?cursor= to advance. Null when this is the last page.')` | ### `ProposalMergeRequest` — [`musehub/models/musehub.py`](musehub/models/musehub.py) Body for POST /musehub/repos/{repo_id}/proposals/{proposal_id}/merge. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `merge_strategy` | `str` | | `Field('merge_commit', pattern='^(merge_commit|squash|rebase)$', description="Merge strategy: 'merge_commit' (default), 'squash', or 'rebase'")` | ### `ProposalMergeResponse` — [`musehub/models/musehub.py`](musehub/models/musehub.py) Confirmation that a merge proposal was merged. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `merged` | `bool` | ✓ | `—` | | `merge_commit_id` | `str` | ✓ | `—` | ### `ProposalResponse` — [`musehub/models/musehub.py`](musehub/models/musehub.py) Wire representation of a MuseHub merge proposal. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `proposal_id` | `str` | ✓ | `—` | | `proposal_number` | `int` | | `Field(0, description='Per-repo sequential proposal number (1-based)')` | | `title` | `str` | ✓ | `—` | | `body` | `str` | ✓ | `—` | | `state` | `str` | ✓ | `—` | | `from_branch` | `str` | ✓ | `—` | | `to_branch` | `str` | ✓ | `—` | | `merge_commit_id` | `str | None` | | `None` | | `merged_at` | `datetime | None` | | `None` | | `author` | `str` | | `''` | | `created_at` | `datetime` | ✓ | `—` | ### `ProposalReviewCreate` — [`musehub/models/musehub.py`](musehub/models/musehub.py) Body for POST /musehub/repos/{repo_id}/proposals/{proposal_id}/reviews. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `event` | `str` | ✓ | `—` | | `body` | `str` | | `Field('', max_length=10000, description="Review body (Markdown). Required when event='request_changes'.", examples=['Sounds great — the harmonic transitions in the bridge are exactly right.'])` | ### `ProposalReviewListResponse` — [`musehub/models/musehub.py`](musehub/models/musehub.py) Cursor-paginated list of reviews for a merge proposal. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `reviews` | `list[ProposalReviewResponse]` | | `(factory)` | | `total` | `int` | | `Field(0, ge=0, description='Total number of review rows')` | | `next_cursor` | `str | None` | | `Field(None, description='Opaque cursor for the next page. Pass verbatim as ?cursor= to advance. Null when this is the last page.')` | ### `ProposalReviewResponse` — [`musehub/models/musehub.py`](musehub/models/musehub.py) Wire representation of a single proposal review. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `id` | `str` | ✓ | `—` | | `proposal_id` | `str` | ✓ | `—` | | `reviewer_username` | `str` | ✓ | `—` | | `state` | `str` | ✓ | `—` | | `body` | `str | None` | | `Field(None, description='Review comment body (Markdown); null for bare assignments')` | | `submitted_at` | `datetime | None` | | `Field(None, description='UTC timestamp when the review was submitted')` | | `created_at` | `datetime` | ✓ | `—` | ### `ProposalReviewerRequest` — [`musehub/models/musehub.py`](musehub/models/musehub.py) Body for POST /musehub/repos/{repo_id}/proposals/{proposal_id}/reviewers. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `reviewers` | `list[str]` | ✓ | `—` | ### `PullResponse` — [`musehub/models/musehub.py`](musehub/models/musehub.py) Response for POST /musehub/repos/{repo_id}/pull. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `commits` | `list[CommitResponse]` | ✓ | `—` | | `objects` | `list[ObjectResponse]` | ✓ | `—` | | `remote_head` | `str | None` | ✓ | `—` | | `has_more` | `bool` | | `False` | | `next_cursor` | `str | None` | | `None` | ### `PushResponse` — [`musehub/models/musehub.py`](musehub/models/musehub.py) Response for POST /musehub/repos/{repo_id}/push. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `ok` | `bool` | ✓ | `—` | | `remote_head` | `str` | ✓ | `—` | ### `RefactorEventResponse` — [`musehub/models/musehub.py`](musehub/models/musehub.py) A single structural refactoring event detected in the release. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `kind` | `str` | | `''` | | `address` | `str` | | `''` | | `detail` | `str` | | `''` | | `commit_id` | `str` | | `''` | ### `ReleaseAssetCreate` — [`musehub/models/musehub.py`](musehub/models/musehub.py) Body for POST /musehub/repos/{repo_id}/releases/{tag}/assets. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `name` | `str` | ✓ | `—` | | `label` | `str` | | `Field('', max_length=255, description="Optional human-readable label, e.g. 'MIDI Bundle'")` | | `content_type` | `str` | | `Field('', max_length=128, description="MIME type, e.g. 'audio/midi', 'application/zip'")` | | `size` | `int` | | `Field(0, ge=0, description='File size in bytes; 0 when unknown')` | | `download_url` | `str` | ✓ | `—` | ### `ReleaseAssetDownloadCount` — [`musehub/models/musehub.py`](musehub/models/musehub.py) Per-asset download count entry in a release download stats response. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `asset_id` | `str` | ✓ | `—` | | `name` | `str` | ✓ | `—` | | `label` | `str` | | `Field('', description='Optional human-readable label')` | | `download_count` | `int` | | `Field(0, ge=0, description='Number of times this asset has been downloaded')` | ### `ReleaseAssetListResponse` — [`musehub/models/musehub.py`](musehub/models/musehub.py) Cursor-paginated list of assets attached to a release. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `release_id` | `str` | ✓ | `—` | | `tag` | `str` | ✓ | `—` | | `assets` | `list[ReleaseAssetResponse]` | ✓ | `—` | | `total` | `int` | | `Field(0, ge=0, description='Total assets attached to this release')` | | `next_cursor` | `str | None` | | `Field(None, description='Opaque cursor for the next page. Pass verbatim as ?cursor= to advance. Null when this is the last page.')` | ### `ReleaseAssetResponse` — [`musehub/models/musehub.py`](musehub/models/musehub.py) Wire representation of a single release asset. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `asset_id` | `str` | ✓ | `—` | | `release_id` | `str` | ✓ | `—` | | `name` | `str` | ✓ | `—` | | `label` | `str` | | `Field('', description='Optional human-readable label')` | | `content_type` | `str` | | `Field('', description='MIME type of the artifact')` | | `size` | `int` | | `Field(0, ge=0, description='File size in bytes; 0 when unknown')` | | `download_url` | `str` | ✓ | `—` | | `download_count` | `int` | | `Field(0, ge=0, description='Number of times the asset has been downloaded')` | | `created_at` | `datetime` | ✓ | `—` | ### `ReleaseCreate` — [`musehub/models/musehub.py`](musehub/models/musehub.py) Body for POST /musehub/repos/{repo_id}/releases. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `tag` | `str` | ✓ | `—` | | `title` | `str` | | `Field('', max_length=500, description='Release title', examples=['Summer Sessions 2024 — Final Mix'])` | | `body` | `str` | | `Field('', max_length=10000, description='Release notes (Markdown)', examples=['## Summer Sessions 2024\n\nFinal arrangement with full brass section and 132 BPM tempo.'])` | | `commit_id` | `str | None` | | `Field(None, description='Commit to pin this release to', examples=['a3f8c1d2e4b5'])` | | `snapshot_id` | `str | None` | | `Field(None, description='Snapshot ID for reproducible builds')` | | `channel` | `str` | | `Field('stable', description='Distribution channel: stable | beta | alpha | nightly', examples=['stable'])` | | `semver_major` | `int` | | `Field(0, ge=0)` | | `semver_minor` | `int` | | `Field(0, ge=0)` | | `semver_patch` | `int` | | `Field(0, ge=0)` | | `semver_pre` | `str` | | `Field('', max_length=255, description="Pre-release label, e.g. 'beta.1'")` | | `semver_build` | `str` | | `Field('', max_length=255, description="Build metadata, e.g. '20250101'")` | | `agent_id` | `str` | | `Field('', max_length=255)` | | `model_id` | `str` | | `Field('', max_length=255)` | | `changelog` | `list[ChangelogEntryResponse]` | | `(factory)` | | `is_draft` | `bool` | | `Field(False, description='Save as draft — not yet publicly visible')` | | `gpg_signature` | `str | None` | | `Field(None, description='ASCII-armoured GPG signature for the tag object; omit when unsigned')` | | `semantic_report` | `SemanticReleaseReportResponse | None` | | `Field(None, description='Semantic analysis blob computed by the Muse CLI at push time.')` | ### `ReleaseDownloadStatsResponse` — [`musehub/models/musehub.py`](musehub/models/musehub.py) Download counts per asset for a single release. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `release_id` | `str` | ✓ | `—` | | `tag` | `str` | ✓ | `—` | | `assets` | `list[ReleaseAssetDownloadCount]` | | `(factory)` | | `total_downloads` | `int` | | `Field(0, ge=0, description='Sum of download_count across all assets')` | ### `ReleaseDownloadUrls` — [`musehub/models/musehub.py`](musehub/models/musehub.py) Structured download package URLs for a release. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `metadata` | `str | None` | | `None` | ### `ReleaseListResponse` — [`musehub/models/musehub.py`](musehub/models/musehub.py) Cursor-paginated list of releases for a repo (newest first). **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `releases` | `list[ReleaseResponse]` | ✓ | `—` | | `total` | `int` | | `Field(0, ge=0, description='Total matching releases across all pages')` | | `next_cursor` | `str | None` | | `Field(None, description='Opaque cursor for the next page. Pass verbatim as ?cursor= to advance. Null when this is the last page.')` | ### `ReleaseResponse` — [`musehub/models/musehub.py`](musehub/models/musehub.py) Wire representation of a MuseHub release. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `release_id` | `str` | ✓ | `—` | | `tag` | `str` | ✓ | `—` | | `title` | `str` | | `''` | | `body` | `str` | | `''` | | `commit_id` | `str | None` | | `None` | | `snapshot_id` | `str | None` | | `None` | | `channel` | `str` | | `'stable'` | | `semver_major` | `int` | | `0` | | `semver_minor` | `int` | | `0` | | `semver_patch` | `int` | | `0` | | `semver_pre` | `str` | | `''` | | `semver_build` | `str` | | `''` | | `download_urls` | `ReleaseDownloadUrls` | ✓ | `—` | | `author` | `str` | | `''` | | `agent_id` | `str` | | `''` | | `model_id` | `str` | | `''` | | `changelog` | `list[ChangelogEntryResponse]` | | `(factory)` | | `is_prerelease` | `bool` | | `False` | | `is_draft` | `bool` | | `False` | | `gpg_signature` | `str | None` | | `None` | | `semantic_report` | `SemanticReleaseReportResponse | None` | | `None` | | `created_at` | `datetime` | ✓ | `—` | ### `RepoListResponse` — [`musehub/models/musehub.py`](musehub/models/musehub.py) Paginated list of repos for the authenticated user. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `repos` | `list[RepoResponse]` | ✓ | `—` | | `next_cursor` | `str | None` | | `Field(None, description='Pagination cursor — pass as ?cursor= to get the next page')` | | `total` | `int` | ✓ | `—` | ### `RepoResponse` — [`musehub/models/musehub.py`](musehub/models/musehub.py) Wire representation of a MuseHub repo. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `repo_id` | `str` | ✓ | `—` | | `name` | `str` | ✓ | `—` | | `owner` | `str` | ✓ | `—` | | `slug` | `str` | ✓ | `—` | | `visibility` | `str` | ✓ | `—` | | `owner_user_id` | `str` | ✓ | `—` | | `clone_url` | `str` | ✓ | `—` | | `description` | `str` | | `Field('', description='Short description shown on the explore page', examples=['Classic jazz standards arranged for quartet'])` | | `tags` | `list[str]` | | `(factory)` | | `domain_id` | `str | None` | | `Field(None, description='ID of the registered Muse domain plugin for this repo')` | | `key_signature` | `str | None` | | `Field(None, description="Musical key signature, e.g. 'Bb major'")` | | `tempo_bpm` | `int | None` | | `Field(None, description='Tempo in beats per minute')` | | `created_at` | `datetime` | ✓ | `—` | ### `RepoSettingsPatch` — [`musehub/models/musehub.py`](musehub/models/musehub.py) Partial update body for ``PATCH /api/repos/{repo_id}/settings``. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `name` | `str | None` | | `Field(None, description='New repo name')` | | `description` | `str | None` | | `Field(None, description='New description')` | | `visibility` | `str | None` | | `Field(None, pattern='^(public|private)$', description="'public' or 'private'")` | | `default_branch` | `str | None` | | `Field(None, description='New default branch name')` | | `has_issues` | `bool | None` | | `Field(None, description='Enable/disable issues tracker')` | | `has_projects` | `bool | None` | | `Field(None, description='Enable/disable projects board')` | | `has_wiki` | `bool | None` | | `Field(None, description='Enable/disable wiki')` | | `topics` | `list[str] | None` | | `Field(None, description='Replace topic tags (full list)')` | | `license` | `str | None` | | `Field(None, description='SPDX license identifier or display name')` | | `homepage_url` | `str | None` | | `Field(None, description='Project homepage URL')` | | `allow_merge_commit` | `bool | None` | | `Field(None, description='Allow merge commits on proposals')` | | `allow_squash_merge` | `bool | None` | | `Field(None, description='Allow squash merges on proposals')` | | `allow_rebase_merge` | `bool | None` | | `Field(None, description='Allow rebase merges on proposals')` | | `delete_branch_on_merge` | `bool | None` | | `Field(None, description='Auto-delete head branch after proposal merge')` | | `domain_id` | `str | None` | | `Field(None, description='UUID of the Muse domain plugin for this repo')` | ### `RepoSettingsResponse` — [`musehub/models/musehub.py`](musehub/models/musehub.py) Mutable settings for a MuseHub repo. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `name` | `str` | ✓ | `—` | | `description` | `str` | | `Field('', description='Short description shown on the explore page')` | | `visibility` | `str` | ✓ | `—` | | `default_branch` | `str` | | `Field('main', description='Default branch name (used for clone and proposals)')` | | `has_issues` | `bool` | | `Field(True, description='Whether the issues tracker is enabled')` | | `has_projects` | `bool` | | `Field(False, description='Whether the projects board is enabled')` | | `has_wiki` | `bool` | | `Field(False, description='Whether the wiki is enabled')` | | `topics` | `list[str]` | | `(factory)` | | `license` | `str | None` | | `Field(None, description="SPDX license identifier or display name, e.g. 'CC BY 4.0'")` | | `homepage_url` | `str | None` | | `Field(None, description='Project homepage URL')` | | `allow_merge_commit` | `bool` | | `Field(True, description='Allow merge commits on proposals')` | | `allow_squash_merge` | `bool` | | `Field(True, description='Allow squash merges on proposals')` | | `allow_rebase_merge` | `bool` | | `Field(False, description='Allow rebase merges on proposals')` | | `delete_branch_on_merge` | `bool` | | `Field(True, description='Auto-delete head branch after proposal merge')` | | `domain_id` | `str | None` | | `Field(None, description='UUID of the Muse domain plugin for this repo')` | ### `RepoStatsResponse` — [`musehub/models/musehub.py`](musehub/models/musehub.py) Aggregated counts for the repo home page stats bar. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `commit_count` | `int` | | `Field(0, ge=0, description='Total number of commits across all branches')` | | `branch_count` | `int` | | `Field(0, ge=0, description='Number of branches (including default)')` | | `release_count` | `int` | | `Field(0, ge=0, description='Number of published releases / tags')` | ### `SearchCommitMatch` — [`musehub/models/musehub.py`](musehub/models/musehub.py) A single commit returned by a search query. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `commit_id` | `str` | ✓ | `—` | | `branch` | `str` | ✓ | `—` | | `message` | `str` | ✓ | `—` | | `author` | `str` | ✓ | `—` | | `timestamp` | `datetime` | ✓ | `—` | | `score` | `float` | | `Field(1.0, ge=0.0, le=1.0, description='Match score (0–1); always 1.0 for exact-match modes')` | | `match_source` | `str` | | `Field('message', description="Where the match was found: 'message', 'branch', or 'property'")` | ### `SearchResponse` — [`musehub/models/musehub.py`](musehub/models/musehub.py) Response envelope for all four in-repo search modes. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `mode` | `str` | ✓ | `—` | | `query` | `str` | ✓ | `—` | | `matches` | `list[SearchCommitMatch]` | ✓ | `—` | | `total_scanned` | `int` | ✓ | `—` | | `limit` | `int` | ✓ | `—` | ### `SemanticReleaseReportResponse` — [`musehub/models/musehub.py`](musehub/models/musehub.py) Semantic analysis of a release, computed by the Muse CLI at push time. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `languages` | `list[LanguageStatResponse]` | | `(factory)` | | `total_files` | `int` | | `0` | | `semantic_files` | `int` | | `0` | | `total_symbols` | `int` | | `0` | | `symbols_by_kind` | `list[SymbolKindCountResponse]` | | `(factory)` | | `files_changed` | `int` | | `0` | | `api_added` | `list[ApiChangeSummaryResponse]` | | `(factory)` | | `api_removed` | `list[ApiChangeSummaryResponse]` | | `(factory)` | | `api_modified` | `list[ApiChangeSummaryResponse]` | | `(factory)` | | `file_hotspots` | `list[FileHotspotResponse]` | | `(factory)` | | `refactor_events` | `list[RefactorEventResponse]` | | `(factory)` | | `breaking_changes` | `list[str]` | | `(factory)` | | `human_commits` | `int` | | `0` | | `agent_commits` | `int` | | `0` | | `unique_agents` | `list[str]` | | `(factory)` | | `unique_models` | `list[str]` | | `(factory)` | | `reviewers` | `list[str]` | | `(factory)` | ### `SessionCreate` — [`musehub/models/musehub.py`](musehub/models/musehub.py) Body for POST /musehub/repos/{repo_id}/sessions. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `started_at` | `datetime | None` | | `None` | | `participants` | `list[str]` | | `(factory)` | | `intent` | `str` | | `Field('', description='Free-text creative goal for this session', examples=['Finish the bossa nova bridge — add percussion and finalize the chord changes'])` | | `location` | `str` | | `Field('', max_length=255, description='Studio or location label', examples=['Blue Note Studio, NYC'])` | | `is_active` | `bool` | | `Field(True, description='True if the session is currently live')` | ### `SessionListResponse` — [`musehub/models/musehub.py`](musehub/models/musehub.py) Cursor-paginated list of sessions for a repo (newest first). **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `sessions` | `list[SessionResponse]` | ✓ | `—` | | `total` | `int` | ✓ | `—` | | `next_cursor` | `str | None` | | `None` | ### `SessionResponse` — [`musehub/models/musehub.py`](musehub/models/musehub.py) Wire representation of a single recording session. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `session_id` | `str` | ✓ | `—` | | `started_at` | `datetime` | ✓ | `—` | | `ended_at` | `datetime | None` | | `None` | | `duration_seconds` | `float | None` | | `None` | | `participants` | `list[str]` | ✓ | `—` | | `commits` | `list[str]` | | `(factory)` | | `notes` | `str` | | `Field('', description='Closing notes for the session (markdown)')` | | `intent` | `str` | ✓ | `—` | | `location` | `str` | ✓ | `—` | | `is_active` | `bool` | ✓ | `—` | | `created_at` | `datetime` | ✓ | `—` | ### `SessionStop` — [`musehub/models/musehub.py`](musehub/models/musehub.py) Body for POST /musehub/repos/{repo_id}/sessions/{session_id}/stop. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `ended_at` | `datetime | None` | | `None` | ### `SnapshotBatchRequest` — [`musehub/models/musehub.py`](musehub/models/musehub.py) Request body for the batch snapshot lookup endpoint. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `snapshot_ids` | `list[str]` | ✓ | `—` | | `include_entries` | `bool` | | `Field(False, description='When true, each result includes its file-tree entries (heavier)')` | ### `SnapshotDiffEntry` — [`musehub/models/musehub.py`](musehub/models/musehub.py) A single file-level change between two snapshots. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `path` | `str` | ✓ | `—` | | `status` | `str` | ✓ | `—` | | `base_object_id` | `str | None` | | `Field(None, description='Object ID in the base snapshot (null for added files)', examples=['b2a7d9e1c3f4'])` | | `new_object_id` | `str | None` | | `Field(None, description='Object ID in the new snapshot (null for removed files)', examples=['c3b8e0f2d5a6'])` | | `base_size_bytes` | `int` | | `Field(0, ge=0, description='File size in base snapshot')` | | `new_size_bytes` | `int` | | `Field(0, ge=0, description='File size in new snapshot')` | ### `SnapshotDiffResponse` — [`musehub/models/musehub.py`](musehub/models/musehub.py) File-level diff between two snapshots. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `snapshot_id` | `str` | ✓ | `—` | | `base_snapshot_id` | `str` | ✓ | `—` | | `added_count` | `int` | | `Field(0, ge=0, description='Files added in new snapshot')` | | `removed_count` | `int` | | `Field(0, ge=0, description='Files removed from base snapshot')` | | `modified_count` | `int` | | `Field(0, ge=0, description='Files present in both but with changed content')` | | `unchanged_count` | `int` | | `Field(0, ge=0, description='Files identical in both snapshots')` | | `bytes_added` | `int` | | `Field(0, ge=0, description='Total bytes added (new file sizes)')` | | `bytes_removed` | `int` | | `Field(0, ge=0, description='Total bytes removed (base file sizes)')` | | `changes` | `list[SnapshotDiffEntry]` | | `(factory)` | ### `SnapshotEntryListResponse` — [`musehub/models/musehub.py`](musehub/models/musehub.py) Cursor-paginated file-tree entries for a single snapshot. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `snapshot_id` | `str` | ✓ | `—` | | `entries` | `list[SnapshotEntryResponse]` | ✓ | `—` | | `total` | `int` | ✓ | `—` | | `next_cursor` | `str | None` | | `Field(None, description='Opaque cursor for the next page. Pass verbatim as ?cursor= to advance. Null when this is the last page.')` | ### `SnapshotEntryResponse` — [`musehub/models/musehub.py`](musehub/models/musehub.py) One file-tree entry within a snapshot. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `path` | `str` | ✓ | `—` | | `object_id` | `str` | ✓ | `—` | | `size_bytes` | `int` | | `Field(0, ge=0, description='Stored file size in bytes; 0 when unknown', examples=[4096])` | ### `SnapshotInput` — [`musehub/models/musehub.py`](musehub/models/musehub.py) A snapshot manifest transferred in a push payload. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `snapshot_id` | `str` | ✓ | `—` | | `manifest` | `StrDict` | | `(factory)` | | `created_at` | `str` | | `''` | ### `SnapshotListResponse` — [`musehub/models/musehub.py`](musehub/models/musehub.py) Cursor-paginated list of snapshot summaries (newest first). **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `snapshots` | `list[SnapshotSummaryResponse]` | ✓ | `—` | | `total` | `int` | ✓ | `—` | | `next_cursor` | `str | None` | | `Field(None, description='Opaque cursor for the next page. Pass verbatim as ?cursor= to advance. Null when this is the last page.')` | ### `SnapshotResponse` — [`musehub/models/musehub.py`](musehub/models/musehub.py) Full snapshot record including all file-tree entries. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `snapshot_id` | `str` | ✓ | `—` | | `repo_id` | `str` | ✓ | `—` | | `directories` | `list[str]` | | `(factory)` | | `entries` | `list[SnapshotEntryResponse]` | | `(factory)` | | `entry_count` | `int` | | `Field(0, ge=0, description='Total number of entries (equal to len(entries) unless paginated)', examples=[142])` | | `total_size_bytes` | `int` | | `Field(0, ge=0, description='Sum of all entry size_bytes', examples=[1048576])` | | `created_at` | `datetime` | ✓ | `—` | ### `SnapshotSummaryResponse` — [`musehub/models/musehub.py`](musehub/models/musehub.py) Lightweight snapshot summary — no file-tree entries. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `snapshot_id` | `str` | ✓ | `—` | | `repo_id` | `str` | ✓ | `—` | | `entry_count` | `int` | | `Field(0, ge=0, description='Number of file-tree entries (files) tracked at this snapshot', examples=[142])` | | `total_size_bytes` | `int` | | `Field(0, ge=0, description='Sum of all entry size_bytes; 0 when sizes were not recorded', examples=[1048576])` | | `directories` | `list[str]` | | `(factory)` | | `created_at` | `datetime` | ✓ | `—` | ### `StarResponse` — [`musehub/models/musehub.py`](musehub/models/musehub.py) Confirmation that a star was added or removed. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `starred` | `bool` | ✓ | `—` | | `star_count` | `int` | ✓ | `—` | ### `StargazerEntry` — [`musehub/models/musehub.py`](musehub/models/musehub.py) A single user who has starred a repo. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `user_id` | `str` | ✓ | `—` | | `starred_at` | `datetime` | ✓ | `—` | ### `StargazerListResponse` — [`musehub/models/musehub.py`](musehub/models/musehub.py) Paginated list of users who have starred a repo. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `stargazers` | `list[StargazerEntry]` | ✓ | `—` | | `total` | `int` | ✓ | `—` | ### `SymbolBlameEntry` — [`musehub/models/musehub.py`](musehub/models/musehub.py) One blame annotation attributing a symbol to the commit that last modified it. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `symbol_address` | `str` | ✓ | `—` | | `symbol_name` | `str` | ✓ | `—` | | `commit_id` | `str` | ✓ | `—` | | `commit_message` | `str` | ✓ | `—` | | `author` | `str` | ✓ | `—` | | `timestamp` | `datetime` | ✓ | `—` | | `op` | `str` | ✓ | `—` | | `change_count` | `int` | | `1` | | `is_hotspot` | `bool` | | `False` | | `is_dead` | `bool` | | `False` | | `is_blast_risk` | `bool` | | `False` | | `blast_co_symbols` | `list[str]` | | `(factory)` | ### `SymbolBlameResponse` — [`musehub/models/musehub.py`](musehub/models/musehub.py) Response envelope for symbol-level blame. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `entries` | `list[SymbolBlameEntry]` | | `(factory)` | | `total_entries` | `int` | | `0` | | `path` | `str` | | `''` | ### `SymbolKindCountResponse` — [`musehub/models/musehub.py`](musehub/models/musehub.py) Count of symbols of a specific kind in the release snapshot. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `kind` | `str` | ✓ | `—` | | `count` | `int` | | `0` | ### `TagListResponse` — [`musehub/models/musehub.py`](musehub/models/musehub.py) All tags for a repo, grouped by namespace. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `tags` | `list[TagResponse]` | ✓ | `—` | | `namespaces` | `list[str]` | | `(factory)` | ### `TagResponse` — [`musehub/models/musehub.py`](musehub/models/musehub.py) A single tag entry for the tag browser page. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `tag` | `str` | ✓ | `—` | | `namespace` | `str` | ✓ | `—` | | `commit_id` | `str | None` | | `Field(None, description='Commit this tag is pinned to')` | | `message` | `str` | | `Field('', description='Release title / description')` | | `created_at` | `datetime` | ✓ | `—` | ### `TimelineCommitEvent` — [`musehub/models/musehub.py`](musehub/models/musehub.py) A commit plotted as a point on the timeline. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `event_type` | `str` | | `'commit'` | | `commit_id` | `str` | ✓ | `—` | | `branch` | `str` | ✓ | `—` | | `message` | `str` | ✓ | `—` | | `author` | `str` | ✓ | `—` | | `timestamp` | `datetime` | ✓ | `—` | | `parent_ids` | `list[str]` | ✓ | `—` | ### `TimelineEmotionEvent` — [`musehub/models/musehub.py`](musehub/models/musehub.py) An emotion-vector data point overlaid on the timeline as a line chart. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `event_type` | `str` | | `'emotion'` | | `commit_id` | `str` | ✓ | `—` | | `timestamp` | `datetime` | ✓ | `—` | | `valence` | `float` | ✓ | `—` | | `energy` | `float` | ✓ | `—` | | `tension` | `float` | ✓ | `—` | ### `TimelineResponse` — [`musehub/models/musehub.py`](musehub/models/musehub.py) Chronological timeline of musical evolution for a repo. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `commits` | `list[TimelineCommitEvent]` | ✓ | `—` | | `emotion` | `list[TimelineEmotionEvent]` | ✓ | `—` | | `sections` | `list[TimelineSectionEvent]` | ✓ | `—` | | `tracks` | `list[TimelineTrackEvent]` | ✓ | `—` | | `total_commits` | `int` | ✓ | `—` | ### `TimelineSectionEvent` — [`musehub/models/musehub.py`](musehub/models/musehub.py) A detected section change plotted as a marker on the timeline. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `event_type` | `str` | | `'section'` | | `commit_id` | `str` | ✓ | `—` | | `timestamp` | `datetime` | ✓ | `—` | | `section_name` | `str` | ✓ | `—` | | `action` | `str` | ✓ | `—` | ### `TimelineTrackEvent` — [`musehub/models/musehub.py`](musehub/models/musehub.py) A detected track addition or removal plotted as a marker on the timeline. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `event_type` | `str` | | `'track'` | | `commit_id` | `str` | ✓ | `—` | | `timestamp` | `datetime` | ✓ | `—` | | `track_name` | `str` | ✓ | `—` | | `action` | `str` | ✓ | `—` | ### `TransferOwnershipRequest` — [`musehub/models/musehub.py`](musehub/models/musehub.py) Request body for transferring repo ownership to another user. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `new_owner_user_id` | `str` | ✓ | `—` | ### `TreeEntryResponse` — [`musehub/models/musehub.py`](musehub/models/musehub.py) A single entry (file or directory) in the Muse tree browser. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `type` | `str` | ✓ | `—` | | `name` | `str` | ✓ | `—` | | `path` | `str` | ✓ | `—` | | `size_bytes` | `int | None` | | `Field(None, description='File size in bytes; None for directories')` | | `object_id` | `str | None` | | `Field(None, description='Content-addressed object ID; None for directories and legacy entries')` | ### `TreeListResponse` — [`musehub/models/musehub.py`](musehub/models/musehub.py) Directory listing for the Muse tree browser. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `owner` | `str` | ✓ | `—` | | `repo_slug` | `str` | ✓ | `—` | | `ref` | `str` | ✓ | `—` | | `dir_path` | `str` | ✓ | `—` | | `entries` | `list[TreeEntryResponse]` | | `(factory)` | ### `UserActivityEventItem` — [`musehub/models/musehub.py`](musehub/models/musehub.py) A single event in a user's public activity feed. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `id` | `str` | ✓ | `—` | | `type` | `str` | ✓ | `—` | | `actor` | `str` | ✓ | `—` | | `repo` | `str` | ✓ | `—` | | `payload` | `dict[str, PydanticJson]` | | `(factory)` | | `created_at` | `datetime` | ✓ | `—` | ### `UserActivityFeedResponse` — [`musehub/models/musehub.py`](musehub/models/musehub.py) Cursor-paginated public activity feed for a MuseHub user (newest-first). **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `events` | `list[UserActivityEventItem]` | ✓ | `—` | | `next_cursor` | `str | None` | | `Field(None, description='Pass as before_id to fetch the next page; None on the last page')` | | `type_filter` | `str | None` | | `Field(None, description='Active type filter value, or None when all types are shown')` | ### `UserForkedRepoEntry` — [`musehub/models/musehub.py`](musehub/models/musehub.py) A single forked repo entry shown on a user's profile Forked tab. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `fork_id` | `str` | ✓ | `—` | | `fork_repo` | `RepoResponse` | ✓ | `—` | | `source_owner` | `str` | ✓ | `—` | | `source_slug` | `str` | ✓ | `—` | | `forked_at` | `datetime` | ✓ | `—` | ### `UserForksResponse` — [`musehub/models/musehub.py`](musehub/models/musehub.py) Paginated list of repos forked by a user. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `forks` | `list[UserForkedRepoEntry]` | ✓ | `—` | | `total` | `int` | ✓ | `—` | ### `UserStarredRepoEntry` — [`musehub/models/musehub.py`](musehub/models/musehub.py) A single starred-repo entry shown on a user's profile Starred tab. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `star_id` | `str` | ✓ | `—` | | `repo` | `RepoResponse` | ✓ | `—` | | `starred_at` | `datetime` | ✓ | `—` | ### `UserStarredResponse` — [`musehub/models/musehub.py`](musehub/models/musehub.py) Paginated list of repos starred by a user. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `starred` | `list[UserStarredRepoEntry]` | ✓ | `—` | | `total` | `int` | ✓ | `—` | ### `UserWatchedRepoEntry` — [`musehub/models/musehub.py`](musehub/models/musehub.py) A single watched-repo entry shown on a user's profile Watching tab. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `watch_id` | `str` | ✓ | `—` | | `repo` | `RepoResponse` | ✓ | `—` | | `watched_at` | `datetime` | ✓ | `—` | ### `UserWatchedResponse` — [`musehub/models/musehub.py`](musehub/models/musehub.py) Paginated list of repos watched by a user. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `watched` | `list[UserWatchedRepoEntry]` | ✓ | `—` | | `total` | `int` | ✓ | `—` | ### `WebhookCreate` — [`musehub/models/musehub.py`](musehub/models/musehub.py) Body for POST /musehub/repos/{repo_id}/webhooks. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `url` | `str` | ✓ | `—` | | `events` | `list[str]` | ✓ | `—` | | `secret` | `str` | | `Field('', description='Optional HMAC-SHA256 signing secret')` | ### `WebhookDeliveryListResponse` — [`musehub/models/musehub.py`](musehub/models/musehub.py) Cursor-paginated list of delivery attempts for a webhook (newest first). **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `deliveries` | `list[WebhookDeliveryResponse]` | ✓ | `—` | | `total` | `int` | | `Field(0, ge=0, description='Total delivery attempts for this webhook')` | | `next_cursor` | `str | None` | | `Field(None, description='Opaque cursor for the next page (older deliveries). Pass verbatim as ?cursor= to advance. Null when this is the last page.')` | ### `WebhookDeliveryResponse` — [`musehub/models/musehub.py`](musehub/models/musehub.py) Wire representation of a single webhook delivery attempt. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `delivery_id` | `str` | ✓ | `—` | | `webhook_id` | `str` | ✓ | `—` | | `event_type` | `str` | ✓ | `—` | | `payload` | `str` | | `Field('', description='JSON body sent to the subscriber URL')` | | `attempt` | `int` | ✓ | `—` | | `success` | `bool` | ✓ | `—` | | `response_status` | `int` | ✓ | `—` | | `response_body` | `str` | ✓ | `—` | | `delivered_at` | `datetime` | ✓ | `—` | ### `WebhookListResponse` — [`musehub/models/musehub.py`](musehub/models/musehub.py) Cursor-paginated list of webhook subscriptions for a repo. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `webhooks` | `list[WebhookResponse]` | ✓ | `—` | | `total` | `int` | | `Field(0, ge=0, description='Total webhooks registered for this repo')` | | `next_cursor` | `str | None` | | `Field(None, description='Opaque cursor for the next page. Pass verbatim as ?cursor= to advance. Null when this is the last page.')` | ### `WebhookRedeliverResponse` — [`musehub/models/musehub.py`](musehub/models/musehub.py) Confirmation that a delivery reattempt was executed. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `original_delivery_id` | `str` | ✓ | `—` | | `webhook_id` | `str` | ✓ | `—` | | `event_type` | `str` | ✓ | `—` | | `success` | `bool` | ✓ | `—` | | `response_status` | `int` | ✓ | `—` | | `response_body` | `str` | | `Field('', description='Response body snippet from the final attempt (≤512 chars)')` | ### `WebhookResponse` — [`musehub/models/musehub.py`](musehub/models/musehub.py) Wire representation of a registered webhook subscription. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `webhook_id` | `str` | ✓ | `—` | | `repo_id` | `str` | ✓ | `—` | | `url` | `str` | ✓ | `—` | | `events` | `list[str]` | ✓ | `—` | | `active` | `bool` | ✓ | `—` | | `created_at` | `datetime` | ✓ | `—` | ### `WireTagInput` — [`musehub/models/musehub.py`](musehub/models/musehub.py) A single lightweight tag pushed from a Muse CLI client. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `tag_id` | `str` | ✓ | `—` | | `commit_id` | `str` | ✓ | `—` | | `tag` | `str` | ✓ | `—` | | `created_at` | `str` | | `Field('', description='ISO-8601 creation timestamp from the client')` | ### `AgentRegistrationRequest` — [`musehub/models/musehub_auth.py`](musehub/models/musehub_auth.py) Operator-signed agent provisioning request — ``POST /api/identities/agent``. **Bases:** `BaseModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `handle` | `str` | ✓ | `—` | | `public_key_b64` | `str` | ✓ | `—` | | `fingerprint` | `str` | ✓ | `—` | | `algorithm` | `str` | | `'ed25519'` | | `agent_model` | `str` | | `''` | | `scope` | `list[str]` | | `(factory)` | | `expires_at` | `str | None` | | `Field(None, description='ISO-8601 UTC expiry time for this agent key. null = no expiry.')` | | `label` | `str` | | `''` | ### `AgentRegistrationResponse` — [`musehub/models/musehub_auth.py`](musehub/models/musehub_auth.py) Response for ``POST /api/identities/agent``. **Bases:** `BaseModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `handle` | `str` | ✓ | `—` | | `identity_id` | `str` | ✓ | `—` | | `is_new_identity` | `bool` | ✓ | `—` | | `spawned_by` | `str` | ✓ | `—` | | `key` | `AuthKeyResponse` | ✓ | `—` | ### `AuthKeyResponse` — [`musehub/models/musehub_auth.py`](musehub/models/musehub_auth.py) Public summary of a registered auth key (never exposes key material). **Bases:** `BaseModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `key_id` | `str` | ✓ | `—` | | `algorithm` | `str` | ✓ | `—` | | `fingerprint` | `str` | ✓ | `—` | | `label` | `str` | ✓ | `—` | | `created_at` | `str` | ✓ | `—` | | `last_used_at` | `str | None` | ✓ | `—` | ### `ChallengeRequest` — [`musehub/models/musehub_auth.py`](musehub/models/musehub_auth.py) Request a challenge nonce for the given public key fingerprint. **Bases:** `BaseModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `fingerprint` | `str` | ✓ | `—` | | `algorithm` | `str` | | `Field(default=KeyAlgorithm.ED25519.value, description=f'Signing algorithm for this key. Implemented: {_IMPLEMENTED_ALGO_VALUES}.')` | ### `ChallengeResponse` — [`musehub/models/musehub_auth.py`](musehub/models/musehub_auth.py) Challenge nonce to sign and submit to /api/auth/verify. **Bases:** `BaseModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `challenge_token` | `str` | ✓ | `—` | | `is_new_key` | `bool` | ✓ | `—` | | `expires_in` | `int` | | `Field(300, description='Challenge validity in seconds.')` | | `algorithm` | `str` | ✓ | `—` | ### `VerifyRequest` — [`musehub/models/musehub_auth.py`](musehub/models/musehub_auth.py) Submit a signed challenge to complete authentication. **Bases:** `BaseModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `challenge_token` | `str` | ✓ | `—` | | `public_key_b64` | `str` | ✓ | `—` | | `signature_b64` | `str` | ✓ | `—` | | `handle` | `str | None` | | `Field(None, min_length=1, max_length=64, description='Desired handle (username). Required when registering a new key.')` | | `display_name` | `str | None` | | `Field(None, max_length=128, description='Optional display name shown on the profile.')` | | `label` | `str | None` | | `Field(None, max_length=255, description='Optional friendly key label, e.g. "MacBook Pro" or "CI agent".')` | | `identity_type` | `str` | | `'human'` | ### `VerifyResponse` — [`musehub/models/musehub_auth.py`](musehub/models/musehub_auth.py) Successful key registration / re-registration response. **Bases:** `BaseModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `handle` | `str` | ✓ | `—` | | `identity_id` | `str` | ✓ | `—` | | `is_new_identity` | `bool` | ✓ | `—` | | `auth_method` | `str` | ✓ | `—` | | `key` | `AuthKeyResponse` | ✓ | `—` | ### `ActiveProposalContext` — [`musehub/models/musehub_context.py`](musehub/models/musehub_context.py) An open proposal that may inform composition decisions. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `proposal_id` | `str` | ✓ | `—` | | `title` | `str` | ✓ | `—` | | `from_branch` | `str` | ✓ | `—` | | `to_branch` | `str` | ✓ | `—` | | `state` | `str` | ✓ | `—` | | `body` | `str` | | `''` | ### `AgentContextResponse` — [`musehub/models/musehub_context.py`](musehub/models/musehub_context.py) Complete agent context document for one project ref. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `repo_id` | `str` | ✓ | `—` | | `ref` | `str` | ✓ | `Field(description='The resolved branch name or commit ID')` | | `depth` | `str` | ✓ | `Field(description='Depth level used to build this response')` | | `musical_state` | `MusicalStateContext` | ✓ | `—` | | `history` | `list[HistoryEntryContext]` | | `(factory)` | | `analysis` | `AnalysisSummaryContext` | ✓ | `—` | | `active_proposals` | `list[ActiveProposalContext]` | | `(factory)` | | `open_issues` | `list[OpenIssueContext]` | | `(factory)` | | `suggestions` | `list[str]` | | `(factory)` | ### `AnalysisSummaryContext` — [`musehub/models/musehub_context.py`](musehub/models/musehub_context.py) Per-dimension analysis highlights for the current state. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `key_finding` | `Annotated[str | None, Field(description='Key and mode detection summary')]` | | `None` | | `chord_progression` | `Annotated[list[str] | None, Field(description="Detected chord progression (e.g. ['Cm', 'Ab', 'Eb', 'Bb'])")]` | | `None` | | `groove_score` | `Annotated[float | None, Field(description='Groove quality score [0.0, 1.0]')]` | | `None` | | `emotion` | `Annotated[str | None, Field(description='Emotional character')]` | | `None` | | `harmonic_tension` | `Annotated[str | None, Field(description="Harmonic tension assessment ('low', 'medium', 'high')")]` | | `None` | | `melodic_contour` | `Annotated[str | None, Field(description='Melodic contour description')]` | | `None` | ### `HistoryEntryContext` — [`musehub/models/musehub_context.py`](musehub/models/musehub_context.py) A single commit entry in the composition history. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `commit_id` | `str` | ✓ | `—` | | `message` | `str` | ✓ | `—` | | `author` | `str` | ✓ | `—` | | `timestamp` | `str` | ✓ | `Field(description='ISO-8601 UTC timestamp')` | | `active_tracks` | `list[str]` | | `(factory)` | ### `MusicalStateContext` — [`musehub/models/musehub_context.py`](musehub/models/musehub_context.py) Current musical state of the project at the resolved ref. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `active_tracks` | `list[str]` | | `(factory)` | ### `OpenIssueContext` — [`musehub/models/musehub_context.py`](musehub/models/musehub_context.py) An open issue that may describe desired compositional changes. **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `issue_id` | `str` | ✓ | `—` | | `number` | `int` | ✓ | `—` | | `title` | `str` | ✓ | `—` | | `labels` | `list[str]` | | `(factory)` | | `body` | `str` | | `''` | ### `WireMPack` — [`musehub/models/wire.py`](musehub/models/wire.py) An mpack sent in a push request. **Bases:** `BaseModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `commits` | `list[WireCommit]` | | `(factory)` | | `snapshots` | `list[WireSnapshot]` | | `(factory)` | | `objects` | `list[WireObject]` | | `(factory)` | | `branch_heads` | `StrDict` | | `(factory)` | ### `WireCommit` — [`musehub/models/wire.py`](musehub/models/wire.py) Muse native commit record — mirrors CommitDict from muse.core.store. **Bases:** `BaseModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `commit_id` | `str` | ✓ | `—` | | `repo_id` | `str` | | `''` | | `branch` | `str` | | `''` | | `snapshot_id` | `str | None` | | `None` | | `message` | `str` | | `''` | | `committed_at` | `str` | | `''` | | `parent_commit_id` | `str | None` | | `None` | | `parent2_commit_id` | `str | None` | | `None` | | `author` | `str` | | `''` | | `metadata` | `StrDict` | | `(factory)` | | `structured_delta` | `PydanticJson | None` | | `None` | | `sem_ver_bump` | `str` | | `'none'` | | `breaking_changes` | `list[str]` | | `(factory)` | | `agent_id` | `str` | | `''` | | `model_id` | `str` | | `''` | | `toolchain_id` | `str` | | `''` | | `prompt_hash` | `str` | | `''` | | `signature` | `str` | | `''` | | `signer_public_key` | `str` | | `''` | | `signer_key_id` | `str` | | `''` | | `format_version` | `int` | | `7` | | `reviewed_by` | `list[str]` | | `(factory)` | | `test_runs` | `int` | | `0` | ### `WireConfirmObjectsRequest` — [`musehub/models/wire.py`](musehub/models/wire.py) Body for ``POST /{owner}/{slug}/push/objects/confirm``. **Bases:** `BaseModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `object_ids` | `list[str]` | | `(factory)` | | `sizes` | `dict[str, int]` | | `(factory)` | ### `WireConfirmObjectsResponse` — [`musehub/models/wire.py`](musehub/models/wire.py) Response for ``POST /{owner}/{slug}/push/objects/confirm``. **Bases:** `BaseModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `registered` | `int` | ✓ | `—` | | `skipped` | `int` | ✓ | `—` | ### `WireFetchObjectsRequest` — [`musehub/models/wire.py`](musehub/models/wire.py) Body for ``POST /{owner}/{slug}/fetch/objects``. **Bases:** `BaseModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `object_ids` | `list[str]` | | `(factory)` | ### `WireFetchRequest` — [`musehub/models/wire.py`](musehub/models/wire.py) Body for ``POST /wire/repos/{repo_id}/fetch``. **Bases:** `BaseModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `want` | `list[str]` | | `(factory)` | | `have` | `list[str]` | | `(factory)` | ### `WireFetchResponse` — [`musehub/models/wire.py`](musehub/models/wire.py) Response for ``POST /wire/repos/{repo_id}/fetch``. **Bases:** `BaseModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `commits` | `list[WireCommit]` | | `(factory)` | | `snapshots` | `list[WireSnapshot]` | | `(factory)` | | `branch_heads` | `StrDict` | | `(factory)` | ### `WireFilterRequest` — [`musehub/models/wire.py`](musehub/models/wire.py) Body for ``POST /{owner}/{slug}/filter-objects``. **Bases:** `BaseModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `object_ids` | `list[str]` | | `(factory)` | | `object_hints` | `dict[str, str]` | | `(factory)` | ### `WireFilterResponse` — [`musehub/models/wire.py`](musehub/models/wire.py) Response for ``POST /{owner}/{slug}/filter-objects``. **Bases:** `BaseModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `missing` | `list[str]` | ✓ | `—` | | `bases` | `dict[str, str]` | | `(factory)` | ### `WireObject` — [`musehub/models/wire.py`](musehub/models/wire.py) Content-addressed object payload — mirrors ObjectPayload from muse.core.mpack. **Bases:** `BaseModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `object_id` | `str` | ✓ | `—` | | `content` | `bytes` | ✓ | `Field(max_length=MAX_OBJECT_BYTES)` | | `path` | `str` | | `''` | | `encoding` | `str` | | `'raw'` | | `base_id` | `str | None` | | `None` | ### `WireObjectPackRequest` — [`musehub/models/wire.py`](musehub/models/wire.py) Body for ``POST /{owner}/{slug}/push/object-pack``. **Bases:** `BaseModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `objects` | `list[WireObject]` | | `(factory)` | ### `WireObjectPackResponse` — [`musehub/models/wire.py`](musehub/models/wire.py) Response for ``POST /{owner}/{slug}/push/object-pack``. **Bases:** `BaseModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `stored` | `int` | ✓ | `—` | | `skipped` | `int` | ✓ | `—` | ### `WireObjectsRequest` — [`musehub/models/wire.py`](musehub/models/wire.py) Body for ``POST /{owner}/{slug}/push/objects`` — chunked object pre-upload. **Bases:** `BaseModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `objects` | `list[WireObject]` | | `(factory)` | ### `WireObjectsResponse` — [`musehub/models/wire.py`](musehub/models/wire.py) Response for ``POST /{owner}/{slug}/push/objects``. **Bases:** `BaseModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `stored` | `int` | ✓ | `—` | | `skipped` | `int` | ✓ | `—` | ### `WirePresignRequest` — [`musehub/models/wire.py`](musehub/models/wire.py) Body for ``POST /{owner}/{slug}/presign``. **Bases:** `BaseModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `object_ids` | `list[str]` | | `(factory)` | | `direction` | `str` | | `'put'` | | `ttl_seconds` | `int` | | `3600` | ### `WirePresignResponse` — [`musehub/models/wire.py`](musehub/models/wire.py) Response for ``POST /{owner}/{slug}/presign``. **Bases:** `BaseModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `presigned` | `StrDict` | | `(factory)` | | `inline` | `list[str]` | | `(factory)` | ### `WirePushRequest` — [`musehub/models/wire.py`](musehub/models/wire.py) Body for ``POST /wire/repos/{repo_id}/push``. **Bases:** `BaseModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `mpack` | `WireMPack` | ✓ | `—` | | `branch` | `str` | ✓ | `—` | | `force` | `bool` | | `False` | | `local_head` | `str | None` | | `None` | ### `WirePushResponse` — [`musehub/models/wire.py`](musehub/models/wire.py) Response for ``POST /wire/repos/{repo_id}/push``. **Bases:** `BaseModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `ok` | `bool` | ✓ | `—` | | `message` | `str` | ✓ | `—` | | `branch_heads` | `StrDict` | ✓ | `—` | | `remote_head` | `str` | | `''` | ### `WireRefsResponse` — [`musehub/models/wire.py`](musehub/models/wire.py) Response for ``GET /wire/repos/{repo_id}/refs``. **Bases:** `BaseModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `repo_id` | `str` | ✓ | `—` | | `domain` | `str` | ✓ | `—` | | `default_branch` | `str` | ✓ | `—` | | `branch_heads` | `StrDict` | ✓ | `—` | | `pack_origin` | `str | None` | | `None` | ### `WireSnapshot` — [`musehub/models/wire.py`](musehub/models/wire.py) Muse native snapshot — mirrors SnapshotDict from muse.core.store. **Bases:** `BaseModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `snapshot_id` | `str` | ✓ | `—` | | `manifest` | `StrDict` | | `(factory)` | | `directories` | `list[str]` | | `(factory)` | | `created_at` | `str` | | `''` | ### `MCPInputSchemaWire` — [`musehub/muse_contracts/mcp_types.py`](musehub/muse_contracts/mcp_types.py) Pydantic-safe wire model for an MCP tool's JSON Schema input descriptor. **Bases:** `BaseModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `type` | `str` | | `'object'` | | `properties` | `dict[str, 'MCPPropertyDefWire']` | | `(factory)` | | `required` | `list[str] | None` | | `None` | ### `MCPPropertyDefWire` — [`musehub/muse_contracts/mcp_types.py`](musehub/muse_contracts/mcp_types.py) Pydantic-safe wire model for a single JSON Schema property definition. **Bases:** `BaseModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `type` | `str` | ✓ | `—` | | `description` | `str | None` | | `None` | | `enum` | `list[str | int | float] | None` | | `None` | | `minimum` | `float | None` | | `None` | | `maximum` | `float | None` | | `None` | | `default` | `PydanticJson | None` | | `None` | | `items` | `_ItemsSchema | None` | | `None` | | `properties` | `_PropWireMap | None` | | `None` | ### `MCPToolDefWire` — [`musehub/muse_contracts/mcp_types.py`](musehub/muse_contracts/mcp_types.py) Pydantic-safe wire model for a single MCP tool definition. **Bases:** `BaseModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `name` | `str` | ✓ | `—` | | `description` | `str` | ✓ | `—` | | `inputSchema` | `MCPInputSchemaWire` | | `(factory)` | | `annotations` | `_AnnotationsMap | None` | | `None` | | `server_side` | `bool | None` | | `None` | ### `ProtocolInfoResponse` — [`musehub/protocol/responses.py`](musehub/protocol/responses.py) Response shape for ``GET /protocol``. **Bases:** `BaseModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `version` | `str` | ✓ | `—` | | `protocol_hash` | `str` | ✓ | `—` | | `event_count` | `int` | ✓ | `—` | | `tool_count` | `int` | ✓ | `—` | ### `M` — [`tests/test_api_contracts_section37.py`](tests/test_api_contracts_section37.py) **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `owner_id` | `str` | ✓ | `—` | ### `MyModel` — [`tests/test_api_contracts_section37.py`](tests/test_api_contracts_section37.py) **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `my_field` | `str` | ✓ | `—` | ### `MyModel` — [`tests/test_api_contracts_section37.py`](tests/test_api_contracts_section37.py) **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `repo_id` | `str` | ✓ | `—` | ### `MyModel` — [`tests/test_api_contracts_section37.py`](tests/test_api_contracts_section37.py) **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `repo_id` | `str` | ✓ | `—` | ### `MyModel` — [`tests/test_api_contracts_section37.py`](tests/test_api_contracts_section37.py) **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `repo_id` | `str` | ✓ | `—` | ### `MyModel` — [`tests/test_api_contracts_section37.py`](tests/test_api_contracts_section37.py) **Bases:** `CamelModel` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `repo_id` | `str` | ✓ | `—` | ## SQLAlchemy ORM Models ### `MusehubCoordRecord` — [`musehub/db/coord_models.py`](musehub/db/coord_models.py) A single coordination record pushed from a Muse CLI agent. **Bases:** `Base` **Table:** `musehub_coord_records` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `id` | `Mapped[int]` | | `mapped_column(Integer, primary_key=True, autoincrement=True)` | | `repo_id` | `Mapped[str]` | | `mapped_column(String(36), ForeignKey('musehub_repos.repo_id', ondelete='CASCADE'), nullable=False, index=True)` | | `kind` | `Mapped[str]` | | `mapped_column(String(32), nullable=False)` | | `record_uuid` | `Mapped[str]` | | `mapped_column(String(36), nullable=False)` | | `run_id` | `Mapped[str]` | | `mapped_column(String(255), nullable=False, default='')` | | `payload` | `Mapped[dict[str, object]]` | | `mapped_column(JSON, nullable=False)` | | `created_at` | `Mapped[datetime]` | | `mapped_column(DateTime(timezone=True), nullable=False, default=_utc_now)` | | `expires_at` | `Mapped[datetime | None]` | | `mapped_column(DateTime(timezone=True), nullable=True, default=None)` | ### `MusehubCoordReservation` — [`musehub/db/coord_models.py`](musehub/db/coord_models.py) Persistent store for muse coord reserve events synced from agents. **Bases:** `Base` **Table:** `musehub_coord_reservations` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `reservation_id` | `Mapped[str]` | | `mapped_column(String(36), primary_key=True, default=_new_uuid)` | | `repo_id` | `Mapped[str]` | | `mapped_column(String(36), ForeignKey('musehub_repos.repo_id', ondelete='CASCADE'), nullable=False, index=True)` | | `symbol_address` | `Mapped[str]` | | `mapped_column(String(512), nullable=False)` | | `agent_id` | `Mapped[str]` | | `mapped_column(String(255), nullable=False)` | | `agent_model_id` | `Mapped[str]` | | `mapped_column(String(255), nullable=False, default='')` | | `ttl_s` | `Mapped[int]` | | `mapped_column(Integer, nullable=False, default=300)` | | `created_at` | `Mapped[datetime]` | | `mapped_column(DateTime(timezone=True), nullable=False, default=_utc_now)` | | `expires_at` | `Mapped[datetime]` | | `mapped_column(DateTime(timezone=True), nullable=False)` | | `released_at` | `Mapped[datetime | None]` | | `mapped_column(DateTime(timezone=True), nullable=True)` | ### `MusehubCoordTask` — [`musehub/db/coord_models.py`](musehub/db/coord_models.py) Persistent task queue mirroring muse coord enqueue/claim/complete. **Bases:** `Base` **Table:** `musehub_coord_tasks` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `task_id` | `Mapped[str]` | | `mapped_column(String(36), primary_key=True, default=_new_uuid)` | | `repo_id` | `Mapped[str]` | | `mapped_column(String(36), ForeignKey('musehub_repos.repo_id', ondelete='CASCADE'), nullable=False, index=True)` | | `queue` | `Mapped[str]` | | `mapped_column(String(255), nullable=False, default='default')` | | `priority` | `Mapped[int]` | | `mapped_column(Integer, nullable=False, default=50)` | | `payload` | `Mapped[dict[str, object]]` | | `mapped_column(JSON, nullable=False)` | | `status` | `Mapped[str]` | | `mapped_column(String(20), nullable=False, default='pending', index=True)` | | `claimed_by` | `Mapped[str | None]` | | `mapped_column(String(255), nullable=True)` | | `claimed_at` | `Mapped[datetime | None]` | | `mapped_column(DateTime(timezone=True), nullable=True)` | | `completed_at` | `Mapped[datetime | None]` | | `mapped_column(DateTime(timezone=True), nullable=True)` | | `depends_on` | `Mapped[list[str]]` | | `mapped_column(JSON, nullable=False, default=list)` | | `run_id` | `Mapped[str | None]` | | `mapped_column(String(255), nullable=True)` | | `created_at` | `Mapped[datetime]` | | `mapped_column(DateTime(timezone=True), nullable=False, default=_utc_now)` | ### `MuseCliCommit` — [`musehub/db/muse_cli_models.py`](musehub/db/muse_cli_models.py) A versioned commit record pointing to a snapshot and its parent. **Bases:** `Base` **Table:** `muse_commits` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `commit_id` | `Mapped[str]` | | `mapped_column(String(64), primary_key=True)` | | `repo_id` | `Mapped[str]` | | `mapped_column(String(36), nullable=False, index=True)` | | `branch` | `Mapped[str]` | | `mapped_column(String(255), nullable=False)` | | `parent_commit_id` | `Mapped[str | None]` | | `mapped_column(String(64), nullable=True, index=True)` | | `parent2_commit_id` | `Mapped[str | None]` | | `mapped_column(String(64), nullable=True, index=True)` | | `snapshot_id` | `Mapped[str]` | | `mapped_column(String(64), ForeignKey('muse_snapshots.snapshot_id', ondelete='RESTRICT'), nullable=False)` | | `message` | `Mapped[str]` | | `mapped_column(Text, nullable=False)` | | `author` | `Mapped[str]` | | `mapped_column(String(255), nullable=False, default='')` | | `committed_at` | `Mapped[datetime]` | | `mapped_column(DateTime(timezone=True), nullable=False)` | | `created_at` | `Mapped[datetime]` | | `mapped_column(DateTime(timezone=True), nullable=False, default=_utc_now)` | | `commit_metadata` | `Mapped[dict[str, object] | None]` | | `mapped_column(JSON, nullable=True, default=None)` | ### `MuseCliObject` — [`musehub/db/muse_cli_models.py`](musehub/db/muse_cli_models.py) A content-addressed blob: sha256(file_bytes) → bytes on disk. **Bases:** `Base` **Table:** `muse_objects` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `object_id` | `Mapped[str]` | | `mapped_column(String(64), primary_key=True)` | | `size_bytes` | `Mapped[int]` | | `mapped_column(Integer, nullable=False)` | | `created_at` | `Mapped[datetime]` | | `mapped_column(DateTime(timezone=True), nullable=False, default=_utc_now)` | ### `MuseCliSnapshot` — [`musehub/db/muse_cli_models.py`](musehub/db/muse_cli_models.py) An immutable snapshot manifest: sha256(sorted(path:object_id pairs)). **Bases:** `Base` **Table:** `muse_snapshots` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `snapshot_id` | `Mapped[str]` | | `mapped_column(String(64), primary_key=True)` | | `manifest` | `Mapped[dict[str, str]]` | | `mapped_column(JSON, nullable=False)` | | `created_at` | `Mapped[datetime]` | | `mapped_column(DateTime(timezone=True), nullable=False, default=_utc_now)` | ### `MuseCliTag` — [`musehub/db/muse_cli_models.py`](musehub/db/muse_cli_models.py) A music-semantic tag attached to a Muse CLI commit. **Bases:** `Base` **Table:** `muse_tags` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `tag_id` | `Mapped[str]` | | `mapped_column(String(36), primary_key=True, default=lambda: str(uuid.uuid4()))` | | `repo_id` | `Mapped[str]` | | `mapped_column(String(36), nullable=False, index=True)` | | `commit_id` | `Mapped[str]` | | `mapped_column(String(64), ForeignKey('muse_commits.commit_id', ondelete='CASCADE'), nullable=False, index=True)` | | `tag` | `Mapped[str]` | | `mapped_column(Text, nullable=False, index=True)` | | `created_at` | `Mapped[datetime]` | | `mapped_column(DateTime(timezone=True), nullable=False, default=_utc_now)` | ### `MusehubAuthChallenge` — [`musehub/db/musehub_auth_models.py`](musehub/db/musehub_auth_models.py) In-flight challenge nonce row. **Bases:** `Base` **Table:** `musehub_auth_challenges` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `challenge_id` | `Mapped[str]` | | `mapped_column(String(36), primary_key=True, default=_new_uuid)` | | `nonce_hex` | `Mapped[str]` | | `mapped_column(String(64), nullable=False)` | | `fingerprint` | `Mapped[str]` | | `mapped_column(String(64), nullable=False)` | | `algorithm` | `Mapped[str]` | | `mapped_column(String(32), nullable=False, default='ed25519')` | | `expires_at` | `Mapped[datetime]` | | `mapped_column(DateTime(timezone=True), nullable=False)` | ### `MusehubAuthKey` — [`musehub/db/musehub_auth_models.py`](musehub/db/musehub_auth_models.py) One registered public key for a MuseHub identity. **Bases:** `Base` **Table:** `musehub_auth_keys` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `key_id` | `Mapped[str]` | | `mapped_column(String(36), primary_key=True, default=_new_uuid)` | | `identity_id` | `Mapped[str]` | | `mapped_column(String(36), ForeignKey('musehub_identities.id', ondelete='CASCADE'), nullable=False)` | | `algorithm` | `Mapped[str]` | | `mapped_column(String(32), nullable=False, default='ed25519')` | | `public_key_b64` | `Mapped[str]` | | `mapped_column(Text, nullable=False)` | | `fingerprint` | `Mapped[str]` | | `mapped_column(String(64), nullable=False)` | | `label` | `Mapped[str]` | | `mapped_column(String(255), nullable=False, default='')` | | `created_at` | `Mapped[datetime]` | | `mapped_column(DateTime(timezone=True), nullable=False, default=_utc_now)` | | `last_used_at` | `Mapped[datetime | None]` | | `mapped_column(DateTime(timezone=True), nullable=True)` | ### `MusehubCollaborator` — [`musehub/db/musehub_collaborator_models.py`](musehub/db/musehub_collaborator_models.py) A collaborator record granting a user explicit access to a repo. **Bases:** `Base` **Table:** `musehub_collaborators` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `id` | `Mapped[str]` | | `mapped_column(String(36), primary_key=True, default=_new_uuid)` | | `repo_id` | `Mapped[str]` | | `mapped_column(String(36), ForeignKey('musehub_repos.repo_id', ondelete='CASCADE'), nullable=False)` | | `identity_handle` | `Mapped[str]` | | `mapped_column(String(64), nullable=False)` | | `permission` | `Mapped[str]` | | `mapped_column(String(20), nullable=False, default='write')` | | `invited_by_handle` | `Mapped[str | None]` | | `mapped_column(String(2048), nullable=True)` | | `invited_at` | `Mapped[datetime]` | | `mapped_column(DateTime(timezone=True), nullable=False, default=_utc_now)` | | `accepted_at` | `Mapped[datetime | None]` | | `mapped_column(DateTime(timezone=True), nullable=True)` | ### `MusehubDomain` — [`musehub/db/musehub_domain_models.py`](musehub/db/musehub_domain_models.py) A registered Muse domain plugin in the MuseHub registry. **Bases:** `Base` **Table:** `musehub_domains` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `domain_id` | `Mapped[str]` | | `mapped_column(String(36), primary_key=True, default=_new_uuid)` | | `author_user_id` | `Mapped[str | None]` | | `mapped_column(String(36), nullable=True, index=True)` | | `author_slug` | `Mapped[str]` | | `mapped_column(String(64), nullable=False, index=True)` | | `slug` | `Mapped[str]` | | `mapped_column(String(64), nullable=False, index=True)` | | `display_name` | `Mapped[str]` | | `mapped_column(String(255), nullable=False)` | | `description` | `Mapped[str]` | | `mapped_column(Text, nullable=False, default='')` | | `version` | `Mapped[str]` | | `mapped_column(String(32), nullable=False, default='1.0.0')` | | `manifest_hash` | `Mapped[str]` | | `mapped_column(String(64), nullable=False, default='')` | | `capabilities` | `Mapped[dict[str, object]]` | | `mapped_column(JSON, nullable=False, default=dict)` | | `viewer_type` | `Mapped[str]` | | `mapped_column(String(64), nullable=False, default='generic')` | | `install_count` | `Mapped[int]` | | `mapped_column(Integer, nullable=False, default=0)` | | `is_verified` | `Mapped[bool]` | | `mapped_column(Boolean, nullable=False, default=False)` | | `is_deprecated` | `Mapped[bool]` | | `mapped_column(Boolean, nullable=False, default=False)` | | `created_at` | `Mapped[datetime]` | | `mapped_column(DateTime(timezone=True), nullable=False, default=_utc_now)` | | `updated_at` | `Mapped[datetime]` | | `mapped_column(DateTime(timezone=True), nullable=False, default=_utc_now, onupdate=_utc_now)` | ### `MusehubDomainInstall` — [`musehub/db/musehub_domain_models.py`](musehub/db/musehub_domain_models.py) Records a user's installation/adoption of a domain plugin. **Bases:** `Base` **Table:** `musehub_domain_installs` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `install_id` | `Mapped[str]` | | `mapped_column(String(36), primary_key=True, default=_new_uuid)` | | `user_id` | `Mapped[str]` | | `mapped_column(String(36), nullable=False, index=True)` | | `domain_id` | `Mapped[str]` | | `mapped_column(String(36), nullable=False, index=True)` | | `created_at` | `Mapped[datetime]` | | `mapped_column(DateTime(timezone=True), nullable=False, default=_utc_now)` | ### `MusehubIssueLabel` — [`musehub/db/musehub_label_models.py`](musehub/db/musehub_label_models.py) Join table linking issues to labels. **Bases:** `Base` **Table:** `musehub_issue_labels` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `issue_id` | `Mapped[str]` | | `mapped_column(String(36), ForeignKey('musehub_issues.issue_id', ondelete='CASCADE'), primary_key=True)` | | `label_id` | `Mapped[str]` | | `mapped_column(String(36), ForeignKey('musehub_labels.id', ondelete='CASCADE'), primary_key=True)` | | `label` | `Mapped[MusehubLabel]` | | `relationship('MusehubLabel', back_populates='issue_labels')` | ### `MusehubLabel` — [`musehub/db/musehub_label_models.py`](musehub/db/musehub_label_models.py) A coloured label tag that can be applied to issues and proposals. **Bases:** `Base` **Table:** `musehub_labels` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `id` | `Mapped[str]` | | `mapped_column(String(36), primary_key=True, default=_new_uuid)` | | `repo_id` | `Mapped[str]` | | `mapped_column(String(36), ForeignKey('musehub_repos.repo_id', ondelete='CASCADE'), nullable=False)` | | `name` | `Mapped[str]` | | `mapped_column(String(50), nullable=False)` | | `color` | `Mapped[str]` | | `mapped_column(String(7), nullable=False)` | | `description` | `Mapped[str | None]` | | `mapped_column(String(200), nullable=True)` | | `created_at` | `Mapped[datetime]` | | `mapped_column(DateTime(timezone=True), nullable=False, default=_utc_now)` | | `issue_labels` | `Mapped[list[MusehubIssueLabel]]` | | `relationship('MusehubIssueLabel', back_populates='label', cascade='all, delete-orphan')` | | `proposal_labels` | `Mapped[list[MusehubProposalLabel]]` | | `relationship('MusehubProposalLabel', back_populates='label', cascade='all, delete-orphan')` | ### `MusehubProposalLabel` — [`musehub/db/musehub_label_models.py`](musehub/db/musehub_label_models.py) Join table linking proposals to labels. **Bases:** `Base` **Table:** `musehub_proposal_labels` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `proposal_id` | `Mapped[str]` | | `mapped_column(String(36), ForeignKey('musehub_proposals.proposal_id', ondelete='CASCADE'), primary_key=True)` | | `label_id` | `Mapped[str]` | | `mapped_column(String(36), ForeignKey('musehub_labels.id', ondelete='CASCADE'), primary_key=True)` | | `label` | `Mapped[MusehubLabel]` | | `relationship('MusehubLabel', back_populates='proposal_labels')` | ### `MusehubBackgroundJob` — [`musehub/db/musehub_models.py`](musehub/db/musehub_models.py) A durable background job enqueued by the web process and processed by the worker. **Bases:** `Base` **Table:** `musehub_background_jobs` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `job_id` | `Mapped[str]` | | `mapped_column(String(36), primary_key=True, default=_new_uuid)` | | `repo_id` | `Mapped[str]` | | `mapped_column(String(36), ForeignKey('musehub_repos.repo_id', ondelete='CASCADE'), nullable=False, index=True)` | | `job_type` | `Mapped[str]` | | `mapped_column(String(64), nullable=False)` | | `payload` | `Mapped[dict[str, object]]` | | `mapped_column(JSON, nullable=False, default=dict)` | | `status` | `Mapped[str]` | | `mapped_column(String(16), nullable=False, default='pending', index=True)` | | `created_at` | `Mapped[datetime]` | | `mapped_column(DateTime(timezone=True), nullable=False, default=_utc_now)` | | `claimed_at` | `Mapped[datetime | None]` | | `mapped_column(DateTime(timezone=True), nullable=True)` | | `done_at` | `Mapped[datetime | None]` | | `mapped_column(DateTime(timezone=True), nullable=True)` | | `attempt` | `Mapped[int]` | | `mapped_column(Integer, nullable=False, default=0)` | | `error` | `Mapped[str | None]` | | `mapped_column(Text, nullable=True)` | ### `MusehubBranch` — [`musehub/db/musehub_models.py`](musehub/db/musehub_models.py) A named branch pointer inside a MuseHub repo. **Bases:** `Base` **Table:** `musehub_branches` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `branch_id` | `Mapped[str]` | | `mapped_column(String(36), primary_key=True, default=_new_uuid)` | | `repo_id` | `Mapped[str]` | | `mapped_column(String(36), ForeignKey('musehub_repos.repo_id', ondelete='CASCADE'), nullable=False, index=True)` | | `name` | `Mapped[str]` | | `mapped_column(String(255), nullable=False)` | | `head_commit_id` | `Mapped[str | None]` | | `mapped_column(String(2048), nullable=True)` | | `repo` | `Mapped[MusehubRepo]` | | `relationship('MusehubRepo', back_populates='branches')` | ### `MusehubCommit` — [`musehub/db/musehub_models.py`](musehub/db/musehub_models.py) A commit record pushed to the MuseHub. **Bases:** `Base` **Table:** `musehub_commits` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `commit_id` | `Mapped[str]` | | `mapped_column(String(64), primary_key=True)` | | `repo_id` | `Mapped[str]` | | `mapped_column(String(36), ForeignKey('musehub_repos.repo_id', ondelete='CASCADE'), nullable=False, index=True)` | | `branch` | `Mapped[str]` | | `mapped_column(String(255), nullable=False, index=True)` | | `parent_ids` | `Mapped[list[str]]` | | `mapped_column(JSON, nullable=False, default=list)` | | `message` | `Mapped[str]` | | `mapped_column(Text, nullable=False)` | | `author` | `Mapped[str]` | | `mapped_column(String(255), nullable=False)` | | `timestamp` | `Mapped[datetime]` | | `mapped_column(DateTime(timezone=True), nullable=False, index=True)` | | `snapshot_id` | `Mapped[str | None]` | | `mapped_column(String(2048), nullable=True)` | | `commit_meta` | `Mapped[dict[str, object]]` | | `mapped_column(JSON, nullable=False, default=dict)` | | `created_at` | `Mapped[datetime]` | | `mapped_column(DateTime(timezone=True), nullable=False, default=_utc_now)` | | `repo` | `Mapped[MusehubRepo]` | | `relationship('MusehubRepo', back_populates='commits')` | ### `MusehubFileIntelCache` — [`musehub/db/musehub_models.py`](musehub/db/musehub_models.py) Per-file IntelSnapshot cache, keyed by (repo_id, file_path). **Bases:** `Base` **Table:** `musehub_file_intel_cache` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `cache_id` | `Mapped[str]` | | `mapped_column(String(36), primary_key=True, default=_new_uuid)` | | `repo_id` | `Mapped[str]` | | `mapped_column(String(36), ForeignKey('musehub_repos.repo_id', ondelete='CASCADE'), nullable=False)` | | `file_path` | `Mapped[str]` | | `mapped_column(String(1024), nullable=False)` | | `ref` | `Mapped[str]` | | `mapped_column(String(64), nullable=False)` | | `intel_json` | `Mapped[str]` | | `mapped_column(sa.Text, nullable=False)` | | `symbol_history_json` | `Mapped[str]` | | `mapped_column(sa.Text, nullable=False)` | | `computed_at` | `Mapped[datetime]` | | `mapped_column(DateTime(timezone=True), nullable=False, default=_utc_now)` | ### `MusehubFork` — [`musehub/db/musehub_models.py`](musehub/db/musehub_models.py) Fork relationship record — links a source repo to its forked copy. **Bases:** `Base` **Table:** `musehub_forks` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `fork_id` | `Mapped[str]` | | `mapped_column(String(36), primary_key=True, default=_new_uuid)` | | `source_repo_id` | `Mapped[str]` | | `mapped_column(String(36), ForeignKey('musehub_repos.repo_id', ondelete='CASCADE'), nullable=False, index=True)` | | `fork_repo_id` | `Mapped[str]` | | `mapped_column(String(36), ForeignKey('musehub_repos.repo_id', ondelete='CASCADE'), nullable=False, index=True)` | | `forked_by` | `Mapped[str]` | | `mapped_column(String(255), nullable=False, index=True)` | | `created_at` | `Mapped[datetime]` | | `mapped_column(DateTime(timezone=True), nullable=False, default=_utc_now)` | ### `MusehubIdentity` — [`musehub/db/musehub_models.py`](musehub/db/musehub_models.py) Unified identity — human, agent, or org. **Bases:** `Base` **Table:** `musehub_identities` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `id` | `Mapped[str]` | | `mapped_column(String(36), primary_key=True, default=_new_uuid)` | | `handle` | `Mapped[str]` | | `mapped_column(String(64), nullable=False, index=True)` | | `identity_type` | `Mapped[str]` | | `mapped_column(String(16), nullable=False, default='human')` | | `display_name` | `Mapped[str | None]` | | `mapped_column(String(255), nullable=True)` | | `bio` | `Mapped[str | None]` | | `mapped_column(Text, nullable=True)` | | `avatar_url` | `Mapped[str | None]` | | `mapped_column(String(2048), nullable=True)` | | `website_url` | `Mapped[str | None]` | | `mapped_column(String(2048), nullable=True)` | | `email` | `Mapped[str | None]` | | `mapped_column(String(255), nullable=True, index=True)` | | `agent_model` | `Mapped[str | None]` | | `mapped_column(String(255), nullable=True)` | | `agent_capabilities` | `Mapped[list[str]]` | | `mapped_column(JSON, nullable=False, default=list)` | | `location` | `Mapped[str | None]` | | `mapped_column(String(255), nullable=True)` | | `social_url` | `Mapped[str | None]` | | `mapped_column(String(2048), nullable=True)` | | `is_verified` | `Mapped[bool]` | | `mapped_column(Boolean, nullable=False, default=False, index=True)` | | `cc_license` | `Mapped[str | None]` | | `mapped_column(String(50), nullable=True)` | | `pinned_repo_ids` | `Mapped[list]` | | `mapped_column(JSON, nullable=False, default=list)` | | `created_at` | `Mapped[datetime]` | | `mapped_column(DateTime(timezone=True), nullable=False, default=_utc_now)` | | `updated_at` | `Mapped[datetime]` | | `mapped_column(DateTime(timezone=True), nullable=False, default=_utc_now, onupdate=_utc_now)` | | `deleted_at` | `Mapped[datetime | None]` | | `mapped_column(DateTime(timezone=True), nullable=True, default=None)` | | `spawned_by` | `Mapped[str | None]` | | `mapped_column(String(64), nullable=True, index=True)` | | `scope` | `Mapped[list[str] | None]` | | `mapped_column(JSON, nullable=True)` | | `expires_at` | `Mapped[datetime | None]` | | `mapped_column(DateTime(timezone=True), nullable=True, index=True)` | | `tos_accepted_at` | `Mapped[datetime | None]` | | `mapped_column(DateTime(timezone=True), nullable=True, default=None)` | | `tos_version` | `Mapped[str | None]` | | `mapped_column(String(16), nullable=True, default=None)` | ### `MusehubIssue` — [`musehub/db/musehub_models.py`](musehub/db/musehub_models.py) An issue opened against a MuseHub repo. **Bases:** `Base` **Table:** `musehub_issues` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `issue_id` | `Mapped[str]` | | `mapped_column(String(36), primary_key=True, default=_new_uuid)` | | `repo_id` | `Mapped[str]` | | `mapped_column(String(36), ForeignKey('musehub_repos.repo_id', ondelete='CASCADE'), nullable=False, index=True)` | | `number` | `Mapped[int]` | | `mapped_column(Integer, nullable=False, index=True)` | | `title` | `Mapped[str]` | | `mapped_column(String(500), nullable=False)` | | `body` | `Mapped[str]` | | `mapped_column(Text, nullable=False, default='')` | | `state` | `Mapped[str]` | | `mapped_column(String(20), nullable=False, default='open', index=True)` | | `labels` | `Mapped[list[str]]` | | `mapped_column(JSON, nullable=False, default=list)` | | `symbol_anchors` | `Mapped[list[str]]` | | `mapped_column(JSON, nullable=False, default=list)` | | `commit_anchors` | `Mapped[list[str]]` | | `mapped_column(JSON, nullable=False, default=list)` | | `author` | `Mapped[str]` | | `mapped_column(String(255), nullable=False, default='')` | | `assignee` | `Mapped[str | None]` | | `mapped_column(String(255), nullable=True)` | | `agent_id` | `Mapped[str]` | | `mapped_column(String(255), nullable=False, default='')` | | `model_id` | `Mapped[str]` | | `mapped_column(String(255), nullable=False, default='')` | | `created_at` | `Mapped[datetime]` | | `mapped_column(DateTime(timezone=True), nullable=False, default=_utc_now)` | | `updated_at` | `Mapped[datetime]` | | `mapped_column(DateTime(timezone=True), nullable=False, default=_utc_now, onupdate=_utc_now)` | | `repo` | `Mapped[MusehubRepo]` | | `relationship('MusehubRepo', back_populates='issues')` | | `comments` | `Mapped[list[MusehubIssueComment]]` | | `relationship('MusehubIssueComment', back_populates='issue', cascade='all, delete-orphan', order_by='MusehubIssueComment.created_at')` | | `events` | `Mapped[list[MusehubIssueEvent]]` | | `relationship('MusehubIssueEvent', back_populates='issue', cascade='all, delete-orphan', order_by='MusehubIssueEvent.created_at')` | ### `MusehubIssueComment` — [`musehub/db/musehub_models.py`](musehub/db/musehub_models.py) A comment in a threaded discussion on a MuseHub issue. **Bases:** `Base` **Table:** `musehub_issue_comments` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `comment_id` | `Mapped[str]` | | `mapped_column(String(36), primary_key=True, default=_new_uuid)` | | `issue_id` | `Mapped[str]` | | `mapped_column(String(36), ForeignKey('musehub_issues.issue_id', ondelete='CASCADE'), nullable=False, index=True)` | | `repo_id` | `Mapped[str]` | | `mapped_column(String(36), ForeignKey('musehub_repos.repo_id', ondelete='CASCADE'), nullable=False, index=True)` | | `author` | `Mapped[str]` | | `mapped_column(String(255), nullable=False, default='')` | | `body` | `Mapped[str]` | | `mapped_column(Text, nullable=False)` | | `parent_id` | `Mapped[str | None]` | | `mapped_column(String(36), nullable=True, index=True)` | | `is_deleted` | `Mapped[bool]` | | `mapped_column(Boolean, nullable=False, default=False)` | | `created_at` | `Mapped[datetime]` | | `mapped_column(DateTime(timezone=True), nullable=False, default=_utc_now, index=True)` | | `updated_at` | `Mapped[datetime]` | | `mapped_column(DateTime(timezone=True), nullable=False, default=_utc_now, onupdate=_utc_now)` | | `issue` | `Mapped[MusehubIssue]` | | `relationship('MusehubIssue', back_populates='comments')` | ### `MusehubIssueEvent` — [`musehub/db/musehub_models.py`](musehub/db/musehub_models.py) A typed activity event on a MuseHub issue (Phase 4B). **Bases:** `Base` **Table:** `musehub_issue_events` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `event_id` | `Mapped[str]` | | `mapped_column(String(36), primary_key=True, default=_new_uuid)` | | `issue_id` | `Mapped[str]` | | `mapped_column(String(36), ForeignKey('musehub_issues.issue_id', ondelete='CASCADE'), nullable=False, index=True)` | | `repo_id` | `Mapped[str]` | | `mapped_column(String(36), ForeignKey('musehub_repos.repo_id', ondelete='CASCADE'), nullable=False, index=True)` | | `actor` | `Mapped[str]` | | `mapped_column(String(255), nullable=False, default='')` | | `event_type` | `Mapped[str]` | | `mapped_column(String(64), nullable=False)` | | `payload` | `Mapped[dict[str, object]]` | | `mapped_column(JSON, nullable=False, default=dict)` | | `created_at` | `Mapped[datetime]` | | `mapped_column(DateTime(timezone=True), nullable=False, default=_utc_now, index=True)` | | `issue` | `Mapped[MusehubIssue]` | | `relationship('MusehubIssue', back_populates='events')` | ### `MusehubObject` — [`musehub/db/musehub_models.py`](musehub/db/musehub_models.py) A binary artifact (MIDI, MP3, WebP piano roll) stored in MuseHub. **Bases:** `Base` **Table:** `musehub_objects` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `object_id` | `Mapped[str]` | | `mapped_column(String(128), primary_key=True)` | | `path` | `Mapped[str]` | | `mapped_column(String(1024), nullable=False)` | | `size_bytes` | `Mapped[int]` | | `mapped_column(Integer, nullable=False, default=0)` | | `storage_uri` | `Mapped[str | None]` | | `mapped_column(String(2048), nullable=True)` | | `content_cache` | `Mapped[bytes | None]` | | `mapped_column(sa.LargeBinary, nullable=True, default=None)` | | `created_at` | `Mapped[datetime]` | | `mapped_column(DateTime(timezone=True), nullable=False, default=_utc_now)` | | `deleted_at` | `Mapped[datetime | None]` | | `mapped_column(DateTime(timezone=True), nullable=True, default=None)` | ### `MusehubProposal` — [`musehub/db/musehub_models.py`](musehub/db/musehub_models.py) A merge proposal — the V2 name for a proposal. **Bases:** `Base` **Table:** `musehub_proposals` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `proposal_id` | `Mapped[str]` | | `mapped_column(String(36), primary_key=True, default=_new_uuid)` | | `repo_id` | `Mapped[str]` | | `mapped_column(String(36), ForeignKey('musehub_repos.repo_id', ondelete='CASCADE'), nullable=False, index=True)` | | `proposal_number` | `Mapped[int]` | | `mapped_column(Integer, nullable=False)` | | `title` | `Mapped[str]` | | `mapped_column(String(500), nullable=False)` | | `body` | `Mapped[str]` | | `mapped_column(Text, nullable=False, default='')` | | `state` | `Mapped[str]` | | `mapped_column(String(20), nullable=False, default='open', index=True)` | | `from_branch` | `Mapped[str]` | | `mapped_column(String(255), nullable=False)` | | `to_branch` | `Mapped[str]` | | `mapped_column(String(255), nullable=False)` | | `merge_commit_id` | `Mapped[str | None]` | | `mapped_column(String(2048), nullable=True)` | | `merged_at` | `Mapped[datetime | None]` | | `mapped_column(DateTime(timezone=True), nullable=True)` | | `author` | `Mapped[str]` | | `mapped_column(String(255), nullable=False, default='')` | | `created_at` | `Mapped[datetime]` | | `mapped_column(DateTime(timezone=True), nullable=False, default=_utc_now)` | | `updated_at` | `Mapped[datetime]` | | `mapped_column(DateTime(timezone=True), nullable=False, default=_utc_now, onupdate=_utc_now)` | | `domain_diff` | `Mapped[dict[str, object] | None]` | | `mapped_column(JSON, nullable=True, default=None)` | | `risk_score` | `Mapped[float | None]` | | `mapped_column(sa.Float, nullable=True)` | | `blast_delta` | `Mapped[float | None]` | | `mapped_column(sa.Float, nullable=True)` | | `breakage_count` | `Mapped[int]` | | `mapped_column(Integer, nullable=False, default=0)` | | `test_gap_count` | `Mapped[int]` | | `mapped_column(Integer, nullable=False, default=0)` | | `symbols_changed` | `Mapped[int]` | | `mapped_column(Integer, nullable=False, default=0)` | | `touched_symbols` | `Mapped[list[str]]` | | `mapped_column(JSON, nullable=False, default=list)` | | `repo` | `Mapped[MusehubRepo]` | | `relationship('MusehubRepo', back_populates='proposals')` | | `reviews` | `Mapped[list[MusehubProposalReview]]` | | `relationship('MusehubProposalReview', back_populates='proposal', cascade='all, delete-orphan')` | | `review_comments` | `Mapped[list[MusehubProposalComment]]` | | `relationship('MusehubProposalComment', back_populates='proposal', cascade='all, delete-orphan')` | ### `MusehubProposalComment` — [`musehub/db/musehub_models.py`](musehub/db/musehub_models.py) Inline review comment on a dimensional diff within a merge proposal. **Bases:** `Base` **Table:** `musehub_proposal_comments` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `comment_id` | `Mapped[str]` | | `mapped_column(String(36), primary_key=True, default=_new_uuid)` | | `proposal_id` | `Mapped[str]` | | `mapped_column(String(36), ForeignKey('musehub_proposals.proposal_id', ondelete='CASCADE'), nullable=False, index=True)` | | `repo_id` | `Mapped[str]` | | `mapped_column(String(36), nullable=False, index=True)` | | `author` | `Mapped[str]` | | `mapped_column(String(255), nullable=False)` | | `body` | `Mapped[str]` | | `mapped_column(Text, nullable=False)` | | `dimension_ref` | `Mapped[dict[str, object]]` | | `mapped_column(JSON, nullable=False, default=dict)` | | `symbol_address` | `Mapped[str | None]` | | `mapped_column(String(512), nullable=True)` | | `parent_comment_id` | `Mapped[str | None]` | | `mapped_column(String(36), nullable=True, index=True)` | | `created_at` | `Mapped[datetime]` | | `mapped_column(DateTime(timezone=True), nullable=False, default=_utc_now, index=True)` | | `proposal` | `Mapped[MusehubProposal]` | | `relationship('MusehubProposal', back_populates='review_comments')` | ### `MusehubProposalReview` — [`musehub/db/musehub_models.py`](musehub/db/musehub_models.py) A formal review submission on a merge proposal. **Bases:** `Base` **Table:** `musehub_proposal_reviews` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `id` | `Mapped[str]` | | `mapped_column(String(36), primary_key=True, default=_new_uuid)` | | `proposal_id` | `Mapped[str]` | | `mapped_column(String(36), ForeignKey('musehub_proposals.proposal_id', ondelete='CASCADE'), nullable=False, index=True)` | | `reviewer_username` | `Mapped[str]` | | `mapped_column(String(255), nullable=False, index=True)` | | `state` | `Mapped[str]` | | `mapped_column(String(30), nullable=False, default='pending', index=True)` | | `body` | `Mapped[str | None]` | | `mapped_column(Text, nullable=True)` | | `submitted_at` | `Mapped[datetime | None]` | | `mapped_column(DateTime(timezone=True), nullable=True)` | | `created_at` | `Mapped[datetime]` | | `mapped_column(DateTime(timezone=True), nullable=False, default=_utc_now)` | | `proposal` | `Mapped[MusehubProposal]` | | `relationship('MusehubProposal', back_populates='reviews')` | ### `MusehubRelease` — [`musehub/db/musehub_models.py`](musehub/db/musehub_models.py) A published version release for a MuseHub repo. **Bases:** `Base` **Table:** `musehub_releases` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `release_id` | `Mapped[str]` | | `mapped_column(String(36), primary_key=True, default=_new_uuid)` | | `repo_id` | `Mapped[str]` | | `mapped_column(String(36), ForeignKey('musehub_repos.repo_id', ondelete='CASCADE'), nullable=False, index=True)` | | `tag` | `Mapped[str]` | | `mapped_column(String(100), nullable=False, index=True)` | | `title` | `Mapped[str]` | | `mapped_column(String(500), nullable=False, default='')` | | `body` | `Mapped[str]` | | `mapped_column(Text, nullable=False, default='')` | | `commit_id` | `Mapped[str | None]` | | `mapped_column(String(2048), nullable=True)` | | `snapshot_id` | `Mapped[str | None]` | | `mapped_column(String(128), nullable=True)` | | `semver_major` | `Mapped[int]` | | `mapped_column(Integer, nullable=False, default=0)` | | `semver_minor` | `Mapped[int]` | | `mapped_column(Integer, nullable=False, default=0)` | | `semver_patch` | `Mapped[int]` | | `mapped_column(Integer, nullable=False, default=0)` | | `semver_pre` | `Mapped[str]` | | `mapped_column(String(255), nullable=False, default='')` | | `semver_build` | `Mapped[str]` | | `mapped_column(String(255), nullable=False, default='')` | | `channel` | `Mapped[str]` | | `mapped_column(String(20), nullable=False, default='stable', index=True)` | | `download_urls` | `Mapped[dict[str, str]]` | | `mapped_column(JSON, nullable=False, default=dict)` | | `author` | `Mapped[str]` | | `mapped_column(String(255), nullable=False, default='')` | | `agent_id` | `Mapped[str]` | | `mapped_column(String(255), nullable=False, default='')` | | `model_id` | `Mapped[str]` | | `mapped_column(String(255), nullable=False, default='')` | | `changelog_json` | `Mapped[str]` | | `mapped_column(Text, nullable=False, default='[]')` | | `is_draft` | `Mapped[bool]` | | `mapped_column(Boolean, nullable=False, default=False)` | | `gpg_signature` | `Mapped[str | None]` | | `mapped_column(Text, nullable=True)` | | `semantic_report_json` | `Mapped[str]` | | `mapped_column(Text, nullable=False, default='')` | | `created_at` | `Mapped[datetime]` | | `mapped_column(DateTime(timezone=True), nullable=False, default=_utc_now)` | | `updated_at` | `Mapped[datetime]` | | `mapped_column(DateTime(timezone=True), nullable=False, default=_utc_now, onupdate=_utc_now)` | | `repo` | `Mapped[MusehubRepo]` | | `relationship('MusehubRepo', back_populates='releases')` | | `assets` | `Mapped[list[MusehubReleaseAsset]]` | | `relationship('MusehubReleaseAsset', back_populates='release', cascade='all, delete-orphan')` | ### `MusehubReleaseAsset` — [`musehub/db/musehub_models.py`](musehub/db/musehub_models.py) An asset (file attachment) associated with a MuseHub release. **Bases:** `Base` **Table:** `musehub_release_assets` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `asset_id` | `Mapped[str]` | | `mapped_column(String(36), primary_key=True, default=_new_uuid)` | | `release_id` | `Mapped[str]` | | `mapped_column(String(36), ForeignKey('musehub_releases.release_id', ondelete='CASCADE'), nullable=False, index=True)` | | `repo_id` | `Mapped[str]` | | `mapped_column(String(36), nullable=False, index=True)` | | `name` | `Mapped[str]` | | `mapped_column(String(500), nullable=False)` | | `label` | `Mapped[str]` | | `mapped_column(String(255), nullable=False, default='')` | | `content_type` | `Mapped[str]` | | `mapped_column(String(128), nullable=False, default='')` | | `size` | `Mapped[int]` | | `mapped_column(Integer, nullable=False, default=0)` | | `download_url` | `Mapped[str]` | | `mapped_column(String(2048), nullable=False)` | | `download_count` | `Mapped[int]` | | `mapped_column(Integer, nullable=False, default=0)` | | `created_at` | `Mapped[datetime]` | | `mapped_column(DateTime(timezone=True), nullable=False, default=_utc_now)` | | `release` | `Mapped[MusehubRelease]` | | `relationship('MusehubRelease', back_populates='assets')` | ### `MusehubRepo` — [`musehub/db/musehub_models.py`](musehub/db/musehub_models.py) A remote Muse repository — the hub-side equivalent of a Git remote. **Bases:** `Base` **Table:** `musehub_repos` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `repo_id` | `Mapped[str]` | | `mapped_column(String(36), primary_key=True, default=_new_uuid)` | | `name` | `Mapped[str]` | | `mapped_column(String(255), nullable=False)` | | `owner` | `Mapped[str]` | | `mapped_column(String(64), nullable=False, index=True)` | | `slug` | `Mapped[str]` | | `mapped_column(String(64), nullable=False, index=True)` | | `visibility` | `Mapped[str]` | | `mapped_column(String(20), nullable=False, default='public')` | | `owner_user_id` | `Mapped[str]` | | `mapped_column(String(36), nullable=False, index=True)` | | `description` | `Mapped[str]` | | `mapped_column(Text, nullable=False, default='')` | | `tags` | `Mapped[list[str]]` | | `mapped_column(JSON, nullable=False, default=list)` | | `domain_id` | `Mapped[str | None]` | | `mapped_column(String(36), nullable=True, index=True)` | | `domain_meta` | `Mapped[dict[str, object]]` | | `mapped_column(JSON, nullable=False, default=dict)` | | `settings` | `Mapped[dict[str, object] | None]` | | `mapped_column(JSON, nullable=True)` | | `default_branch` | `Mapped[str]` | | `mapped_column(String(255), nullable=False, default='main')` | | `pushed_at` | `Mapped[datetime | None]` | | `mapped_column(DateTime(timezone=True), nullable=True, default=None)` | | `created_at` | `Mapped[datetime]` | | `mapped_column(DateTime(timezone=True), nullable=False, default=_utc_now)` | | `updated_at` | `Mapped[datetime]` | | `mapped_column(DateTime(timezone=True), nullable=False, default=_utc_now, onupdate=_utc_now)` | | `deleted_at` | `Mapped[datetime | None]` | | `mapped_column(DateTime(timezone=True), nullable=True, default=None)` | | `training_opt_out` | `Mapped[bool]` | | `mapped_column(Boolean, nullable=False, default=False)` | | `branches` | `Mapped[list[MusehubBranch]]` | | `relationship('MusehubBranch', back_populates='repo', cascade='all, delete-orphan')` | | `commits` | `Mapped[list[MusehubCommit]]` | | `relationship('MusehubCommit', back_populates='repo', cascade='all, delete-orphan')` | | `objects` | `Mapped[list[MusehubObject]]` | | `relationship('MusehubObject', back_populates='repo', cascade='all, delete-orphan')` | | `issues` | `Mapped[list[MusehubIssue]]` | | `relationship('MusehubIssue', back_populates='repo', cascade='all, delete-orphan')` | | `proposals` | `Mapped[list[MusehubProposal]]` | | `relationship('MusehubProposal', back_populates='repo', cascade='all, delete-orphan')` | | `releases` | `Mapped[list[MusehubRelease]]` | | `relationship('MusehubRelease', back_populates='repo', cascade='all, delete-orphan')` | | `sessions` | `Mapped[list[MusehubSession]]` | | `relationship('MusehubSession', back_populates='repo', cascade='all, delete-orphan')` | | `webhooks` | `Mapped[list[MusehubWebhook]]` | | `relationship('MusehubWebhook', back_populates='repo', cascade='all, delete-orphan')` | | `wire_tags` | `Mapped[list[MusehubWireTag]]` | | `relationship('MusehubWireTag', back_populates='repo', cascade='all, delete-orphan')` | ### `MusehubSession` — [`musehub/db/musehub_models.py`](musehub/db/musehub_models.py) A recording session record pushed to MuseHub from the CLI. **Bases:** `Base` **Table:** `musehub_sessions` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `session_id` | `Mapped[str]` | | `mapped_column(String(36), primary_key=True, default=_new_uuid)` | | `repo_id` | `Mapped[str]` | | `mapped_column(String(36), ForeignKey('musehub_repos.repo_id', ondelete='CASCADE'), nullable=False, index=True)` | | `schema_version` | `Mapped[str]` | | `mapped_column(String(10), nullable=False, default='1')` | | `started_at` | `Mapped[datetime]` | | `mapped_column(DateTime(timezone=True), nullable=False, index=True)` | | `ended_at` | `Mapped[datetime | None]` | | `mapped_column(DateTime(timezone=True), nullable=True)` | | `participants` | `Mapped[list[str]]` | | `mapped_column(JSON, nullable=False, default=list)` | | `location` | `Mapped[str]` | | `mapped_column(String(500), nullable=False, default='')` | | `intent` | `Mapped[str]` | | `mapped_column(Text, nullable=False, default='')` | | `commits` | `Mapped[list[str]]` | | `mapped_column(JSON, nullable=False, default=list)` | | `notes` | `Mapped[str]` | | `mapped_column(Text, nullable=False, default='')` | | `is_active` | `Mapped[bool]` | | `mapped_column(Boolean, nullable=False, default=False, index=True)` | | `created_at` | `Mapped[datetime]` | | `mapped_column(DateTime(timezone=True), nullable=False, default=_utc_now)` | | `repo` | `Mapped[MusehubRepo]` | | `relationship('MusehubRepo', back_populates='sessions')` | ### `MusehubSnapshot` — [`musehub/db/musehub_models.py`](musehub/db/musehub_models.py) Immutable file-tree record stored alongside commits. **Bases:** `Base` **Table:** `musehub_snapshots` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `snapshot_id` | `Mapped[str]` | | `mapped_column(String(128), primary_key=True)` | | `repo_id` | `Mapped[str]` | | `mapped_column(String(36), ForeignKey('musehub_repos.repo_id', ondelete='CASCADE'), nullable=False, index=True)` | | `directories` | `Mapped[list[str]]` | | `mapped_column(JSON, nullable=False, default=list)` | | `manifest_blob` | `Mapped[bytes]` | | `mapped_column(sa.LargeBinary, nullable=False)` | | `entry_count` | `Mapped[int]` | | `mapped_column(Integer(), nullable=False, default=0)` | | `created_at` | `Mapped[datetime]` | | `mapped_column(DateTime(timezone=True), nullable=False, default=_utc_now)` | ### `MusehubSymbolIndex` — [`musehub/db/musehub_models.py`](musehub/db/musehub_models.py) Materialized symbol intelligence cache for a repo at a given commit. **Bases:** `Base` **Table:** `musehub_symbol_index` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `index_id` | `Mapped[str]` | | `mapped_column(String(36), primary_key=True, default=_new_uuid)` | | `repo_id` | `Mapped[str]` | | `mapped_column(String(36), ForeignKey('musehub_repos.repo_id', ondelete='CASCADE'), nullable=False, index=True)` | | `ref` | `Mapped[str]` | | `mapped_column(String(64), nullable=False)` | | `symbol_history` | `Mapped[bytes | None]` | | `mapped_column(sa.LargeBinary, nullable=True)` | | `hash_occurrence` | `Mapped[bytes | None]` | | `mapped_column(sa.LargeBinary, nullable=True)` | | `intel_summary` | `Mapped[str | None]` | | `mapped_column(sa.Text, nullable=True)` | | `intel_full_json` | `Mapped[str | None]` | | `mapped_column(sa.Text, nullable=True)` | | `per_symbol_intel_json` | `Mapped[str | None]` | | `mapped_column(sa.Text, nullable=True)` | | `built_at` | `Mapped[datetime]` | | `mapped_column(DateTime(timezone=True), nullable=False, default=_utc_now)` | ### `MusehubWebhook` — [`musehub/db/musehub_models.py`](musehub/db/musehub_models.py) A registered webhook subscription for a MuseHub repo. **Bases:** `Base` **Table:** `musehub_webhooks` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `webhook_id` | `Mapped[str]` | | `mapped_column(String(36), primary_key=True, default=_new_uuid)` | | `repo_id` | `Mapped[str]` | | `mapped_column(String(36), ForeignKey('musehub_repos.repo_id', ondelete='CASCADE'), nullable=False, index=True)` | | `url` | `Mapped[str]` | | `mapped_column(String(2048), nullable=False)` | | `events` | `Mapped[list[str]]` | | `mapped_column(JSON, nullable=False, default=list)` | | `secret` | `Mapped[str]` | | `mapped_column(Text, nullable=False, default='')` | | `active` | `Mapped[bool]` | | `mapped_column(Boolean, nullable=False, default=True)` | | `created_at` | `Mapped[datetime]` | | `mapped_column(DateTime(timezone=True), nullable=False, default=_utc_now)` | | `updated_at` | `Mapped[datetime]` | | `mapped_column(DateTime(timezone=True), nullable=False, default=_utc_now, onupdate=_utc_now)` | | `repo` | `Mapped[MusehubRepo]` | | `relationship('MusehubRepo', back_populates='webhooks')` | | `deliveries` | `Mapped[list[MusehubWebhookDelivery]]` | | `relationship('MusehubWebhookDelivery', back_populates='webhook', cascade='all, delete-orphan')` | ### `MusehubWebhookDelivery` — [`musehub/db/musehub_models.py`](musehub/db/musehub_models.py) One delivery attempt for a webhook event. **Bases:** `Base` **Table:** `musehub_webhook_deliveries` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `delivery_id` | `Mapped[str]` | | `mapped_column(String(36), primary_key=True, default=_new_uuid)` | | `webhook_id` | `Mapped[str]` | | `mapped_column(String(36), ForeignKey('musehub_webhooks.webhook_id', ondelete='CASCADE'), nullable=False, index=True)` | | `event_type` | `Mapped[str]` | | `mapped_column(String(64), nullable=False, index=True)` | | `payload` | `Mapped[str]` | | `mapped_column(Text, nullable=False, default='')` | | `attempt` | `Mapped[int]` | | `mapped_column(Integer, nullable=False, default=1)` | | `success` | `Mapped[bool]` | | `mapped_column(Boolean, nullable=False, default=False)` | | `response_status` | `Mapped[int]` | | `mapped_column(Integer, nullable=False, default=0)` | | `response_body` | `Mapped[str]` | | `mapped_column(Text, nullable=False, default='')` | | `delivered_at` | `Mapped[datetime]` | | `mapped_column(DateTime(timezone=True), nullable=False, default=_utc_now)` | | `webhook` | `Mapped[MusehubWebhook]` | | `relationship('MusehubWebhook', back_populates='deliveries')` | ### `MusehubWireTag` — [`musehub/db/musehub_models.py`](musehub/db/musehub_models.py) A lightweight tag pushed from a Muse CLI client via the wire protocol. **Bases:** `Base` **Table:** `musehub_wire_tags` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `tag_id` | `Mapped[str]` | | `mapped_column(String(36), primary_key=True, default=_new_uuid)` | | `repo_id` | `Mapped[str]` | | `mapped_column(String(36), ForeignKey('musehub_repos.repo_id', ondelete='CASCADE'), nullable=False, index=True)` | | `commit_id` | `Mapped[str]` | | `mapped_column(String(64), nullable=False)` | | `tag` | `Mapped[str]` | | `mapped_column(String(500), nullable=False, index=True)` | | `created_at` | `Mapped[datetime]` | | `mapped_column(DateTime(timezone=True), nullable=False, default=_utc_now)` | | `repo` | `Mapped[MusehubRepo]` | | `relationship('MusehubRepo', back_populates='wire_tags')` | ### `_A` — [`tests/test_schema_check.py`](tests/test_schema_check.py) **Bases:** `_ABase` **Table:** `a_table` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `id` | `Mapped[int]` | | `mapped_column(Integer, primary_key=True)` | | `python_name` | `Mapped[str | None]` | | `mapped_column('db_name', String(64), nullable=True)` | ### `_A` — [`tests/test_schema_check.py`](tests/test_schema_check.py) **Bases:** `_ABase` **Table:** `atbl` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `id` | `Mapped[int]` | | `mapped_column(Integer, primary_key=True)` | | `py_name` | `Mapped[str | None]` | | `mapped_column('db_name', String(64), nullable=True)` | ### `_B` — [`tests/test_schema_check.py`](tests/test_schema_check.py) **Bases:** `_BBase` **Table:** `btbl` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `id` | `Mapped[int]` | | `mapped_column(Integer, primary_key=True)` | | `new_name` | `Mapped[str | None]` | | `mapped_column('old_name', String(64), nullable=True)` | ### `_Clean` — [`tests/test_schema_check.py`](tests/test_schema_check.py) **Bases:** `_CleanBase` **Table:** `clean` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `id` | `Mapped[int]` | | `mapped_column(Integer, primary_key=True)` | | `value` | `Mapped[str]` | | `mapped_column(String(64), nullable=False)` | ### `_Gadget` — [`tests/test_schema_check.py`](tests/test_schema_check.py) **Bases:** `_TestBase` **Table:** `gadgets` | Field | Type | Required | Default | |-------|------|:--------:|---------| | `id` | `Mapped[int]` | | `mapped_column(Integer, primary_key=True)` | | `serial` | `Mapped[str]` | | `mapped_column(String(64), nullable=False)` | | `notes` | `Mapped[str | None]` | | `mapped_column(String(256), nullable=True)` | ## Protocols ### `StorageBackend` — [`musehub/storage/backends.py`](musehub/storage/backends.py) Content-addressed binary store protocol. **Bases:** `Protocol` _No annotated fields._ ### `_S3Client` — [`musehub/storage/backends.py`](musehub/storage/backends.py) **Bases:** `Protocol` _No annotated fields._ ### `_S3Response` — [`musehub/storage/backends.py`](musehub/storage/backends.py) **Bases:** `Protocol` _No annotated fields._ ### `_StreamingBody` — [`musehub/storage/backends.py`](musehub/storage/backends.py) **Bases:** `Protocol` _No annotated fields._