gabriel / muse public
feat patch harmony task/harmony-phase1 #1 / 1
AI Agent gabriel · 162 days ago · Apr 17, 2026 · Diff

feat(harmony): Phase 1 — Resolution Intelligence core data model + 135-test suite

Introduces muse.core.harmony — a greenfield resolution intelligence system built from the ground up for Muse's agent-first, domain-agnostic paradigm. Replaces the mechanical rerere replay model with a three-tier pipeline: policy → exact replay → semantic match → escalate.

Core concepts - ConflictPattern: semantic identity with blob + semantic fingerprints - Resolution: committed decision with strategy, rationale, AgentProvenance, confidence, human_verified, applied_count - Policy: declarative rule scoped workspace→repo→domain→file; first match wins - ResolutionProposal: candidate with confidence score for agent auto-accept - AgentProvenance: attribution (type: agent|human, agent_id, model_id)

Open string-constant namespaces (ConflictType, ResolutionStrategy, PolicyAction, PolicyScope, AuditEventType) — extensible by domain plugins without modifying this module.

Storage: .muse/harmony/patterns/<id>/pattern.json + resolutions/, .muse/harmony/policies/<id>.json, .muse/harmony/audit/<YYYYMMDD>-<uuid4>.json

Security: hex64 + URL-safe ID validation, symlink guards, size caps (32/16/8/4 KiB), atomic writes via temp-file + os.replace.

Test suite (tests/test_harmony_phase1.py — 135 tests, all green): I Unit (35) — fingerprints, validation, namespaces, dataclasses, condition matching II Integration (60) — pattern/resolution/policy/audit CRUD, gc_stale III End-to-end (7) — full conflict lifecycle + audit trail IV Stress (4) — 100-pattern scan, concurrent record/increment V Data integrity (11) — atomic write, JSON round-trip, field types VI Security (14) — path traversal, symlinks, size caps, malformed JSON VII Performance (7) — per-operation timing assertions

