fson runs no file-watcher thread — that is platform-specific and an application policy. Instead, snapshot after loading and probe later.

static std::set<std::string> Fson::dependenciesOf( std::string const& filename );

static Snapshot Fson::snapshot( std::string const& filename );

enum class StaleMode { MtimeSize, ContentHash };
static bool Fson::isStale( std::string const& filename,
                           Snapshot const& snapshot,
                           StaleMode mode = StaleMode::MtimeSize );

All three cover the whole dependency set — the host file plus every file reachable through %include, transitively. A missing host yields an empty result; nothing throws.

dependenciesOf

The file set to register with your OS watcher, computed without keeping a document. Same list as LoadResult::dependencySet.

snapshot / isStale

auto result = Fson::load( "config.fson" );
auto snap   = Fson::snapshot( "config.fson" );

// ... on a timer or an OS file event ...
if( Fson::isStale( "config.fson", snap, StaleMode::ContentHash ) )
{
  result = Fson::load( "config.fson" );
  snap   = Fson::snapshot( "config.fson" );   // re-snapshot after reload
}
StaleModeCostBare touch (same bytes)
MtimeSizestat onlycounts as stale
ContentHashre-reads every file (FNV-1a)not stale

Either mode also catches a deleted dependency and an include-graph change (a %include added or removed, even with identical file contents). One snapshot serves either mode.

Snapshot::empty() reports whether the host was missing; Snapshot::files() lists the canonical paths it covers.