Backing up one step. The ONLY time 'window_safe' (and likewise the majority of the above discussion) is an issue is when using pipeline AND when factors are used as inputs to other factors.
When using any of the built in datasets as inputs, the input data is dutifully adjusted each day to be the data one would have seen on that day. It's really sort of a three step process. First the data is fetched, then it's adjusted, then it is fed to the compute method of any factors.
Adjusting the data is not a trivial process. As an example, prices are divided by the split ratios (ie a 2:1 split will divide the price by 2), however volumes are multiplied by the split ratio (ie a 2:1 split will multiply the volume by 2). Zipline takes care of adjusting the data BEFORE feeding the data into any pipeline factors. The data is always adjusted as of the simulation date.
So far so good...
Now we get to using factors as inputs to other factors. While the built in datasets are dutifully adjusted for splits and dividends, zipline/pipeline doesn't have a clue how to adjust an arbitrary input (such as a custom factor). Does it multiply? Does it divide? Does it do some other funky math? So, it doesn't do anything. (Well I suppose technically it does something. It throws an error if window_safe isn't set to True). In any case, it's really now a two step process. Fetch all the data and send the data to the compute method of the factors. No intermediate adjusting. It doesn't try to 'adjust' it because it doesn't know how to. It just thinks of it as raw data. That's what's happening in the notebook example above.
@Grant, I wouldn't think in terms of 'lagging' a pipeline factor or 'effective simulation' dates. That's complicating it too much. First, one concept which may not be apparent, is that a factor ALWAYS has the same output(s) when run on a specific day. One could run the factor standalone in a notebook or in the IDE or as an input to another factor, and it will ALWAYS output the same value(s) for a specific day. It's like static dictionary. On this date this is the factor output. Period.
Now, when using factors as inputs there are just two steps. First, the factor output is computed. (Remember the output is a fixed series of dates and associated outputs -one date - one output.) Second, this output is passed to the compute method of the other factor. No adjusting is done. ''Factor_N_Days_Ago" is really only taking the fixed output from the input factor (which is a series of dates and the associated output) and 'looking up' the output from 2 days ago. It's not any more complicated than that.
Hope that helps?