
    4jS1                    p   d Z ddlmZ ddlZddlmc mZ ddl	Z	ddl
ZddlZddlZddlZddlZddlZddlmZ ddlZ ee      j+                         j,                  j,                  j,                  Zedz  Zedz  Zedz  Zedz  Zed	z  Zed
z  Zg dZeeeeedZ ej@                  ejC                  d            Z"e"d   Z#ddZ$d Z% e%       Z&ddZ'ejP                  jS                  d e*e            d        Z+d Z,d Z-d Z.d Z/d Z0d Z1e2dk(  r% ejf                   ejh                  edg             yy)u  tests/regression/test_fallback_acceptance_2606_hardening.py

task-2606 (TRACK C) — TASK_2553_PLUS58_MICRO_FIX, additive-only hardening.

Spec: memory/tasks/task-2606.md
(sha256 842758659aa026280c76d27ba6b20e647a239d2e6b0374ebac33f247a8d59037).
Preflight: memory/events/task-2604-multitrack-preflight-decision_260519.json
(TrackC).

회장 §2 / Codex **HIGH** (additive-only — 기존 +58 산출물 byte-0):

  +58 ``test_fallback_acceptance_2553plus58.py::test_15`` mock-guard defect:
  guard 가 ``M.sha256_of(PATH) == _sha(PATH)`` 형태로 *동일 disk 파일을
  양변에서 재해시*하므로, 실 entrypoint 모듈/함수가 stub 으로 치환되어도
  self-hash 가 **trivially 일치**한다. 외부 고정(pinned) 기대 digest 가
  없어 stub-only FAIL 을 강제하지 못한다.

본 파일은 그 결함을 **신규 additive 모듈로만** 막는다 — 기존 +58 test
파일·validator·schema·criteria·fixture 는 **무수정(byte-0)**, read-only
소비만 한다. 닫는 방식:

  1  +58 산출물 5종의 test-local **독립** hashlib digest 가 fixture 의
     **외부 pinned 상수**(memory/fixtures/task-2606.hardening-cases.json)
     와 일치 — 모듈 under test 의 자기 해시 함수가 아니라 외부 anchor 대조.
  2  실 entrypoint ``evaluate_fallback_acceptance`` 의 code-object
     ``co_filename`` 과 ``inspect.getsource`` 소스 해시가 실 SCRIPT_PATH
     에서 옴 (monkeypatch 된 순수 mock 은 co_filename 불일치 → FAIL).
  3  +58 모듈 자체 hasher ``M.sha256_of`` 가 pinned 상수를 반환(정직성) —
     trivial-equality 가 아니라 하드코딩 anchor 와 대조.
  4  MOCK-ONLY FAIL 실증: ``sha256_of`` 를 상수반환으로 위조한 stub 모듈을
     hardening 가드에 넣으면 **AssertionError 로 거부**됨을 직접 보인다
     (+58 test_15 는 이 stub 을 통과시키지만 본 가드는 못 통과).
  5  실 entrypoint 직접 호출 행위 회귀 (문서-only 금지) — criterion (b)
     OPERATIONAL_PASS 재확인.
  6  +58 frozen anchor byte-0 + git HEAD/branch 불변.

모든 테스트 100% offline — network / git mutation / cron / dispatch /
cokacdir / subprocess(write) / 파일 write 0. 진행 트리거 0.
    )annotationsN)Path2scripts/validate_fallback_acceptance_2553plus58.py7tests/regression/test_fallback_acceptance_2553plus58.py/memory/events/fallback_acceptance_criteria.json)schemas/non_blocking_fallback_schema.json*memory/fixtures/task-2553plus58.cases.jsonz.memory/fixtures/task-2606.hardening-cases.json)zEmemory/events/task-2553.legacy-pending-fallback-inventory_260518.jsonzJmemory/events/task-2553+37.fallback-duplicate-callback-ignored_260518.jsonz)memory/events/callback_4tuple_index.jsonl)r   r   r   r   r	   utf-8encodingpinned_sha256c                d    t        j                  | j                               j                         S )uG   test-local hashlib — intentionally NOT M.sha256_of (anti trivial-eq).)hashlibsha256
