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 schedule-cost-linkgit 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/schedule-cost-link)<a href="https://agentmods.dev/skills/jdmorag97-rgb/ddc_skills_for_ai_agents_in_construction/schedule-cost-link"><img src="https://agentmods.dev/badge/skills/jdmorag97-rgb/ddc_skills_for_ai_agents_in_construction/schedule-cost-link/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/schedule-cost-link"><img src="https://agentmods.dev/badge/skills/jdmorag97-rgb/ddc_skills_for_ai_agents_in_construction/schedule-cost-link.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.00026 | $0.03154 |
| Opus 5 | $0.00013 | $0.01577 |
| Sonnet 5 | $0.00005 | $0.00631 |
| Haiku 4.5 | $0.00003 | $0.00315 |
Grade A, and why
schedule-cost-link 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 9d 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 schedule-cost-link — 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 — 435 lines — stays where its author put it; the contents beside it link to each section on GitHub.
Schedule-Cost Linker
Business Case
Problem Statement
Integrating schedule and cost requires:
- Linking activities to budget items
- Creating cost-loaded schedules
- Generating cash flow forecasts
- Tracking earned value metrics
Solution
Systematic linkage between schedule activities and cost data to enable integrated project control.
Technical Implementation
import pandas as pd
import numpy as np
from typing import Dict, Any, List, Optional, Tuple
from dataclasses import dataclass, field
from datetime import date, timedelta
from enum import Enum
from collections import defaultdict
class LoadingMethod(Enum):
UNIFORM = "uniform" # Even distribution
FRONT_LOADED = "front_loaded"
BACK_LOADED = "back_loaded"
BELL_CURVE = "bell_curve"
@dataclass
class ScheduleActivity:
activity_id: str
name: str
start_date: date
finish_date: date
duration: int
percent_complete: float = 0
@dataclass
class CostItem:
cost_code: str
description: str
budgeted_cost: float
labor_cost: float
material_cost: float
equipment_cost: float
@dataclass
class ActivityCostLink:
activity_id: str
cost_code: str
budgeted_cost: float
loading_method: LoadingMethod
@dataclass
class EarnedValueMetrics:
data_date: date
bcws: float # Budgeted Cost of Work Scheduled (PV)
bcwp: float # Budgeted Cost of Work Performed (EV)
acwp: float # Actual Cost of Work Performed (AC)
sv: float # Schedule Variance
cv: float # Cost Variance
spi: float # Schedule Performance Index
cpi: float # Cost Performance Index
eac: float # Estimate at Completion
etc: float # Estimate to Complete
vac: float # Variance at Completion
class ScheduleCostLinker:
"""Link schedule activities to cost items."""
def __init__(self, project_name: str, budget_at_completion: float):
self.project_name = project_name
self.bac = budget_at_completion
self.activities: Dict[str, ScheduleActivity] = {}
self.cost_items: Dict[str, CostItem] = {}
self.links: List[ActivityCostLink] = []
self.actual_costs: Dict[str, float] = {} # activity_id -> actual cost
def add_activity(self,
activity_id: str,
name: str,
start_date: date,
finish_date: date,
percent_complete: float = 0):
"""Add schedule activity."""
duration = (finish_date - start_date).days + 1
self.activities[activity_id] = ScheduleActivity(
activity_id=activity_id,
name=name,
start_date=start_date,
finish_date=finish_date,
duration=duration,
percent_complete=percent_complete
)
def add_cost_item(self,
cost_code: str,
description: str,
budgeted_cost: float,
labor_pct: float = 0.4,
material_pct: float = 0.5,
equipment_pct: float = 0.1):
"""Add cost item."""
self.cost_items[cost_code] = CostItem(
cost_code=cost_code,
description=description,
budgeted_cost=budgeted_cost,
labor_cost=budgeted_cost * labor_pct,
material_cost=budgeted_cost * material_pct,
equipment_cost=budgeted_cost * equipment_pct
)
def link_activity_cost(self,
activity_id: str,
cost_code: str,
loading_method: LoadingMethod = LoadingMethod.UNIFORM):
"""Link activity to cost item."""
if activity_id not in self.activities:
return
cost_item = self.cost_items.get(cost_code)
budgeted = cost_item.budgeted_cost if cost_item else 0
self.links.append(ActivityCostLink(
activity_id=activity_id,
cost_code=cost_code,
budgeted_cost=budgeted,
loading_method=loading_method
))
def record_actual_cost(self, activity_id: str, actual_cost: float):
"""Record actual cost for activity."""
self.actual_costs[activity_id] = actual_cost
def _distribute_cost(self,
cost: float,
start_date: date,
duration: int,
method: LoadingMethod) -> Dict[date, float]:
"""Distribute cost over activity duration."""
daily_costs = {}
if duration <= 0:
return {start_date: cost}
if method == LoadingMethod.UNIFORM:
daily = cost / duration
for i in range(duration):
daily_costs[start_date + timedelta(days=i)] = daily
elif method == LoadingMethod.FRONT_LOADED:
total_weight = sum(range(duration, 0, -1))
for i in range(duration):
weight = (duration - i) / total_weight
daily_costs[start_date + timedelta(days=i)] = cost * weight
elif method == LoadingMethod.BACK_LOADED:
total_weight = sum(range(1, duration + 1))
for i in range(duration):
weight = (i + 1) / total_weight
daily_costs[start_date + timedelta(days=i)] = cost * weight
elif method == LoadingMethod.BELL_CURVE:
# Simplified bell curve
mid = duration / 2
for i in range(duration):
distance = abs(i - mid)
weight = 1 - (distance / mid) * 0.5
daily_costs[start_date + timedelta(days=i)] = cost * weight / duration
return daily_costs
def generate_cost_loaded_schedule(self) -> pd.DataFrame:
"""Generate cost-loaded schedule."""
data = []
for link in self.links:
activity = self.activities.get(link.activity_id)
cost_item = self.cost_items.get(link.cost_code)
if activity and cost_item:
data.append({
'Activity ID': activity.activity_id,
'Activity Name': activity.name,
'Cost Code': link.cost_code,
'Description': cost_item.description,
'Start': activity.start_date,
'Finish': activity.finish_date,
'Duration': activity.duration,
'Budget': link.budgeted_cost,
'% Complete': activity.percent_complete,
'Earned Value': link.budgeted_cost * activity.percent_complete / 100,
'Loading': link.loading_method.value
})
return pd.DataFrame(data)
def generate_cash_flow(self,
project_start: date = None,
project_end: date = None) -> pd.DataFrame:
"""Generate cash flow curve."""
if not self.links:
return pd.DataFrame()
# Get date range
if project_start is None:
project_start = min(self.activities[l.activity_id].start_date for l in self.links)
if project_end is None:
project_end = max(self.activities[l.activity_id].finish_date for l in self.links)
# Aggregate daily costs
daily_totals = defaultdict(float)
for link in self.links:
activity = self.activities.get(link.activity_id)
if not activity:
continue
daily_costs = self._distribute_cost(
link.budgeted_cost,
activity.start_date,
activity.duration,
link.loading_method
)
for day, cost in daily_costs.items():
daily_totals[day] += cost
# Build cash flow data
data = []
cumulative = 0
current = project_start
while current <= project_end:
daily = daily_totals.get(current, 0)
cumulative += daily
data.append({
'Date': current,
'Daily': round(daily, 2),
'Cumulative': round(cumulative, 2),
'Cumulative %': round(cumulative / self.bac * 100, 1) if self.bac > 0 else 0
})
current += timedelta(days=1)
return pd.DataFrame(data)
def calculate_earned_value(self, data_date: date) -> EarnedValueMetrics:
"""Calculate earned value metrics at data date."""
# BCWS - Planned Value through data date
bcws = 0
for link in self.links:
activity = self.activities.get(link.activity_id)
if not activity:
continue
daily_costs = self._distribute_cost(
link.budgeted_cost,
activity.start_date,
activity.duration,
link.loading_method
)
for day, cost in daily_costs.items():
if day <= data_date:
bcws += cost
# BCWP - Earned Value (budget * % complete)
bcwp = 0
for link in self.links:
activity = self.activities.get(link.activity_id)
if activity:
bcwp += link.budgeted_cost * activity.percent_complete / 100
# ACWP - Actual Cost
acwp = sum(self.actual_costs.values())
# Variances
sv = bcwp - bcws
cv = bcwp - acwp
# Indices
spi = bcwp / bcws if bcws > 0 else 0
cpi = bcwp / acwp if acwp > 0 else 0
# Forecasts
eac = self.bac / cpi if cpi > 0 else self.bac
etc = eac - acwp
vac = self.bac - eac
return EarnedValueMetrics(
data_date=data_date,
bcws=round(bcws, 2),
bcwp=round(bcwp, 2),
acwp=round(acwp, 2),
sv=round(sv, 2),
cv=round(cv, 2),
spi=round(spi, 2),
cpi=round(cpi, 2),
eac=round(eac, 2),
etc=round(etc, 2),
vac=round(vac, 2)
)
def get_monthly_cash_flow(self) -> pd.DataFrame:
"""Aggregate cash flow by month."""
daily = self.generate_cash_flow()
if daily.empty:
return pd.DataFrame()
daily['Month'] = pd.to_datetime(daily['Date']).dt.to_period('M')
monthly = daily.groupby('Month').agg({
'Daily': 'sum',
'Cumulative': 'last'
}).reset_index()
monthly.columns = ['Month', 'Monthly Cost', 'Cumulative']
return monthly
def export_to_excel(self, output_path: str) -> str:
"""Export integrated data to Excel."""
with pd.ExcelWriter(output_path, engine='openpyxl') as writer:
# Cost-loaded schedule
schedule = self.generate_cost_loaded_schedule()
schedule.to_excel(writer, sheet_name='Cost-Loaded Schedule', index=False)
# Cash flow
cash_flow = self.generate_cash_flow()
if not cash_flow.empty:
cash_flow.to_excel(writer, sheet_name='Cash Flow', index=False)
# Monthly
monthly = self.get_monthly_cash_flow()
if not monthly.empty:
monthly.to_excel(writer, sheet_name='Monthly', index=False)
# Earned Value
evm = self.calculate_earned_value(date.today())
evm_df = pd.DataFrame([{
'Data Date': evm.data_date,
'BCWS (PV)': evm.bcws,
'BCWP (EV)': evm.bcwp,
'ACWP (AC)': evm.acwp,
'SV': evm.sv,
'CV': evm.cv,
'SPI': evm.spi,
'CPI': evm.cpi,
'EAC': evm.eac,
'ETC': evm.etc,
'VAC': evm.vac
}])
evm_df.to_excel(writer, sheet_name='Earned Value', index=False)
return output_path
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.
- 9d ago First seen · 435 lines · 26 tokens per session scan A 124c02dbe16c
schedule-cost-link 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 26 tokens to every session and 3,154 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 schedule-cost-link, differing in 0 lines, and is treated as a copy.
Other skills, from other repositories
weekly-update
OpenDesign's weekly metrics standup: this week's numbers, the one anomaly, and the single decision it forces. Built as a decision-grade data & finance deck for ops & growth team.
close-management
Manage the month-end close process with task sequencing, dependencies, and status tracking. Use when planning the close calendar, tracking close progress, identifying blockers, or sequencing close activities by day.
dd-checklist
Generate and track comprehensive due diligence checklists tailored to the target company's sector, deal type, and complexity. Covers all major workstreams with request lists, status tracking, and red flag escalation. Use when kicking off diligence, organizing a data room review, or tracking outstanding items. Triggers…
closing-checklist
What's blocking close — maintain the closing checklist with status, critical path, and days to close. Self-updating: ingests new items from diligence findings and schedule builds, tracks status, surfaces what's blocking. Use when user says "closing checklist", "what's left to close", "checklist status", "add to the…
syndic
Gère un parc de copropriétés en France avec vue portfolio consolidée. Couvre administration, comptabilité (décret 2005, plan comptable copro, 5 annexes), assemblées générales (convocation, PV, notification), appels de fonds, travaux, fournisseurs, recouvrement d'impayés et transition de syndic. Maîtrise les majorités…
Freelance Empire
Complete freelance business operating system — from first client to six-figure solo business. Covers positioning, pricing, proposals, client management, finances, scaling, and the transition from side-hustle to full-time. Use when starting freelancing, raising rates, managing clients, building recurring revenue, or…