@@ -25,6 +25,42 @@ pub(crate) fn watch_recursive_mutations(
2525 Some ( watcher)
2626}
2727
28+ /// Watch only declaration inputs for the supervisor. Runtime state (PTY registry, bus, logs,
29+ /// locks, inboxes, and generated materializations) must never wake reconciliation.
30+ pub ( crate ) fn watch_catalog_declarations (
31+ root : & Path ,
32+ tx : Sender < ( ) > ,
33+ ) -> Option < notify:: RecommendedWatcher > {
34+ let root = root. to_path_buf ( ) ;
35+ let callback_root = root. clone ( ) ;
36+ let mut watcher = notify:: recommended_watcher ( move |result : notify:: Result < Event > | {
37+ if result. is_ok_and ( |event| {
38+ is_mutation ( & event)
39+ && event
40+ . paths
41+ . iter ( )
42+ . any ( |path| is_declaration_path ( & callback_root, path) )
43+ } ) {
44+ let _ = tx. send ( ( ) ) ;
45+ }
46+ } )
47+ . ok ( ) ?;
48+ watcher. watch ( & root, RecursiveMode :: Recursive ) . ok ( ) ?;
49+ Some ( watcher)
50+ }
51+
52+ fn is_declaration_path ( root : & Path , path : & Path ) -> bool {
53+ let rel = path. strip_prefix ( root) . unwrap_or ( path) ;
54+ let mut components = rel. components ( ) ;
55+ if matches ! (
56+ components. next( ) . and_then( |c| c. as_os_str( ) . to_str( ) ) ,
57+ Some ( "_templates" )
58+ ) {
59+ return true ;
60+ }
61+ path. file_name ( ) . and_then ( |n| n. to_str ( ) ) == Some ( "agent.kdl" )
62+ }
63+
2864fn is_mutation ( event : & Event ) -> bool {
2965 matches ! (
3066 event. kind,
@@ -60,6 +96,31 @@ mod tests {
6096 }
6197 }
6298
99+ #[ test]
100+ fn declaration_filter_ignores_runtime_state ( ) {
101+ let root = Path :: new ( "/catalog" ) ;
102+ assert ! ( is_declaration_path(
103+ root,
104+ Path :: new( "/catalog/team/agent.kdl" )
105+ ) ) ;
106+ assert ! ( is_declaration_path(
107+ root,
108+ Path :: new( "/catalog/_templates/base.kdl" )
109+ ) ) ;
110+ assert ! ( !is_declaration_path(
111+ root,
112+ Path :: new( "/catalog/pty/session.json" )
113+ ) ) ;
114+ assert ! ( !is_declaration_path(
115+ root,
116+ Path :: new( "/catalog/bus/inbox/msg" )
117+ ) ) ;
118+ assert ! ( !is_declaration_path(
119+ root,
120+ Path :: new( "/catalog/team/rendered.kdl" )
121+ ) ) ;
122+ }
123+
63124 #[ cfg( target_os = "linux" ) ]
64125 #[ test]
65126 fn linux_reads_are_silent_but_real_mutations_wake ( ) {
0 commit comments