read_bytes	hexdigest)paths    O/home/jay/workspace/tests/regression/test_fallback_acceptance_2606_hardening.py_independent_shar   P   s!    >>$//+,6688    c                    t         j                  j                  dt              } g }| }| r| j                  }|}|sdddt        j                         v st        j                  |       rt        j                  |       ndiz  }|j                  |       | rlddt        j                         v st        j                  |       rt        j                  |       ndt        j                        dz  }|j                  |       t        j                  |d      i z  }dd	|iz  }t        t        j                  |            d
x}x}}t         j                  j                  |       }| j                  j                  |       |S )z@Load the REAL +58 validator straight from SCRIPT_PATH (no stub).0validate_fallback_acceptance_2553plus58_for_2606z%(py2)spy2specz#%(py6)s
{%(py6)s = %(py4)s.loader
})py4py6r   zassert %(py9)spy9N)	importlibutilspec_from_file_locationSCRIPT_PATHloader@py_builtinslocals
@pytest_ar_should_repr_global_name	_safereprappend_format_boolopAssertionError_format_explanationmodule_from_specexec_module)	r   @py_assert1@py_assert0@py_assert5@py_format3@py_format7@py_format8@py_format10mods	            r   _load_real_plus58_moduler6   U   s    >>11:KD  44DKKK444DDK
..
)
)$
/CKKC Jr   c                   t        | dd      }d}||u}|st        j                  d|fd||f      dt        j                         v st        j
                  |      rt        j                  |      ndt        j                  |      dz  }t        j                  d      dz   d	|iz  }t        t        j                  |            dx}}t        |      }|j                  } |       }t        j                  } |       }	||	k(  }
|
st        j                  d
|
fd||	f      dt        j                         v st        j
                  t              rt        j                  t              nddt        j                         v st        j
                  |      rt        j                  |      ndt        j                  |      t        j                  |      t        j                  |      dt        j                         v st        j
                  t              rt        j                  t              ndt        j                  |      t        j                  |	      dz  }t        j                  d|       dz   d|iz  }t        t        j                  |            dx}x}x}x}
x}}	t        | dd      }t        |      }|st        j                  d      dz   dt        j                         v st        j
                  t              rt        j                  t              nddt        j                         v st        j
                  |      rt        j                  |      ndt        j                  |      dz  }t        t        j                  |            d}|j                  }| j                  }||k(  }|st        j                  d
|fd||f      dt        j                         v st        j
                  |      rt        j                  |      ndt        j                  |      dt        j                         v st        j
                  |       rt        j                  |       ndt        j                  |      dz  }t        j                  d      dz   d|iz  }t        t        j                  |            dx}x}}t        |j                   j"                        j                         }t        j                  } |       }||k(  }|st        j                  d
|fd||f      dt        j                         v st        j
                  |      rt        j                  |      nddt        j                         v st        j
                  t              rt        j                  t              ndt        j                  |      t        j                  |      dz  }t        j                  d |       dz   d|iz  }t        t        j                  |            dx}x}}t%        j&                  |      }d}||u}|st        j                  d|fd||f      d!t        j                         v st        j
                  |      rt        j                  |      nd!t        j                  |      dz  }t        j                  d"      dz   d	|iz  }t        t        j                  |            dx}}t        |      }|j                  } |       }t        j                  } |       }	||	k(  }
|
s{t        j                  d
|
fd||	f      dt        j                         v st        j
                  t              rt        j                  t              ndd!t        j                         v st        j
                  |      rt        j                  |      nd!t        j                  |      t        j                  |      t        j                  |      dt        j                         v st        j
                  t              rt        j                  t              ndt        j                  |      t        j                  |	      dz  }d#d|iz  }t        t        j                  |            dx}x}x}x}
