delay-analysis

delay-analysis is a skill for Claude Code, Codex from jdmorag97-rgb/DDC_Skills_for_AI_Agents_in_Construction. It costs 29 tokens per session (4,175 once invoked), scanned A, a copy of delay-analysis, MIT.

A construction delay analysis tool examines project schedules to determine when delays happened, what caused them, and how they affected completion. It can support claims, recovery planning, and dispute documentation.

In plain words
What is it for?
It is for comparing planned and actual progress, testing the effect of delay events, identifying concurrent delays, calculating delay damages, and preparing evidence for disputes.
Why use it?
It replaces manual schedule comparisons and helps separate overlapping delays from other causes. This gives project teams a structured basis for discussing responsibility and delay-related costs.

Skill for Claude CodeCodex

Which agent this was written for is unclear — built for openclaw. Also seen: built for openclaw.

Good fit It is for comparing planned and actual progress, testing the effect of delay events, identifying concurrent delays, calculating delay damages, and preparing evidence for disputes.

Compare 6 skills from other repositories ↓
Install with agentmods
npx agentmods add skills/jdmorag97-rgb/ddc_skills_for_ai_agents_in_construction/delay-analysis
Install

Getting it into your agent

One page per mod, every tool's command on it. A separate URL per tool would split the same page into five that compete with each other.

Any agent
npx skills add jdmorag97-rgb/DDC_Skills_for_AI_Agents_in_Construction --skill delay-analysis
Clone the repo
git clone --depth 1 https://github.com/jdmorag97-rgb/DDC_Skills_for_AI_Agents_in_Construction

Made for: Claude Code, Codex.

Wrote this? Show the measurements

A badge with what this costs and how it scanned, read live from this page, so it follows the numbers instead of freezing them. Markdown for a README, HTML for a documentation site or a project page.

agentmods badge for delay-analysis

