Skip to main content
Glama

Server Details

Primavera P6 XER forensic scheduling: AACE windows, TIA, impacted as-planned, DCMA-14, Monte Carlo.

If you are the author of this connector, you can claim ownership by verifying the domain or GitHub account it belongs to. Claimed connector authors can inspect health checks, view analytics, and manage their listing.
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

A4.5/5.0

Scored across 14 tools

Disambiguation4/5

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).

Naming Consistency4/5

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.

Tool Count5/5

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.

Completeness4/5

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 tools
claim_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)
            }
        
NameRequiredDescriptionDefault
companyNo
output_dirNo
folder_pathNo
project_nameNo
run_forensicNo
contract_formNoCCDC2
evidence_filesNo
original_baseline_xer_filenameNo

TDQS

A4.4/5.0
Behavior4/5

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.

Conciseness3/5

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.

Completeness4/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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)"
            }
        
NameRequiredDescriptionDefault
companyNo
preparerNo
output_dirNo
delay_eventsNo
project_nameNo
removal_methodNoshorten
as_built_xer_pathNo
contractor_filterNo
as_built_xer_contentNo

TDQS

A4.7/5.0
Behavior4/5

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.

Conciseness4/5

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.

Completeness5/5

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.

Parameters5/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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
            }
        
NameRequiredDescriptionDefault
schedulesNo
xer_pathsNo
xer_contentsNo

TDQS

A4.9/5.0
Behavior5/5

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.

Conciseness4/5

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.

Completeness5/5

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.

Parameters5/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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
        
NameRequiredDescriptionDefault
profileNocommercial
xer_pathNo
xer_contentNo
project_indexNo
baseline_xer_pathNo
baseline_xer_contentNo

TDQS

A4.7/5.0
Behavior4/5

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.

Conciseness4/5

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.

Completeness5/5

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.

Parameters5/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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.
        
NameRequiredDescriptionDefault
debugNo
companyNo
output_pathNo
timeout_secondsNo
current_xer_pathNo
baseline_xer_pathNo
return_html_inlineNo
current_xer_contentNo
baseline_xer_contentNo

TDQS

A4.8/5.0
Behavior5/5

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.

Conciseness3/5

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.

Completeness5/5

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.

Parameters5/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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.
        
NameRequiredDescriptionDefault
companyNo
schedulesYes
output_dirNo
baseline_idxNo
project_nameNo
entitlement_milestoneNo

TDQS

A4.9/5.0
Behavior5/5

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.

Conciseness4/5

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.

Completeness5/5

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.

Parameters5/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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
            }
        
NameRequiredDescriptionDefault
modeNoscreen
companyNo
proj_idNo
fragnetsNo
opposingNo
preparerNo
output_dirNo
own_resultsNo
project_nameNo
screen_bandsNo
baseline_nameNo
opposing_nameNo
baseline_xer_pathNo
baseline_xer_contentNo
opposing_impacted_xer_pathNo
opposing_impacted_xer_contentNo

TDQS

A4.9/5.0
Behavior5/5

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.

Conciseness4/5

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.

Completeness5/5

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.

Parameters5/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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
        
NameRequiredDescriptionDefault
seedNo
companyNo
xer_pathNo
iterationsNo
output_dirNo
xer_contentNo
distributionNoTriangular
optimistic_pctNo
most_likely_pctNo
pessimistic_pctNo

TDQS

A4.4/5.0
Behavior3/5

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.

Conciseness4/5

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.

Completeness5/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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":      ...
            }
        
NameRequiredDescriptionDefault
companyNo
xer_pathNo
directionNoboth
output_dirNo
xer_contentNo
include_near_criticalNo
target_activity_codesNo

TDQS

A4.6/5.0
Behavior4/5

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.

Conciseness4/5

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.

Completeness4/5

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.

Parameters5/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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.
        
NameRequiredDescriptionDefault
sra_resultYes

TDQS