x}}	t)        t              }t*        d$   }||k(  }|st        j                  d
|fd%||f      d&t        j                         v st        j
                  |      rt        j                  |      nd&t        j                  |      dz  }t        j                  d'      dz   d	|iz  }t        t        j                  |            dx}}| j-                  t              }t*        d$   }||k(  }|st        j                  d
|fd%||f      d(t        j                         v st        j
                  |      rt        j                  |      nd(t        j                  |      dz  }t        j                  d)      dz   d	|iz  }t        t        j                  |            dx}}||k(  }|st        j                  d
|fd*||f      d(t        j                         v st        j
                  |      rt        j                  |      nd(d&t        j                         v st        j
                  |      rt        j                  |      nd&d+z  }t        j                  d,      d-z   d.|iz  }t        t        j                  |            d}y)/u  Reject anything that is not the genuine +58 entrypoint module.

    Unlike +58 test_15 (which compares ``mod.sha256_of(p) == _sha(p)`` — a
    trivial self-equality that any disk-reading stub passes), this guard
    anchors every check to an **external pinned constant** and to the
    code-object provenance of the entrypoint function. A monkeypatched /
    fabricated module fails here even though it would pass +58 test_15.
    __file__N)is not)z%(py0)s is not %(py3)smod_filepy0py3zstub module has no __file__
>assert %(py5)spy5==)z%(py7)s
{%(py7)s = %(py5)s
{%(py5)s = %(py3)s
{%(py3)s = %(py0)s(%(py1)s)
}.resolve
}()
} == %(py13)s
{%(py13)s = %(py11)s
{%(py11)s = %(py9)s.resolve
}()
}r   r!   )r<   py1r=   r?   py7r   py11py13z)module not loaded from real SCRIPT_PATH: z
>assert %(py15)spy15evaluate_fallback_acceptancez1evaluate_fallback_acceptance missing/not callablez.
>assert %(py3)s
{%(py3)s = %(py0)s(%(py1)s)
}callablefn)r<   rB   r=   )zP%(py2)s
{%(py2)s = %(py0)s.__module__
} == %(py6)s
{%(py6)s = %(py4)s.__name__
}r5   )r<   r   r   r   z$entrypoint reassigned from elsewherez
>assert %(py8)spy8)zF%(py0)s == %(py6)s
{%(py6)s = %(py4)s
{%(py4)s = %(py2)s.resolve
}()
}co_filez1entrypoint co_filename is not the real artifact: src_filez)entrypoint has no source file (pure mock)zassert %(py15)sr   z%(py0)s == %(py3)sfile_shaz<real +58 script content drifted from task-2606 pinned anchorownz8module self-hasher disagrees with external pinned anchorz%(py0)s == %(py2)sr<   r   z2module self-hasher disagrees with independent hashz
>assert %(py4)sr   )getattrr%   _call_reprcomparer#   r$   r&   r'   _format_assertmsgr*   r+   r   resolver!   rH   
__module____name____code__co_filenameinspectgetsourcefiler   PINNED	sha256_of)r5   r:   @py_assert2r.   @py_format4@py_format6@py_assert4@py_assert6@py_assert10@py_assert12@py_assert8@py_format14@py_format16rI   r0   @py_assert3r2   @py_format9rK   rL   rN   rO   r1   @py_format5s                           r   assert_real_plus58_entrypointrk   d   s    sJ-H>84>>>84>>>>>>8>>>8>>>4>>>!>>>>>>>> >!! !# {':': ':'< #'<<   #'<                            "    $      (3    (3    (;    (=    4H:>      
4d	;BB<L<LLLLLLLLL8LLL8LLLLLLBLLLBLLL<LLLLLL==PCLLP=L(PPP=LPPPPPP2PPP2PPP=PPPPPPCPPPCPPPLPPP*PPPPPPPP2;;**+335G!)) )+ 7++   7+                "    "    *    ,    <G9E     $$R(HL84LLL84LLLLLL8LLL8LLL4LLL!LLLLLLL><>!!<!#<{':':<':'<<#'<<<<<#'<<<<<<<4<<<4<<<<<<<<<<<<><<<!<<<#<<<<<<{<<<{<<<':<<<'<<<<<<<<<,H < F8   F4E4EF8  F F?EvF F-E-E  F F<EI  F F<EI F F4E4EEF F F2E2EF F --
$C< B3   B0A0AB3  B B;A6B B)A)A  B B8A	  B B8A	 B B0A0AAB B B.A.AB B (?PPP3(PPPPPP3PPP3PPPPPP(PPP(PPPPPPPPPPPr   relc                   t        t        |          }t        |    }||k(  }|st        j                  d|fd||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      dz  }t        j                  |  d| dt        |     d      dz   d	|iz  }t        t        j                  |            d x}}y )
Nr@   rM   actualr;   z. drifted from task-2606 pinned anchor (actual=z	, pinned=)r>   r?   )r   PLUS58_FROZENr\   r%   rS   r#   r$   r&   r'   rT   r*   r+   )rl   rn   r^   r.   r_   r`   s         r   6test_01_plus58_artifact_matches_external_pinned_digestrq      s    mC01FC[ 6[   6[              !    % ()F3K=	3    r   c                 "    t        t               y N)rk   M r   r   .test_02_real_entrypoint_code_object_provenancerv      s
    !!$r   c                    t         j                  }  | t              }t        d   }||k(  }|st	        j
                  d|fd||f      dt        j                         v st	        j                  t               rt	        j                  t               ndt	        j                  |       dt        j                         v st	        j                  t              rt	        j                  t              ndt	        j                  |      t	        j                  |      dz  }dd|iz  }t        t	        j                  |            d x} x}x}}t         j                  }  | t              }t        d	   }||k(  }|st	        j
                  d|fd||f      dt        j                         v st	        j                  t               rt	        j                  t               ndt	        j                  |       d
