Critical Path Partners
Server Details
Primavera P6 XER forensic scheduling: AACE windows, TIA, impacted as-planned, DCMA-14, Monte Carlo.
- Status
- Healthy
- Uptime
- 100.0% over the last 24 hours
- Last Tested
- Transport
- Streamable HTTP · MCP 2025-11-25
- URL
- Repository
- danafitkowski/cpp-cpm-engine
- GitHub Stars
- 0
- ChatGPT
- –
- Claude
- –
TDQS
Scored across 14 tools
Each tool's description explicitly states its forensic method (AACE 29R-03 MIP 3.3/3.6/3.7/3.8) and names the sibling tool to use instead, which resolves most overlap by design. Residual ambiguity remains because concurrent_delay_matrix, slip_velocity, and claim_workbench_evidence_ledger are all derived views that internally re-run the same windows math as forensic_windows_analysis, and impacted_as_planned vs time_impact_analysis_fragnet both insert fragnets (differing only by MIP variant and base handling).
All 14 names are lowercase snake_case with a consistent noun-phrase style (collapsed_as_built, forensic_windows_analysis, woet_classifier, xer_parser), so the convention is predictable even though there is no verb_noun pattern. Minor outliers are the long claim_workbench_evidence_ledger and the numeric monte_carlo_p50_p80, which mixes a metric range into the name.
14 tools sit squarely in the well-scoped 3-15 range for a forensic delay-analysis server. Each tool maps to a distinct AACE method, a validation surface, or a supporting utility, with no redundant filler.
The surface covers the full AACE 29R-03 method spectrum (windows, TIA single/multi-base, IAP, collapsed as-built), DCMA-14 from two engines, SRA plus QRAMM maturity, per-day execution classification, and XER ingestion. Minor gaps: no standalone risk-register builder to feed monte_carlo_p50_p80, no raw row-level XER export/query path, and no claim-narrative assembly tool outside the per-analysis dashboards.
Available Tools
14 toolsclaim_workbench_evidence_ledgerAInspect
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 "").
company: optional, the firm the dashboard, the trust report and the forensic step carry (title
block, print cover). Blank unless supplied, and blank
carries no firm: a hosted run is the caller's document.
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)
}
| Name | Required | Description | Default |
|---|---|---|---|
| company | No | ||
| output_dir | No | ||
| folder_path | No | ||
| project_name | No | ||
| run_forensic | No | ||
| contract_form | No | CCDC2 | |
| evidence_files | No | ||
| original_baseline_xer_filename | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations supplied, the description carries the full burden and does most of the work: it discloses filename sanitization rules, the per-call tempdir lifecycle (create, run, clean up), hard caps of 500 files / 60 MB with the promise of an explicit tool_error rather than silent truncation, and a per-step errors log. What it does not say is whether the source folder is read-only or mutated, what the runtime/scale looks like on a 500-file run, or any auth requirement, so it stops short of full behavioral disclosure.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The structure is strong — bolded mode headers, a bulleted output list, and an Args/Returns block that mirrors the schema — and the critical constraints are front-loaded. However, the 'Built from the real-world workflow where forensic delay analysis starts from a folder containing...' paragraph is narrative padding that restates the first sentence, and the company field's three-line parenthetical is written in a style that obscures rather than compresses.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For an 8-parameter, multi-mode orchestration tool with no output schema and no annotations, this is close to complete: it documents both input modes, the caps, the exact return keys (including nullable step results and an errors log), and the delegation to forensic_windows_analysis. The remaining hole is contract_form — an agent cannot tell which template tags are legal, so it must guess or accept the default.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% (bare titles and defaults only), so the Args block is the only parameter documentation and it covers all eight parameters, including the non-obvious run_forensic toggle and the strict semantics of folder_path. Gaps remain: contract_form gives only the default 'CCDC2' with no list of valid contract tags, output_dir's behavior is one parenthetical, and the company field's explanation is wordy without clarifying how a blank differs functionally from a supplied firm in the output.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource ('analyzes a folder of mixed evidence ... produces a unified workbench dashboard') and then enumerates the six concrete outputs, so an agent knows exactly what comes back. It also explicitly names the sibling it is not ('For single-XER-pair forensic with hand-prepared events, use forensic_windows_analysis instead'), which distinguishes it from the other 13 forensic tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It states the triggering condition ('Use this tool when starting forensic delay analysis from raw evidence') and the exclusion plus named alternative (forensic_windows_analysis). It also resolves the biggest ambiguity in the schema: the two mutually exclusive input modes, with the instruction 'supply exactly one' and how each mode must be sourced.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
collapsed_as_builtAInspect
Collapsed As-Built / But-For analysis on a post-impact XER.
Implements AACE RP 29R-03 §3.8 Modeled / Subtractive / Single
Simulation 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).
preparer / company: optional, printed on the dashboard and
narrative as who prepared the analysis. Both are blank
unless supplied.
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)"
}
| Name | Required | Description | Default |
|---|---|---|---|
| company | No | ||
| preparer | No | ||
| output_dir | No | ||
| delay_events | No | ||
| project_name | No | ||
| removal_method | No | shorten | |
| as_built_xer_path | No | ||
| contractor_filter | No | ||
| as_built_xer_content | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations exist, so the description carries the full burden, and it does substantial work: it discloses the mutation-like behavior (activity durations shortened by impact_days on that activity's calendar, or removed entirely), the cumulative pass semantics, contractor_filter's owner-audit behavior, and interpretability caveats ('locked_by_actuals' zero is not 'no impact'). Remaining gaps are operational rather than conceptual — it does not say what happens when a task_code in affected_activities is not found in the XER, nor whether the XER must be a validated/post-impact file, nor anything about runtime cost on large schedules.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Well structured and front-loaded: purpose, then method framing, then usage/exclusions, then Args, then Returns. It is long, and the middle methodological paragraph partly restates the Returns annotations (working-days vs calendar-days explanation appears in both places), which is mild redundancy. Given the domain complexity, the length is largely earned rather than padding.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
There is no output schema, but the description supplies a detailed Returns block covering as_built_finish, per_event_results with the diagnostic keys, cumulative results, dual_method_gap, output_files, warnings, and method. It also documents the unit disambiguation (day_unit_basis, workday_calendar) that would otherwise be a common source of misinterpretation, which is exactly the gap a missing output schema would leave.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% and the schema itself is nearly bare (only titles and defaults), so the Args block is doing all the work — and it documents all nine parameters, including the nested delay_events dict keys (event_id, affected_activities, impact_days, removal_method, responsible_party, name, description). It adds genuinely non-inferable meaning: 'Supply EXACTLY ONE of path/content', impact_days being in working days on the affected activity's calendar, removal_method per-event vs the global default, and contractor_filter as an exclusion switch for cumulative results.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific technique and resource ('Collapsed As-Built / But-For analysis on a post-impact XER') tied to a named standard (AACE RP 29R-03 §3.8) and explains the mechanism in one sentence (subtractive removal, CPM re-run, but-for finish compared to as-built). It also names the sibling it is NOT ('For prospective fragnet insertion (MIP 3.7), use time_impact_analysis_fragnet instead'), so an agent can disambiguate without opening schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit when-to-use ('when opposing counsel demands a but-for analysis or you need a dual-method validation pairing §3.3 (windows) with §3.8') and an explicit alternative with its selecting condition (fragnet insertion → time_impact_analysis_fragnet). It also specifies the paired-sibling relationship for the dual-method gap report, leaving little to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
concurrent_delay_matrixAInspect
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
}
| Name | Required | Description | Default |
|---|---|---|---|
| schedules | No | ||
| xer_paths | No | ||
| xer_contents | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does so richly: it explains the conservation check semantics, warns that conservation is NOT attribution, describes the unattributed_share_pct/high_unattributed_share_warning fields, flags data-date corrections as quality warnings, and cites the governing AACE standard. This is exactly the behavioral context an agent needs to interpret results correctly.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The purpose and the sibling routing are front-loaded in the first paragraph, and most length is justified return-value documentation. However, the Returns block is verbose, repeating legacy aliases (shift_days/shift_workdays/grand_total_shift) with considerable redundancy that could be tightened.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema and no annotations, the description explains the return shape in detail (parties, rows, column_totals, conservation fields, warnings) and covers usage, alternatives, and parameters. Nothing an agent needs to call or interpret the tool is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, so the description must compensate and does: it documents schedules, xer_paths, and xer_contents individually, states the EXACTLY-ONE constraint, notes the minimum of 2 entries, and explains the hosted/remote vs local use cases. This fully compensates for the undocumented schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource — building a per-window x per-party concurrent-delay attribution matrix from chronological XER snapshots — and explicitly distinguishes itself from forensic_windows_analysis by contrasting the questions each answers. An agent can tell it apart from its siblings without opening a schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states when to use this tool ('when you only need the matrix view') and names the alternative plus the condition selecting it ('use forensic_windows_analysis for the full claim'). It also explains the defensive/attack context on a window-by-window basis, leaving little to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
critical_path_validatorAInspect
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
| Name | Required | Description | Default |
|---|---|---|---|
| profile | No | commercial | |
| xer_path | No | ||
| xer_content | No | ||
| project_index | No | ||
| baseline_xer_path | No | ||
| baseline_xer_content | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the behavioral burden. It is highly transparent about output semantics, including that overall_rating is logic-health only, the DCMA worst severity is surfaced separately, and BLOCK/RED can appear despite a GREEN logic rating. It does not explicitly state whether the operation is read-only or mutates anything, but the validator/analysis framing strongly implies no side effects.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but well-organized with short paragraphs, an Args section, and a Returns bullet list. Each sentence contributes useful semantics for automation. It is slightly verbose in the return-field explanation but overall stays purposeful.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool has 6 unannotated parameters, no output schema, and high complexity with DCMA-14 metrics, the description provides a complete mental model: what inputs are accepted, how the analysis differs from a full DCMA check, the meaning of the rating scope, and the layout of the result. This is sufficient for an agent to select and invoke the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, and the description compensates exceptionally. It explains each of the six parameters, including the mutually exclusive xer_path/xer_content relationship, profile thresholds (commercial/nuclear/mining), and optional baseline inputs. It also details the return dictionary, filling the gap left by the absent output schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific action: validates critical-path logic, health, and DCMA-14 metrics for a Primavera P6 schedule. It clearly distinguishes this tool from sibling dcma14_health_check by positioning this one as logic-health grading and the other as a full HTML dashboard render.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit when-to-use context: 'Use this tool to grade a schedule's logic health and find what should be fixed before forensic analysis.' It also names the sibling alternative, dcma14_health_check, for the full HTML dashboard render, giving clear exclusion guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
dcma14_health_checkAInspect
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 CPP's other DCMA-14 engine
(``critical-path-validator/scripts/dcma14.py``). Since
7 November 2026 both engines, and CPP Lens, measure to one written
definition (``_cpp_common/references/DCMA_DEFINITION.md``,
published at criticalpathpartners.ca/dcma-14-definition.html),
and every engine's test suite checks it against the same
hand-worked parity fixtures, check by check and count by count.
They remain two programs with different outputs: this tool renders
the client deliverable and grades it A to F (CPP's convention, not
DCMA's, given only when at least 10 of the 14 are scored); the
validator returns passed of scored with its own critical-path
findings. 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; its .manifest.json
sidecar is written beside it. Left empty, both go in a new
folder of their own in the server temp directory.
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.
company: optional, the firm the report carries (title block,
print cover, closing). Blank unless supplied, and blank
carries no firm and reads its method notes without CPP:
a hosted run is the caller's document (9 November 2026).
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; None when fewer
# than 10 of the 14 are scored
"health_score": 69, # gauge percent = round(PASS/SCORED*100)
"status_band": "YELLOW", # GREEN | YELLOW | RED; None when not graded
"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,
"graded": bool, # False when fewer than 10 of 14 scored
"scored_of_14": 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.
# Both engines measure to the one
# DCMA definition — 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.
| Name | Required | Description | Default |
|---|---|---|---|
| debug | No | ||
| company | No | ||
| output_path | No | ||
| timeout_seconds | No | ||
| current_xer_path | No | ||
| baseline_xer_path | No | ||
| return_html_inline | No | ||
| current_xer_content | No | ||
| baseline_xer_content | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations supplied, the description carries the full behavioral burden and does so thoroughly: it discloses Node + Playwright prerequisites, clear errors when they are missing, optional baseline behavior, degraded-mode semantics, content-over-path precedence, output-path sidecar behavior, timeout handling, and inline HTML transport-size risks. It also clarifies result fields, including tri-state pass values and deprecated aliases, so an agent can interpret the response safely.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The definition is front-loaded with purpose and key warnings and is organized into clear sections, but it is substantially bloated. Historical bug notes, repeated deprecation warnings, and detailed migration commentary go beyond what an agent needs to select and invoke the tool correctly.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a complex, prerequisite-heavy report generator with no annotations and no output schema, the description is complete: it covers execution environment requirements, input alternatives, failure modes, degraded-mode interpretation, output paths, response contents, and transport limitations. An agent has enough information to call it correctly and to interpret the result without opening additional documentation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, but the description documents every one of the nine parameters with meaningful semantics: path versus content alternatives, precedence rules, output_path sidecar behavior, the timeout floor and adaptive deadline, debug output, return_html_inline bandwidth implications, and company branding behavior. This fully compensates for the bare input schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific deliverable — a Full Schedule Health Dashboard HTML report covering DCMA-14, CPLI, BEI, variance, and slip register — with enough specificity that the agent knows exactly what resource is produced. It explicitly distinguishes this tool from critical_path_validator, including why they are not interchangeable and when citing one versus the other matters.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It states when to use the tool ('when you need the formal HTML deliverable'), what not to assume about the sibling validator, and how to choose between *_xer_path and *_xer_content depending on local versus hosted MCP execution. It also explains optional baseline behavior and the degraded-mode consequences, which is exactly the when-to-use nuance an agent needs.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
forensic_windows_analysisAInspect
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 a critical flag (total float of zero or less, or the driving
path in a schedule with negative float)), 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 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 (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.
company: optional, the firm the dashboard and the DOCX report carry (title
block, print cover). Blank unless supplied, and blank
carries no firm: a hosted run is the caller's document.
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", ...},
"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
"analysis"."criticality_basis": the schedules read by
their driving path because they have negative float,
and those beside them ([] when no schedule has
negative float); the box they write is one
data-quality warning
}
On failure: {"error": "..."} with no schedules processed.
| Name | Required | Description | Default |
|---|---|---|---|
| company | No | ||
| schedules | Yes | ||
| output_dir | No | ||
| baseline_idx | No | ||
| project_name | No | ||
| entitlement_milestone | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations supplied, the description carries the full burden and does so well: it discloses the computed outputs, the CPP conservation check and tolerance, failure behavior, tempdir handling for output_dir when blank, and data-quality records such as baseline stability and data date corrections.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with purpose and usage, then follows a clear Args/Returns structure. It is unusually long but mostly earns its length through substantive detail; the conservation-check parenthetical is dense but relevant.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
This is a complex multi-parameter forensic computation with no output schema, so the description's explanation of return keys, error shape, and file-output behavior is essential and sufficiently complete for an agent to invoke it confidently.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate, and it documents every parameter including nested schedules requirements: chronological order, label, and exactly one of xer_path or xer_content. It also explains the optional fields baseline_idx, entitlement_milestone, company, and output_dir.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description gives a specific verb and resource, naming the AACE forensic windows method and its inputs. It explicitly distinguishes itself from the sibling tool concurrent_delay_matrix, so an agent can select it without opening other schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It states when to use this tool for the full multi-window forensic claim and names the exact alternative for the narrower per-window × per-party grid view. It also imposes the minimum-two-schedules requirement, leaving little inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
impacted_as_plannedAInspect
Impacted As-Planned (IAP) on an unprogressed as-planned baseline. Implements AACE RP 29R-03 MIP 3.6 (Modeled / Additive / Single Base) and SCL Protocol 2nd ed. §11.6(a). Two modes.
**screen** (default): inserts each delay fragnet into the
as-planned baseline, first one at a time and then all together,
re-runs CPM, and reads the joint impact against verdict bands
(NO SIGNAL, LOW SIGNAL, MODERATE SIGNAL, STRONG SIGNAL, or
INDETERMINATE when the joint pass fails). Use it as a quick read
on whether a delay claim has legs before a fuller analysis. The
sum of the one-at-a-time impacts is reported beside the joint
impact; ``overstatement_days`` is the difference, from fragnets
that share a path. Check each ``per_fragnet[].status`` before
quoting a figure: a fragnet that failed on its own carries
``status`` "error" and its ``error``, and is left out of the
one-at-a-time sum. The joint pass inserts every fragnet
together, so read ``joint.status`` and the "iap-joint" warnings
too: with a bad fragnet the joint pass can fail (verdict
INDETERMINATE) or run without the ties it could not insert.
**rebut**: tests an opposing expert's IAP submission. Supply at
least one of: ``opposing_impacted_xer_path`` or
``opposing_impacted_xer_content`` (tier A: re-runs their
impacted schedule and diffs it against the baseline),
``opposing["fragnets"]`` (tier B: re-models their fragnets on
the baseline), or ``opposing["claimed_impact_days"]`` (tier C:
their stated figure).
IAP does not look at what actually happened on site: it
measures the planned logic plus the inserted delays. The result
carries ``iap_method_caveat`` saying so, and a ``precondition``
block that flags a baseline carrying progress (not a pure
as-planned schedule). Every activity is laid out on one uniform
timeline with no weekends or holidays, each timeline day being
one working day of that activity's own calendar. Where every
unfinished activity is on one calendar, each impact is exact in
working days on it, apart from constraint dates and any stretch
before the data date, which the run places on the project's
default calendar. With more than one calendar, paths on
different calendars change length against each other on that
timeline, so float, the driving path and the impact can differ
from a calendar-aware run, and the impact is a mix of those
calendars' working days; the result lists the calendars
(``calendars_in_use``, and ``opposing_calendars_in_use`` for a
tier A file) and warns when there is more than one. The absolute
dates the run shows are not P6 calendar dates (``date_basis``):
quote the day counts, not the dates. For an impact measured on each event's own
contemporaneous baseline use ``time_impact_analysis_fragnet``
(MIP 3.7); for retrospective windows use
``forensic_windows_analysis`` (MIP 3.3); for a subtractive
but-for use ``collapsed_as_built`` (MIP 3.8).
Args:
baseline_xer_path: server-side as-planned baseline XER.
baseline_xer_content: full text of the as-planned baseline
XER (alternative for hosted/remote use).
Supply EXACTLY ONE of path/content.
fragnets: SCREEN (required): list of fragnet dicts, each
with ``id``, ``name``, ``liability`` (responsible
party), ``activities`` (list of {code, name,
duration_days}; duration_days in working days) and
``ties`` (list of {from_code, to_code, type, lag_days};
pred/succ are accepted aliases for from_code/to_code;
type is FS, SS, FF or SF in any case, with or without
P6's PR_ prefix; a missing type is FS and any other
type is refused).
mode: "screen" (default) or "rebut" (case does not matter).
opposing: REBUT: dict of the opposing material, with any of
``fragnets`` (same shape as above),
``claimed_impact_days`` (number), ``claimed_finish``
(YYYY-MM-DD), ``proj_id``, ``expert_name``,
``report_ref``. Other keys are refused. Pass the
opposing impacted schedule through the two arguments
below, not in this dict.
opposing_impacted_xer_path: REBUT tier A: server-side
opposing impacted XER.
opposing_impacted_xer_content: REBUT tier A: full text of
the opposing impacted XER.
Supply at most ONE of this
path/content pair.
own_results: REBUT, optional: your own results from the
primary methods in working days, {windows_days,
tia_days, collapsed_days}, read beside the opposing
figure.
proj_id: optional project selector inside a multi-project
baseline XER.
screen_bands: SCREEN, optional: verdict band overrides,
{low_pct, strong_pct, wd_floor_moderate}. Defaults
2.0, 5.0 and 20; low_pct must stay below strong_pct.
baseline_name / opposing_name: optional file names to
print in the report for XERs sent as content (a
content upload has no file name of its own).
preparer / company: optional, printed on the report and
dashboard as who prepared the analysis. Both are blank
unless supplied.
output_dir: output dir for the HTML dashboard, TXT report
and CSVs (tempdir if "").
project_name: optional override.
Limits for hosted use: 500 fragnets on each side, and 5,000
inserted activities and 20,000 ties across all of them.
Returns:
{
"mode": "screen" | "rebut",
"method": "Impacted As-Planned — AACE 29R-03 §3.6 / MIP 3.6 ...",
"baseline": {project_finish, plan_start,
baseline_duration_wd, critical_count, ...},
"precondition": {progressed_count, total_count,
pure_as_planned},
"per_fragnet": [{fragnet_id, status, error,
impact_days, impact_working_days, ...}], # SCREEN
"joint": {status, impact_days, impact_working_days, ...}, # SCREEN
"sum_isolated_days": int, # SCREEN
"sum_isolated_working_days": int, # SCREEN
"overstatement_days": int, # SCREEN: sum minus joint
"screen_verdict": {band, pct, joint_wd, bands_used, basis}, # SCREEN
"rebut": {...}, # REBUT: tiers A/B/C and findings
"critique": {...},
"iap_method_caveat": str,
"date_basis": str,
"day_unit_basis": str, # what every day count counts
"calendars_in_use": [str] | None, # None: could not be read
"opposing_calendars_in_use": [str] | None, # REBUT tier A
"output_files": {report, events_csv, dashboard, ...},
"warnings": [...],
"baseline_sha256": str, "baseline_sha256_basis": str,
"opposing_impacted_sha256": str, # REBUT tier A
"opposing_impacted_sha256_basis": str, # REBUT tier A
}
| Name | Required | Description | Default |
|---|---|---|---|
| mode | No | screen | |
| company | No | ||
| proj_id | No | ||
| fragnets | No | ||
| opposing | No | ||
| preparer | No | ||
| output_dir | No | ||
| own_results | No | ||
| project_name | No | ||
| screen_bands | No | ||
| baseline_name | No | ||
| opposing_name | No | ||
| baseline_xer_path | No | ||
| baseline_xer_content | No | ||
| opposing_impacted_xer_path | No | ||
| opposing_impacted_xer_content | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations supplied, the description carries the full burden and does so: it discloses the method's core limitation (IAP ignores as-built reality), the iap_method_caveat and precondition block emitted in the result, per-fragnet and joint failure semantics, calendar/timeline distortion effects, that displayed dates are not P6 calendar dates, and hosted limits (500 fragnets, 5,000 inserted activities, 20,000 ties).
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
It is front-loaded with the two modes and the sibling routing before the long Args block, and nearly every sentence carries operational information. It is nonetheless very long, with an embedded Returns tree that partly re-states fields discussed earlier in prose (overstatement_days, calendars_in_use), which is borderline duplication even without an output schema.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 16-parameter, nested, dual-mode analytical tool with no output schema and no annotations, the definition covers method caveats, preconditions, parameter constraints, failure modes, returned fields and artifact outputs. An agent can select a mode, assemble a valid call, and interpret the verdict bands without further information.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% across 16 parameters, so the description must compensate and does: it documents the EXACTLY-ONE constraint on baseline path/content, the at-most-one constraint on the opposing file pair, the nested fragnet dict shape (id, name, liability, activities, ties) and tie type normalization rules, the accepted keys of the opposing dict, and the meaning of screen_bands defaults.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names the specific method (Impacted As-Planned on an unprogressed as-planned baseline), the governing standards (AACE RP 29R-03 MIP 3.6, SCL Protocol §11.6(a)), and its two modes (screen, rebut). It also explicitly distinguishes itself from the sibling methods time_impact_analysis_fragnet (MIP 3.7), forensic_windows_analysis (MIP 3.3) and collapsed_as_built (MIP 3.8).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is spelled out per mode: 'screen' is framed as a quick read on whether a delay claim has legs, 'rebut' as testing an opposing expert's submission, with the minimum inputs required for each of tiers A/B/C. It goes further and routes the agent to alternative tools for contemporaneous-baseline, retrospective-window and subtractive but-for analyses.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
monte_carlo_p50_p80AInspect
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 "".
company: optional, the firm the dashboard carries (title
block, print cover). Blank unless supplied, and blank
carries no firm: a hosted run is the caller's document.
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
| Name | Required | Description | Default |
|---|---|---|---|
| seed | No | ||
| company | No | ||
| xer_path | No | ||
| iterations | No | ||
| output_dir | No | ||
| xer_content | No | ||
| distribution | No | Triangular | |
| optimistic_pct | No | ||
| most_likely_pct | No | ||
| pessimistic_pct | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does a fair amount: it explains the simulation mechanics, that seed=0 means system entropy and non-reproducible runs, that output_dir falls back to a tempdir, and that blank company carries no firm name in hosted runs. It omits operational traits an agent would want — expected runtime for 5000 iterations, whether the XER is read from server filesystem with what permissions, and whether HTML/DOCX emission is optional or automatic.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Purpose, usage routing, parameters, and return shape are front-loaded and cleanly sectioned, with the critical lowercase-key caveat called out in caps. The aside about being the Python counterpart of CPP's Tool_11 is slightly self-referential padding, and the Args block restates defaults already visible in the schema, but the structure still serves the reader.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a ten-parameter tool with no output schema and no annotations, the description fills both gaps: it documents every parameter and maps the exact return dict key paths, including the lowercase percentile convention and the conditional risk_register_simulation branch. An agent can construct a call and parse the response without opening anything else.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the docstring's Args block is the only parameter documentation and it covers all ten: the xer_path/xer_content mutual exclusivity ("Supply EXACTLY ONE"), the accepted distribution names and case-insensitivity, the percentage-of-baseline meaning of optimistic/most_likely/pessimistic with their defaults, and the seed semantics. It stops short of stating valid ranges (e.g. whether pessimistic_pct must exceed optimistic_pct) or what happens if both path and content are supplied.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The opening states a specific verb and resource — Monte Carlo schedule risk analysis producing P10/P50/P80/P90 completion-date forecasts for a Primavera P6 schedule — and the algorithm used (duration sampling plus CPM re-runs) is spelled out. It is clearly separable from siblings like dcma14_health_check or slip_velocity because the probabilistic forecast and tornado output are named.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives an explicit trigger ("Use this tool when you need probabilistic completion forecasts or a tornado/sensitivity ranking") and routes the agent to the correct follow-up tool (qramm_maturity) for the AACE 122R-22 maturity badge. It also implicitly excludes the deterministic siblings by framing this as the probabilistic path.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
path_explorerAInspect
Logic-trace driver-chain explorer — answers "WHY is this activity critical?" and "WHAT does it drive?".
Traces driving predecessors backward from a target activity to
project start (the "why critical" chain) and/or driving
successors forward to project finish (the "what it drives"
chain). Detects constraint-driven artificial criticality and
cites AACE RP 49R-06 when found. Supports multiple parallel
critical paths (MCPM) and near-critical paths.
Use this tool when investigating a single activity's logic
chain. For a project-wide CP / logic health audit, use
``critical_path_validator``.
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.
target_activity_codes: list of task_codes to trace; if
empty, all CP / near-critical endpoints are traced.
direction: 'backward' (predecessors), 'forward'
(successors), or 'both' (default).
include_near_critical: also trace near-critical endpoints
(within float band).
output_dir: optional dir for HTML / CSV / JSON outputs.
company: optional, the firm the dashboard carries (title
block, print cover). Blank unless supplied, and blank
carries no firm: a hosted run is the caller's document.
Returns:
{
"paths": [{chain dicts ...}],
"output_files": {dashboard, csv, json},
"project_finish": "YYYY-MM-DD",
"project_name": ...,
"data_date": ...
}
| Name | Required | Description | Default |
|---|---|---|---|
| company | No | ||
| xer_path | No | ||
| direction | No | both | |
| output_dir | No | ||
| xer_content | No | ||
| include_near_critical | No | ||
| target_activity_codes | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are supplied, so the description carries the full burden, and it discloses meaningful behavior: constraint-driven artificial criticality detection with an AACE RP 49R-06 citation, MCPM support, and near-critical band handling. It also reveals a side effect (files written via output_dir: dashboard, csv, json) and the exactly-one-of path/content constraint, though it omits failure behavior, cost/runtime, and any read-only/write framing for the output artifacts.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Well front-loaded: purpose, mechanics, sibling routing, then args and returns in a conventional order. The company parameter entry drifts into wordy editorializing ("blank carries no firm: a hosted run is the caller's document"), which is the one passage that does not earn its space.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the inline Returns block is necessary and present, listing paths, output_files, project_finish/name, and data_date. Arguments, alternatives, and the one-of input constraint are all covered; only error/empty-result behavior and permissions are absent, which is a modest gap for a 7-parameter analytical tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% across 7 parameters, and the description compensates almost completely: it documents xer_path vs xer_content with an "EXACTLY ONE" exclusivity rule, supplies the direction enum values the schema lacks, explains the empty-list default for target_activity_codes, and clarifies the float-band meaning of include_near_critical. This is genuine added meaning, not schema restatement.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with a specific verb+resource ("Logic-trace driver-chain explorer") and frames the exact questions it answers ("WHY is this activity critical?" / "WHAT does it drive?"), then names the actual traversal semantics (predecessors backward to project start, successors forward to finish). An agent can distinguish it from critical_path_validator without opening either schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly scopes the tool to "investigating a single activity's logic chain" and routes project-wide audits to the named sibling ``critical_path_validator``. The direction parameter documentation adds the sub-choice (backward/forward/both) that selects between the two trace modes.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
qramm_maturityAInspect
QRAMM-aligned maturity reading for an SRA result.
Places a Schedule Risk Analysis run (from
``monte_carlo_p50_p80`` or any equivalent dict) on the five
named maturity levels of AACE RP 122R-22 (Quantitative Risk
Analysis Maturity Model), section 3: level 1 Reactive,
level 2 Ad-hoc, level 3 Centralized, level 4 Dynamic,
level 5 Adaptive.
Inputs the SRA inspects (defensively, all keys optional):
- baseline.percentiles (lowercase p50 / p80 presence)
- baseline.config (iterations, opt/ml/pes %, distribution)
- baseline.sensitivity (per-activity tornado rows, on_cp)
- mitigated (scenario comparison evidence)
- risk_register_simulation + risk_register_used
(Hulett quantified risk register evidence)
- convergence (MC diagnostics, required for level 5)
Use this tool any time you have an SRA result and want a
maturity reading for a forensic-claim methodology section.
Note the scope limit the badge carries on every render: AACE
122R-22 assesses the quantitative-risk capability of an
ORGANIZATION and states it is guidelines rather than a
standard, so a reading on one simulation run is CPP's
placement on the RP's scale, not a QRAMM score. Report it as
"QRAMM-aligned", never as "per AACE 122R-22".
Args:
sra_result: dict from ``monte_carlo_p50_p80``. May be {} -
the badge degrades to level 1 with the missing
evidence listed.
Returns:
{
"rp_citation": "AACE RP 122R-22 ...",
"scale_max": 5,
"scale_note": "... names five levels ...",
"level": int (1-5),
"level_name": "Reactive" | "Ad-hoc" | "Centralized"
| "Dynamic" | "Adaptive",
"level_label": "Level 3: Centralized",
"level_description": what CPP requires of a run there,
"level_color": "#xxxxxx",
"evidence": ["..." what the SRA had / lacked],
"gaps_to_next_level": ["..." concrete advance steps],
"caveat": scope-limit string
}
The keys "tier", "tier_label", "tier_description",
"tier_color" and "gaps_to_next_tier" are retained as
aliases carrying the same five-level values.
| Name | Required | Description | Default |
|---|---|---|---|
| sra_result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description details the tool's behavior: it inspects specific fields (baseline.percentiles, baseline.config, etc.), degrades to level 1 for empty input, and outputs a structured result with evidence and gaps. It also explains the aliases in the return value. This provides comprehensive transparency beyond the simple schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with clear sections (purpose, usage, caveat, args, returns) but is somewhat verbose, repeating the level names and containing redundant phrasing. It could be tightened without losing essential information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity and the absence of an output schema, the description fully specifies the return structure, including all keys and their meaning, and the scope limitation. It also covers the input requirements and the degradation behavior, making it self-contained.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
For the single parameter sra_result, the description explains it is a dict from monte_carlo_p50_p80, may be empty, and that an empty dict results in level 1 with missing evidence listed. It also enumerates the specific subfields the tool inspects, greatly enriching the minimal schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's function: it 'Places a Schedule Risk Analysis run on the five named maturity levels of AACE RP 122R-22', naming the specific standard and levels. It distinguishes itself from sibling tools by focusing on maturity assessment rather than direct delay or risk analysis.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly says 'Use this tool any time you have an SRA result and want a maturity reading for a forensic-claim methodology section.' It also notes the input source (monte_carlo_p50_p80) and provides a scope-limit caveat, giving clear when-to-use guidance and context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
slip_velocityAInspect
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
}
| Name | Required | Description | Default |
|---|---|---|---|
| schedules | No | ||
| xer_paths | No | ||
| xer_contents | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral burden and does so unusually well: it discloses the working-day vs calendar-day denominator fallback and the velocity_basis flag for legacy windows, the None-when-absent rule for per-basis means, the MIXED units case, a data-quality warnings channel (data_date_corrections), and mandatory honesty caveats distinguishing centroids from observed events and finite differences from true derivatives.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The first line is a strong front-loaded summary and the Args/Returns blocks are well structured, but the body is bloated: the 2026-09-03 changelog paragraph about a past naming bug and the multi-paragraph re-derivation of each velocity field name read as internal documentation rather than invocation guidance. Substantive, but it could shed roughly a third of its length without losing decision-relevant information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no annotations, no output schema, and 0% schema description coverage, the description supplies essentially everything an agent needs: input shapes and exclusivity, the full returned field set, unit/basis semantics, and caveats. Nothing material for correct invocation or interpretation is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0% and all three params are undocumented in the schema, yet the description fully compensates: it defines the schedules dict shape (label plus EXACTLY ONE of xer_content/xer_path) and marks xer_paths/xer_contents as legacy alternatives, plus the mutual-exclusion rule and the minimum of 2 entries. This is more than the schema would have provided.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The opening line names the specific verb/resource ('slip velocity & acceleration trend across XER snapshots') and the following paragraph defines the three exact metrics computed. It explicitly distinguishes itself from the closest sibling: 'Use this tool when you want a slip-rate trend line on top of the same per-window math forensic_windows_analysis already computes,' so an agent can route between the two without opening either schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives an explicit when-to-use condition and names the alternative tool (forensic_windows_analysis) it builds on. It does not state when NOT to use it or mention the other forensic siblings (time_impact_analysis_fragnet, concurrent_delay_matrix), so routing guidance is clear but not exhaustive.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
time_impact_analysis_fragnetAInspect
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: one shared baseline is
AACE 29R-03 MIP 3.6 (Modeled / Additive / Single Base), not
MIP 3.7 Multiple Base; acceptable when all events share a
single baseline window.
**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). For an
impacted as-planned screen or rebuttal on the unprogressed
as-planned baseline (MIP 3.6), use ``impacted_as_planned``.
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.
preparer / company: optional, printed in the report header as
who prepared the analysis. Both are blank unless supplied.
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 (the method label, or why
nothing was measured),
"per_event_base_count": int (count of unique base XERs
read; 0 when none could be read),
"per_event_bases_used": {fragnet_id: sha256_hash8} (multi-base only),
"per_event_unread": [fragnet_id] (multi-base only: events
whose base could not be read, so not
measured),
"per_event_requested": int (multi-base only: every event
asked for),
"not_measured": bool (True when no base could be read: every
figure is 0 only because nothing was
measured, not a finding of no delay),
"single_base_disclosure": str (whenever every event
measured shared one base, MIP 3.6),
"cumulative_caveat": str (multi-base only),
}
| Name | Required | Description | Default |
|---|---|---|---|
| company | No | ||
| fragnets | No | ||
| preparer | No | ||
| output_dir | No | ||
| project_name | No | ||
| per_event_bases | No | ||
| baseline_xer_path | No | ||
| baseline_xer_content | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations the description carries the full burden and does so: it discloses the error path ({"error": ...} when a fragnet id is missing from per_event_bases), the file artifacts written (TIA_Report.txt + CSV), the not_measured flag semantics (zeros mean nothing was measured, not "no delay"), and the two disclosure strings (single_base_disclosure, cumulative_caveat) that warn when a figure is methodologically invalid. It also surfaces the audit-reproducibility hashes and the per_event_unread list, which an agent could not infer from any structured field.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the mode distinction and the mutual-exclusivity rule, then Args, then Returns, so an agent can stop reading early. The Returns block is lengthy, though that length is largely earned by the absence of an output schema; some of it (restating the cumulative caveat twice) could be tightened.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For an eight-parameter, nested-object, no-output-schema tool this covers everything an agent needs: which mode to pick, the exact dict shape per mode, the failure mode, and the semantics of every returned field including the ones that guard against misreading zeros or summing non-joint impacts. Nothing material is left to inference.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0% and the description fully compensates, documenting all eight parameters including the nested fragnet contract (required id/name/liability, activities with code/name/duration_days/clndr_id, ties with pred/succ/type/lag_days, optional description) and a worked per_event_bases example. It even explains that clndr_id is inert for this scheduler, which is meaning the schema cannot convey.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Names a specific technique and operation — prospective fragnet insertion into a pre-impact baseline XER — and enumerates the two execution modes (single-base vs AACE MIP 3.7 multiple-base) with the exact parameters each requires. The opening line alone distinguishes it from forensic_windows_analysis and impacted_as_planned without opening a schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit positive guidance ("modeling delay impact prospectively, e.g. quantifying RFI / change-order delay before settlement") and routes two named siblings to their own conditions (retrospective windows → forensic_windows_analysis; unprogressed as-planned rebuttal → impacted_as_planned). It also states the hard constraint that exactly one of the three baseline parameters must be supplied, which is the main invocation pitfall.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
woet_classifierAInspect
Worked-vs-On-time Execution Timeline (WOET) per-activity day-by-day classification of as-built execution against baseline.
For each pairable activity (matched by ``task_code``), classifies
execution into 4 day-states:
- PROGRESS: work performed during the baseline-planned window
- GAIN: work performed BEFORE the baseline window opened
- EXTENDED: work performed AFTER the baseline window closed
- VOID: baseline-window day where activity was NOT active
This is a CPP-disclosed enhancement layered on top of AACE
29R-03 §3.3 Windows Analysis — a per-day execution classifier
(Progress/Gain/Extended/Void) NOT itself AACE-defined. It is
not a substitute for fragnet-based AACE 29R-03 §3.7 (TIA)
modeling. It gives the trier-of-fact a calendar picture of
how the project executed versus how it was supposed to
execute, which is otherwise buried in finish-date deltas.
Use this tool when you want a per-activity execution-quality
picture (on-time %, count of activities with VOID days, etc.).
Args:
baseline_xer_path: server-side path to baseline XER (target dates).
actual_xer_path: server-side path to as-built XER (act dates).
baseline_xer_content: full text of baseline XER (alternative).
actual_xer_content: full text of as-built XER (alternative).
Supply EXACTLY ONE of path/content per pair.
today: optional ISO date (YYYY-MM-DD) reference
for in-progress activities. Defaults to actual XER's
last_recalc_date if available, else today's date.
Returns:
{
"method": "WOET",
"standard": "AACE 29R-03 §3.3 Windows Analysis — per-day execution classification overlay (CPP-disclosed enhancement, not AACE-defined)",
"today": "YYYY-MM-DD",
"project_totals": {progress, gain, extended, void},
"per_activity": [{code, name, baseline_start, ...,
"dominant": str ('progress'|'gain'|'extended'|'void'
or 'mixed' on a tie),
"dominant_tie": bool (True when 2+ states share the top
day count — do NOT assert one characterization),
"dominant_states": [tied top states, never truncated]},
...],
"on_time_pct": float (0-100)
}
| Name | Required | Description | Default |
|---|---|---|---|
| today | No | ||
| actual_xer_path | No | ||
| baseline_xer_path | No | ||
| actual_xer_content | No | ||
| baseline_xer_content | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden and excels. It discloses internal classification logic (PROGRESS/GAIN/EXTENDED/VOID), the 'dominant_tie' behavior, default handling for 'today', and the fact that it is a CPP-disclosed enhancement not AACE-defined. It also explains the return semantics in detail, leaving no ambiguity about side effects or default behaviors.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but well-structured with clear sections (states, context, usage, args, returns). Every section earns its place, but there is some redundancy, such as repeating the AACE 29R-03 §3.3 reference. A slightly tighter prose would earn a 5, but it is still sufficiently organized and front-loaded with a one-line summary.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (5 parameters, no output schema, no annotations), the description is exceptionally complete. It covers input constraints, output structure, default behavior, and conceptual positioning. The detailed Returns section compensates for the missing output schema, and the methodology context helps the agent assess suitability.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema provides no descriptions and marks no parameters required, but the description's Args section explains every parameter, including the rule to supply exactly one of path/content per pair. This adds critical meaning beyond the schema, clarifying alternative input methods and constraints.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states a specific verb-resource pair: 'per-activity day-by-day classification of as-built execution against baseline.' It further distinguishes itself from sibling tools by explicitly noting it is not a substitute for fragnet-based AACE 29R-03 §3.7 (TIA) modeling and provides a per-activity execution-quality picture.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly states when to use it: 'Use this tool when you want a per-activity execution-quality picture' and gives clear exclusions by stating it is 'not a substitute for fragnet-based AACE 29R-03 §3.7 (TIA) modeling.' This provides both positive and negative usage guidance, naming alternate approaches.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
xer_parserAInspect
Parse a Primavera P6 XER file and return a TABLE SUMMARY (not the full row-level data — XER row dumps explode the MCP context window).
For each table in the XER, returns the table name, field list,
and record count. Per-row data is intentionally omitted — for
forensic / DCMA / windows analysis use the dedicated tools
(``forensic_windows_analysis``, ``critical_path_validator``, etc.)
which consume the parsed XER internally and return analytical
summaries, not raw rows.
Use this tool to confirm an XER is parseable, list its tables, see
the data date / project name from PROJECT, or count activities in
TASK before deciding which deeper tool to run.
Args:
xer_path: server-side filesystem path to the XER file.
xer_content: full text of the XER file (alternative for
hosted/remote use). Supply EXACTLY ONE of path/content.
Returns:
{
"filepath": absolute path,
"encoding_used": "utf-8" | "cp1252" | ...,
"ermhdr": file header dict (P6 version, export user, etc.),
"tables": [{"name", "fields", "record_count"}, ...],
"table_count": int,
"total_records": int,
"project_summary": {
"proj_id", "proj_short_name", "proj_long_name",
"data_date", "plan_end_date"
} (from first PROJECT row, if any)
}
| Name | Required | Description | Default |
|---|---|---|---|
| xer_path | No | ||
| xer_content | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries full responsibility for behavioral transparency. It thoroughly discloses that the tool returns a summary, not raw rows, and explains why ('XER row dumps explode the MCP context window'). It also outlines the exact return structure, including encoding, table summaries, and project summary, providing complete insight into behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Although the description is longer than minimal, every sentence adds value. It is well-structured with a clear purpose statement, usage context, parameter explanations, and a detailed return format. The information is front-loaded and not repetitive, ensuring concise, purposeful prose.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity and absence of an output schema, the description is remarkably complete. It includes a full return structure with field names and examples, explains the input alternatives, and dictates usage scenarios. This makes the tool fully self-documented and actionable for an agent.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema description coverage is 0%, so the description must fully explain parameters. It does so: 'xer_path: server-side filesystem path to the XER file. xer_content: full text of the XER file (alternative for hosted/remote use).' It also adds a critical constraint: 'Supply EXACTLY ONE of path/content.' This goes beyond schema alone and gives clear usage semantics.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's function: 'Parse a Primavera P6 XER file and return a TABLE SUMMARY', specifying the verb 'parse' and the resource 'XER file'. It also differentiates from siblings by explicitly noting that for full row-level analysis, dedicated tools like 'forensic_windows_analysis' and 'critical_path_validator' should be used, making the scope unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit when-to-use guidance: 'Use this tool to confirm an XER is parseable, list its tables, see the data date / project name from PROJECT, or count activities in TASK before deciding which deeper tool to run.' It also clearly states alternatives and exclusions, such as omitting raw row data and directing users to dedicated tools for deeper analysis.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
1 tool update
- Changed
dcma14_health_check1 field changed- added
Input schema / properties / companyAdded value: +{ + "default": "", + "title": "Company", + "type": "string" +}
4 tool updates
- Changed
claim_workbench_evidence_ledger1 field changed- added
Input schema / properties / companyAdded value: +{ + "default": "", + "title": "Company", + "type": "string" +}
- Changed
forensic_windows_analysis1 field changed- added
Input schema / properties / companyAdded value: +{ + "default": "", + "title": "Company", + "type": "string" +}
- Changed
monte_carlo_p50_p801 field changed- added
Input schema / properties / companyAdded value: +{ + "default": "", + "title": "Company", + "type": "string" +}
- Changed
path_explorer1 field changed- added
Input schema / properties / companyAdded value: +{ + "default": "", + "title": "Company", + "type": "string" +}
2 tool updates
- Changed
collapsed_as_built2 fields changed- added
Input schema / properties / companyAdded value: +{ + "default": "", + "title": "Company", + "type": "string" +} - added
Input schema / properties / preparerAdded value: +{ + "default": "", + "title": "Preparer", + "type": "string" +}
- Changed
time_impact_analysis_fragnet2 fields changed- added
Input schema / properties / companyAdded value: +{ + "default": "", + "title": "Company", + "type": "string" +} - added
Input schema / properties / preparerAdded value: +{ + "default": "", + "title": "Preparer", + "type": "string" +}
14 tool updates
- First observed
claim_workbench_evidence_ledger - First observed
collapsed_as_built - First observed
concurrent_delay_matrix - First observed
critical_path_validator - First observed
dcma14_health_check - First observed
forensic_windows_analysis - First observed
impacted_as_planned - First observed
monte_carlo_p50_p80 - First observed
path_explorer - First observed
qramm_maturity - First observed
slip_velocity - First observed
time_impact_analysis_fragnet - First observed
woet_classifier - First observed
xer_parser
Related MCP Connectors
Project scheduling: Gantt chart, dependencies, baselines, reports and AI agents
AI-powered project controls tools for Primavera P6 and Primavera Unifier.
Project controls for construction schedules: approved changes, look-aheads, briefs, signed records.
Construction cost & project management: APU analysis, budgets, price lists, site execution.
Related MCP Servers
- AlicenseAqualityCmaintenanceEnables assistants to read and analyze construction schedules like a scheduler: CPM, float, critical paths, DCMA 14-point, logic checks, update-to-update comparison, baseline variance, and S-curves from P6 XER and MS Project files.1722 PyPIMIT
- AlicenseAqualityCmaintenanceEnables AI assistants to analyze Primavera P6 XER files for insights into critical paths, schedule health, and project performance. It provides 23 specialized tools for managing schedule data, resources, and earned value through local or remote interfaces.2918 PyPI16MIT
- AlicenseNot gradedqualityBmaintenanceEnables MCP-compatible AI clients to query, analyze, and mutate Oracle Primavera P6 schedules from XER files or live P6 EPPM, with tools for critical path, DCMA compliance, earned value, resources, baselines, and exports.37 PyPI1MIT
- AlicenseAqualityBmaintenanceEnables an AI assistant to analyse, and when permitted edit, Primavera P6 Professional schedules on a Windows PC, whether they live in a standalone SQLite database or plain XER files. It provides critical path and float analysis, DCMA health checks, progress comparisons, and in-memory what-if scenarios, with write operations off by default and protected by dry runs, backups, and an edit log.115Apache 2.0
Glama MCP Gateway
Add one secure layer between your agents and this server.