sha256:50452d2577f9354841ee5a7d3ca3ffbc6c8b2daf9b0b4ef867cda97953cf8acc sha
+305 symbols
sha256:88ab774ca9bc89fc3249580dc891c63a5c3461f26be11fb457db2e58f71fae4e snapshot
+305
symbols added
0
dead code introduced
Semantic Changes 305 symbols
~ muse/core/harmony.py .py 92 symbols added
+ AgentProvenance class class AgentProvenance L238–278
+ agent method method agent L258–265
+ from_dict method method from_dict L272–278
+ human method method human L253–255
+ to_dict method method to_dict L267–269
+ AuditEvent class class AuditEvent L472–482
+ AuditEventType class class AuditEventType L215–229
+ ConflictPattern class class ConflictPattern L301–335
+ ConflictType class class ConflictType L143–164
+ Policy class class Policy L365–390
+ PolicyAction class class PolicyAction L182–196
+ PolicyCondition class class PolicyCondition L282–297
+ PolicyScope class class PolicyScope L199–212
+ Resolution class class Resolution L339–361
+ ResolutionProposal class class ResolutionProposal L394–416
+ ResolutionStrategy class class ResolutionStrategy L167–179
+ _AUDIT variable variable _AUDIT L105–105
+ _HARMONY variable variable _HARMONY L102–102
+ _HEX64_RE variable variable _HEX64_RE L132–132
+ _MAX_AUDIT_BYTES variable variable _MAX_AUDIT_BYTES L120–120
+ _MAX_AUDIT_ENTRIES variable variable _MAX_AUDIT_ENTRIES L129–129
+ _MAX_PATTERN_BYTES variable variable _MAX_PATTERN_BYTES L111–111
+ _MAX_POLICIES variable variable _MAX_POLICIES L126–126
+ _MAX_POLICY_BYTES variable variable _MAX_POLICY_BYTES L117–117
+ _MAX_RESOLUTION_BYTES variable variable _MAX_RESOLUTION_BYTES L114–114
+ _MAX_SCAN variable variable _MAX_SCAN L123–123
+ _PATTERNS variable variable _PATTERNS L103–103
+ _PATTERN_FILE variable variable _PATTERN_FILE L107–107
+ _POLICIES variable variable _POLICIES L104–104
+ _POLICY_ID_RE variable variable _POLICY_ID_RE L135–135
+ _PatternDict class class _PatternDict L424–435
+ _PolicyConditionDict class class _PolicyConditionDict L452–456
+ _PolicyDict class class _PolicyDict L459–469
+ _RESOLUTIONS variable variable _RESOLUTIONS L106–106
+ _ResolutionDict class class _ResolutionDict L438–449
+ _condition_matches function function _condition_matches L1489–1511
+ _dict_to_pattern function function _dict_to_pattern L714–732
+ _dict_to_policy function function _dict_to_policy L796–820
+ _dict_to_resolution function function _dict_to_resolution L751–769
+ _now_utc function function _now_utc L651–653
+ _parse_dt function function _parse_dt L656–668
+ _pattern_entry_dir function function _pattern_entry_dir L510–516
+ _pattern_to_dict function function _pattern_to_dict L698–711
+ _policy_condition_to_dict function function _policy_condition_to_dict L772–778
+ _policy_to_dict function function _policy_to_dict L781–793
+ _resolution_to_dict function function _resolution_to_dict L735–748
+ _resolutions_dir function function _resolutions_dir L519–524
+ _validate_id function function _validate_id L532–550
+ _validate_policy_id function function _validate_policy_id L553–570
+ _write_atomic function function _write_atomic L671–690
+ append_audit function function append_audit L1260–1300
+ audit_dir function function audit_dir L505–507
+ best_resolution function function best_resolution L1193–1206
+ blob_fingerprint function function blob_fingerprint L578–594
+ clear_all function function clear_all L996–1022
+ compute_pattern_id function function compute_pattern_id L597–613
+ compute_resolution_id function function compute_resolution_id L616–643
+ forget_pattern function function forget_pattern L950–993
+ gc_stale function function gc_stale L1214–1252
+ harmony_dir function function harmony_dir L490–492
+ Any import import Any L94–94
+ Literal import import Literal L94–94
+ TypedDict import import TypedDict L94–94
+ annotations import import annotations L81–81
+ dataclass class import dataclass L93–93
+ datetime import import datetime L83–83
+ dc_replace import import dc_replace L93–93
+ fnmatch import import fnmatch L84–84
+ hashlib import import hashlib L85–85
+ json import import json L86–86
+ logging import import logging L87–87
+ os import import os L88–88
+ pathlib import import pathlib L89–89
+ re import import re L90–90
+ tempfile import import tempfile L91–91
+ uuid import import uuid L92–92
+ increment_applied_count function function increment_applied_count L1162–1190
+ list_audit function function list_audit L1303–1344
+ list_patterns function function list_patterns L906–947
+ list_policies function function list_policies L1413–1454
+ list_resolutions function function list_resolutions L1124–1159
+ load_pattern function function load_pattern L865–903
+ load_policy function function load_policy L1377–1410
+ load_resolution function function load_resolution L1079–1121
+ logger variable variable logger L96–96
+ match_policy function function match_policy L1514–1534
+ patterns_dir function function patterns_dir L495–497
+ policies_dir function function policies_dir L500–502
+ record_pattern function function record_pattern L828–862
+ remove_policy function function remove_policy L1457–1481
+ save_policy function function save_policy L1352–1374
+ save_resolution function function save_resolution L1030–1076
~ tests/test_harmony_phase1.py .py 213 symbols added
+ TestAuditLog class class TestAuditLog L786–834
+ test_append_and_list method method test_append_and_list L789–794
+ test_audit_fields_present method method test_audit_fields_present L820–834
+ test_entries_sorted_newest_first method method test_entries_sorted_newest_first L796–808
+ test_limit_respected method method test_limit_respected L813–818
+ test_list_audit_empty method method test_list_audit_empty L810–811
+ TestBlobFingerprint class class TestBlobFingerprint L187–215
+ test_commutativity method method test_commutativity L190–192
+ test_determinism method method test_determinism L194–198
+ test_distinct_pairs_differ method method test_distinct_pairs_differ L206–209
+ test_output_is_64_hex method method test_output_is_64_hex L200–204
+ test_same_id_both_sides method method test_same_id_both_sides L211–215
+ TestComputePatternId class class TestComputePatternId L218–244
+ test_64_hex_output method method test_64_hex_output L241–244
+ test_blob_changes_id method method test_blob_changes_id L235–239
+ test_deterministic method method test_deterministic L221–226
+ test_path_changes_id method method test_path_changes_id L228–233
+ TestComputeResolutionId class class TestComputeResolutionId L247–275
+ test_deterministic method method test_deterministic L250–257
+ test_different_agents_differ method method test_different_agents_differ L259–267
+ test_human_provenance_encodes_as_human method method test_human_provenance_encodes_as_human L269–275
+ TestConditionMatching class class TestConditionMatching L427–487
+ _pattern method method _pattern L430–431
+ test_all_conditions_must_match method method test_all_conditions_must_match L457–464
+ test_all_none_matches_anything method method test_all_none_matches_anything L433–435
+ test_conflict_type_match method method test_conflict_type_match L437–440
+ test_domain_match method method test_domain_match L442–445
+ test_match_policy_empty_list method method test_match_policy_empty_list L479–481
+ test_match_policy_first_match_wins method method test_match_policy_first_match_wins L466–472
+ test_match_policy_no_match_returns_none method method test_match_policy_no_match_returns_none L474–477
+ test_min_confidence_not_evaluated_here method method test_min_confidence_not_evaluated_here L483–487
+ test_path_pattern_glob method method test_path_pattern_glob L447–450
+ test_path_pattern_prefix_glob method method test_path_pattern_prefix_glob L452–455
+ TestDataIntegrity class class TestDataIntegrity L1056–1166
+ test_agent_provenance_human_round_trip method method test_agent_provenance_human_round_trip L1138–1141
+ test_agent_provenance_round_trip method method test_agent_provenance_round_trip L1132–1136
+ test_applied_count_starts_at_zero method method test_applied_count_starts_at_zero L1159–1166
+ test_no_temp_files_after_record_pattern method method test_no_temp_files_after_record_pattern L1059–1064
+ test_no_temp_files_after_save_policy method method test_no_temp_files_after_save_policy L1075–1079
+ test_no_temp_files_after_save_resolution method method test_no_temp_files_after_save_resolution L1066–1073
+ test_pattern_json_round_trip method method test_pattern_json_round_trip L1081–1096
+ test_policy_json_round_trip method method test_policy_json_round_trip L1112–1130
+ test_recorded_at_is_utc_aware method method test_recorded_at_is_utc_aware L1143–1148
+ test_resolution_json_round_trip method method test_resolution_json_round_trip L1098–1110
+ test_resolved_at_is_utc_aware method method test_resolved_at_is_utc_aware L1150–1157
+ TestDataclasses class class TestDataclasses L366–424
+ test_agent_provenance_agent method method test_agent_provenance_agent L375–379
+ test_agent_provenance_agent_no_model method method test_agent_provenance_agent_no_model L381–383
+ test_agent_provenance_frozen method method test_agent_provenance_frozen L385–388
+ test_agent_provenance_human method method test_agent_provenance_human L369–373
+ test_conflict_pattern_frozen method method test_conflict_pattern_frozen L402–405
+ test_policy_condition_all_none_wildcard method method test_policy_condition_all_none_wildcard L390–395
+ test_policy_condition_frozen method method test_policy_condition_frozen L397–400
+ test_resolution_frozen method method test_resolution_frozen L407–411
+ test_resolution_proposal_defaults method method test_resolution_proposal_defaults L413–424
+ TestFullLifecycle class class TestFullLifecycle L877–964
+ test_audit_trail_through_lifecycle method method test_audit_trail_through_lifecycle L948–964
+ test_complete_lifecycle method method test_complete_lifecycle L880–920
+ test_policy_does_not_fire_wrong_domain method method test_policy_does_not_fire_wrong_domain L940–946
+ test_policy_fires_on_matching_pattern method method test_policy_fires_on_matching_pattern L922–938
+ TestGcStale class class TestGcStale L837–869
+ test_gc_empty_store method method test_gc_empty_store L868–869
+ test_gc_keeps_recent_unresolved method method test_gc_keeps_recent_unresolved L862–866
+ test_gc_keeps_resolved_pattern method method test_gc_keeps_resolved_pattern L850–860
+ test_gc_removes_old_unresolved method method test_gc_removes_old_unresolved L840–848
+ TestNamespaces class class TestNamespaces L328–363
+ test_audit_event_type_are_strings method method test_audit_event_type_are_strings L352–357
+ test_conflict_type_are_strings method method test_conflict_type_are_strings L331–336
+ test_plugin_can_use_custom_conflict_type method method test_plugin_can_use_custom_conflict_type L359–363
+ test_policy_action_are_strings method method test_policy_action_are_strings L344–346
+ test_policy_scope_are_strings method method test_policy_scope_are_strings L348–350
+ test_resolution_strategy_are_strings method method test_resolution_strategy_are_strings L338–342
+ TestPatternCRUD class class TestPatternCRUD L495–588
+ test_clear_all_empty_store method method test_clear_all_empty_store L580–581
+ test_clear_all_removes_all method method test_clear_all_removes_all L573–578
+ test_forget_also_removes_resolutions method method test_forget_also_removes_resolutions L563–571
+ test_forget_invalid_id_returns_false method method test_forget_invalid_id_returns_false L560–561
+ test_forget_nonexistent_returns_false method method test_forget_nonexistent_returns_false L557–558
+ test_forget_pattern_removes_entry method method test_forget_pattern_removes_entry L551–555
+ test_list_patterns_empty method method test_list_patterns_empty L524–525
+ test_list_patterns_multiple method method test_list_patterns_multiple L527–535
+ test_list_patterns_sorted_newest_first method method test_list_patterns_sorted_newest_first L537–549
+ test_load_invalid_id_returns_none method method test_load_invalid_id_returns_none L521–522
+ test_load_nonexistent_returns_none method method test_load_nonexistent_returns_none L518–519
+ test_record_and_load method method test_record_and_load L498–506
+ test_record_is_idempotent method method test_record_is_idempotent L508–516
+ test_record_pattern_invalid_id_raises method method test_record_pattern_invalid_id_raises L583–588
+ TestPerformance class class TestPerformance L1278–1338
+ test_append_audit_under_20ms method method test_append_audit_under_20ms L1323–1328
+ test_increment_applied_count_under_20ms method method test_increment_applied_count_under_20ms L1330–1338
+ test_list_100_patterns_under_500ms method method test_list_100_patterns_under_500ms L1305–1313
+ test_load_pattern_under_10ms method method test_load_pattern_under_10ms L1288–1294
+ test_record_pattern_under_50ms method method test_record_pattern_under_50ms L1281–1286
+ test_save_and_load_policy_under_20ms method method test_save_and_load_policy_under_20ms L1315–1321
+ test_save_resolution_under_50ms method method test_save_resolution_under_50ms L1296–1303
+ TestPolicyCRUD class class TestPolicyCRUD L712–783
+ test_condition_round_trips method method test_condition_round_trips L776–783
+ test_list_policies_empty method method test_list_policies_empty L740–741
+ test_list_policies_scope_order method method test_list_policies_scope_order L743–755
+ test_load_invalid_id_returns_none method method test_load_invalid_id_returns_none L737–738
+ test_load_nonexistent_returns_none method method test_load_nonexistent_returns_none L734–735
+ test_remove_invalid_id_returns_false method method test_remove_invalid_id_returns_false L766–767
+ test_remove_nonexistent_returns_false method method test_remove_nonexistent_returns_false L763–764
+ test_remove_policy_returns_true method method test_remove_policy_returns_true L757–761
+ test_save_and_load method method test_save_and_load L715–722
+ test_save_invalid_id_raises method method test_save_invalid_id_raises L769–774
+ test_save_overwrites_existing method method test_save_overwrites_existing L724–732
+ TestResolutionCRUD class class TestResolutionCRUD L591–709
+ test_best_resolution_none_when_no_resolutions method method test_best_resolution_none_when_no_resolutions L706–709
+ test_best_resolution_returns_highest_quality method method test_best_resolution_returns_highest_quality L690–704
+ test_increment_applied_count method method test_increment_applied_count L666–674
+ test_increment_applied_count_multiple_times method method test_increment_applied_count_multiple_times L676–685
+ test_increment_nonexistent_returns_false method method test_increment_nonexistent_returns_false L687–688
+ test_list_resolutions_empty method method test_list_resolutions_empty L627–630
+ test_list_resolutions_sorted_by_quality method method test_list_resolutions_sorted_by_quality L632–664
+ test_load_invalid_ids_return_none method method test_load_invalid_ids_return_none L623–625
+ test_load_nonexistent_returns_none method method test_load_nonexistent_returns_none L620–621
+ test_save_and_load method method test_save_and_load L594–604
+ test_save_is_idempotent method method test_save_is_idempotent L606–612
+ test_save_requires_parent_pattern method method test_save_requires_parent_pattern L614–618
+ TestSecurity class class TestSecurity L1174–1270
+ test_crafted_policy_id_with_null_byte method method test_crafted_policy_id_with_null_byte L1197–1199
+ test_crafted_policy_id_with_slash method method test_crafted_policy_id_with_slash L1193–1195
+ test_malformed_json_pattern_returns_none method method test_malformed_json_pattern_returns_none L1249–1255
+ test_malformed_json_resolution_returns_none method method test_malformed_json_resolution_returns_none L1257–1264
+ test_non_hex_dir_in_patterns_dir_skipped method method test_non_hex_dir_in_patterns_dir_skipped L1266–1270
+ test_oversized_pattern_file_rejected method method test_oversized_pattern_file_rejected L1222–1229
+ test_oversized_policy_file_rejected method method test_oversized_policy_file_rejected L1241–1247
+ test_oversized_resolution_file_rejected method method test_oversized_resolution_file_rejected L1231–1239
+ test_path_traversal_in_forget_pattern method method test_path_traversal_in_forget_pattern L1189–1191
+ test_path_traversal_in_load_pattern method method test_path_traversal_in_load_pattern L1181–1183
+ test_path_traversal_in_load_resolution method method test_path_traversal_in_load_resolution L1185–1187
+ test_path_traversal_in_pattern_id_rejected method method test_path_traversal_in_pattern_id_rejected L1177–1179
+ test_symlinks_in_patterns_dir_skipped method method test_symlinks_in_patterns_dir_skipped L1201–1210
+ test_symlinks_in_policies_dir_skipped method method test_symlinks_in_policies_dir_skipped L1212–1220
+ TestStress class class TestStress L972–1048
+ test_100_patterns_scan method method test_100_patterns_scan L975–981
+ test_concurrent_increment_applied_count method method test_concurrent_increment_applied_count L1005–1038
+ test_concurrent_record_pattern_no_corruption method method test_concurrent_record_pattern_no_corruption L983–1003
+ test_list_patterns_scan_cap_does_not_crash method method test_list_patterns_scan_cap_does_not_crash L1040–1048
+ TestValidation class class TestValidation L278–325
+ test_validate_id_accepts_64_hex method method test_validate_id_accepts_64_hex L281–282
+ test_validate_id_rejects_63_chars method method test_validate_id_rejects_63_chars L284–286
+ test_validate_id_rejects_65_chars method method test_validate_id_rejects_65_chars L288–290
+ test_validate_id_rejects_empty method method test_validate_id_rejects_empty L301–303
+ test_validate_id_rejects_path_traversal method method test_validate_id_rejects_path_traversal L296–299
+ test_validate_id_rejects_uppercase method method test_validate_id_rejects_uppercase L292–294
+ test_validate_policy_id_accepts_128_chars method method test_validate_policy_id_accepts_128_chars L324–325
+ test_validate_policy_id_accepts_alphanumeric method method test_validate_policy_id_accepts_alphanumeric L305–306
+ test_validate_policy_id_rejects_129_chars method method test_validate_policy_id_rejects_129_chars L320–322
+ test_validate_policy_id_rejects_dot method method test_validate_policy_id_rejects_dot L312–314
+ test_validate_policy_id_rejects_empty method method test_validate_policy_id_rejects_empty L316–318
+ test_validate_policy_id_rejects_slash method method test_validate_policy_id_rejects_slash L308–310
+ _fake_id function function _fake_id L86–88
+ _make_pattern function function _make_pattern L95–122
+ _make_policy function function _make_policy L154–179
+ _make_resolution function function _make_resolution L125–151
+ _utc_now function function _utc_now L91–92
+ AgentProvenance import import AgentProvenance L31–31
+ Any import import Any L25–25
+ AuditEvent import import AuditEvent L31–31
+ AuditEventType import import AuditEventType L31–31
+ ConflictPattern import import ConflictPattern L31–31
+ ConflictType import import ConflictType L31–31
+ FrozenInstanceError import import FrozenInstanceError L24–24
+ Policy import import Policy L31–31
+ PolicyAction import import PolicyAction L31–31
+ PolicyCondition import import PolicyCondition L31–31
+ PolicyScope import import PolicyScope L31–31
+ Resolution import import Resolution L31–31
+ ResolutionProposal import import ResolutionProposal L31–31
+ ResolutionStrategy import import ResolutionStrategy L31–31
+ _MAX_AUDIT_BYTES import import _MAX_AUDIT_BYTES L31–31
+ _MAX_PATTERN_BYTES import import _MAX_PATTERN_BYTES L31–31
+ _MAX_POLICY_BYTES import import _MAX_POLICY_BYTES L31–31
+ _MAX_RESOLUTION_BYTES import import _MAX_RESOLUTION_BYTES L31–31
+ _MAX_SCAN import import _MAX_SCAN L31–31
+ _condition_matches import import _condition_matches L31–31
+ annotations import import annotations L13–13
+ append_audit import import append_audit L31–31
+ best_resolution import import best_resolution L31–31
+ blob_fingerprint import import blob_fingerprint L31–31
+ clear_all import import clear_all L31–31
+ compute_pattern_id import import compute_pattern_id L31–31
+ compute_resolution_id import import compute_resolution_id L31–31
+ futures import import concurrent.futures L15–15
+ datetime import import datetime L16–16
+ forget_pattern import import forget_pattern L31–31
+ gc_stale import import gc_stale L31–31
+ h import import h L30–30
+ hashlib import import hashlib L17–17
+ increment_applied_count import import increment_applied_count L31–31
+ json import import json L18–18
+ list_audit import import list_audit L31–31
+ list_patterns import import list_patterns L31–31
+ list_policies import import list_policies L31–31
+ list_resolutions import import list_resolutions L31–31
+ load_pattern import import load_pattern L31–31
+ load_policy import import load_policy L31–31
+ load_resolution import import load_resolution L31–31
+ match_policy import import match_policy L31–31
+ mock import import mock L26–26
+ os import import os L19–19
+ pathlib import import pathlib L20–20
+ pytest import import pytest L28–28
+ record_pattern import import record_pattern L31–31
+ remove_policy import import remove_policy L31–31
+ save_policy import import save_policy L31–31
+ save_resolution import import save_resolution L31–31
+ tempfile import import tempfile L21–21
+ threading import import threading L22–22
+ time import import time L23–23
+ repo function function repo L80–83
← Older Oldest on task/harmony-phase1
All commits
Newer → Latest on task/harmony-phase1

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:50452d2577f9354841ee5a7d3ca3ffbc6c8b2daf9b0b4ef867cda97953cf8acc --body "your comment"