3737
3838import pytest
3939
40+ from tests ._nc_harness import patch_restore as _patch_restore
41+
4042pytestmark = pytest .mark .unit
4143
4244HERE = os .path .dirname (os .path .abspath (__file__ ))
@@ -548,13 +550,12 @@ def test_NC_dispatch_drops_peer_markers(monkeypatch):
548550 """NC-OBSERVE: no-op the marker-propagation block in dispatch_next_queued →
549551 the persisted turn loses its peer markers → the observability test FAILS
550552 (the arrival becomes indistinguishable from user input)."""
551- import importlib
552-
553553 captured = {}
554554
555555 def run ():
556+ # The harness already swapped the NEUTERED module into sys.modules —
557+ # this import resolves to it (no reload; a reload would un-neuter).
556558 import lib .message_queue as mq
557- importlib .reload (mq )
558559 monkeypatch .setattr (mq , 'dequeue_next' , lambda c : {
559560 'queueId' : 'q1' , 'config' : {},
560561 'payload' : {'text' : 'hi' , '_peerMessage' : True , '_fromConv' : 'cS' }})
@@ -578,41 +579,24 @@ def run():
578579 " pass # NC-OBSERVE (marker propagation disabled)" ,
579580 run ,
580581 )
581- import lib .message_queue as mq
582- importlib .reload (mq )
583582
584583
585584# ════════════════════════════════════════════════════════════════════
586- # Source-level NEGATIVE CONTROLS (byte-reverting)
585+ # Source-level NEGATIVE CONTROLS (in-memory harness: the neutered module is
586+ # compiled into a throwaway sys.modules entry — the shipped file is READ-ONLY)
587587# ════════════════════════════════════════════════════════════════════
588588
589- def _patch_restore (path , old , new , run ):
590- with open (path , encoding = 'utf-8' ) as f :
591- original = f .read ()
592- assert old in original , f'anchor not found in { path } '
593- try :
594- with open (path , 'w' , encoding = 'utf-8' ) as f :
595- f .write (original .replace (old , new , 1 ))
596- run ()
597- finally :
598- with open (path , 'w' , encoding = 'utf-8' ) as f :
599- f .write (original )
600- with open (path , encoding = 'utf-8' ) as f :
601- assert f .read () == original , 'source not restored byte-identical'
602-
603-
604589def test_NC_storm_guard_noop_breaks_rate_limit (_stub_io ):
605590 """NC-STORM: disable the rate cap in _prune_and_check → the 4th message is
606591 no longer refused → the storm guard test FAILS."""
607- import importlib
608-
609592 def run ():
593+ # The harness already swapped the NEUTERED module into sys.modules —
594+ # this import resolves to it (no reload; a reload would un-neuter).
610595 import lib .conversations .project_peer as pp
611- importlib .reload (pp )
612- # Reload re-binds _resolve_target_conv_id to the real (DB-reading) fn;
613- # re-stub to identity so this DB-free NC uses synthetic ids.
596+ # The neutered module binds the real (DB-reading) resolver; re-stub to
597+ # identity on the swapped module so this DB-free NC uses synthetic ids.
614598 pp ._resolve_target_conv_id = lambda t : ((t or '' ).strip (), '' )
615- # Re-stub via module attrs the reloaded code reads at call time.
599+ # Re-stub via module attrs the neutered code reads at call time.
616600 for i in range (3 ):
617601 pp .send_peer_message ('/p' , 'cA' , 'cB' , f'm{ i } ' )
618602 blocked = pp .send_peer_message ('/p' , 'cA' , 'cB' , 'm4' )
@@ -628,24 +612,20 @@ def run():
628612 " return True, kept + [now], 0.0 # NC-STORM (rate cap disabled)" ,
629613 run ,
630614 )
631- import lib .conversations .project_peer as pp
632- importlib .reload (pp )
633615
634616
635617def test_NC_audit_gate_noop_allows_unapproved_abort (monkeypatch ):
636618 """NC-GATE: no-op the approval check in _authorize_hard_abort → an
637619 unapproved hard abort now proceeds → the gate test FAILS."""
638- import importlib
639-
640620 aborted = []
641621 monkeypatch .setattr ('lib.tasks_pkg.manager.abort_running_tasks_for_conv' ,
642622 lambda c , ** k : aborted .append (c ) or 1 )
643623 monkeypatch .setattr ('lib.conversations.project_feed.emit_project_event' ,
644624 lambda * a , ** k : None )
645625
646626 def run ():
627+ # Harness already swapped the NEUTERED module into sys.modules.
647628 import lib .conversations .project_peer as pp
648- importlib .reload (pp )
649629 pp ._resolve_target_conv_id = lambda t : ((t or '' ).strip (), '' )
650630 monkeypatch .setattr ('lib.conversations.project_peer.audit_log' ,
651631 lambda * a , ** k : None )
@@ -662,25 +642,21 @@ def run():
662642 " return True, 'approved' # NC-GATE (approval check disabled)" ,
663643 run ,
664644 )
665- import lib .conversations .project_peer as pp
666- importlib .reload (pp )
667645
668646
669647def test_NC_deny_branch_noop_runs_abort_despite_denial (_stub_io , monkeypatch ):
670648 """NC-DENY: no-op the deny branch (treat a falsy approval as approved) → a
671649 DENIED hard abort now runs the abort anyway → the deny-path test FAILS.
672650 This proves the deny branch is what actually stops an unapproved kill."""
673- import importlib
674-
675651 aborted = []
676652 monkeypatch .setattr ('lib.tasks_pkg.manager.abort_running_tasks_for_conv' ,
677653 lambda c , ** k : aborted .append (c ) or 1 )
678654 monkeypatch .setattr ('lib.conversations.project_feed.emit_project_event' ,
679655 lambda * a , ** k : None )
680656
681657 def run ():
658+ # Harness already swapped the NEUTERED module into sys.modules.
682659 import lib .conversations .project_peer as pp
683- importlib .reload (pp )
684660 pp ._resolve_target_conv_id = lambda t : ((t or '' ).strip (), '' )
685661 monkeypatch .setattr ('lib.conversations.project_peer.audit_log' ,
686662 lambda * a , ** k : None )
@@ -698,18 +674,14 @@ def run():
698674 " approved_by = str(approver).strip() if approver else 'nc-deny-forced' # NC-DENY" ,
699675 run ,
700676 )
701- import lib .conversations .project_peer as pp
702- importlib .reload (pp )
703677
704678
705679def test_NC_join_exclude_noop_leaks_self ():
706680 """NC-JOIN: no-op the exclude_conv filter → a conversation sees ITSELF in
707681 its own peer list → the self-exclusion test FAILS."""
708- import importlib
709-
710682 def run ():
683+ # Harness already swapped the NEUTERED module into sys.modules.
711684 import lib .conversations .project_peer as pp
712- importlib .reload (pp )
713685 view = pp ._join_peers (_peers (), {}, {}, exclude_conv = 'cA' )
714686 # With the exclusion disabled, cA leaks into its own peer view.
715687 assert any (v ['convId' ] == 'cA' for v in view ), \
@@ -721,5 +693,3 @@ def run():
721693 " if not conv_id:\n continue # NC-JOIN (self-exclude disabled)" ,
722694 run ,
723695 )
724- import lib .conversations .project_peer as pp
725- importlib .reload (pp )
0 commit comments