t        j                         v st	        j                  t              rt	        j                  t              nd
t	        j                  |      t	        j                  |      dz  }dd|iz  }t        t	        j                  |            d x} x}x}}t         j                  }  | t              }t        d   }||k(  }|st	        j
                  d|fd||f      dt        j                         v st	        j                  t               rt	        j                  t               ndt	        j                  |       dt        j                         v st	        j                  t              rt	        j                  t              ndt	        j                  |      t	        j                  |      dz  }dd|iz  }t        t	        j                  |            d x} x}x}}y )Nr   r@   )zO%(py5)s
{%(py5)s = %(py2)s
{%(py2)s = %(py0)s.sha256_of
}(%(py3)s)
} == %(py8)srt   r!   )r<   r   r=   r?   rJ   zassert %(py10)spy10r   SCHEMA_PATHr   CRITERIA_PATH)rt   r]   r!   r\   r%   rS   r#   r$   r&   r'   r*   r+   ry   rz   )r.   ra   @py_assert7rb   ri   @py_format11s         r   5test_03_module_self_hasher_matches_pinned_not_trivialr}      sM    ;; ;{# v<( # (    # (                    #    #    $   (        ;; ;{# v3( # (    # (                    #    #    $   (        ;; ;}% 9* % *    % *                    %    %    &   *       r   c            
       	 t         d   	t        j                  d      } t        t              | _        	fd}d }t        | d|       t        | d|       t        j                  t              5  t        |        ddd       | j                  } |t              }t        t              }||k(  }|st        j                  d|fd	||f      d