README.md
[![agentmods](https://agentmods.dev/badge/skills/jdmorag97-rgb/ddc_skills_for_ai_agents_in_construction/delay-analysis/github.svg)](https://agentmods.dev/skills/jdmorag97-rgb/ddc_skills_for_ai_agents_in_construction/delay-analysis)
Your own site
<a href="https://agentmods.dev/skills/jdmorag97-rgb/ddc_skills_for_ai_agents_in_construction/delay-analysis"><img src="https://agentmods.dev/badge/skills/jdmorag97-rgb/ddc_skills_for_ai_agents_in_construction/delay-analysis/github.svg" alt="Measured on agentmods" height="20"></a>

Or the 80×15 button, for a site that already has a row of RSS and ATOM ones. Only the verdict fits; the numbers stay here.

agentmods 80×15 button for delay-analysis

Your own site · 80×15
<a href="https://agentmods.dev/skills/jdmorag97-rgb/ddc_skills_for_ai_agents_in_construction/delay-analysis"><img src="https://agentmods.dev/badge/skills/jdmorag97-rgb/ddc_skills_for_ai_agents_in_construction/delay-analysis.svg" alt="Reviewed on agentmods" width="80" height="20"></a>
Per session 29 Skills are progressive disclosure: only the name and description are preloaded; the body loads when the skill is used.
When invoked 4,175 The whole file, excluding the scripts and references it only reads on demand.
Security scan A 0 findings. A grade says what 26 rules found in the file — not that it is safe.
Origin 100% copy Near-identical to another mod in the catalogue.
Token cost

What it costs to keep this loaded

Counted locally with the o200k_base tokenizer, which is exact for GPT models; Claude uses its own tokenizer and its counts differ. Treat this as one consistent yardstick across the catalogue rather than a bill. Prices are per million input tokens.

ModelPer sessionOnce invoked
Fable 5.1 $0.00029 $0.04175
Opus 5 $0.00015 $0.02087
Sonnet 5 $0.00006 $0.00835
Haiku 4.5 $0.00003 $0.00417

Measured 8d ago against content hash ea3dcdae90be, method: parsed. Prices are Anthropic first-party input rates as of 2026-09-11, from the pricing page.

Security

Grade A, and why

delay-analysis scanned grade A with 0 findings against 26 rules in 11 categories — prompt injection, anti-refusal, data exfiltration, privilege escalation, supply chain, agent snooping, system-prompt leakage, SSRF and excessive agency — measured 8d ago.

A static scan of the body, not an audit. Every finding is printed with the line that produced it so you can judge whether it matters here. A mod is markdown that instructs an agent; that is exactly why what it instructs is worth reading.

Nothing flagged

None of the 26 patterns this scan looks for appear in this file: no shell pipes, no recursive deletes, no credential paths, no hidden text, no instruction-override or anti-refusal phrasing, no agent-config snooping. That is not a guarantee, it is the absence of the things that are checkable.

Origin

This is a copy

100% identical to delay-analysis — 0 lines differ, which has more behind it and is treated as the original. This page carries a canonical link to it rather than competing with it.

3_DDC_Insights/Schedule-Optimization/delay-analysis/SKILL.md · 537 lines

How it starts

The opening of the file, as written. The whole thing — 537 lines — stays where its author put it; the contents beside it link to each section on GitHub.

Delay Analysis

Overview

Analyze construction schedule delays for project recovery and claims. Perform time impact analysis (TIA), identify concurrent delays, calculate delay damages, and prepare documentation for dispute resolution.

"Proper delay analysis is essential for fair resolution of construction disputes" — DDC Community

Delay Analysis Methods

┌─────────────────────────────────────────────────────────────────┐
│                    DELAY ANALYSIS METHODS                        │
├─────────────────────────────────────────────────────────────────┤
│                                                                  │
│  As-Planned vs As-Built    │    Time Impact Analysis (TIA)      │
│  ─────────────────────     │    ────────────────────────────    │
│  Compare original to       │    Insert delay events into        │
│  actual schedule           │    schedule to measure impact      │
│                            │                                     │
│  Windows Analysis          │    Collapsed As-Built              │
│  ────────────────          │    ─────────────────               │
│  Divide project into       │    Remove delays from as-built     │
│  time periods              │    to find "but-for" completion    │
│                                                                  │
└─────────────────────────────────────────────────────────────────┘

Technical Implementation

from dataclasses import dataclass, field
from typing import List, Dict, Optional, Tuple
from datetime import datetime, timedelta
from enum import Enum
from collections import defaultdict

class DelayType(Enum):
    EXCUSABLE_COMPENSABLE = "excusable_compensable"      # Owner caused - time + money
    EXCUSABLE_NON_COMPENSABLE = "excusable_non_compensable"  # Neither party - time only
    NON_EXCUSABLE = "non_excusable"                      # Contractor caused - no relief
    CONCURRENT = "concurrent"                            # Both parties - complex

class DelayCause(Enum):
    OWNER_CHANGE = "owner_change"
    LATE_INFORMATION = "late_information"
    DIFFERING_CONDITIONS = "differing_conditions"
    PERMIT_DELAY = "permit_delay"
    WEATHER = "weather"
    LABOR_SHORTAGE = "labor_shortage"
    MATERIAL_DELAY = "material_delay"
    SUBCONTRACTOR = "subcontractor"
    COORDINATION = "coordination"
    ACCESS = "access"
    FORCE_MAJEURE = "force_majeure"

@dataclass
class DelayEvent:
    id: str
    description: str
    cause: DelayCause
    delay_type: DelayType
    start_date: datetime
    end_date: datetime
    affected_activities: List[str]
    responsible_party: str
    documented: bool = True
    supporting_docs: List[str] = field(default_factory=list)
    calculated_impact: int = 0  # days
    concurrent_with: List[str] = field(default_factory=list)

@dataclass
class ScheduleVersion:
    version_id: str
    version_type: str  # baseline, update, as-built
    data_date: datetime
    completion_date: datetime
    activities: Dict[str, Dict]  # activity_id -> {start, finish, duration}

@dataclass
class WindowPeriod:
    window_id: str
    start_date: datetime
    end_date: datetime
    planned_progress: float
    actual_progress: float
    delay_days: int
    delay_events: List[str]
    responsible_parties: Dict[str, int]  # party -> delay days

@dataclass
class DelayAnalysisReport:
    project_name: str
    analysis_date: datetime
    original_completion: datetime
    actual_completion: datetime
    total_delay: int
    excusable_delay: int
    non_excusable_delay: int
    concurrent_delay: int
    delay_events: List[DelayEvent]
    delay_by_cause: Dict[str, int]
    delay_by_party: Dict[str, int]
    recommended_extension: int
    potential_damages: float

class DelayAnalyzer:
    """Analyze construction schedule delays."""

    # Daily delay costs by project size
    DEFAULT_DAILY_COSTS = {
        "small": 5000,      # < $10M
        "medium": 15000,    # $10M - $50M
        "large": 40000,     # $50M - $200M
        "mega": 100000      # > $200M
    }

    def __init__(self, project_name: str, contract_completion: datetime):
        self.project_name = project_name
        self.contract_completion = contract_completion
        self.delay_events: Dict[str, DelayEvent] = {}
        self.schedule_versions: Dict[str, ScheduleVersion] = {}
        self.window_periods: List[WindowPeriod] = []
        self.daily_cost = self.DEFAULT_DAILY_COSTS["medium"]

    def set_daily_delay_cost(self, cost: float):
        """Set daily delay cost for damages calculation."""
        self.daily_cost = cost

    def add_schedule_version(self, version_id: str, version_type: str,
                            data_date: datetime, completion_date: datetime,
                            activities: Dict[str, Dict]) -> ScheduleVersion:
        """Add schedule version for analysis."""
        version = ScheduleVersion(
            version_id=version_id,
            version_type=version_type,
            data_date=data_date,
            completion_date=completion_date,
            activities=activities
        )
        self.schedule_versions[version_id] = version
        return version

    def add_delay_event(self, id: str, description: str,
                       cause: DelayCause, delay_type: DelayType,
                       start_date: datetime, end_date: datetime,
                       affected_activities: List[str],
                       responsible_party: str,
                       supporting_docs: List[str] = None) -> DelayEvent:
        """Add delay event for analysis."""
        event = DelayEvent(
            id=id,
            description=description,
            cause=cause,
            delay_type=delay_type,
            start_date=start_date,
            end_date=end_date,
            affected_activities=affected_activities,
            responsible_party=responsible_party,
            supporting_docs=supporting_docs or []
        )
        self.delay_events[id] = event
        return event

    def perform_as_planned_vs_as_built(self) -> Dict:
        """Perform As-Planned vs As-Built analysis."""
        baseline = self.schedule_versions.get("baseline")
        as_built = self.schedule_versions.get("as_built")

        if not baseline or not as_built:
            raise ValueError("Need baseline and as-built schedules")

        total_delay = (as_built.completion_date - baseline.completion_date).days

        # Analyze each activity
        activity_delays = []
        for act_id, baseline_act in baseline.activities.items():
            if act_id in as_built.activities:
                as_built_act = as_built.activities[act_id]

                baseline_finish = baseline_act['finish']
                actual_finish = as_built_act['finish']

                if isinstance(baseline_finish, str):
                    baseline_finish = datetime.fromisoformat(baseline_finish)
                if isinstance(actual_finish, str):
                    actual_finish = datetime.fromisoformat(actual_finish)

                delay = (actual_finish - baseline_finish).days

                if delay > 0:
                    activity_delays.append({
                        'activity_id': act_id,
                        'planned_finish': baseline_finish,
                        'actual_finish': actual_finish,
                        'delay_days': delay
                    })

        return {
            'method': 'As-Planned vs As-Built',
            'baseline_completion': baseline.completion_date,
            'actual_completion': as_built.completion_date,
            'total_delay': total_delay,
            'activity_delays': sorted(activity_delays, key=lambda x: -x['delay_days'])
        }

    def perform_time_impact_analysis(self, delay_event_id: str) -> Dict:
        """Perform Time Impact Analysis for specific delay event."""
        if delay_event_id not in self.delay_events:
            raise ValueError(f"Delay event {delay_event_id} not found")

        event = self.delay_events[delay_event_id]

        # Find schedule version just before delay
        pre_delay_schedule = None
        for version in sorted(self.schedule_versions.values(),
                            key=lambda v: v.data_date, reverse=True):
            if version.data_date < event.start_date:
                pre_delay_schedule = version
                break

        if not pre_delay_schedule:
            pre_delay_schedule = self.schedule_versions.get("baseline")

        if not pre_delay_schedule:
            raise ValueError("No pre-delay schedule found")

        # Calculate impact
        original_completion = pre_delay_schedule.completion_date
        delay_duration = (event.end_date - event.start_date).days

        # Check if delay is on critical path
        critical_impact = False
        for act_id in event.affected_activities:
            if act_id in pre_delay_schedule.activities:
                act = pre_delay_schedule.activities[act_id]
                if act.get('is_critical', False):
                    critical_impact = True
                    break

        if critical_impact:
            impact_days = delay_duration
            new_completion = original_completion + timedelta(days=delay_duration)
        else:
            # Need to check float
            impact_days = max(0, delay_duration - 5)  # Simplified - assume 5 days float
            new_completion = original_completion + timedelta(days=impact_days)

        event.calculated_impact = impact_days

        return {
            'method': 'Time Impact Analysis',
            'delay_event': event.id,
            'delay_description': event.description,
            'delay_duration': delay_duration,
            'critical_path_impact': critical_impact,
            'schedule_impact_days': impact_days,
            'original_completion': original_completion,
            'impacted_completion': new_completion,
            'delay_type': event.delay_type.value,
            'responsible_party': event.responsible_party
        }

    def identify_concurrent_delays(self) -> List[Tuple[str, str, int]]:
        """Identify concurrent delay events."""
        concurrent = []

        events = list(self.delay_events.values())
        for i, event1 in enumerate(events):
            for event2 in events[i+1:]:
                # Check for overlap
                overlap_start = max(event1.start_date, event2.start_date)
                overlap_end = min(event1.end_date, event2.end_date)

                if overlap_start < overlap_end:
                    overlap_days = (overlap_end - overlap_start).days
                    concurrent.append((event1.id, event2.id, overlap_days))

                    event1.concurrent_with.append(event2.id)
                    event2.concurrent_with.append(event1.id)

        return concurrent

    def perform_windows_analysis(self, window_days: int = 30) -> List[WindowPeriod]:
        """Perform windows analysis by dividing project into periods."""
        baseline = self.schedule_versions.get("baseline")
        as_built = self.schedule_versions.get("as_built")

        if not baseline or not as_built:
            raise ValueError("Need baseline and as-built schedules")

        windows = []
        current_start = baseline.data_date
        window_num = 1

        while current_start < as_built.completion_date:
            window_end = min(
                current_start + timedelta(days=window_days),
                as_built.completion_date
            )

            # Find delay events in this window
            window_events = [
                e.id for e in self.delay_events.values()
                if e.start_date < window_end and e.end_date > current_start
            ]

            # Calculate delay by party
            party_delays = defaultdict(int)
            for event_id in window_events:
                event = self.delay_events[event_id]
                overlap_start = max(event.start_date, current_start)
                overlap_end = min(event.end_date, window_end)
                days = (overlap_end - overlap_start).days
                party_delays[event.responsible_party] += days

            window = WindowPeriod(
                window_id=f"W{window_num:02d}",
                start_date=current_start,
                end_date=window_end,
                planned_progress=0.0,  # Would calculate from schedule
                actual_progress=0.0,
                delay_days=sum(party_delays.values()),
                delay_events=window_events,
                responsible_parties=dict(party_delays)
            )
            windows.append(window)

            current_start = window_end
            window_num += 1

        self.window_periods = windows
        return windows

    def calculate_delay_damages(self) -> Dict:
        """Calculate potential delay damages."""
        # Summarize delays by type
        excusable_compensable = 0
        excusable_non_compensable = 0
        non_excusable = 0

        for event in self.delay_events.values():
            impact = event.calculated_impact or (event.end_date - event.start_date).days

            # Adjust for concurrency
            if event.concurrent_with:
                impact = impact // 2  # Simplified concurrency handling

            if event.delay_type == DelayType.EXCUSABLE_COMPENSABLE:
                excusable_compensable += impact
            elif event.delay_type == DelayType.EXCUSABLE_NON_COMPENSABLE:
                excusable_non_compensable += impact
            elif event.delay_type == DelayType.NON_EXCUSABLE:
                non_excusable += impact

        # Calculate damages
        contractor_damages = excusable_compensable * self.daily_cost
        owner_ld = non_excusable * self.daily_cost

        return {
            'excusable_compensable_days': excusable_compensable,
            'excusable_non_compensable_days': excusable_non_compensable,
            'non_excusable_days': non_excusable,
            'recommended_time_extension': excusable_compensable + excusable_non_compensable,
            'contractor_delay_damages': contractor_damages,
            'owner_liquidated_damages': owner_ld,
            'daily_rate_used': self.daily_cost
        }

    def generate_analysis_report(self, actual_completion: datetime) -> DelayAnalysisReport:
        """Generate comprehensive delay analysis report."""
        total_delay = (actual_completion - self.contract_completion).days

        # Categorize delays
        delay_by_cause = defaultdict(int)
        delay_by_party = defaultdict(int)
        excusable = 0
        non_excusable = 0
        concurrent = 0

        for event in self.delay_events.values():
            impact = event.calculated_impact or (event.end_date - event.start_date).days

            delay_by_cause[event.cause.value] += impact
            delay_by_party[event.responsible_party] += impact

            if event.concurrent_with:
                concurrent += impact // 2
            elif event.delay_type in [DelayType.EXCUSABLE_COMPENSABLE,
                                      DelayType.EXCUSABLE_NON_COMPENSABLE]:
                excusable += impact
            else:
                non_excusable += impact

        damages = self.calculate_delay_damages()

        return DelayAnalysisReport(
            project_name=self.project_name,
            analysis_date=datetime.now(),
            original_completion=self.contract_completion,
            actual_completion=actual_completion,
            total_delay=total_delay,
            excusable_delay=excusable,
            non_excusable_delay=non_excusable,
            concurrent_delay=concurrent,
            delay_events=list(self.delay_events.values()),
            delay_by_cause=dict(delay_by_cause),
            delay_by_party=dict(delay_by_party),
            recommended_extension=damages['recommended_time_extension'],
            potential_damages=damages['contractor_delay_damages']
        )

    def generate_report_markdown(self, report: DelayAnalysisReport) -> str:
        """Generate markdown report."""
        lines = [
            "# Delay Analysis Report",
            "",
            f"**Project:** {report.project_name}",
            f"**Analysis Date:** {report.analysis_date.strftime('%Y-%m-%d')}",
            "",
            "## Schedule Summary",
            "",
            f"| Milestone | Date |",
            f"|-----------|------|",
            f"| Contract Completion | {report.original_completion.strftime('%Y-%m-%d')} |",
            f"| Actual Completion | {report.actual_completion.strftime('%Y-%m-%d')} |",
            f"| **Total Delay** | **{report.total_delay} days** |",
            "",
            "## Delay Classification",
            "",
            f"| Category | Days |",
            f"|----------|------|",
            f"| Excusable Delay | {report.excusable_delay} |",
            f"| Non-Excusable Delay | {report.non_excusable_delay} |",
            f"| Concurrent Delay | {report.concurrent_delay} |",
            "",
            "## Delay by Cause",
            ""
        ]

        for cause, days in sorted(report.delay_by_cause.items(), key=lambda x: -x[1]):
            lines.append(f"- **{cause}**: {days} days")

        lines.extend([
            "",
            "## Delay by Responsible Party",
            ""
        ])

        for party, days in sorted(report.delay_by_party.items(), key=lambda x: -x[1]):
            lines.append(f"- **{party}**: {days} days")

        lines.extend([
            "",
            "## Recommendations",
            "",
            f"- **Recommended Time Extension:** {report.recommended_extension} days",
            f"- **Potential Delay Damages:** ${report.potential_damages:,.0f}",
            ""
        ])

        return "\n".join(lines)

Read the full file on GitHub · 537 lines

Files

What ships with it

2 files beside SKILL.md in the same directory: the scripts, references and assets a skill reads on demand. Not counted in the per-session cost; read them before you install if any of them is executable.

Changes

What this file has done since we first saw it

Hashed on every crawl. A supply-chain change to an agent config is a question of when, not whether, so the history is kept rather than the latest state alone.

  1. 8d ago First seen · 537 lines · 29 tokens per session scan A ea3dcdae90be

Subscribe to this mod's changes

delay-analysis is a skill published in the GitHub repository jdmorag97-rgb/DDC_Skills_for_AI_Agents_in_Construction (2 stars, last pushed 6mo ago), licensed MIT. It adds 29 tokens to every session and 4,175 once invoked, about $0.0001 per session on Opus 5. A static security scan graded it A with 0 findings. It is 100% identical to delay-analysis, differing in 0 lines, and is treated as a copy.

Related

Other skills, from other repositories

vendor-review

Evaluate a vendor — cost analysis, risk assessment, and recommendation. Use when reviewing a new vendor proposal, deciding whether to renew or replace a contract, comparing two vendors side-by-side, or building a TCO breakdown and negotiation points before procurement sign-off.

anthropics/knowledge-work-plugins · 54 tokens

entity-compliance

Entity compliance tracker — initialize, report upcoming deadlines, update status, run health audit, export to CSV. Maintains a compliance-tracker.yaml built from the entity table, calculates filing deadlines by entity and jurisdiction, and surfaces what's due in the next 30/60/90 days. Use when user says "entity…

anthropics/claude-for-legal · 98 tokens

integration-management

Post-closing M&A integration tracker — phased workplan, consent tracking, contract assignment at scale, weekly status reports. Initializes from whatever deal artifacts are available (purchase agreement, deal summary, closing checklist) and connects to deal-context.md and closing-checklist.yaml from the M&A cold-start.…

anthropics/claude-for-legal · 100 tokens

matter-workspace

Manage matter workspaces — new, list, switch, close, or detach (practice-level). File-management logic for keeping one client or engagement's context separate from every other. Use when working across multiple clients or matters, when the user says "new matter", "switch matter", "list matters", "close matter", or when…

anthropics/claude-for-legal · 82 tokens

patent-docket

A workflow coordinator for patent case files, from an inventor's technical disclosure to patent application documents. A patent docket is the tracked record of a patent matter, including its stage, questions, drafts, and handoffs.

handsomestWei/patent-disclosure-skill · 93 tokens

performance-management

Runs performance systems that change behavior — expectations, feedback, review cycles, calibration, and handling underperformance. Use this to design or fix a review process, run calibration, write or coach on feedback, address sustained underperformance, or work out why reviews consume weeks and change nothing.

cbrock84/headcount · 59 tokens