A4.9/5.0
Behavior5/5

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.

Conciseness4/5

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.

Completeness5/5

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.

Parameters5/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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
            }
        
NameRequiredDescriptionDefault
schedulesNo
xer_pathsNo
xer_contentsNo

TDQS

A4.6/5.0
Behavior5/5

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.

Conciseness3/5

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.

Completeness5/5

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.

Parameters5/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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),
            }
        
NameRequiredDescriptionDefault
companyNo
fragnetsNo
preparerNo
output_dirNo
project_nameNo
per_event_basesNo
baseline_xer_pathNo
baseline_xer_contentNo

TDQS

A4.9/5.0
Behavior5/5

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.

Conciseness4/5

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.

Completeness5/5

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.

Parameters5/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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)
            }
        
NameRequiredDescriptionDefault
todayNo
actual_xer_pathNo
baseline_xer_pathNo
actual_xer_contentNo
baseline_xer_contentNo

TDQS

A4.9/5.0
Behavior5/5

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.

Conciseness4/5

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.

Completeness5/5

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.

Parameters5/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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)
        }
    
NameRequiredDescriptionDefault
xer_pathNo
xer_contentNo

TDQS

A5/5.0
Behavior5/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters5/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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. 1 tool update
    • Changeddcma14_health_check1 field changed
      • addedInput schema / properties / company
        Added value: +{
        +  "default": "",
        +  "title": "Company",
        +  "type": "string"
        +}
  2. 4 tool updates
    • Changedclaim_workbench_evidence_ledger1 field changed
      • addedInput schema / properties / company
        Added value: +{
        +  "default": "",
        +  "title": "Company",
        +  "type": "string"
        +}
    • Changedforensic_windows_analysis1 field changed
      • addedInput schema / properties / company
        Added value: +{
        +  "default": "",
        +  "title": "Company",
        +  "type": "string"
        +}
    • Changedmonte_carlo_p50_p801 field changed
      • addedInput schema / properties / company
        Added value: +{
        +  "default": "",
        +  "title": "Company",
        +  "type": "string"
        +}
    • Changedpath_explorer1 field changed
      • addedInput schema / properties / company
        Added value: +{
        +  "default": "",
        +  "title": "Company",
        +  "type": "string"
        +}
  3. 2 tool updates
    • Changedcollapsed_as_built2 fields changed
      • addedInput schema / properties / company
        Added value: +{
        +  "default": "",
        +  "title": "Company",
        +  "type": "string"
        +}
      • addedInput schema / properties / preparer
        Added value: +{
        +  "default": "",
        +  "title": "Preparer",
        +  "type": "string"
        +}
    • Changedtime_impact_analysis_fragnet2 fields changed
      • addedInput schema / properties / company
        Added value: +{
        +  "default": "",
        +  "title": "Company",
        +  "type": "string"
        +}
      • addedInput schema / properties / preparer
        Added value: +{
        +  "default": "",
        +  "title": "Preparer",
        +  "type": "string"
        +}
  4. 14 tool updates
    • First observedclaim_workbench_evidence_ledger
    • First observedcollapsed_as_built
    • First observedconcurrent_delay_matrix
    • First observedcritical_path_validator
    • First observeddcma14_health_check
    • First observedforensic_windows_analysis
    • First observedimpacted_as_planned
    • First observedmonte_carlo_p50_p80
    • First observedpath_explorer
    • First observedqramm_maturity
    • First observedslip_velocity
    • First observedtime_impact_analysis_fragnet
    • First observedwoet_classifier
    • First observedxer_parser

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    C
    maintenance
    Enables 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.
    17
    22 PyPI
    MIT
  • A
    license
    A
    quality
    C
    maintenance
    Enables 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.
    29
    18 PyPI
    16
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables 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 PyPI
    1
    MIT
  • A
    license
    A
    quality
    B
    maintenance
    Enables 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.
    11
    5
    Apache 2.0
Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.