t        j                          v st        j"                  |       rt        j$                  |       nd
t        j$                  |      dt        j                          v st        j"                  t              rt        j$                  t              ndt        j$                  |      dt        j                          v st        j"                  t              rt        j$                  t              nddt        j                          v st        j"                  t              rt        j$                  t              ndt        j$                  |      dz  }t        j&                  d      dz   d|iz  }t        t        j(                  |            dx}x}x}}y# 1 sw Y   xY w)a  Demonstrates the defect is closed.

    This stub is exactly what defeats +58 test_15's self-hash check:
    ``sha256_of`` simply returns whatever it is asked to look honest about.
    +58 test_15 would pass it (self-eq holds); the hardened guard MUST
    reject it.
    r   fake_plus58c                    	 t        j                  t        |       j                               j	                         S # t
        $ r cY S w xY wrs   )r   r   r   r   r   OSError)r   _pinneds    r   	_fake_shaz7test_04_mock_only_fail_stub_rejected.<locals>._fake_sha   sA    	>>$t*"7"7"9:DDFF 	N	s   9= A
Ac                
    ddiS )NverdictOPERATIONAL_PASSru   )_observation_kws     r   _fake_entrypointz>test_04_mock_only_fail_stub_rejected.<locals>._fake_entrypoint   s    -..r   r]   rG   Nr@   )zo%(py5)s
{%(py5)s = %(py2)s
{%(py2)s = %(py0)s.sha256_of
}(%(py3)s)
} == %(py10)s
{%(py10)s = %(py7)s(%(py8)s)
}stubr!   r   )r<   r   r=   r?   rC   rJ   rx   uE   stub self-hash trivially equals disk hash — the +58 mock-guard holez
>assert %(py12)spy12)r\   types
ModuleTypestrr!   r8   setattrpytestraisesr*   rk   r]   r   r%   rS   r#   r$   r&   r'   rT   r+   )
r   r   r   r.   ra   @py_assert9rb   r|   @py_format13r   s
            @r   $test_04_mock_only_fail_stub_rejectedr      s    IJGM*D$DM/ D+y)D02BC	~	& ,%d+,
 >> >+& *:;*G &*GG   &*G                    &    &    '      +;    +;      <G    <G    +H    	P     , ,s   /I--I7c                 2   t        j                  t        j                  d            } ddddd| d   d}t        j                  |      }|d   }t        j                  }||k(  }|st        j                  d	|fd
||f      t        j                  |      dt        j                         v st        j                  t              rt        j                  t              ndt        j                  |      dz  }dd|iz  }t        t        j                  |            d x}x}}|d   }dg}||k(  }|slt        j                  d	|fd||f      t        j                  |      t        j                  |      dz  }	dd|	iz  }
t        t        j                  |
            d x}x}}t        j                  ddddddddd      }|d   }t        j                  }||k(  }|st        j                  d	|fd||f      t        j                  |      dt        j                         v st        j                  t              rt        j                  t              ndt        j                  |      dz  }dd|iz  }t        t        j                  |            d x}x}}|d   }d}||k(  }|slt        j                  d	|fd||f      t        j                  |      t        j                  |      dz  }	dd|	iz  }
t        t        j                  |
            d x}x}}y )Nr
   r   task-2553+58F0683510-FBTvalid_non_blocking_mark)task_idfallback_cron_idfallback_boundnormal_callback_durable_successnormal_success_unchangedregistry_non_blocking_markr   r@   )z8%(py1)s == %(py5)s
{%(py5)s = %(py3)s.OPERATIONAL_PASS
}rt   )rB   r=   r?   zassert %(py7)srC   satisfied_criterionb)z%(py1)s == %(py4)s)rB   r   zassert %(py6)sr   ztask-2553+50C7359B43FDUPLICATE_CALLBACK_IGNORED)r   r   r   r   r   cancel_on_success_appliedfallback_firedfallback_handling)z@%(py1)s == %(py5)s
{%(py5)s = %(py3)s.OPERATIONAL_QUALITY_FAIL
}reasonDUPLICATE_IGNORED_ONLY_NO_MARK)jsonloads
FIX58_PATH	read_textrt   rG   r   r%   rS   r'   r#   r$   r&   r*   r+   OPERATIONAL_QUALITY_FAIL)fix58obsvr/   ra   r^   r`   r3   rh   rj   r2   v2s               r   9test_05_real_entrypoint_behavioral_regression_criterion_br      s   JJz++W+=>E!)+/$(&+,E&FC 	
&&s+AY<-1---<-----<----<------1---1-----------"#,u,#u,,,,#u,,,#,,,u,,,,,,,	
	'	'% *"/3(,)."!=		

