gabriel / musehub public
feat BREAKING task/issue-15-genesis-phase2 #1 / 1
AI Agent gabriel · 157 days ago · Apr 21, 2026 · Diff

feat: genesis-address Phase 2 entities — label, asset, webhook, fork, collaborator, key, domain

- Add compute_label_id, compute_asset_id, compute_webhook_id, compute_fork_id, compute_collaborator_id, compute_key_id, compute_domain_id to genesis.py - Widen all entity PK/FK columns from String(36) to String(128) in DB models: musehub_labels, musehub_issue_labels, musehub_proposal_labels, musehub_collaborators, musehub_auth_keys, musehub_domains, musehub_domain_installs, musehub_release_assets, musehub_webhooks, musehub_forks, plus repo/issue/proposal FK references - Replace uuid4() at every creation site with the appropriate compute_*_id call: labels.py, collaborators.py, musehub_auth.py, musehub_domains.py, musehub_releases.py, musehub_repository.py, musehub_webhook_dispatcher.py, mcp/write_tools/labels.py - Delete legacy POST /api/identities endpoint (password-seeded UUID identity, bypassed MSign auth) — all identity creation goes through MSign keys - Add genesis ID validators to WebhookResponse, UserForkedRepoEntry, LabelResponse, CollaboratorResponse Pydantic models - Add Alembic migration genesis_phase2_entity_ids.py - Extend test_genesis_ids.py with Phase 2 Tier 1/2/3/3b/6 tests (120 passing)

Intentionally left as UUID: challenge_id (security), delivery_id (ephemeral retry log), install_id (M2M join), job_id, event_id (internal ops)

Closes issue #15

