
    j              
      V   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
e
j                  j                  dd       ddlZde	j                  d<   ddlmZ g dZd	d
difddddfddddfddddddfddddfddddfgZdi fddd ifdddifd!i fddd"ifd dd"ifd#d$d%d&ifgZ G d' d(      Zy))u(  Tests for v3.6 Harness — regression: safe commands must remain ALLOW.

chair_authorization_id=CHAIR-AUTH-TASK-2703-V36-HARNESS-MVP-260528

DoD #7: existing safe commands must not be blocked (false-positive prevention).
Also covers edge cases: None input, empty dict, malformed tool_input, etc.
    )annotationsNz/home/jay/workspace1ANU_V36_HARNESS_TEST_MODE)evaluate)-zpython3 -m pytestzpython3 -m pytest tests/ -vz#python3 -m pytest tests/harness/ -vz.pytest tests/harness/test_v36_harness_rules.pyzpytest --tb=shortz
git statuszgit log --oneline -10zgit log --format='%H %s' -5zgit diff HEAD~1zgit diffzgit diff --statzgit show HEADz
git branchzgit branch -azgit fetch originzgit remote -vzgh pr view 158zgh pr view 158 --json statez
gh pr listzgh pr list --state opengh run view 12345zgh run listzgh issue view 100zgh issue listz2cat /home/jay/workspace/memory/events/task-2703.mdz#cat /home/jay/.claude/settings.jsonzls -la /home/jay/workspacez+ls /home/jay/workspace/scripts/harness/v36/z7grep -r 'evaluate' /home/jay/workspace/scripts/harness/zDgrep 'matched_rule' /home/jay/workspace/scripts/harness/v36/guard.pyz9head -20 /home/jay/workspace/scripts/harness/v36/rules.pyz6wc -l /home/jay/workspace/scripts/harness/v36/rules.pyz1python3 -c "import json; print(json.loads('{}'))"zpython3 -c "print('hello')"zecho 'test output'z+find /home/jay/workspace/tests -name '*.py'zwhich python3zenv | grep ANUzgit log --all --onelinezgit stash listzgit tagzpip listzpython3 --versionzmkdir -p /tmp/test-harness-dirzcp /tmp/test.py /tmp/test2.pyRead	file_path0/home/jay/workspace/scripts/harness/v36/guard.pyGlobz**/*.py)patternpathGrepr   LSPhoverzguard.py   )	operationfilePathline	characterTaskzcheck somethingbash)descriptiontypeWebFetchzhttps://example.comzwhat is this?)urlpromptBashcommand Writels)r   NUnknownTool	arbitraryvalc                     e Zd Zej                  j                  de      d        Zej                  j                  de      d        Z	ej                  j                  de
      d        Zd Zd Zd Zd	 Zd
 Zd Zd Zd Zd Zy)TestSafeCommandsAllowcmdc                   t        dd|ii       }|d   }d}||k(  }|st        j                  d|fd||f      t        j                  |      t        j                  |      dz  }t        j                  d|d	|d   d
|j                  d      d|j                  d            dz   d|iz  }t        t        j                  |            d x}x}}y )Nr   r   decisionALLOW==z%(py1)s == %(py4)spy1py4z)REGRESSION: Safe command blocked!
  cmd: 
  decision: 	
  rule: matched_rulez
  reason: reason
>assert %(py6)spy6r   
@pytest_ar_call_reprcompare	_saferepr_format_assertmsggetAssertionError_format_explanation)selfr'   d@py_assert0@py_assert3@py_assert2@py_format5@py_format7s           @/home/jay/workspace/tests/harness/test_v36_harness_regression.pytest_safe_bash_command_allowsz3TestSafeCommandsAllow.test_safe_bash_command_allowsd   s    Vi-r2} 	
 	
}' 	
 	
} 	
 	
 
	  	
 	
 
	 !( 	
 	
 W Z=+ ,uu^,/ 0x+	-	
 	
 	
 	
 	
 	
    ztool_name,tool_inputc                   t        ||i       }|d   }d}||k(  }|st        j                  d|fd||f      t        j                  |      t        j                  |      dz  }t        j                  d|d|d|d   d	|j                  d
            dz   d|iz  }t        t        j                  |            d x}x}}y )Nr)   r*   r+   r-   r.   z'REGRESSION: Safe tool blocked!
  tool: z

  input: r1   r2   r3   r5   r6   r7   )	r?   	tool_name
tool_inputr@   rA   rB   rC   rD   rE   s	            rF   test_safe_non_bash_tool_allowsz4TestSafeCommandsAllow.test_safe_non_bash_tool_allowso   s    Y
B/} 	
 	
}' 	
 	
} 	
 	
 
	  	
 	
 
	 !( 	
 	
  m $"~ &Z=+ ,uu^,/	1	
 	
 	
 	
 	
 	
rH   c                   	 t        ||i       }|d   }d}||k(  }|st        j                  d|fd||f      t        j                  |      t        j                  |      dz  }t        j                  d|d|d|d   d	|j                  d
            dz   d|iz  }t        t        j                  |            dx}x}}y# t        $ r(}	t        j                  d|d|d|	        Y d}	~	yd}	~	ww xY w)u3   Edge cases must never raise — fail-safe to ALLOW.r)   r*   r+   r-   r.   z%Edge case unexpectedly blocked: tool=z, input=z, decision=z, rule=r3   r5   r6   Nz"evaluate raised on edge case tool=z: )r   r8   r9   r:   r;   r<   r=   r>   	Exceptionpytestfail)