B i=6A666=66666=6666=666666A666A66666666666h<;;;<;;;;;<;;;;<;;;;;;;;;;;r   c            
        t         D  ci c]  } | t        t        | z         }} t        j	                         D ci c]  \  }}|t        |       }}}t        t               t        j                  dddddddd       t         D  ci c]  } | t        t        | z         }} t        j	                         D ci c]  \  }}|t        |       }}}||k(  }|st        j                  d|fd||f      dt        j                         v st        j                  |      rt        j                  |      ndd	t        j                         v st        j                  |      rt        j                  |      nd	d
z  }dd|iz  }	t        t        j                  |	            d }||k(  }|st        j                  d|fd||f      dt        j                         v st        j                  |      rt        j                  |      nddt        j                         v st        j                  |      rt        j                  |      ndd
z  }dd|iz  }	t        t        j                  |	            d }y c c} w c c}}w c c} w c c}}w )Nr   r   TF)r   r   r   r   r   r   r   r@   rP   
pre_anchorpost_anchorrQ   zassert %(py4)sr   pre_58post_58)FROZEN_ANCHORSr   	WORKSPACErp   itemsrk   rt   rG   r%   rS   r#   r$   r&   r'   r*   r+   )
ar   rpr   r   r   r.   r1   rj   s
             r   'test_06_plus58_and_frozen_anchors_byte0r      s   >LM!%i!m44MJM1>1D1D1FGAa!!$$GFG!!$""% -"/3(,)-#	

 @NN!1&y1}55NKN2?2E2E2GH$!Qq"1%%HGH$$$$:$$$$$$:$$$:$$$$$$$$$$$$$$$$W6W66WW% NG OHs   I4I9	I?<Jc                    t        j                  ddt        t              ddgddd      j                  j                         } t        j                  ddt        t              ddgddd      j                  j                         }t        d	   d
   }| |k(  }|st        j                  d|fd| |f      d
t        j                         v st        j                  |       rt        j                  |       nd
t        j                  |      dz  }dd|iz  }t        t        j                  |            d x}}t        d	   d   }||k(  }|st        j                  d|fd||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      dz  }dd|iz  }t        t        j                  |            d x}}y )Ngitz-Cz	rev-parseHEADT)capture_outputtextcheckbranchz--show-currentgit_invariantheadr@   rM   r;   zassert %(py5)sr?   )
subprocessrunr   r   stdoutstrip
HARDEN_FIXr%   rS   r#   r$   r&   r'   r*   r+   )r   r   r^   r.   r_   r`   s         r   !test_07_git_head_branch_unchangedr     sA   >>	c)nk6:$d fUUW 	 ^^	c)nh0@A$d fUUW  o.v664666664666666646664666666666660::6:::::6:::::::6:::6:::::::::::r   __main__z-q)r   r   returnr   )r   None)5__doc__
__future__r   builtinsr#   _pytest.assertion.rewrite	assertionrewriter%   r   importlib.utilr   rZ   r   r   sysr   pathlibr   r   r8   rU   parentr   r!   TEST58_PATHrz   ry   r   HARDEN_FIX_PATHr   rp   r   r   r   r\   r   r6   rt   rk   markparametrizesortedrq   rv   r}   r   r   r   r   rW   exitmainru   r   r   <module>r      sp  &N #        
   N""$++2299	NNSSMMEEEE
NN ;F?J1<7D2< TZZ1171CD
	O	$9
 .Qd } 56 7%
 !J<>,
; zCHH[V[[(D)*+ r   