sha256:b19993b535df23c461c19debc8e4ac5cea0662e5c4b2d8a7c6a600eccfdad489 sha
+112 ~57 −11 symbols
sha256:2988e752c44aaaeff15799db0bd6e86ac69ef0a2547704ab3566f5931506c427 snapshot
+112
symbols added
~57
symbols modified
−11
symbols removed
0
dead code introduced
Semantic Changes 180 symbols
+ _PK_FK_COLUMNS variable variable _PK_FK_COLUMNS L43–77
+ branch_labels variable variable branch_labels L39–39
+ depends_on variable variable depends_on L40–40
+ down_revision variable variable down_revision L38–38
+ downgrade function function downgrade L91–99
+ Union import import Union L32–32
+ annotations import import annotations L30–30
+ op import import op L35–35
+ sa import import sa L34–34
+ revision variable variable revision L37–37
+ upgrade function function upgrade L80–88
~ musehub/api/routes/api/identities.py .py 3 symbols removed, 5 symbols modified
− CreateIdentityRequest class class CreateIdentityRequest L44–53
− create_identity function async_function create_identity L123–166
− uuid import import uuid L21–21
~ musehub/api/routes/musehub/collaborators.py .py 6 symbols added, 1 symbol removed, 3 symbols modified
− uuid import import uuid L21–21
+ _check_genesis_ids method method _check_genesis_ids L98–100
+ MusehubIdentity import import MusehubIdentity L33–33
+ compute_collaborator_id import import compute_collaborator_id L30–30
+ datetime import import datetime L21–21
+ field_validator import import field_validator L25–25
+ timezone import import timezone L21–21
~ Field
~ musehub/api/routes/musehub/labels.py .py 3 symbols added, 1 symbol removed, 5 symbols modified
− uuid import import uuid L25–25
+ _check_genesis_ids method method _check_genesis_ids L95–97
+ compute_label_id import import compute_label_id L33–33
+ field_validator import import field_validator L28–28
~ Field
~ musehub/core/genesis.py .py 7 symbols added
+ compute_asset_id function function compute_asset_id L302–315
+ compute_collaborator_id function function compute_collaborator_id L361–373
+ compute_domain_id function function compute_domain_id L399–413
+ compute_fork_id function function compute_fork_id L342–354
+ compute_key_id function function compute_key_id L380–392
+ compute_label_id function function compute_label_id L282–295
+ compute_webhook_id function function compute_webhook_id L322–335
~ musehub/db/musehub_collaborator_models.py .py 2 symbols removed, 1 symbol modified
− _new_uuid function function _new_uuid L18–19
− uuid import import uuid L9–9
~ musehub/db/musehub_label_models.py .py 2 symbols removed, 3 symbols modified
− _new_uuid function function _new_uuid L20–21
− uuid import import uuid L11–11
~ musehub/mcp/write_tools/labels.py .py 3 symbols added, 1 symbol removed, 1 symbol modified
− uuid import import uuid L12–12
+ compute_label_id import import compute_label_id L14–14
+ datetime import import datetime L12–12
+ timezone import import timezone L12–12
~ musehub/models/musehub.py .py 2 symbols added, 2 symbols modified
+ _check_fork_id method method _check_fork_id L2492–2493
+ _check_genesis_ids method method _check_genesis_ids L1792–1793
~ musehub/services/musehub_auth.py .py 1 symbol added, 1 symbol removed, 3 symbols modified
− uuid import import uuid L44–44
+ compute_key_id import import compute_key_id L46–46
~ musehub/services/musehub_domains.py .py 1 symbol added, 1 symbol modified
+ compute_domain_id import import compute_domain_id L17–17
~ musehub/services/musehub_releases.py .py 1 symbol added, 2 symbols modified
+ compute_asset_id import import compute_asset_id L26–26
~ musehub/services/musehub_repository.py .py 1 symbol added, 4 symbols modified
+ compute_fork_id import import compute_fork_id L23–23
~ musehub/services/musehub_webhook_dispatcher.py .py 1 symbol added, 1 symbol modified
+ compute_webhook_id import import compute_webhook_id L34–34
~ tests/test_genesis_ids.py .py 75 symbols added, 17 symbols modified
+ TestPhase2CanonicalForm class class TestPhase2CanonicalForm L809–830
+ test_asset_id_canonical method method test_asset_id_canonical L814–815
+ test_collaborator_id_canonical method method test_collaborator_id_canonical L823–824
+ test_domain_id_canonical method method test_domain_id_canonical L829–830
+ test_fork_id_canonical method method test_fork_id_canonical L820–821
+ test_key_id_canonical method method test_key_id_canonical L826–827
+ test_label_id_canonical method method test_label_id_canonical L811–812
+ test_webhook_id_canonical method method test_webhook_id_canonical L817–818
+ TestPhase2Determinism class class TestPhase2Determinism L838–925
+ test_all_phase2_ids_are_distinct method method test_all_phase2_ids_are_distinct L918–920
+ test_asset_different_filenames_differ method method test_asset_different_filenames_differ L859–862
+ test_asset_id_deterministic method method test_asset_id_deterministic L855–857
+ test_collaborator_different_identities_differ method method test_collaborator_different_identities_differ L887–891
+ test_collaborator_id_deterministic method method test_collaborator_id_deterministic L883–885
+ test_domain_different_slugs_differ method method test_domain_different_slugs_differ L913–916
+ test_domain_id_deterministic method method test_domain_id_deterministic L909–911
+ test_fork_different_source_repos_differ method method test_fork_different_source_repos_differ L877–881
+ test_fork_id_deterministic method method test_fork_id_deterministic L873–875
+ test_key_different_pubkeys_differ method method test_key_different_pubkeys_differ L897–900
+ test_key_id_deterministic method method test_key_id_deterministic L893–895
+ test_key_no_timestamp_by_design method method test_key_no_timestamp_by_design L902–907
+ test_label_different_names_differ method method test_label_different_names_differ L844–847
+ test_label_different_repos_differ method method test_label_different_repos_differ L849–853
+ test_label_id_deterministic method method test_label_id_deterministic L840–842
+ test_phase2_ids_distinct_from_phase1_ids method method test_phase2_ids_distinct_from_phase1_ids L922–925
+ test_webhook_different_urls_differ method method test_webhook_different_urls_differ L868–871
+ test_webhook_id_deterministic method method test_webhook_id_deterministic L864–866
+ TestPhase2SeparatorInjection class class TestPhase2SeparatorInjection L933–960
+ test_domain_slug_with_path_separator_is_safe method method test_domain_slug_with_path_separator_is_safe L946–948
+ test_fork_nul_in_repo_id_does_not_collide method method test_fork_nul_in_repo_id_does_not_collide L955–960
+ test_key_id_with_base64_padding_chars_is_safe method method test_key_id_with_base64_padding_chars_is_safe L950–953
+ test_label_nul_in_name_is_safe_canonical method method test_label_nul_in_name_is_safe_canonical L935–939
+ test_webhook_url_with_colons_is_safe method method test_webhook_url_with_colons_is_safe L941–944
+ TestPydanticBoundaryPhase2 class class TestPydanticBoundaryPhase2 L968–1144
+ _make_fork_repo_response method method _make_fork_repo_response L1077–1089
+ test_collaborator_response_accepts_future_algo method method test_collaborator_response_accepts_future_algo L1027–1035
+ test_collaborator_response_rejects_bad_collaborator_id method method test_collaborator_response_rejects_bad_collaborator_id L1007–1015
+ test_collaborator_response_rejects_bad_repo_id method method test_collaborator_response_rejects_bad_repo_id L1017–1025
+ test_forked_repo_entry_accepts_future_algo method method test_forked_repo_entry_accepts_future_algo L1124–1144
+ test_forked_repo_entry_rejects_bad_fork_id method method test_forked_repo_entry_rejects_bad_fork_id L1091–1099
+ test_forked_repo_entry_rejects_bad_fork_repo_id method method test_forked_repo_entry_rejects_bad_fork_repo_id L1113–1122
+ test_forked_repo_entry_rejects_bad_source_repo_id method method test_forked_repo_entry_rejects_bad_source_repo_id L1101–1111
+ test_label_response_accepts_future_algo method method test_label_response_accepts_future_algo L994–1003
+ test_label_response_rejects_bad_label_id method method test_label_response_rejects_bad_label_id L972–981
+ test_label_response_rejects_bad_repo_id method method test_label_response_rejects_bad_repo_id L983–992
+ test_webhook_response_accepts_future_algo method method test_webhook_response_accepts_future_algo L1063–1073
+ test_webhook_response_rejects_bad_repo_id method method test_webhook_response_rejects_bad_repo_id L1051–1061
+ test_webhook_response_rejects_bad_webhook_id method method test_webhook_response_rejects_bad_webhook_id L1039–1049
+ TestServiceLayerPhase2GenesisIds class class TestServiceLayerPhase2GenesisIds L1152–1424
+ _async_session method method _async_session L1155–1175
+ test_create_label_uses_compute_label_id method async_method test_create_label_uses_compute_label_id L1180–1219
+ test_create_webhook_uses_compute_webhook_id method async_method test_create_webhook_uses_compute_webhook_id L1224–1255
+ test_fork_repo_uses_compute_fork_id method async_method test_fork_repo_uses_compute_fork_id L1260–1334
+ test_invite_collaborator_uses_compute_collaborator_id method async_method test_invite_collaborator_uses_compute_collaborator_id L1372–1424
+ test_register_key_uses_compute_key_id method async_method test_register_key_uses_compute_key_id L1339–1367
+ _ASSET_ID variable variable _ASSET_ID L131–131
+ _COLLABORATOR_ID variable variable _COLLABORATOR_ID L136–136
+ _COLLAB_IDENTITY_ID variable variable _COLLAB_IDENTITY_ID L135–135
+ _DOMAIN_ID variable variable _DOMAIN_ID L138–138
+ _FORK_ID variable variable _FORK_ID L134–134
+ _FORK_REPO_ID variable variable _FORK_REPO_ID L133–133
+ _KEY_ID variable variable _KEY_ID L137–137
+ _LABEL_ID variable variable _LABEL_ID L130–130
+ _WEBHOOK_ID variable variable _WEBHOOK_ID L132–132
+ CollaboratorResponse import import CollaboratorResponse L62–62
+ LabelResponse import import LabelResponse L63–63
+ UserForkedRepoEntry import import UserForkedRepoEntry L52–52
+ WebhookResponse import import WebhookResponse L52–52
+ compute_asset_id import import compute_asset_id L73–73
+ compute_collaborator_id import import compute_collaborator_id L73–73
+ compute_domain_id import import compute_domain_id L73–73
+ compute_fork_id import import compute_fork_id L73–73
+ compute_key_id import import compute_key_id L73–73
+ compute_label_id import import compute_label_id L73–73
+ compute_webhook_id import import compute_webhook_id L73–73
← Older Oldest on task/issue-15-genesis-phase2
All commits
Newer → Latest on task/issue-15-genesis-phase2

0 comments

No comments yet. Be the first to start the discussion.

To add a comment, use the Muse CLI: muse hub commit comment sha256:b19993b535df23c461c19debc8e4ac5cea0662e5c4b2d8a7c6a600eccfdad489 --body "your comment"