gabriel / muse public
feat patch identity task/identity-domain #1 / 1
AI Agent gabriel · 153 days ago · Apr 21, 2026 · Diff

feat(identity): identity domain plugin — version-controlled human/agent/org graph

Working tree: identities/<handle>.json + relationships/<from>--<edge>--<to>.json Records layer: IdentityRecord, RelationshipRecord, SignatureRecord + path codec DAG layer: lightweight cycle detector (I1), self-contained, no external deps Plugin: MuseDomainPlugin + StructuredMergePlugin + HarmonyPlugin - snapshot(): walks .identity/ tree, hashes JSON files - diff(): snapshot_diff() over SetSchema dimensions - merge(): three-way + I1 acyclicity enforcement; cyclic new edges → conflicts - drift(): snapshot + diff delegation - schema(): two independently-mergeable dimensions (identities, relationships) - conflict_fingerprint(): structural hash ignoring timestamps/signatures Registered as 'identity' domain in plugin registry. 83 TDD tests — all passing.

sha256:9ef9e1c3cd263b29c5ad21f2be44526fca5a1c290c874f858de038573bb43861 sha
+223 ~1 symbols
sha256:a840dfe98133f2b45d4ade7f5116a76937c6044c607dced049a95fcb515d4aaf snapshot
+223
symbols added
~1
symbol modified
0
dead code introduced
Semantic Changes 224 symbols
~ muse/plugins/identity/dag.py .py 7 symbols added
+ _DAG class class _DAG L12–33
+ __init__ method method __init__ L13–14
+ add_edge method method add_edge L16–17
+ would_cycle method method would_cycle L19–33
+ build_dag_from_paths function function build_dag_from_paths L36–46
+ annotations import import annotations L7–7
+ defaultdict import import defaultdict L9–9
~ muse/plugins/identity/plugin.py .py 35 symbols added
+ IdentityPlugin class class IdentityPlugin L50–271
+ _check_i1 method method _check_i1 L243–271
+ _snapshot_dir method method _snapshot_dir L207–241
+ apply method method apply L127–128
+ conflict_fingerprint method method conflict_fingerprint L176–203
+ diff method method diff L60–67
+ drift method method drift L121–125
+ merge method method merge L69–119
+ merge_ops method method merge_ops L162–172
+ schema method method schema L130–158
+ snapshot method method snapshot L55–58
+ _DOMAIN variable variable _DOMAIN L46–46
+ _VALID_DIRS variable variable _VALID_DIRS L47–47
+ DimensionSpec import import DimensionSpec L31–31
+ DomainOp import import DomainOp L32–32
+ DomainSchema import import DomainSchema L31–31
+ DriftReport import import DriftReport L32–32
+ LiveState import import LiveState L32–32
+ MergeResult import import MergeResult L32–32
+ SetSchema import import SetSchema L31–31
+ SnapshotManifest import import SnapshotManifest L32–32
+ StateDelta import import StateDelta L32–32
+ StateSnapshot import import StateSnapshot L32–32
+ StructuredDelta import import StructuredDelta L32–32
+ _DAG import import _DAG L43–43
+ __version__ import import __version__ L29–29
+ _stat import import _stat L27–27
+ annotations import import annotations L21–21
+ build_dag_from_paths import import build_dag_from_paths L43–43
+ hashlib import import hashlib L23–23
+ json import import json L24–24
+ os import import os L25–25
+ parse_relationship_path import import parse_relationship_path L44–44
+ pathlib import import pathlib L26–26
+ snapshot_diff import import snapshot_diff L30–30
~ muse/plugins/identity/records.py .py 14 symbols added
+ IdentityRecord class class IdentityRecord L14–20
+ RelationshipRecord class class RelationshipRecord L23–28
+ SignatureRecord class class SignatureRecord L8–11
+ identity_path function function identity_path L33–34
+ Any import import Any L5–5
+ Literal import import Literal L5–5
+ TypedDict import import TypedDict L5–5
+ annotations import import annotations L2–2
+ json import import json L4–4
+ parse_identity_path function function parse_identity_path L41–47
+ parse_relationship_path function function parse_relationship_path L50–61
+ record_from_bytes function function record_from_bytes L70–71
+ record_to_bytes function function record_to_bytes L66–67
+ relationship_path function function relationship_path L37–38
~ tests/test_identity_domain_diff.py .py 26 symbols added
+ TestCompoundDiff class class TestCompoundDiff L125–153
+ test_add_identity_and_relationship method method test_add_identity_and_relationship L126–133
+ test_remove_and_add_simultaneously method method test_remove_and_add_simultaneously L135–141
+ test_summary_empty_for_no_changes method method test_summary_empty_for_no_changes L149–153
+ test_summary_non_empty_for_changes method method test_summary_non_empty_for_changes L143–147
+ TestIdentityDiff class class TestIdentityDiff L49–93
+ test_add_identity_address_is_path method method test_add_identity_address_is_path L61–65
+ test_add_identity_produces_insert_op method method test_add_identity_produces_insert_op L55–59
+ test_modify_identity_produces_replace_op method method test_modify_identity_produces_replace_op L88–93
+ test_multiple_adds_produce_multiple_inserts method method test_multiple_adds_produce_multiple_inserts L79–86
+ test_no_change_empty_delta method method test_no_change_empty_delta L50–53
+ test_remove_identity_address_is_path method method test_remove_identity_address_is_path L73–77
+ test_remove_identity_produces_delete_op method method test_remove_identity_produces_delete_op L67–71
+ TestRelationshipDiff class class TestRelationshipDiff L98–120
+ test_add_multiple_relationships method method test_add_multiple_relationships L112–120
+ test_add_relationship_produces_insert_op method method test_add_relationship_produces_insert_op L99–104
+ test_remove_relationship_produces_delete_op method method test_remove_relationship_produces_delete_op L106–110
+ IdentityPlugin import import IdentityPlugin L18–18
+ SnapshotManifest import import SnapshotManifest L17–17
+ annotations import import annotations L13–13
+ pytest import import pytest L15–15
+ op_addresses function function op_addresses L39–40
+ op_kinds function function op_kinds L43–44
+ plugin function function plugin L22–23
+ snap function function snap L26–32
+ snap_with function function snap_with L35–36
~ tests/test_identity_domain_merge.py .py 37 symbols added
+ TestAutoMerge class class TestAutoMerge L69–110
+ test_add_identity_and_relationship_disjoint method method test_add_identity_and_relationship_disjoint L97–103
+ test_both_add_same_file_identically method method test_both_add_same_file_identically L88–95
+ test_disjoint_identity_adds method method test_disjoint_identity_adds L70–77
+ test_disjoint_relationship_adds method method test_disjoint_relationship_adds L79–86
+ test_domain_preserved_in_merged method method test_domain_preserved_in_merged L105–110
+ TestConflict class class TestConflict L115–129
+ test_both_modify_same_identity_differently method method test_both_modify_same_identity_differently L116–121
+ test_both_modify_same_relationship_differently method method test_both_modify_same_relationship_differently L123–129
+ TestDeletion class class TestDeletion L134–161
+ test_deleted_on_both_branches method method test_deleted_on_both_branches L144–151
+ test_deleted_on_left_unchanged_on_right method method test_deleted_on_left_unchanged_on_right L135–142
+ test_unchanged_on_both_branches_preserved method method test_unchanged_on_both_branches_preserved L153–161
+ TestHarmonyFingerprint class class TestHarmonyFingerprint L263–327
+ test_different_structural_conflict_different_fingerprint method method test_different_structural_conflict_different_fingerprint L303–327
+ test_plugin_has_conflict_fingerprint method method test_plugin_has_conflict_fingerprint L271–272
+ test_same_structural_conflict_same_fingerprint method method test_same_structural_conflict_same_fingerprint L274–301
+ TestI1AcyclicityEnforcement class class TestI1AcyclicityEnforcement L166–258
+ test_cross_edge_type_cycle_rejected method method test_cross_edge_type_cycle_rejected L248–258
+ test_cycle_in_merged_result_becomes_conflict method method test_cycle_in_merged_result_becomes_conflict L174–187
+ test_diamond_dag_not_a_cycle method method test_diamond_dag_not_a_cycle L223–235
+ test_indirect_cycle_three_nodes_rejected method method test_indirect_cycle_three_nodes_rejected L198–209
+ test_member_of_cycle_rejected method method test_member_of_cycle_rejected L237–246
+ test_non_cyclic_new_edge_is_accepted method method test_non_cyclic_new_edge_is_accepted L211–221
+ test_self_loop_becomes_conflict method method test_self_loop_becomes_conflict L189–196
+ _CTR variable variable _CTR L36–36
+ _hash function function _hash L38–39
+ id_path function function id_path L59–60
+ IdentityPlugin import import IdentityPlugin L26–26
+ SnapshotManifest import import SnapshotManifest L25–25
+ annotations import import annotations L21–21
+ pytest import import pytest L23–23
+ plugin function function plugin L30–31
+ rel_path function function rel_path L63–64
+ snap function function snap L42–47
+ with_custom function function with_custom L54–55
+ with_files function function with_files L50–51
~ tests/test_identity_domain_records.py .py 36 symbols added
+ TestIdentityPath class class TestIdentityPath L30–52
+ test_agent_handle method method test_agent_handle L34–35
+ test_human_handle method method test_human_handle L31–32
+ test_non_identity_path_returns_none method method test_non_identity_path_returns_none L50–52
+ test_org_handle method method test_org_handle L37–38
+ test_parse_round_trips method method test_parse_round_trips L45–48
+ test_path_is_posix method method test_path_is_posix L40–43
+ TestIdentityRecordSerialisation class class TestIdentityRecordSerialisation L86–129
+ _human_record method method _human_record L87–95
+ test_round_trip_agent method method test_round_trip_agent L120–129
+ test_round_trip_human method method test_round_trip_human L97–101
+ test_round_trip_org method method test_round_trip_org L109–118
+ test_serialised_is_valid_json method method test_serialised_is_valid_json L103–107
+ TestRelationshipPath class class TestRelationshipPath L55–81
+ test_member_of_edge method method test_member_of_edge L60–62
+ test_non_relationship_path_returns_none method method test_non_relationship_path_returns_none L79–81
+ test_parse_round_trips method method test_parse_round_trips L69–77
+ test_path_is_posix method method test_path_is_posix L64–67
+ test_spawns_edge method method test_spawns_edge L56–58
+ TestRelationshipRecordSerialisation class class TestRelationshipRecordSerialisation L132–178
+ _spawns_record method method _spawns_record L133–146
+ test_round_trip_member_of method method test_round_trip_member_of L152–166
+ test_round_trip_spawns method method test_round_trip_spawns L148–150
+ test_serialised_preserves_weight method method test_serialised_preserves_weight L168–178
+ IdentityRecord import import IdentityRecord L15–15
+ RelationshipRecord import import RelationshipRecord L15–15
+ SignatureRecord import import SignatureRecord L15–15
+ annotations import import annotations L9–9
+ identity_path import import identity_path L15–15
+ json import import json L11–11
+ parse_identity_path import import parse_identity_path L15–15
+ parse_relationship_path import import parse_relationship_path L15–15
+ pytest import import pytest L13–13
+ record_from_bytes import import record_from_bytes L15–15
+ record_to_bytes import import record_to_bytes L15–15
+ relationship_path import import relationship_path L15–15
~ tests/test_identity_domain_schema.py .py 37 symbols added
+ TestApply class class TestApply L130–145
+ test_apply_returns_live_state method method test_apply_returns_live_state L131–135
+ test_apply_with_manifest_returns_manifest method method test_apply_with_manifest_returns_manifest L137–145
+ TestDrift class class TestDrift L101–125
+ test_drift_detected_on_new_file method method test_drift_detected_on_new_file L107–112
+ test_drift_report_has_summary method method test_drift_report_has_summary L114–119
+ test_no_drift_summary_indicates_clean method method test_no_drift_summary_indicates_clean L121–125
+ test_no_drift_when_tree_matches_commit method method test_no_drift_when_tree_matches_commit L102–105
+ TestProtocolConformance class class TestProtocolConformance L81–96
+ test_has_all_six_required_methods method method test_has_all_six_required_methods L91–93
+ test_has_conflict_fingerprint_harmony method method test_has_conflict_fingerprint_harmony L88–89
+ test_has_merge_ops method method test_has_merge_ops L95–96
+ test_satisfies_muse_domain_plugin method method test_satisfies_muse_domain_plugin L82–83
+ test_satisfies_structured_merge_plugin method method test_satisfies_structured_merge_plugin L85–86
+ TestSchema class class TestSchema L41–76
+ test_both_dimensions_independently_mergeable method method test_both_dimensions_independently_mergeable L60–62
+ test_description_non_empty method method test_description_non_empty L45–46
+ test_domain_is_identity method method test_domain_is_identity L42–43
+ test_has_two_dimensions method method test_has_two_dimensions L48–50
+ test_identities_dimension_exists method method test_identities_dimension_exists L52–54
+ test_identities_dimension_is_set_schema method method test_identities_dimension_is_set_schema L64–66
+ test_merge_mode_is_three_way method method test_merge_mode_is_three_way L72–73
+ test_relationships_dimension_exists method method test_relationships_dimension_exists L56–58
+ test_relationships_dimension_is_set_schema method method test_relationships_dimension_is_set_schema L68–70
+ test_schema_version_is_string method method test_schema_version_is_string L75–76
+ DriftReport import import DriftReport L21–21
+ IdentityPlugin import import IdentityPlugin L31–31
+ LiveState import import LiveState L21–21
+ MergeResult import import MergeResult L21–21
+ MuseDomainPlugin import import MuseDomainPlugin L21–21
+ SnapshotManifest import import SnapshotManifest L21–21
+ StateDelta import import StateDelta L21–21
+ StateSnapshot import import StateSnapshot L21–21
+ StructuredMergePlugin import import StructuredMergePlugin L21–21
+ annotations import import annotations L17–17
+ pytest import import pytest L19–19
+ plugin function function plugin L35–36
+ TestSnapshotFromDirectory class class TestSnapshotFromDirectory L79–125
+ test_content_hash_changes_on_edit method method test_content_hash_changes_on_edit L115–122
+ test_domain_field_is_identity method method test_domain_field_is_identity L124–125
+ test_empty_tree_produces_empty_manifest method method test_empty_tree_produces_empty_manifest L80–83
+ test_multiple_identities_all_appear method method test_multiple_identities_all_appear L90–96
+ test_relationship_file_appears method method test_relationship_file_appears L98–101
+ test_single_identity_file_appears method method test_single_identity_file_appears L85–88
+ test_stability_two_calls method method test_stability_two_calls L110–113
+ test_unknown_extension_ignored method method test_unknown_extension_ignored L103–108
+ TestSnapshotFromManifest class class TestSnapshotFromManifest L130–150
+ test_pass_through_manifest method method test_pass_through_manifest L131–139
+ test_pass_through_preserves_all_keys method method test_pass_through_preserves_all_keys L141–150
+ IdentityPlugin import import IdentityPlugin L19–19
+ IdentityRecord import import IdentityRecord L20–20
+ RelationshipRecord import import RelationshipRecord L20–20
+ SignatureRecord import import SignatureRecord L20–20
+ annotations import import annotations L12–12
+ identity_path import import identity_path L20–20
+ json import import json L14–14
+ pathlib import import pathlib L15–15
+ pytest import import pytest L17–17
+ record_to_bytes import import record_to_bytes L20–20
+ relationship_path import import relationship_path L20–20
+ make_human function function make_human L49–53
+ make_member_of function function make_member_of L70–74
+ make_org function function make_org L56–60
+ make_spawns function function make_spawns L63–67
+ plugin function function plugin L31–32
+ write_identity function function write_identity L35–38
+ write_relationship function function write_relationship L41–46
~ muse/plugins/registry.py .py 1 symbol added, 1 symbol modified
+ IdentityPlugin import import IdentityPlugin L25–25
← Older Oldest on task/identity-domain
All commits
Newer → Latest on task/identity-domain

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:9ef9e1c3cd263b29c5ad21f2be44526fca5a1c290c874f858de038573bb43861 --body "your comment"