@@ -476,6 +476,64 @@ def test_setup_execute_persists_private_binding_after_verified_pin(
476476 _assert_public_packet (payload )
477477
478478
479+ def test_setup_execute_defaults_human_gate_auto_notify_on (tmp_path : Path ) -> None :
480+ registry_path = tmp_path / ".loopx" / "registry.json"
481+ binding_path = tmp_path / ".loopx" / "goal-channel.json"
482+ kanban_path = tmp_path / ".loopx" / "lark-kanban.json"
483+ calls : list [list [str ]] = []
484+
485+ payload = setup_lark_goal_channel (
486+ registry = _registry (tmp_path ),
487+ registry_path = registry_path ,
488+ goal_id = GOAL_ID ,
489+ binding_path = binding_path ,
490+ kanban_config_path = kanban_path ,
491+ bot_app_id = "cli_public_fixture" ,
492+ execute = True ,
493+ runner = _fake_runner (calls ),
494+ )
495+ assert payload ["ok" ] is True
496+ assert payload ["status" ] == "configured"
497+ persisted = read_goal_channel_binding (binding_path )["bindings" ][GOAL_ID ]
498+ assert persisted ["automation" ]["human_gate_auto_notify_enabled" ] is True
499+ marker_path = goal_channel_contracts .human_gate_auto_notify_marker_path (
500+ binding_path , GOAL_ID
501+ )
502+ assert goal_channel_contracts .human_gate_auto_notify_marker_enabled (marker_path )
503+
504+
505+ def test_setup_execute_preserves_explicit_auto_notify_opt_out (tmp_path : Path ) -> None :
506+ binding_path = tmp_path / ".loopx" / "goal-channel.json"
507+ binding_path .parent .mkdir (parents = True )
508+ kanban_path = tmp_path / ".loopx" / "lark-kanban.json"
509+ _write_binding (binding_path , kanban_path )
510+ payload = read_goal_channel_binding (binding_path )
511+ payload ["bindings" ][GOAL_ID ]["automation" ] = {
512+ "human_gate_auto_notify_enabled" : False
513+ }
514+ write_goal_channel_binding (binding_path , payload )
515+ calls : list [list [str ]] = []
516+
517+ result = setup_lark_goal_channel (
518+ registry = _registry (tmp_path ),
519+ registry_path = tmp_path / ".loopx" / "registry.json" ,
520+ goal_id = GOAL_ID ,
521+ binding_path = binding_path ,
522+ kanban_config_path = kanban_path ,
523+ bot_app_id = "cli_public_fixture" ,
524+ execute = True ,
525+ runner = _fake_runner (calls ),
526+ )
527+ assert result ["ok" ] is True
528+ assert result ["status" ] == "configured"
529+ persisted = read_goal_channel_binding (binding_path )["bindings" ][GOAL_ID ]
530+ assert persisted ["automation" ]["human_gate_auto_notify_enabled" ] is False
531+ marker_path = goal_channel_contracts .human_gate_auto_notify_marker_path (
532+ binding_path , GOAL_ID
533+ )
534+ assert not goal_channel_contracts .human_gate_auto_notify_marker_enabled (marker_path )
535+
536+
479537def test_configure_auto_notify_is_preview_first_and_persists_private_opt_in (
480538 tmp_path : Path ,
481539) -> None :
@@ -556,9 +614,12 @@ def test_configure_can_disable_auto_notify_for_incomplete_binding(
556614 _assert_public_packet (payload )
557615
558616
559- def test_auto_notify_gate_is_disabled_by_default_and_suppressible (
617+ def test_auto_notify_gate_is_disabled_when_unconfigured_and_suppressible (
560618 tmp_path : Path ,
561619) -> None :
620+ # A raw binding with no automation setting is unconfigured (disabled); the
621+ # setup path now defaults human-gate auto-notify to on (see
622+ # test_setup_execute_defaults_human_gate_auto_notify_on).
562623 binding_path = tmp_path / ".loopx" / "goal-channel.json"
563624 binding_path .parent .mkdir (parents = True )
564625 kanban_path = tmp_path / ".loopx" / "lark-kanban.json"
0 commit comments