r?   rJ   rK   r@   rA   rB   rC   rD   rE   es
             rF   (test_edge_case_allows_and_does_not_raisez>TestSafeCommandsAllow.test_edge_case_allows_and_does_not_raisez   s   	gJ3AZ= G =G+  =G   I !   I %,    8	}HZN [jM,GAEE.4I3LN       	gKK<YMR\Q__abcadeff	gs   CC 	C5C00C5c                   	 t        dddid      }|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# t        $ r"}t        j                  d|        Y d}~yd}~ww xY w)zNone context must not raise.r   r   r!   Nr)   r*   r+   r-   r.   assert %(py6)sr6   z#evaluate raised with None context: 	r   r8   r9   r:   r=   r>   rN   rO   rP   r?   r@   rA   rB   rC   rD   rE   rQ   s           rF    test_none_context_does_not_raisez6TestSafeCommandsAllow.test_none_context_does_not_raise   s    	C)T!2D9AZ=+G+=G++++=G+++=+++G+++++++ 	CKK=aSABB	C   BB 	B=B88B=c                   	 t        dddid      }|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# t        $ r"}t        j                  d|        Y d}~yd}~ww xY w)z*Malformed context (string) must not raise.r   r   r!   zbad contextr)   r*   r+   r-   r.   rT   r6   Nz%evaluate raised with string context: rU   rV   s           rF   %test_malformed_context_does_not_raisez;TestSafeCommandsAllow.test_malformed_context_does_not_raise   s    	E)T!2MBAZ=+G+=G++++=G+++=+++G+++++++ 	EKK?sCDD	ErX   c                $   t        ddddi       }|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)z Writing .py files must be ALLOW.r    z3/home/jay/workspace/scripts/harness/v36/new_rule.pyz# coder	   contentr)   r*   r+   r-   r.   rT   r6   Nr   r8   r9   r:   r=   r>   r?   r@   rA   rB   rC   rD   rE   s          rF   test_write_to_py_file_allowsz2TestSafeCommandsAllow.test_write_to_py_file_allows   sk    O\de

 }''}''''}'''}''''''''''rH   c                $   t        ddddi       }|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)z:Writing .json files must be ALLOW (non-.done, non-report).r    z/home/jay/workspace/config.jsonz{}r\   r)   r*   r+   r-   r.   rT   r6   Nr^   r_   s          rF   test_write_to_json_file_allowsz4TestSafeCommandsAllow.test_write_to_json_file_allows   sj    ;M

 }''}''''}'''}''''''''''rH   c                &   t        dddddi       }|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)z Editing .py files must be ALLOW.Editr
   z	# commentz# updated comment)r	   
old_string
new_stringr)   r*   r+   r-   r.   rT   r6   Nr^   r_   s          rF   test_edit_to_py_file_allowsz1TestSafeCommandsAllow.test_edit_to_py_file_allows   sr    O)1
 
 }''}''''}'''}''''''''''rH   c                "   t        dddii       }|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)z'gh run view without --watch must ALLOW.r   r   r   r)   r*   r+   r-   r.   rT   r6   Nr^   r_   s          rF   %test_gh_run_view_without_watch_allowsz;TestSafeCommandsAllow.test_gh_run_view_without_watch_allows   sd    Vi)<=rB}''}''''}'''}''''''''''rH   c                "   t        dddii       }|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}}|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)z?git push to any branch is DENY per spec (all git push blocked).r   r   z#git push origin feature/test-branchr)   DENYr+   r-   r.   rT   r6   Nr3   zpattern.forbidden_tool_or_shellr^   r_   s          rF   &test_git_push_to_feature_branch_deniedz<TestSafeCommandsAllow.test_git_push_to_feature_branch_denied   s    Vi)NOQST}&&}&&&&}&&&}&&&&&&&&&& E$EE $EEEEE $EEEE EEE$EEEEEEEErH   c                ,   ddd}t        dddi|      }|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)z5finish-task.sh with sufficient code files must ALLOW.      )new_code_filesnew_md_filesr   r   z9bash /home/jay/workspace/scripts/finish-task.sh task-2703r)   r*   r+   r-   r.   rT   r6   Nr^   )r?   ctxr@   rA   rB   rC   rD   rE   s           rF   'test_finish_task_with_code_files_allowsz=TestSafeCommandsAllow.test_finish_task_with_code_files_allows   so    !"A6Vi)degjk}''}''''}'''}''''''''''rH   c                "   t        dddii       }|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)ztail without -f must ALLOW.r   r   ztail -20 /var/log/syslogr)   r*   r+   r-   r.   rT   r6   Nr^   r_   s          rF   test_tail_without_f_flag_allowsz5TestSafeCommandsAllow.test_tail_without_f_flag_allows   sd    Vi)CDbI}''}''''}'''}''''''''''rH   N)__name__
__module____qualname__rO   markparametrizeSAFE_BASH_COMMANDSrG   SAFE_NON_BASH_TOOLSrL   
EDGE_CASESrR   rW   rZ   r`   rb   rg   ri   rl   rs   ru    rH   rF   r&   r&   c   s    [[U$67
 8
 [[35HI
 J
 [[3Z@	g A	gCE((((
F((rH   r&   )__doc__
__future__r   builtins@py_builtins_pytest.assertion.rewrite	assertionrewriter8   ossysr   insertrO   environscripts.harness.v36.guardr   r{   r|   r}   r&   r~   rH   rF   <module>r      s   #   	 
 ( )  +.

& ' .1 h kMNO,ABC-BCD
'z1STUV.?@./JK  RLi_ibM	It)T	[%()	
g( g(rH   