@@ -1504,11 +1504,30 @@ def repo_worktree_fingerprint(target: Path) -> str | None:
15041504 return localio .stable_hash (sorted (lines ))
15051505
15061506
1507- def _bash_write_detected (target : Path , baseline : object ) -> bool :
1507+ def _bash_write_detected (
1508+ target : Path ,
1509+ baseline : object ,
1510+ * ,
1511+ session_id : str ,
1512+ started_at : object ,
1513+ ) -> bool :
15081514 if not isinstance (baseline , str ) or not baseline :
15091515 return False
15101516 current = repo_worktree_fingerprint (target )
1511- return current is not None and current != baseline
1517+ if current is None or current == baseline :
1518+ return False
1519+ started = localio .parse_iso_datetime (started_at )
1520+ if started is None :
1521+ return True
1522+ for other_state in iter_session_states (target , limit = MAX_RECENT_SESSION_STATES ):
1523+ if other_state .get ("session_id" ) == session_id :
1524+ continue
1525+ if other_state .get ("write_observed" ) is not True or other_state .get ("repo_fingerprint" ) != current :
1526+ continue
1527+ other_write = localio .parse_iso_datetime (other_state .get ("last_write_at" ))
1528+ if other_write is not None and other_write >= started :
1529+ return False
1530+ return True
15121531
15131532
15141533def _session_fingerprint (session_id : str ) -> str :
@@ -1570,6 +1589,9 @@ def _normalize_state(target: Path, session_id: str, payload: dict[str, Any] | No
15701589 pending_fp = payload .get ("pending_bash_fingerprint" )
15711590 if isinstance (pending_fp , str ) and pending_fp :
15721591 normalized ["pending_bash_fingerprint" ] = pending_fp
1592+ pending_started = localio .parse_iso_datetime (payload .get ("pending_bash_started_at" ))
1593+ if pending_started is not None and pending_started <= now :
1594+ normalized ["pending_bash_started_at" ] = pending_started .isoformat ()
15731595 denied = payload .get ("verify_denied_count" )
15741596 if isinstance (denied , int ) and not isinstance (denied , bool ) and denied >= 0 :
15751597 normalized ["verify_denied_count" ] = denied
@@ -1662,6 +1684,7 @@ def handle_payload(event: str, payload: dict[str, Any]) -> dict[str, Any] | None
16621684 baseline = repo_worktree_fingerprint (target )
16631685 if baseline is not None :
16641686 state ["pending_bash_fingerprint" ] = baseline
1687+ state ["pending_bash_started_at" ] = localio .utc_now_iso ()
16651688 write_session_state (target , session_id , state )
16661689 if not is_raw_verification (command ):
16671690 return None
@@ -1699,7 +1722,12 @@ def handle_payload(event: str, payload: dict[str, Any]) -> dict[str, Any] | None
16991722 tool_name == "Bash" and _is_confident_bash_write (post_tool_input .get ("command" ))
17001723 )
17011724 if not wrote and tool_name == "Bash" :
1702- wrote = _bash_write_detected (target , state .get ("pending_bash_fingerprint" ))
1725+ wrote = _bash_write_detected (
1726+ target ,
1727+ state .get ("pending_bash_fingerprint" ),
1728+ session_id = session_id ,
1729+ started_at = state .get ("pending_bash_started_at" ),
1730+ )
17031731 if wrote :
17041732 state ["write_observed" ] = True
17051733 written_at = localio .utc_now_iso ()
@@ -1713,9 +1741,11 @@ def handle_payload(event: str, payload: dict[str, Any]) -> dict[str, Any] | None
17131741 if updated_fp is not None :
17141742 state ["repo_fingerprint" ] = updated_fp
17151743 state .pop ("pending_bash_fingerprint" , None )
1744+ state .pop ("pending_bash_started_at" , None )
17161745 write_session_state (target , session_id , state )
17171746 elif state .get ("pending_bash_fingerprint" ) is not None :
17181747 state .pop ("pending_bash_fingerprint" , None )
1748+ state .pop ("pending_bash_started_at" , None )
17191749 write_session_state (target , session_id , state )
17201750 return None
17211751
0 commit comments