claim_workbench_evidence_ledger
Forensic claim workbench â analyzes a folder of mixed
evidence (XER chain + MSG/PDF/DOCX/XLSX correspondence) and
produces a unified workbench dashboard.
Built from the real-world workflow where forensic delay
analysis starts from a folder containing schedule updates,
owner correspondence, RFIs, change orders, and meeting
minutes â all mixed together. The workbench produces:
- Evidence ledger (chronological): all artifacts dated and
summarized
- Schedule chain-diff: 14-category manipulation log
(TASKPRED add/remove, constraint flips, retroactive
baseline edits, completion reversals)
- Rolling baseline: per-activity baseline-at-introduction
across the entire XER chain
- Trust score: statistical impossibilities flagged
(zero-duration-variance schedules, no-new-activities,
every-activity-hits-baseline, etc.)
- Slip-to-evidence cross-reference: each forensic slip
auto-paired with documents in its window mentioning
affected activity codes
- Unified HTML dashboard with all of the above
Use this tool when starting forensic delay analysis from raw
evidence. For single-XER-pair forensic with hand-prepared
events, use ``forensic_windows_analysis`` instead.
Two input modes (supply exactly one):
* ``folder_path`` â the ``staged_folder_path`` that POST /stage
returned for YOUR upload, passed back exactly as received.
No other folder is accepted: not a desktop path, not the
server temp directory, not another folder inside it.
* ``evidence_files`` â a CONTENT MANIFEST: a list of
``{"name": str, "content_b64": str}`` entries carrying
base64-encoded file BYTES (handles binary PDF/XLSX/MSG as
well as text). The tool decodes each blob, sanitizes the
filename to a bare basename (rejecting path separators,
``..``, absolute/drive paths, control chars, dot-only
traversal), writes it into a FRESH per-call tempdir under
the allowed server-tempdir root, runs the analysis on that
staged folder, then cleans the staged dir up. Caps: at most
500 files and 60 MB total decoded bytes â an over-cap
manifest returns a clear ``tool_error`` naming the cap and
the actual size (NEVER silently truncated).
Args:
folder_path: the staged_folder_path from POST /stage
(mode 1; must be that exact folder and must exist).
evidence_files: content manifest (mode 2); list of
``{"name": str, "content_b64": str}``.
output_dir: optional dir for outputs (tempdir if "").
project_name: optional override.
original_baseline_xer_filename: optional filename in the
folder identifying the baseline XER.
contract_form: contract template tag (default 'CCDC2').
run_forensic: when True (default), also runs
forensic_windows_analysis on the discovered XER chain.
Returns:
{
"evidence_ledger": {...},
"chain_diff": {...} | None,
"rolling_baseline": {...} | None,
"trust_score": {...} | None,
"cross_reference": {...} | None,
"forensic_result": {...} | None,
"output_files": {...},
"errors": {...} (per-step failure log)
}
Input schema
{'type': 'object', 'title': 'claim_workbench_evidence_ledgerArguments', 'properties': {'output_dir': {'type': 'string', 'title': 'Output Dir', 'default': ''}, 'folder_path': {'type': 'string', 'title': 'Folder Path', 'default': ''}, 'project_name': {'type': 'string', 'title': 'Project Name', 'default': ''}, 'run_forensic': {'type': 'boolean', 'title': 'Run Forensic', 'default': True}, 'contract_form': {'type': 'string', 'title': 'Contract Form', 'default': 'CCDC2'}, 'evidence_files': {'anyOf': [{'type': 'array', 'items': {}}, {'type': 'null'}], 'title': 'Evidence Files', 'default': None}, 'original_baseline_xer_filename': {'type': 'string', 'title': 'Original Baseline Xer Filename', 'default': ''}}}
collapsed_as_built
Collapsed As-Built / But-For analysis on a post-impact XER.
Implements AACE RP 29R-03 §3.8 Modeled / Subtractive / Single
Base method (paired with MIP 3.3 Windows for the dual-method
gap report per SCL §11.5). Validates a forensic windows
analysis (MIP 3.3) by independently computing the same
project drift via subtractive removal of delays from the
as-built schedule.
For each delay event, the as-built duration of every
``affected_activity`` is shortened by ``impact_days`` working
days on that activity's calendar (or removed entirely if
``removal_method="remove"``), then CPM re-runs and the
resulting "but-for" finish date is compared to the as-built
finish. Cumulative pass removes ALL events at once for a
project-level but-for finish. Every finish shift is stated in
working days on ``workday_calendar``; the calendar-day span of
the same shift is kept beside it, and ``day_unit_basis`` names
the unit of every bare ``*_days`` key in the result.
Use this tool when opposing counsel demands a but-for analysis
or you need a dual-method validation pairing §3.3 (windows) with
§3.8 (collapsed-as-built). For prospective fragnet insertion
(MIP 3.7), use ``time_impact_analysis_fragnet`` instead.
Args:
as_built_xer_path: server-side post-impact XER (after delays incurred).
as_built_xer_content: full text of post-impact XER (alternative for hosted/remote use).
Supply EXACTLY ONE of path/content.
delay_events: list of event dicts. Each must have
``event_id``, ``affected_activities`` (list of
task_codes), and ``impact_days`` (number of working
days on the affected activity's calendar). Optional:
``removal_method`` ('shorten'|'remove'),
``responsible_party``, ``name``, ``description``.
output_dir: optional output dir for HTML/CSV (tempdir if "").
project_name: optional override.
removal_method: global default 'shorten' or 'remove'.
contractor_filter: when True, exclude contractor-caused
events from the cumulative pass (owner audit mode).
Returns:
{
"as_built_finish": "YYYY-MM-DD",
"per_event_results": [{event_id, but_for_finish,
impact_workdays_collapsed,
collapse_state,
duration_removal_basis,
finish_driver_after_removal, ...}, ...],
# impact_workdays_collapsed is the event's finish shift in
# working days on workday_calendar. Each event also carries
# impact_days_collapsed: the same shift in calendar days.
# duration_removal_basis discloses WHAT duration was removed
# and on what basis; finish_driver_after_removal discloses
# WHAT drives the but-for finish (incl. whether it is bound by
# the data-date floor) so a reader sees WHY the finish did or
# did not move across data dates.
"cumulative_but_for_finish": "YYYY-MM-DD",
"cumulative_impact_workdays": int, # working days on workday_calendar
"cumulative_impact_days": int, # the same shift in calendar days
"cumulative_collapse_state": str, # a 'locked_by_actuals' zero is not "no impact"
"workday_calendar": str, # the calendar every working-day figure is stated on
"day_unit_basis": dict, # each bare *_days key: 'working_days' or 'calendar_days'
"dual_method_gap": dict | None, # working days only
"output_files": {...},
"warnings": [...],
"method": "AACE 29R-03 §3.8 (Modeled/Subtractive/Single Simulation)"
}
Input schema
{'type': 'object', 'title': 'collapsed_as_builtArguments', 'properties': {'output_dir': {'type': 'string', 'title': 'Output Dir', 'default': ''}, 'delay_events': {'type': 'array', 'items': {'type': 'object', 'additionalProperties': True}, 'title': 'Delay Events', 'default': None}, 'project_name': {'type': 'string', 'title': 'Project Name', 'default': ''}, 'removal_method': {'type': 'string', 'title': 'Removal Method', 'default': 'shorten'}, 'as_built_xer_path': {'type': 'string', 'title': 'As Built Xer Path', 'default': ''}, 'contractor_filter': {'type': 'boolean', 'title': 'Contractor Filter', 'default': False}, 'as_built_xer_content': {'type': 'string', 'title': 'As Built Xer Content', 'default': ''}}}
concurrent_delay_matrix
Build the per-window x per-party concurrent-delay attribution
matrix from a chronological list of XER snapshots.
Implements the per-window concurrency view per AACE RP 29R-03
§3.3.I (apportionment) and §4.2 (concurrency). Where
``forensic_windows_analysis`` answers "how many days does each
party own across the whole project?", this tool answers "how did
each window distribute its shift across the parties?" â useful
when defending or attacking concurrency findings on a
window-by-window basis.
CPP conservation check, per the AACE 29R-03 §3.3.E.13
requirement that the summed per-period net impacts equal the
difference between the first schedule update and the last
schedule update used in the evaluation: the sum of per-party
column totals equals the sum of per-window completion shifts
within ±1 day of rounding. The column-total definition is this
tool's own bookkeeping, not an AACE rule. The ``conservation_check`` field on
the response reflects this; ``conservation_diff_days`` carries
the exact gap.
IMPORTANT â conservation is NOT attribution. ``conservation_check``
can be True (the columns sum to the grand total) even when 100% of
the shift lands in the Unattributed column, i.e. no party owns any
of the drift. Read ``unattributed_share_pct`` and
``high_unattributed_share_warning`` to know whether a meaningful
apportionment actually occurred. A fully-unattributed matrix
conserves perfectly but attributes nothing â never present its
green conservation check as a validated apportionment.
Use this tool when you only need the matrix view; use
``forensic_windows_analysis`` for the full claim.
Args:
schedules: chronologically ordered list of dicts â the SAME
shape ``forensic_windows_analysis`` accepts. Each dict
carries ``label`` (optional) and EXACTLY ONE of
``xer_content`` (full XER text, hosted/remote use) or
``xer_path`` (server-side path, local use). This is the
preferred input for hosted/remote clients.
xer_paths: legacy chronologically ordered list of server-side
XER file paths (local-server use).
xer_contents: legacy chronologically ordered list of XER text
contents. Each element is the full text of one XER.
Supply EXACTLY ONE of schedules / xer_paths / xer_contents
(lists must have at least 2 entries either way).
Returns:
{
"parties": ["Owner", "Contractor", "Concurrent",
"Force Majeure", "Unattributed"],
# Unit for every shift_* field and the grand totals. Always
# "working_days" â the matrix measures the completion shift
# in working days (Dana default). The *_calendar_days twins
# express the SAME shift in calendar days so an unlabeled
# "11" can never be mistaken for the 15-calendar-day value.
"shift_unit": "working_days",
"rows": [{ "window_label", "period_start", "period_end",
# shift_days == shift_workdays (working days,
# legacy alias). shift_calendar_days is the same
# shift in calendar days; shift_basis names the
# finish driver the shift was measured on.
"shift_days", "shift_unit", "shift_workdays",
"shift_calendar_days", "shift_basis",
"parties": {party: days},
"cascade_inferred": bool }, ...],
"column_totals": {party: days},
"grand_total_shift": int, # working days (legacy)
"grand_total_shift_workdays": int,
"grand_total_shift_calendar_days": int | None,
"conservation_check": bool,
"conservation_diff_days": int,
# Disambiguates "conserved AND attributed" from "conserved
# but entirely Unattributed". unattributed_share_pct is
# |Unattributed| / sum|shift| as a percent; the warning
# flips True when that share is dominant (>= 50%).
"unattributed_share_pct": float,
"high_unattributed_share_warning": bool,
"standard": "AACE RP 29R-03 §3.3.I (apportionment) · §4.2 (concurrency)",
"data_date_corrections": the record of each update whose
data date was moved to its latest actual, and of a
baseline with actual dates after its data date
([] on clean files); each is also a data-quality
warning
}
Input schema
{'type': 'object', 'title': 'concurrent_delay_matrixArguments', 'properties': {'schedules': {'type': 'array', 'items': {'type': 'object', 'additionalProperties': True}, 'title': 'Schedules', 'default': None}, 'xer_paths': {'type': 'array', 'items': {'type': 'string'}, 'title': 'Xer Paths', 'default': None}, 'xer_contents': {'type': 'array', 'items': {'type': 'string'}, 'title': 'Xer Contents', 'default': None}}}
critical_path_validator
Critical-path validation, logic health, and DCMA-14
assessment of a Primavera P6 schedule.
Runs the CPP critical-path validator: checks for false
criticality, constraint-driven CP segments, open ends, broken
logic, and surfaces a DCMA-14 block with the 14 metrics
(logic, leads, lags, FS%, hard constraints, high float, high
duration, invalid dates, resources, missed tasks, critical
tasks, CPLI, BEI, etc.) at the chosen profile threshold
(commercial / nuclear / mining). When ``baseline_xer_path``
is supplied, BEI (Baseline Execution Index) is computed.
Use this tool to grade a schedule's logic health and find what
should be fixed before forensic analysis. For the full HTML
health-dashboard PDF render, use ``dcma14_health_check``.
Args:
xer_path: server-side path to the schedule XER.
xer_content: full text of the schedule XER (alternative for
hosted/remote use). Supply EXACTLY ONE of path/content.
project_index: which project to analyze in a multi-project
XER (0 = first/primary; default).
profile: DCMA threshold profile -
'commercial' (default), 'nuclear', 'mining'.
baseline_xer_path: optional server-side baseline XER for DCMA BEI.
baseline_xer_content: optional baseline XER text content (alternative).
Returns:
Full validator result dict including:
- 'project_name', 'data_date', 'analysis_timestamp'
- 'total_activities', 'complete', activity counts
- 'critical_path_findings': list of issues
- 'logic_findings', 'constraint_findings'
- 'overall_rating' / 'overall_score' / 'overall_confidence':
LOGIC-HEALTH verdict only (open ends, logic continuity,
critical-path correctness, constraints, lags). NOT a full
schedule-health verdict.
- 'overall_rating_scope': always 'logic_health';
'overall_rating_label': 'Logic Health'. Use these so the
headline cannot be read as full DCMA schedule-health.
- 'dcma_worst_severity': the embedded DCMA-14 worst severity
(BLOCK/RED/WARN/INFO/PASS) surfaced at the top level so a
DCMA hard stop is visible next to the logic-health rating
rather than buried in dcma_14.report.summary.
- 'dcma_blocks_despite_logic_rating': True when DCMA-14 says
BLOCK/RED even if the logic-health headline reads GREEN/AMBER.
- 'dcma_14': dict of 14 DCMA metric results
- 'recommendations': list of remediation suggestions
Input schema
{'type': 'object', 'title': 'critical_path_validatorArguments', 'properties': {'profile': {'type': 'string', 'title': 'Profile', 'default': 'commercial'}, 'xer_path': {'type': 'string', 'title': 'Xer Path', 'default': ''}, 'xer_content': {'type': 'string', 'title': 'Xer Content', 'default': ''}, 'project_index': {'type': 'integer', 'title': 'Project Index', 'default': 0}, 'baseline_xer_path': {'type': 'string', 'title': 'Baseline Xer Path', 'default': ''}, 'baseline_xer_content': {'type': 'string', 'title': 'Baseline Xer Content', 'default': ''}}}
dcma14_health_check
Full Schedule Health Dashboard HTML report â DCMA-14 + CPLI
+ BEI + variance/slip register against the baseline.
Wraps the CPP Schedule Health Review skill, which produces a
self-contained ~1.3 MB HTML dashboard. The dashboard renders
DCMA metrics, charts, baseline-vs-current variance, slip
register, GAO/AACE compliance bands, and a reproducibility
manifest.
Baseline XER is OPTIONAL as of Round 7 (Fix MCP-8). When
omitted, the tool runs in "degraded mode": the current XER
is used as its own baseline for a synthetic 0-variance run.
The result carries ``degraded_mode: true`` and
``degraded_mode_reason`` explaining that BEI / variance /
slip register KPIs are NOT meaningful in this mode. Supply
baseline_xer_path or baseline_xer_content to get the real
two-XER variance dashboard.
REQUIRES Node + Playwright on the server (the dashboard renders
via headless Chromium). The tool returns a clear error if
either prerequisite is missing.
Use this tool when you need the formal HTML deliverable.
Do NOT treat ``critical_path_validator`` as a JSON view of this
tool. It runs a SECOND, independent DCMA-14 implementation
(``critical-path-validator/scripts/dcma14.py``) with its own
criterion numbering, its own activity-eligibility rules and its
own CPLI definition. Measured across the real-export corpus on
2026-08-25, the two engines return different verdicts on
individual criteria for the same XER, and on some criteria they
differ by construction on every file. Two separate DCMA-14
implementations, neither derived from the other. Cite one
engine per matter and name which. If what you wanted was the
JSON shape of THESE numbers, it is already in this tool's own
return: ``dcma_14``, ``metrics`` and ``headline`` are extracted
verbatim from the HTML this call produced, so they cannot
disagree with the deliverable the client is reading.
=== HOW TO PASS THE XER FILES ===
For each XER (current, baseline) you supply EXACTLY ONE of:
- ``*_xer_path`` â filesystem path on the server. Use this
when the MCP server runs locally and the
file is already accessible to it.
- ``*_xer_content`` â full text of the XER file as a string.
Use this when calling a HOSTED MCP server
from your local Claude â the server has no
access to your local filesystem, so you
must send the content over the wire. The
server writes it to a tempfile, runs the
pipeline, and cleans up afterward.
If both are supplied for the same XER, content wins (the path
is ignored). If neither is supplied, the call returns an error.
Args:
current_xer_path: server-side path to the current XER.
baseline_xer_path: server-side path to the baseline XER.
current_xer_content: full text of the current XER (alternative).
baseline_xer_content: full text of the baseline XER (alternative).
output_path: optional output HTML path. Ignored when content
is supplied (output goes to a tempdir alongside).
timeout_seconds: per-step Playwright timeout (default 120s).
A floor: for the parse and download waits the server
applies a deadline grown from the activity count of the
XERs supplied, so large schedules need no larger value.
debug: pipe Playwright stderr / browser console to stderr.
return_html_inline: when True (default), the generated HTML
is read off disk and returned as ``html_content`` in the
response. Required for hosted/remote use; set False to
save bandwidth when calling a local server where you can
open ``html_path`` directly.
Returns:
{
"ok": True,
"html_path": "absolute path on the server",
"html_content": "<!DOCTYPE html>..." (when return_html_inline),
"current_xer": "...",
"baseline_xer": "...",
# ââ Deliverable headline â the SAME figures the HTML
# renders in its header / gauge / DCMA footer
# ("GRADE C · 69% · YELLOW"). Extracted verbatim from the
# dashboard's embedded payload; NOT recomputed here. These
# are the authoritative grade for citing the deliverable.
"grade": "C", # letter grade A-F (or None)
"health_score": 69, # gauge percent = round(PASS/SCORED*100)
"status_band": "YELLOW", # GREEN | YELLOW | RED
"headline": { # full block (None if absent)
"grade": "C", "grade_label": "Acceptable",
"health_score": 69, "health_score_exact": 68.75,
"status_band": "YELLOW",
"passed": int, "failed": int, "scored": int,
"not_scored": int,
"basis": "health_score = round(passed / scored * 100); "
"scored excludes not-scored criteria",
},
# NOTE: result["health_score"] (the gauge percent) and
# dcma_14.summary.pass_rate are now the SAME ratio on the
# SAME basis â PASS / SCORED, where SCORED excludes the
# unscored (status "NONE" / pass:null) criteria. So
# round(dcma_14.summary.pass_rate * 100) == health_score
# (e.g. 0.692 â 69), matching the HTML "69% compliance".
# (Before 2026-06-28 pass_rate divided by total-criteria â
# 9/14 = 0.643 â and silently contradicted the 9/13 = 69%
# dashboard; that is the report-safety bug this fixed.) Cite
# `health_score` / `grade` / `status_band` for the headline;
# use dcma_14.summary for the raw criterion tallies.
"dcma_14": { # â sibling of html_content;
# same dict SHAPE as
# critical_path_validator's block.
# The VALUES are this engine's and
# are not interchangeable with that
# tool's â see the note above.
"criteria": {1: {...}, 2: {...}, ...},
# Each criterion carries `scored` (bool) and a TRI-STATE
# `pass`:
# "scored": True/False â did the dashboard reach a
# PASS/FAIL/WARN verdict? False means the criterion
# was NOT evaluated (e.g. C10 Resources when the
# TASKRSRC section is absent; status "NONE").
# "pass": True â scored and PASSED
# "pass": False â scored and FAILED/WARNED
# "pass": null â NOT scored (no verdict). null is
# distinct from false: to count failed criteria,
# filter pass == False (or scored == True and not
# pass), NOT pass != True â an unscored criterion is
# not a failure. `summary.fail` already excludes it.
# `scored` = pass + fail + warn (the dashboard's
# denominator); `pass_rate` = pass / scored, NOT
# pass / total. `unscored` (status NONE) is excluded from
# `scored`. In degraded mode `not_applicable` counts the
# baseline-dependent criteria excluded from the score and
# `degraded: true` + `degraded_note` are stamped inline.
"summary": {"total": int, "scored": int, "pass": int,
"fail": int, "warn": int, "unscored": int,
"pass_rate": float | None},
},
"metrics": { # â DEPRECATED â alias for dcma_14
# DEPRECATED. Identical payload to `dcma_14`. Retained
# for backward-compat with clients written against the
# pre-Round-4 schema. New code should read `dcma_14`.
# The `deprecated_alias_for` key is set on every
# response to make migration explicit. This key may be
# removed in a future major version.
"deprecated_alias_for": "dcma_14",
"criteria": {1: {...}, 2: {...}, ...},
"summary": { # identical payload to dcma_14.summary
"total": int, "scored": int, "pass": int,
"fail": int, "warn": int, "unscored": int,
"pass_rate": float | None,
},
}
}
On error: {"error": "..."}
Note: the inline HTML payload can be ~1.3 MB. Some MCP transport
stacks have request/response size limits (typically 5-20 MB).
For very large XERs / very long dashboards, this may fail at the
transport layer; in that case set ``return_html_inline=False``
and arrange to fetch the file from ``html_path`` separately.
Input schema
{'type': 'object', 'title': 'dcma14_health_checkArguments', 'properties': {'debug': {'type': 'boolean', 'title': 'Debug', 'default': False}, 'output_path': {'type': 'string', 'title': 'Output Path', 'default': ''}, 'timeout_seconds': {'type': 'integer', 'title': 'Timeout Seconds', 'default': 120}, 'current_xer_path': {'type': 'string', 'title': 'Current Xer Path', 'default': ''}, 'baseline_xer_path': {'type': 'string', 'title': 'Baseline Xer Path', 'default': ''}, 'return_html_inline': {'type': 'boolean', 'title': 'Return Html Inline', 'default': True}, 'current_xer_content': {'type': 'string', 'title': 'Current Xer Content', 'default': ''}, 'baseline_xer_content': {'type': 'string', 'title': 'Baseline Xer Content', 'default': ''}}}
monte_carlo_p50_p80
Monte Carlo Schedule Risk Analysis â P10/P50/P80/P90
completion-date forecast for a Primavera P6 schedule.
Implements an AACE-style quantitative SRA (the same math as
CPP's browser Tool_11 Portfolio Risk Engine, scripted Python
counterpart). For each iteration, every activity duration is
sampled from the chosen distribution (Triangular, BetaPERT,
Uniform, Lognormal, etc.) parameterized by % of baseline
duration; CPM re-runs and the project finish date is recorded.
After all iterations, P10/P50/P80/P90 completion dates and a
sensitivity tornado (per-activity correlation to project
finish) are reported.
Use this tool when you need probabilistic completion forecasts
or a tornado/sensitivity ranking. For the QRAMM-aligned
five-level maturity badge (AACE 122R-22) on the result,
pipe the response into
``qramm_maturity``.
Args:
xer_path: server-side path to the schedule XER.
xer_content: full text of the schedule XER (alternative for
hosted/remote use). Supply EXACTLY ONE of path/content.
iterations: number of MC iterations (default 5000).
distribution: 'Triangular', 'BetaPERT', 'Uniform',
'Lognormal' (case-insensitive â passed through).
optimistic_pct, most_likely_pct, pessimistic_pct: %
of baseline duration for the distribution params
(defaults: 85 / 100 / 120).
seed: optional fixed seed for reproducibility (0 = system
entropy = non-reproducible).
output_dir: optional output dir; tempdir if "".
Returns:
Full SRA result dict, key paths:
- 'baseline.percentiles': lowercase p-keys
{'p10','p25','p50','p75','p80','p85','p90','p95'},
each {'day', 'date'}. NOTE: keys are lowercase â read
result['baseline']['percentiles']['p80'], not 'P80'.
- 'baseline.config': sim params used
- 'baseline.sensitivity': per-activity tornado rows
- 'risk_register_simulation.percentiles' (only when a
risk_register is supplied): SAME lowercase convention,
{'p10','p50','p80','p90'} each {'day', 'date'}.
- 'project_name', 'data_date', ...
- HTML / DOCX paths if outputs emitted
Input schema
{'type': 'object', 'title': 'monte_carlo_p50_p80Arguments', 'properties': {'seed': {'type': 'integer', 'title': 'Seed', 'default': 0}, 'xer_path': {'type': 'string', 'title': 'Xer Path', 'default': ''}, 'iterations': {'type': 'integer', 'title': 'Iterations', 'default': 5000}, 'output_dir': {'type': 'string', 'title': 'Output Dir', 'default': ''}, 'xer_content': {'type': 'string', 'title': 'Xer Content', 'default': ''}, 'distribution': {'type': 'string', 'title': 'Distribution', 'default': 'Triangular'}, 'optimistic_pct': {'type': 'number', 'title': 'Optimistic Pct', 'default': 85.0}, 'most_likely_pct': {'type': 'number', 'title': 'Most Likely Pct', 'default': 100.0}, 'pessimistic_pct': {'type': 'number', 'title': 'Pessimistic Pct', 'default': 120.0}}}
slip_velocity
Per-window slip velocity & acceleration trend across XER snapshots.
Computes three signed metrics per window from the underlying
forensic windows analysis:
- slip_velocity_days_per_day: completion shift / window
duration (positive = slipping, negative = recovering).
Numerator is the WORKING-day completion shift. The
denominator is WORKING days between the prior and later
data dates on the same calendar
(``window_duration_workdays``), making this a same-day-type
working-day/working-day rate. It falls back to CALENDAR days
only for legacy window dicts that predate that field, and
such a row is flagged ``velocity_basis="wd/cd"``. Read
``velocity_basis`` to know which denominator produced the
figure.
Each velocity field name states the ratio it holds:
``slip_velocity_workdays_per_workday`` (populated only on
the wd/wd path), ``slip_velocity_workdays_per_calendar_day``
(working-days of slip per CALENDAR day elapsed, computed
against ``window_duration_days``), and
``slip_velocity_days_per_day`` as the retained back-compat
name for whichever basis was selected. Quote ``basis`` in
any expert report.
NOTE (2026-09-03): the two named fields are no longer equal.
``slip_velocity_workdays_per_calendar_day`` used to be a
blind copy of the headline velocity, which made its name
wrong once the denominator moved to working days â it read
5/10 = 0.500 while its name promised 5/14 = 0.357. It now
holds the calendar-day rate it is named for.
- slip_acceleration: velocity[n] - velocity[n-1] (positive
= slip rate increasing, negative = decelerating/recovery)
- half_period_estimated_slip_days: shift / 2 (forensic
"where were we at the midpoint" centroid estimate), in
WORKING days
Cumulative aggregates ``mean_velocity_days_per_day`` plus a
mean per basis â ``mean_velocity_workdays_per_workday`` and
``mean_velocity_workdays_per_calendar_day`` â each computed
only from the rows that actually carry that denominator, so a
mean is never labelled with a basis it did not use (None when
no window carried it). ``velocity_basis_set`` lists the bases
present and ``velocity_units`` describes them, including an
explicit MIXED string when a run spans both.
Also ``max_velocity_window`` and accelerating / decelerating /
recovery window counts.
Honest caveats embedded in the response (mandatory for expert
reports): midpoint estimates are probabilistic centroids, not
observed events; velocity is per-window average, not
instantaneous; acceleration is a finite difference, not a true
second derivative.
Built on top of AACE RP 29R-03 §3.3 windows analysis. Use this
tool when you want a slip-rate trend line on top of the same
per-window math ``forensic_windows_analysis`` already computes.
Args:
schedules: chronologically ordered list of dicts â the SAME
shape ``forensic_windows_analysis`` accepts. Each dict
carries ``label`` (optional) and EXACTLY ONE of
``xer_content`` or ``xer_path``. Preferred input for
hosted/remote clients.
xer_paths: legacy chronologically ordered list of server-side
XER paths.
xer_contents: legacy chronologically ordered list of XER text
contents (alternative for hosted/remote use).
Supply EXACTLY ONE of schedules / xer_paths / xer_contents
(at least 2 entries).
Returns:
{
"rows": [{window_label, period_start, period_end,
window_duration_days, shift_days, shift_workdays,
shift_calendar_days,
velocity_basis,
slip_velocity_days_per_day,
slip_velocity_workdays_per_workday,
slip_velocity_workdays_per_calendar_day,
velocity_field,
velocity_units, slip_acceleration,
acceleration_units, midpoint_estimate_date,
half_period_estimated_slip_days,
half_period_estimated_slip_workdays,
half_period_units}, ...],
"cumulative": {mean_velocity_days_per_day,
mean_velocity_workdays_per_workday,
mean_velocity_workdays_per_calendar_day,
velocity_basis_set,
velocity_units, max_velocity_window,
accelerating_windows,
decelerating_windows,
recovery_windows},
"units": "working-days of slip per working-day elapsed"
" (wd/cd fallback wording on legacy windows;
" MIXED when a run spans both)",
"basis": "<numerator/denominator day-type disclosure>",
"standard": "AACE RP 29R-03 §3.3 (Windows Analysis)",
"caveat": "...",
"data_date_corrections": the record of each update whose
data date was moved to its latest actual, and of a
baseline with actual dates after its data date
([] on clean files); each is also a data-quality
warning
}
Input schema
{'type': 'object', 'title': 'slip_velocityArguments', 'properties': {'schedules': {'type': 'array', 'items': {'type': 'object', 'additionalProperties': True}, 'title': 'Schedules', 'default': None}, 'xer_paths': {'type': 'array', 'items': {'type': 'string'}, 'title': 'Xer Paths', 'default': None}, 'xer_contents': {'type': 'array', 'items': {'type': 'string'}, 'title': 'Xer Contents', 'default': None}}}
time_impact_analysis_fragnet
Time Impact Analysis (TIA) â prospective fragnet insertion
into a pre-impact baseline schedule. Supports two modes.
**Single-base mode** (legacy): supply ``baseline_xer_path`` or
``baseline_xer_content``. All fragnets are inserted into the
same shared baseline XER and impact is measured against that
shared baseline. The result carries a
``single_base_disclosure`` warning explaining this is an AACE
29R-03 §3.7 simplification â acceptable when all events share
a single baseline window, but not strict MIP 3.7 Multiple
Base.
**Multi-base mode** (AACE 29R-03 MIP 3.7 Multiple Base):
supply ``per_event_bases`` â a dict keyed by each fragnet's
``id``, with each value a dict containing EITHER
``xer_path`` OR ``xer_content`` for that event's
pre-event contemporaneous baseline. Each fragnet is inserted
into its OWN base, impact is measured against THAT base's
pre-event finish, and the result carries
``per_event_methodology``, ``per_event_base_count``, and
``per_event_bases_used`` (sha256-truncated content hashes for
audit reproducibility). The cumulative-impact figure carries
``cumulative_caveat`` because the sum of events measured
against different bases is NOT a valid joint impact.
Exactly ONE of {baseline_xer_path, baseline_xer_content,
per_event_bases} must be supplied. Multi-base mode errors out
(returning ``{"error": ...}``) if any fragnet id is missing
from ``per_event_bases``.
Use this tool when modeling delay impact prospectively (e.g.
quantifying RFI / change-order delay before settlement). For
retrospective windows analysis after the fact, use
``forensic_windows_analysis`` (MIP 3.3 windows).
Args:
baseline_xer_path: server-side pre-impact baseline XER
(single-base mode).
baseline_xer_content: full text of pre-impact baseline XER
(single-base mode, hosted/remote use).
per_event_bases: dict {fragnet_id: {"xer_path": "..."}
OR {"xer_content": "<full XER text>"}}
for AACE MIP 3.7 Multiple Base mode.
Example::
{
"F1": {"xer_path": "/tmp/bl_pre_F1.xer"},
"F2": {"xer_content": "<XER text>"},
}
fragnets: list of fragnet dicts. Each must have:
- 'id', 'name', 'liability' (responsible party)
- 'activities': list of {code, name, duration_days,
clndr_id?}
(clndr_id is the P6 calendar id, CALENDAR.clndr_id.
This tool schedules on a uniform timeline that walks
no calendar, so it does not change the result here.)
- 'ties': list of {pred, succ, type, lag_days?}
Optional: 'description'.
output_dir: output dir for TIA_Report.txt + CSV (tempdir if "").
project_name: optional override.
Returns:
{
"report": path to TIA_Report.txt,
"impacts_csv": path to TIA_Impact_Details.csv,
"baseline": {"project_finish", "critical_count", ...},
"per_fragnet": [{fragnet_id, name, liability,
completion_before, completion_after,
impact_days, impact_working_days,
affected_activities, status, error}, ...],
"cumulative_days": int (sum of per-fragnet impacts),
"cumulative_basis": str (BOTH modes â states the cumulative
figure is the sum of independent
per-fragnet impacts and overstates joint
impact when fragnets share a path),
"per_event_methodology": str (canonical label),
"per_event_base_count": int (count of unique base XERs),
"per_event_bases_used": {fragnet_id: sha256_hash8} (multi-base only),
"single_base_disclosure": str (single-base only),
"cumulative_caveat": str (multi-base only),
}
Input schema
{'type': 'object', 'title': 'time_impact_analysis_fragnetArguments', 'properties': {'fragnets': {'type': 'array', 'items': {'type': 'object', 'additionalProperties': True}, 'title': 'Fragnets', 'default': None}, 'output_dir': {'type': 'string', 'title': 'Output Dir', 'default': ''}, 'project_name': {'type': 'string', 'title': 'Project Name', 'default': ''}, 'per_event_bases': {'type': 'object', 'title': 'Per Event Bases', 'default': None, 'additionalProperties': True}, 'baseline_xer_path': {'type': 'string', 'title': 'Baseline Xer Path', 'default': ''}, 'baseline_xer_content': {'type': 'string', 'title': 'Baseline Xer Content', 'default': ''}}}
Changed
collapsed_as_built
Sept. 29, 2026, 2:51 a.m.
Changed
slip_velocity
Sept. 29, 2026, 2:51 a.m.
Changed
concurrent_delay_matrix
Sept. 29, 2026, 2:51 a.m.
Changed
forensic_windows_analysis
Sept. 29, 2026, 2:51 a.m.
Changed
claim_workbench_evidence_ledger
Sept. 23, 2026, 2:42 a.m.
Changed
time_impact_analysis_fragnet
Sept. 23, 2026, 2:42 a.m.
Added
xer_parser
Sept. 17, 2026, 12:41 p.m.
Added
claim_workbench_evidence_ledger
Sept. 17, 2026, 12:41 p.m.
Added
qramm_maturity
Sept. 17, 2026, 12:41 p.m.
Added
monte_carlo_p50_p80
Sept. 17, 2026, 12:41 p.m.
Added
path_explorer
Sept. 17, 2026, 12:41 p.m.
Added
dcma14_health_check
Sept. 17, 2026, 12:41 p.m.
Added
critical_path_validator
Sept. 17, 2026, 12:41 p.m.
Added
time_impact_analysis_fragnet
Sept. 17, 2026, 12:41 p.m.
Added
collapsed_as_built
Sept. 17, 2026, 12:41 p.m.
Added
slip_velocity
Sept. 17, 2026, 12:41 p.m.
Added
woet_classifier
Sept. 17, 2026, 12:41 p.m.
Added
concurrent_delay_matrix
Sept. 17, 2026, 12:41 p.m.
Added
forensic_windows_analysis
Sept. 17, 2026, 12:41 p.m.