{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://artifacts.apis.io/bellatorsi-com/json-schema/bellatorsi-com-dcmadecmrequest-schema.json",
  "title": "DCMADECMRequest",
  "description": "Request body for POST /api/v1/forensics/dcma-decm.",
  "x-generated": "2026-11-02",
  "x-method": "derived",
  "x-generator": "derive-json-schema.py",
  "x-source": "openapi/bellatorsi-com-openapi.json#/components/schemas/DCMADECMRequest",
  "properties": {
    "tasks": {
      "items": {
        "$ref": "#/$defs/Task"
      },
      "type": "array",
      "minItems": 2,
      "title": "Tasks",
      "description": "Task list (minimum 2 tasks required)"
    },
    "status_date": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "title": "Status Date",
      "description": "Project status/data date (ISO 8601). Required for checks 06A212a, 06A506a/b/c. Skipped with informative message if absent."
    },
    "target_finish_date": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "title": "Target Finish Date",
      "description": "Contract/target finish date (ISO 8601). Reserved for future Tier 3 use."
    },
    "start_task_ids": {
      "items": {
        "type": "string"
      },
      "type": "array",
      "title": "Start Task Ids",
      "description": "Task IDs that legitimately have no predecessors (exempt from check 06A204b)."
    },
    "finish_task_ids": {
      "items": {
        "type": "string"
      },
      "type": "array",
      "title": "Finish Task Ids",
      "description": "Task IDs that legitimately have no successors (exempt from check 06A204b)."
    },
    "schedule_history": {
      "items": {
        "$ref": "#/$defs/ScheduleHistorySnapshot"
      },
      "type": "array",
      "title": "Schedule History",
      "description": "Optional historical snapshots for retroactive date change detection (checks 06A504a/b). Each snapshot requires snapshot_date + tasks."
    },
    "scope": {
      "type": "string",
      "title": "Scope",
      "description": "Scope of evaluation. 'schedule_only' (default) = 17 Tier 2 checks. 'guideline_6', 'full' = Tier 3 (not yet implemented).",
      "default": "schedule_only"
    },
    "options": {
      "$ref": "#/$defs/DCMADECMOptions",
      "description": "Assessment options."
    }
  },
  "type": "object",
  "required": [
    "tasks"
  ],
  "$defs": {
    "DCMADECMCustomThresholds": {
      "properties": {
        "check_06A204b_max_pct": {
          "anyOf": [
            {
              "type": "number",
              "maximum": 100.0,
              "minimum": 0.0
            },
            {
              "type": "null"
            }
          ],
          "title": "Check 06A204B Max Pct"
        },
        "check_06A205a_lags_max_pct": {
          "anyOf": [
            {
              "type": "number",
              "maximum": 100.0,
              "minimum": 0.0
            },
            {
              "type": "null"
            }
          ],
          "title": "Check 06A205A Lags Max Pct"
        },
        "check_06A208a_max_pct": {
          "anyOf": [
            {
              "type": "number",
              "maximum": 100.0,
              "minimum": 0.0
            },
            {
              "type": "null"
            }
          ],
          "title": "Check 06A208A Max Pct"
        },
        "check_06A209a_constraints_max_pct": {
          "anyOf": [
            {
              "type": "number",
              "maximum": 100.0,
              "minimum": 0.0
            },
            {
              "type": "null"
            }
          ],
          "title": "Check 06A209A Constraints Max Pct"
        },
        "check_06A210a_max_pct": {
          "anyOf": [
            {
              "type": "number",
              "maximum": 100.0,
              "minimum": 0.0
            },
            {
              "type": "null"
            }
          ],
          "title": "Check 06A210A Max Pct"
        },
        "check_06A212a_max_pct": {
          "anyOf": [
            {
              "type": "number",
              "maximum": 100.0,
              "minimum": 0.0
            },
            {
              "type": "null"
            }
          ],
          "title": "Check 06A212A Max Pct"
        },
        "check_06A504a_max_pct": {
          "anyOf": [
            {
              "type": "number",
              "maximum": 100.0,
              "minimum": 0.0
            },
            {
              "type": "null"
            }
          ],
          "title": "Check 06A504A Max Pct"
        },
        "check_06A504b_max_pct": {
          "anyOf": [
            {
              "type": "number",
              "maximum": 100.0,
              "minimum": 0.0
            },
            {
              "type": "null"
            }
          ],
          "title": "Check 06A504B Max Pct"
        },
        "check_06A505a_max_pct": {
          "anyOf": [
            {
              "type": "number",
              "maximum": 100.0,
              "minimum": 0.0
            },
            {
              "type": "null"
            }
          ],
          "title": "Check 06A505A Max Pct"
        },
        "check_06A505b_max_pct": {
          "anyOf": [
            {
              "type": "number",
              "maximum": 100.0,
              "minimum": 0.0
            },
            {
              "type": "null"
            }
          ],
          "title": "Check 06A505B Max Pct"
        },
        "check_06A506a_max_pct": {
          "anyOf": [
            {
              "type": "number",
              "maximum": 100.0,
              "minimum": 0.0
            },
            {
              "type": "null"
            }
          ],
          "title": "Check 06A506A Max Pct"
        },
        "check_06A506b_max_pct": {
          "anyOf": [
            {
              "type": "number",
              "maximum": 100.0,
              "minimum": 0.0
            },
            {
              "type": "null"
            }
          ],
          "title": "Check 06A506B Max Pct"
        },
        "check_06A506c_max_pct": {
          "anyOf": [
            {
              "type": "number",
              "maximum": 100.0,
              "minimum": 0.0
            },
            {
              "type": "null"
            }
          ],
          "title": "Check 06A506C Max Pct"
        },
        "check_08I101a_max_pct": {
          "anyOf": [
            {
              "type": "number",
              "maximum": 100.0,
              "minimum": 0.0
            },
            {
              "type": "null"
            }
          ],
          "title": "Check 08I101A Max Pct"
        },
        "check_10A303a_max_pct": {
          "anyOf": [
            {
              "type": "number",
              "maximum": 100.0,
              "minimum": 0.0
            },
            {
              "type": "null"
            }
          ],
          "title": "Check 10A303A Max Pct"
        }
      },
      "type": "object",
      "title": "DCMADECMCustomThresholds",
      "description": "Custom threshold overrides for DCMA DECM checks."
    },
    "DCMADECMOptions": {
      "properties": {
        "threshold_profile": {
          "type": "string",
          "title": "Threshold Profile",
          "description": "Threshold profile: 'dcma-decm-default' (default), 'dcma-decm-strict'.",
          "default": "dcma-decm-default"
        },
        "custom_thresholds": {
          "anyOf": [
            {
              "$ref": "#/$defs/DCMADECMCustomThresholds"
            },
            {
              "type": "null"
            }
          ],
          "description": "Per-check threshold overrides (applied on top of selected profile)."
        },
        "include_details": {
          "type": "boolean",
          "title": "Include Details",
          "description": "Include violating task IDs and detailed evidence objects in each check result.",
          "default": false
        }
      },
      "type": "object",
      "title": "DCMADECMOptions",
      "description": "Request options for DCMA DECM assessment."
    },
    "DependencyLink": {
      "properties": {
        "task_id": {
          "type": "string",
          "title": "Task Id",
          "description": "Predecessor task ID"
        },
        "relationship_type": {
          "$ref": "#/$defs/RelationshipType",
          "description": "Relationship type (FS/SS/FF/SF)",
          "default": "FS"
        },
        "lag_days": {
          "type": "number",
          "title": "Lag Days",
          "description": "Lag (positive) or lead (negative) in days",
          "default": 0.0
        },
        "is_external": {
          "type": "boolean",
          "title": "Is External",
          "description": "True if link to external project file",
          "default": false
        },
        "external_path": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "title": "External Path",
          "description": "Path to external file if is_external=True"
        }
      },
      "type": "object",
      "required": [
        "task_id"
      ],
      "title": "DependencyLink",
      "description": "Rich dependency link with relationship type and lag/lead.\n\nSupports parsing from various scheduling tool formats including:\n- MS Project: \"10FS+5 d\", \"/path/file.mpp/10FS+5 d\"\n- Primavera P6: Similar format with XER encoding\n- Server-based: \"<ServerFile>10FS+5 d\"\n- Simple: \"10\" (defaults to FS with zero lag)\n\nExamples:\n    >>> DependencyLink(task_id=\"10\", relationship_type=\"FS\", lag_days=5.0)\n    >>> DependencyLink.from_string(\"10FS+5 d\")\n    >>> DependencyLink.from_string(\"15SS-2 d\")"
    },
    "RelationshipType": {
      "type": "string",
      "enum": [
        "FS",
        "SS",
        "FF",
        "SF"
      ],
      "title": "RelationshipType",
      "description": "Task relationship types per PMBOK 6.3.2.2.\n\nAttributes:\n    FINISH_START: Predecessor finish → successor start (most common, ~90%)\n    START_START: Predecessor start → successor start (~5%)\n    FINISH_FINISH: Predecessor finish → successor finish (~4%)\n    START_FINISH: Predecessor start → successor finish (rare, ~1%)"
    },
    "ScheduleHistorySnapshot": {
      "properties": {
        "snapshot_date": {
          "type": "string",
          "title": "Snapshot Date",
          "description": "Snapshot date (ISO 8601)"
        },
        "tasks": {
          "items": {
            "$ref": "#/$defs/Task"
          },
          "type": "array",
          "title": "Tasks",
          "description": "Task list at snapshot time"
        }
      },
      "type": "object",
      "required": [
        "snapshot_date"
      ],
      "title": "ScheduleHistorySnapshot",
      "description": "A historical snapshot of schedule tasks for retroactive date change detection."
    },
    "Task": {
      "properties": {
        "id": {
          "type": "string",
          "title": "Id",
          "description": "Unique task identifier"
        },
        "duration_days": {
          "type": "number",
          "minimum": 0.0,
          "title": "Duration Days",
          "description": "Task duration in days",
          "default": 0
        },
        "predecessors": {
          "items": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "$ref": "#/$defs/DependencyLink"
              }
            ]
          },
          "type": "array",
          "title": "Predecessors",
          "description": "List of predecessor task IDs or dependency links. Supports: 'T1', 'T1FS+5 d', 'T2SS-2 d', or DependencyLink objects"
        },
        "name": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "title": "Name",
          "description": "Task name"
        },
        "resource": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "title": "Resource",
          "description": "Resource assigned to task"
        },
        "resources": {
          "items": {
            "type": "string"
          },
          "type": "array",
          "title": "Resources",
          "description": "List of resources assigned (for multi-resource tasks)"
        },
        "percent_complete": {
          "type": "number",
          "maximum": 100.0,
          "minimum": 0.0,
          "title": "Percent Complete",
          "description": "Percent complete (0-100)",
          "default": 0
        },
        "physical_percent_complete": {
          "anyOf": [
            {
              "type": "number",
              "maximum": 100.0,
              "minimum": 0.0
            },
            {
              "type": "null"
            }
          ],
          "title": "Physical Percent Complete",
          "description": "Physical percent complete (0-100). Manual EVM entry by scheduler (MSP PhysicalPercentComplete). Authoritative for BCWP calculations. Captured separately from percent_complete on MSP imports."
        },
        "planned_start": {
          "anyOf": [
            {
              "type": "string",
              "format": "date"
            },
            {
              "type": "null"
            }
          ],
          "title": "Planned Start",
          "description": "Planned start date (ISO 8601)"
        },
        "planned_finish": {
          "anyOf": [
            {
              "type": "string",
              "format": "date"
            },
            {
              "type": "null"
            }
          ],
          "title": "Planned Finish",
          "description": "Planned finish date (ISO 8601)"
        },
        "actual_start": {
          "anyOf": [
            {
              "type": "string",
              "format": "date"
            },
            {
              "type": "null"
            }
          ],
          "title": "Actual Start",
          "description": "Actual start date (ISO 8601)"
        },
        "actual_finish": {
          "anyOf": [
            {
              "type": "string",
              "format": "date"
            },
            {
              "type": "null"
            }
          ],
          "title": "Actual Finish",
          "description": "Actual finish date (ISO 8601)"
        },
        "baseline_start": {
          "anyOf": [
            {
              "type": "string",
              "format": "date"
            },
            {
              "type": "null"
            }
          ],
          "title": "Baseline Start",
          "description": "Baseline start date (ISO 8601)"
        },
        "baseline_finish": {
          "anyOf": [
            {
              "type": "string",
              "format": "date"
            },
            {
              "type": "null"
            }
          ],
          "title": "Baseline Finish",
          "description": "Baseline finish date (ISO 8601)"
        },
        "constraint_type": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "title": "Constraint Type",
          "description": "Constraint type: ASAP, ALAP, SNET, SNLT, FNET, FNLT, MSO, MFO"
        },
        "constraint_date": {
          "anyOf": [
            {
              "type": "string",
              "format": "date"
            },
            {
              "type": "null"
            }
          ],
          "title": "Constraint Date",
          "description": "Constraint date if applicable (ISO 8601)"
        },
        "task_type": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "title": "Task Type",
          "description": "Task type classification. Valid values: task (default), milestone, loe, summary, schedule_margin, planning_package, slpp, schedule_visibility. Drives DCMA check exclusions per PAM 200.1 § 3.2."
        },
        "wbs_code": {
          "anyOf": [
            {
              "type": "string",
              "maxLength": 100
            },
            {
              "type": "null"
            }
          ],
          "title": "Wbs Code",
          "description": "WBS code (e.g., '1.2.3')"
        },
        "organization_code": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "title": "Organization Code",
          "description": "Org/dept identifier for anomaly categorization (Progress Audit)"
        },
        "custom_field_map": {
          "anyOf": [
            {
              "additionalProperties": {
                "type": "string"
              },
              "type": "object"
            },
            {
              "type": "null"
            }
          ],
          "title": "Custom Field Map",
          "description": "All WBS/OBS-pattern custom fields discovered in this MS Project file, keyed by alias (e.g., 'CWBS', 'OBS'). Null for XER imports or when no matching aliases exist."
        },
        "forecast_start": {
          "anyOf": [
            {
              "type": "string",
              "format": "date"
            },
            {
              "type": "null"
            }
          ],
          "title": "Forecast Start",
          "description": "Current forecast start date (ISO 8601)"
        },
        "forecast_finish": {
          "anyOf": [
            {
              "type": "string",
              "format": "date"
            },
            {
              "type": "null"
            }
          ],
          "title": "Forecast Finish",
          "description": "Current forecast finish date (ISO 8601)"
        },
        "total_float_days": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "type": "null"
            }
          ],
          "title": "Total Float Days",
          "description": "Pre-computed total float in days. Auto-computed by CPM if absent."
        },
        "baseline_duration_days": {
          "anyOf": [
            {
              "type": "number",
              "minimum": 0.0
            },
            {
              "type": "null"
            }
          ],
          "title": "Baseline Duration Days",
          "description": "Baseline duration in days. Auto-computed from baseline dates if absent."
        },
        "delay_category": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "title": "Delay Category",
          "description": "Delay attribution category. Valid values: owner, contractor, design, procurement, weather, force_majeure."
        },
        "earned_value": {
          "anyOf": [
            {
              "type": "number",
              "minimum": 0.0
            },
            {
              "type": "null"
            }
          ],
          "title": "Earned Value",
          "description": "Earned Value (BCWP) in cost units. Requires options.include_ev_validation."
        },
        "budgeted_cost": {
          "anyOf": [
            {
              "type": "number",
              "minimum": 0.0
            },
            {
              "type": "null"
            }
          ],
          "title": "Budgeted Cost",
          "description": "Budgeted Cost of Work Scheduled (BCWS) in cost units."
        },
        "approval_required": {
          "anyOf": [
            {
              "type": "boolean"
            },
            {
              "type": "null"
            }
          ],
          "title": "Approval Required",
          "description": "Whether this task requires explicit approval before it can start."
        },
        "approval_status": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "title": "Approval Status",
          "description": "Approval workflow state. Valid values: not_required, pending, approved, rejected."
        }
      },
      "type": "object",
      "required": [
        "id"
      ],
      "title": "Task",
      "description": "Unified task model for all schedule analysis endpoints.\n\nThis model is used across all Tier 1 and Tier 2 APIs. Fields are optional\nunless specifically required by an endpoint.\n\nField Naming Rationale:\n- duration_days: Explicit time unit (vs generic \"duration\")\n- predecessors: Standard scheduling terminology (vs generic \"dependencies\")\n\nDependency Format Support:\n- Simple: [\"task1\", \"task2\"]\n- Rich: [\"task1FS+5 d\", \"task2SS-2 d\"]\n- Objects: [DependencyLink(...), ...]"
    }
  }
}