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.
npx skills add jdmorag97-rgb/DDC_Skills_for_AI_Agents_in_Construction --skill delay-analysisgit clone --depth 1 https://github.com/jdmorag97-rgb/DDC_Skills_for_AI_Agents_in_ConstructionWrote 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.
[](https://agentmods.dev/skills/jdmorag97-rgb/ddc_skills_for_ai_agents_in_construction/delay-analysis)<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.
<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>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.
| Model | Per session | Once 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 |
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.
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.
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)
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.
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.
- 8d ago First seen · 537 lines · 29 tokens per session scan A ea3dcdae90be
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.
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.
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…
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.…
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…
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.
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.