Run forensic windows analysis (AACE RP 29R-03 §3.3, MIP 3.3
Observational / Dynamic / Contemporaneous As-Is) across
multiple Primavera P6 XER snapshots and return the full analysis
dict.
This is the headline forensic tool — it computes per-window
completion shifts, per-window slip registers (per-activity slip
with critical/non-critical flag), per-window duration growth on
critical-path activities, per-window per-party attribution
(Owner / Contractor / Concurrent / Force Majeure / Unattributed),
and cumulative project drift from baseline. The attribution math
satisfies the AACE 29R-03 §4.1 conservation rule (per-party day
buckets sum to project drift within ±1 day, no cascade-double-
counting).
Use this tool for the full multi-window forensic claim. If you
already have a windows result and only want the per-window ×
per-party grid view, call ``concurrent_delay_matrix`` instead.
Args:
schedules: list of dicts in chronological order. Minimum 2
entries (baseline + at least one update). Each dict
must contain ``label`` (str) and EXACTLY ONE of:
- ``xer_path`` — server-side filesystem path, OR
- ``xer_content`` — full XER text content.
Use ``xer_content`` when calling a hosted MCP server
from a remote client whose XER lives locally.
project_name: optional override; auto-picked from XER if "".
baseline_idx: which entry in ``schedules`` is the contract
baseline (default 0 = first one).
entitlement_milestone: optional task_code (e.g.
"Ready for Takeover") — recorded on the result, not used
for math.
output_dir: optional dir for HTML dashboard / DOCX report.
If "", a tempdir is used and dropped after — the
dashboard / report paths in the response will point to
the temp location (caller responsible for moving them).
Returns:
{
"analysis": full dict from run_windows() with keys:
"windows", "cumulative", "baseline_label", "data_dates",
"attribution_summary", "mcpm_attribution", ...,
"dashboard": path to HTML dashboard (server-side),
"report": path to DOCX executive report (server-side),
"baseline_stability": {"worst_severity", "has_block", ...}
}
On failure: {"error": "..."} with no schedules processed.