feat BREAKING KH2 main #29 / 31
aaronrene · 56 days ago · Jul 13, 2026 · Diff

feat(KH2): fail-closed Muse-sync hard gate — permanent fix for MuseHub/GitHub drift

Mirrors git commit 4ec24a4 (branch feat/kh2-muse-sync-hard-gate). Adds StatusResult.muse_dirty/git_dirty, tools/muse_sync/ (check_muse_sync, frozen trigger: muse_dirty and not git_dirty), wired fail-closed into status --exit-code / review --freeze / governance-sync (exit 2, no precedence renumbering). Freeze doc reviewed -> pass (KH2-r2). 456 tests green (+27 KH2 seven-tier matrix).

sha256:a5c350ac215f14db6a07f76135744edb756fd6aeee1f86689a84ee016d718665 sha
+126 ~26 symbols
sha256:dc27984c7abd549b780197c081bbe7b74d0f7f18f34542111a75c2861965dd4e snapshot
+126
symbols added
~26
symbols modified
0
dead code introduced
Semantic Changes 152 symbols
~ docs/PHASE-KH2-MUSE-SYNC-HARD-GATE.md .md 20 symbols added
+ Phase KH2 — Muse-sync hard gate (Thinking freeze) section Phase KH2 — Muse-sync hard gate (Thinking freeze) L1–279
+ code[yaml] variable variable code[yaml] L7–43
+ table section table L52–56
+ 0 — Simple summary section §KH2.0 — Simple summary L59–90
+ 1 — Scope section §KH2.1 — Scope L90–124
+ 2 — What exists now (verified, do not redesign) section §KH2.2 — What exists now (verified, do not redesign) L124–145
+ table section table L126–137
+ 3 — StatusResult field additions (frozen) section §KH2.3 — StatusResult field additions (frozen) L145–174
+ code[python] variable variable code[python] L150–160
+ table section table L163–168
+ 4 — MuseSyncReport + check_muse_sync (frozen) section §KH2.4 — MuseSyncReport + check_muse_sync (frozen) L174–219
+ code[python] variable variable code[python] L179–195
+ 5 — Wiring: three fail-closed choke points (frozen) section §KH2.5 — Wiring: three fail-closed choke points (frozen) L219–232
+ table section table L224–229
+ 6 — Boundary: what this gate does and does not catch (frozen, stated plainly) section §KH2.6 — Boundary: what this gate does and does not catch (frozen, stated plainly) L232–247
+ table section table L234–241
+ 7 — Config & regime interaction section §KH2.7 — Config & regime interaction L247–256
+ 8 — Seven-tier test matrix (KH2b Auto build must satisfy) section §KH2.8 — Seven-tier test matrix (KH2b Auto build must satisfy) L256–270
+ table section table L258–267
+ 9 — Close-out (execute only when KH2 marked DONE) section §KH2.9 — Close-out (execute only when KH2 marked DONE) L270–279
+ _status function function _status L12–19
+ StatusResult import import StatusResult L7–7
+ annotations import import annotations L3–3
+ check_muse_sync import import check_muse_sync L9–9
+ itertools import import itertools L5–5
+ load_fixture_config import import load_fixture_config L8–8
+ test_full_input_matrix_is_exhaustively_covered_and_stable function function test_full_input_matrix_is_exhaustively_covered_and_stable L42–52
+ test_identical_inputs_always_yield_identical_report function function test_identical_inputs_always_yield_identical_report L22–28
+ test_no_hidden_state_across_calls_with_varying_inputs function function test_no_hidden_state_across_calls_with_varying_inputs L31–39
+ _mirror_runner function function _mirror_runner L20–28
+ FIXTURES import import FIXTURES L9–9
+ Path import import Path L6–6
+ annotations import import annotations L3–3
+ json import import json L5–5
+ kit_root import import kit_root L8–8
+ make_runner import import make_runner L9–9
+ ok import import ok L9–9
+ pass_provider_factory import import pass_provider_factory L9–9
+ run_cli import import run_cli L9–9
+ seed_freeze_repo import import seed_freeze_repo L9–9
+ seed_muse_substrate import import seed_muse_substrate L9–9
+ test_governance_sync_refuses_then_proceeds_across_a_simulated_muse_commit function function test_governance_sync_refuses_then_proceeds_across_a_simulated_muse_commit L58–98
+ test_review_freeze_refuses_then_proceeds_across_a_simulated_muse_commit function function test_review_freeze_refuses_then_proceeds_across_a_simulated_muse_commit L31–55
+ _init function function _init L19–27
+ FIXTURES import import FIXTURES L9–9
+ Path import import Path L6–6
+ ReadError import import ReadError L8–8
+ adapter_for import import adapter_for L9–9
+ annotations import import annotations L3–3
+ json import import json L5–5
+ make_runner import import make_runner L9–9
+ ok import import ok L9–9
+ run_cli import import run_cli L9–9
+ seed_muse_substrate import import seed_muse_substrate L9–9
+ test_git_only_adapter_leaves_muse_dirty_none function function test_git_only_adapter_leaves_muse_dirty_none L63–74
+ test_mirror_adapter_populates_both_dirty_fields function function test_mirror_adapter_populates_both_dirty_fields L30–45
+ test_muse_only_adapter_leaves_git_dirty_none function function test_muse_only_adapter_leaves_git_dirty_none L48–60
+ test_status_exit_code_0_when_muse_synced function function test_status_exit_code_0_when_muse_synced L93–106
+ test_status_exit_code_2_when_muse_pending function function test_status_exit_code_2_when_muse_pending L77–90
+ test_status_json_payload_reports_muse_sync_state function function test_status_json_payload_reports_muse_sync_state L109–126
+ _runner function function _runner L10–18
+ FIXTURES import import FIXTURES L7–7
+ Path import import Path L5–5
+ annotations import import annotations L3–3
+ make_runner import import make_runner L7–7
+ ok import import ok L7–7
+ run_cli import import run_cli L7–7
+ seed_muse_substrate import import seed_muse_substrate L7–7
+ test_status_call_count_unchanged_by_muse_sync_gate function function test_status_call_count_unchanged_by_muse_sync_gate L21–44
+ FIXTURES import import FIXTURES L8–8
+ Path import import Path L5–5
+ StatusResult import import StatusResult L7–7
+ annotations import import annotations L3–3
+ check_muse_sync import import check_muse_sync L16–16
+ load_fixture_config import import load_fixture_config L8–8
+ make_runner import import make_runner L8–8
+ ok import import ok L8–8
+ run_cli import import run_cli L8–8
+ seed_muse_substrate import import seed_muse_substrate L8–8
+ test_fails_closed_when_dirty_state_unreadable function function test_fails_closed_when_dirty_state_unreadable L19–25
+ test_muse_sync_payload_never_leaks_command_output_or_paths function function test_muse_sync_payload_never_leaks_command_output_or_paths L42–82
+ test_remediation_text_is_a_static_string_never_shell_invoked function function test_remediation_text_is_a_static_string_never_shell_invoked L28–39
+ test_review_freeze_refusal_does_not_run_review_provider function function test_review_freeze_refusal_does_not_run_review_provider L85–114
~ tests/stress/test_muse_sync_stress.py .py 10 symbols added
+ FIXTURES import import FIXTURES L9–9
+ Path import import Path L7–7
+ annotations import import annotations L3–3
+ json import import json L5–5
+ make_runner import import make_runner L9–9
+ ok import import ok L9–9
+ run_cli import import run_cli L9–9
+ seed_muse_substrate import import seed_muse_substrate L9–9
+ time import import time L6–6
+ test_muse_sync_gate_bounded_with_large_muse_status_payload function function test_muse_sync_gate_bounded_with_large_muse_status_payload L12–51
~ tests/unit/test_muse_sync.py .py 17 symbols added
+ _status function function _status L12–19
+ FIXTURES import import FIXTURES L8–8
+ StatusResult import import StatusResult L7–7
+ annotations import import annotations L3–3
+ check_muse_sync import import check_muse_sync L9–9
+ fields import import fields L5–5
+ load_fixture_config import import load_fixture_config L8–8
+ test_fixtures_dir_sane function function test_fixtures_dir_sane L105–107
+ test_git_only_is_not_applicable function function test_git_only_is_not_applicable L31–36
+ test_mirror_pending_when_git_clean_and_muse_dirty function function test_mirror_pending_when_git_clean_and_muse_dirty L46–54
+ test_mirror_synced_when_both_clean function function test_mirror_synced_when_both_clean L57–64
+ test_mirror_synced_when_both_dirty_mid_edit_non_trigger function function test_mirror_synced_when_both_dirty_mid_edit_non_trigger L67–74
+ test_mirror_synced_when_git_dirty_muse_clean_non_trigger function function test_mirror_synced_when_git_dirty_muse_clean_non_trigger L77–84
+ test_mirror_unreadable_when_git_dirty_unknown function function test_mirror_unreadable_when_git_dirty_unknown L96–102
+ test_mirror_unreadable_when_muse_dirty_unknown function function test_mirror_unreadable_when_muse_dirty_unknown L87–93
+ test_muse_only_is_not_applicable function function test_muse_only_is_not_applicable L39–43
+ test_status_result_new_fields_default_to_none function function test_status_result_new_fields_default_to_none L22–28
~ tools/muse_sync/__init__.py .py 3 symbols added
+ __all__ variable variable __all__ L5–5
+ MuseSyncReport import import MuseSyncReport L3–3
+ check_muse_sync import import check_muse_sync L3–3
~ tools/muse_sync/check.py .py 9 symbols added
+ MUSE_GIT_MIRROR_REGIME variable variable MUSE_GIT_MIRROR_REGIME L18–18
+ MuseSyncReport class class MuseSyncReport L23–33
+ ok method method ok L32–33
+ REMEDIATION variable variable REMEDIATION L19–19
+ check_muse_sync function function check_muse_sync L36–75
+ OverseerConfig import import OverseerConfig L15–15
+ StatusResult import import StatusResult L16–16
+ annotations import import annotations L11–11
+ dataclass class import dataclass L13–13
~ adapters/git_only/adapter.py .py 2 symbols modified
~ adapters/types.py .py 1 symbol modified
~ cli/commands/review.py .py 1 symbol added, 1 symbol modified
+ check_muse_sync import import check_muse_sync L20–20
~ cli/commands/status.py .py 2 symbols added, 2 symbols modified
+ _muse_sync_payload function function _muse_sync_payload L284–290
+ check_muse_sync import import check_muse_sync L22–22
~ tools/governance_hygiene/reads.py .py 1 symbol added, 1 symbol modified
+ check_muse_sync import import check_muse_sync L14–14

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