rfi-management
Complete RFI (Request for Information) management system. Create, track, route, and analyze RFIs with automatic notifications and response deadline tracking.
Install / Use
npx skills add datadrivenconstruction/DDC_Skills_for_AI_Agents_in_Construction --skill rfi-managementInstalls into whichever agent you are using.
SKILL.md
Installable skill definition
Quality Score
Category
AutomationSupported Platforms
Our assessment of rfi-management
rfi-management scores 91/100 on our quality scale, 1189th of 2,904 Automation skills we index (top 41%).
Its SKILL.md is 20 KB long, well organised into 14 sections with 5 code examples: a thorough specification that gives an agent plenty to work with.
It has 333 GitHub stars, a meaningful sign that others use it.
Maintenance, license and trust
- The repository was last updated about 2 months ago, so rfi-management is actively maintained.
- It is released under the MIT license, a permissive license that allows use, modification and commercial use with attribution.
- Its trust signals score 100/100, with no cautions. These come from repository metadata, not a code audit β read the skill file before letting an agent act on it.
rfi-management compared with similar skills
All 4 of these similar skills score higher than rfi-management; compare them before choosing.
| Skill | Score | Stars | Updated | Format |
|---|---|---|---|---|
| rfi-management (this skill)by datadrivenconstruction | 91 | 333 | 56d ago | SKILL.md |
| Agent-Reachby Panniantong | 100 | 98.3k | 2d ago | CLAUDE.md |
| headroomby headroomlabs-ai | 100 | 75.5k | today | CLAUDE.md |
| Scraplingby D4Vinci | 100 | 88.2k | today | MCP Server |
| crawl4aiby unclecode | 100 | 85.7k | 2d ago | MCP Server |
Frequently asked questions
- How do I install rfi-management?
- Run
npx skills add datadrivenconstruction/DDC_Skills_for_AI_Agents_in_Construction --skill rfi-management. The install tabs above show the steps for each supported agent. - Which AI agents does rfi-management work with?
- It is written for Universal, as a SKILL.md file. Other agents that read the same format can often use it too.
- Is rfi-management safe to use?
- It is MIT-licensed and scores 100/100 on trust signals. Skills are instructions an agent will follow, so read the file before installing it and do not approve commands you do not understand.
- Is rfi-management still maintained?
- The repository was last updated about 2 months ago, so rfi-management is actively maintained.
Skill content
View source on GitHubname: "rfi-management" description: "Complete RFI (Request for Information) management system. Create, track, route, and analyze RFIs with automatic notifications and response deadline tracking." homepage: "https://datadrivenconstruction.io" metadata: {"openclaw": {"emoji": "π", "os": ["darwin", "linux", "win32"], "homepage": "https://datadrivenconstruction.io", "requires": {"bins": ["python3"]}}}
RFI Management System for Construction
Comprehensive system for managing Requests for Information (RFIs) throughout the construction project lifecycle.
Business Case
Problem: RFI management is chaotic:
- RFIs get lost in email threads
- Response deadlines missed
- No visibility into RFI status
- Difficult to track cost/schedule impacts
- Manual logging wastes hours weekly
Solution: Structured RFI management that:
- Auto-assigns RFI numbers
- Routes to correct parties
- Tracks response deadlines
- Sends automatic reminders
- Maintains audit trail
- Analyzes trends and impacts
ROI: 60% faster RFI response time, 90% reduction in lost RFIs
RFI Workflow
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β RFI LIFECYCLE β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β βββββββββββ βββββββββββ βββββββββββ βββββββββββ β
β β CREATE βββββΊβ SUBMIT βββββΊβ REVIEW βββββΊβ RESPOND β β
β β β β β β β β β β
β β β’ Draft β β β’ Route β β β’ Assignβ β β’ Answerβ β
β β β’ Attachβ β β’ Notifyβ β β’ Track β β β’ Approveβ β
β βββββββββββ βββββββββββ βββββββββββ βββββββββββ β
β β β β β β
β βΌ βΌ βΌ βΌ β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β RFI DATABASE β β
β β β’ RFI Log β’ Attachments β’ Response History β β
β β β’ Status Track β’ Cost Impacts β’ Schedule Impacts β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
β βββββββββββ βββββββββββ βββββββββββ β
β β CLOSE ββββββ VERIFY ββββββIMPLEMENTβ β
β β β β β β β β
β β β’ Archiveβ β β’ Check β β β’ Actionβ β
β β β’ Reportβ β β’ Acceptβ β β’ Updateβ β
β βββββββββββ βββββββββββ βββββββββββ β
β β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Data Structure
RFI Log Schema
RFI_SCHEMA = {
# Identification
'rfi_number': str, # RFI-001, RFI-002, etc.
'project_id': str, # Project identifier
'revision': int, # Revision number (0, 1, 2...)
# Description
'subject': str, # Brief title
'question': str, # Detailed question
'spec_section': str, # CSI spec reference
'drawing_ref': str, # Drawing reference (A-101, S-201)
'location': str, # Building/floor/area
# Parties
'submitted_by': str, # Originator name
'submitted_by_company': str,# Originator company
'assigned_to': str, # Responsible party
'cc_list': list, # Additional recipients
# Dates
'date_submitted': date, # When submitted
'date_required': date, # When response needed
'date_responded': date, # When answered
'date_closed': date, # When closed
# Status
'status': str, # Draft/Open/Pending/Answered/Closed
'priority': str, # Critical/High/Medium/Low
# Response
'response': str, # Answer text
'response_by': str, # Who answered
'attachments': list, # File links
# Impact
'cost_impact': bool, # Has cost impact?
'cost_amount': float, # Estimated cost
'schedule_impact': bool, # Has schedule impact?
'schedule_days': int, # Days of delay
'change_order_ref': str, # Related CO number
}
Python Implementation
import pandas as pd
from datetime import datetime, date, timedelta
from typing import Optional, List, Dict
from dataclasses import dataclass, field
from enum import Enum
import uuid
class RFIStatus(Enum):
DRAFT = "Draft"
OPEN = "Open"
PENDING = "Pending Review"
ANSWERED = "Answered"
CLOSED = "Closed"
VOID = "Void"
class RFIPriority(Enum):
CRITICAL = "Critical" # Stops work
HIGH = "High" # Impacts critical path
MEDIUM = "Medium" # Standard
LOW = "Low" # Informational
@dataclass
class RFI:
"""Request for Information data class"""
rfi_number: str
project_id: str
subject: str
question: str
# Optional fields with defaults
spec_section: str = ""
drawing_ref: str = ""
location: str = ""
submitted_by: str = ""
submitted_by_company: str = ""
assigned_to: str = ""
cc_list: List[str] = field(default_factory=list)
date_submitted: date = field(default_factory=date.today)
date_required: date = None
date_responded: date = None
date_closed: date = None
status: RFIStatus = RFIStatus.DRAFT
priority: RFIPriority = RFIPriority.MEDIUM
response: str = ""
response_by: str = ""
attachments: List[str] = field(default_factory=list)
cost_impact: bool = False
cost_amount: float = 0.0
schedule_impact: bool = False
schedule_days: int = 0
change_order_ref: str = ""
revision: int = 0
def __post_init__(self):
if self.date_required is None:
# Default: 7 days for response
self.date_required = self.date_submitted + timedelta(days=7)
class RFIManager:
"""Complete RFI management system"""
def __init__(self, project_id: str, storage_path: str = None):
self.project_id = project_id
self.storage_path = storage_path or f"rfi_log_{project_id}.xlsx"
self.rfis: Dict[str, RFI] = {}
self._load_rfis()
def _load_rfis(self):
"""Load RFIs from storage"""
try:
df = pd.read_excel(self.storage_path)
for _, row in df.iterrows():
rfi = RFI(
rfi_number=row['rfi_number'],
project_id=row['project_id'],
subject=row['subject'],
question=row['question'],
status=RFIStatus(row['status']),
priority=RFIPriority(row.get('priority', 'Medium'))
)
self.rfis[rfi.rfi_number] = rfi
except FileNotFoundError:
pass
def _save_rfis(self):
"""Save RFIs to storage"""
records = []
for rfi in self.rfis.values():
records.append({
'rfi_number': rfi.rfi_number,
'project_id': rfi.project_id,
'subject': rfi.subject,
'question': rfi.question,
'spec_section': rfi.spec_section,
'drawing_ref': rfi.drawing_ref,
'location': rfi.location,
'submitted_by': rfi.submitted_by,
'submitted_by_company': rfi.submitted_by_company,
'assigned_to': rfi.assigned_to,
'date_submitted': rfi.date_submitted,
'date_required': rfi.date_required,
'date_responded': rfi.date_responded,
'date_closed': rfi.date_closed,
'status': rfi.status.value,
'priority': rfi.priority.value,
'response': rfi.response,
'response_by': rfi.response_by,
'cost_impact': rfi.cost_impact,
'cost_amount': rfi.cost_amount,
'schedule_impact': rfi.schedule_impact,
'schedule_days': rfi.schedule_days,
'change_order_ref': rfi.change_order_ref
})
df = pd.DataFrame(records)
df.to_excel(self.storage_path, index=False)
def _get_next_number(self) -> str:
"""Generate next RFI number"""
existing = [int(r.rfi_number.split('-')[1])
for r in self.rfis.values()
if r.rfi_number.startswith('RFI-')]
next_num = max(existing, default=0) + 1
return f"RFI-{next_num:04d}"
def create_rfi(
self,
subject: str,
question: str,
submitted_by: str,
submitted_by_company: str,
assigned_to: str,
spec_section: str = "",
drawing_ref: str = "",
location: str = "",
priority: RFIPriority = RFIPriority.MEDIUM,
days_for_response: int = 7,
attachments: List[str] = None
) -> RFI:
"""Create new RFI"""
rfi_number = self._get_next_number()
rfi = RFI(
rfi_number=rfi_number,
project_id=self.project_id,
subject=subject,
question=question,
spec_section=spec_section,
drawing_ref=drawing_ref,
location=location,
submitted_by=submitted_by,
submitted_by_company=submitted_by_company,
assigned_to=assigned_to,
priority=priority,
date_required=date.today() + timedelta(days=days_for_response),
attachments=attachments or []
)
self.rfis[rfi_number] = rfi
self._save_rfis()
return rfi
def submit_rfi(self, rfi_number: str) -> RFI:
"""Submit RFI for response"""
rfi = self.rfis.get(rfi_number)
if not rfi:
raise ValueError(f"RFI {rfi_number} not found")
if rfi.status != RFIStatus.DRAFT:
raise ValueError(f"RFI {rfi_number} already submitted")
rfi.status = RFIStatus.OPEN
rfi.date_submitted = date.today()
self._save_rfis()
# Trigger notification
self._notify_submission(rfi)
return rfi
def respond_to_rfi(
self,
rfi_number: str,
response: str,
response_by: str,
attachments: List[str] = None,
cost_impact: bool = False,
cost_amount: float = 0.0,
schedule_impact: bool = False,
schedule_days: int = 0
) -> RFI:
"""Provide response to RFI"""
rfi = self.rfis.get(rfi_number)
if not rfi:
raise ValueError(f"RFI {rfi_number} not found")
rfi.response = response
rfi.response_by = response_by
rfi.date_responded = date.today()
rfi.status = RFIStatus.ANSWERED
if attachments:
rfi.attachments.extend(attachments)
rfi.cost_impact = cost_impact
rfi.cost_amount = cost_amount
rfi.schedule_impact = schedule_impact
rfi.schedule_days = schedule_days
self._save_rfis()
# Trigger notification
self._notify_response(rfi)
return rfi
def close_rfi(self, rfi_number: str, change_order_ref: str = None) -> RFI:
"""Close RFI after implementation"""
rfi = self.rfis.get(rfi_number)
if not rfi:
raise ValueError(f"RFI {rfi_number} not found")
rfi.status = RFIStatus.CLOSED
rfi.date_closed = date.today()
if change_order_ref:
rfi.change_order_ref = change_order_ref
self._save_rfis()
return rfi
def get_overdue_rfis(self) -> List[RFI]:
"""Get list of overdue RFIs"""
today
Truncated for display β read the full file on GitHub.
Related Skills
Agent-Reach
98.3kGive your AI agent eyes to see the entire internet. Read & search Twitter, Reddit, YouTube, GitHub, Bilibili, XiaoHongShu β one CLI, zero API fees.
headroom
75.5kCompress tool outputs, logs, files, and RAG chunks before they reach the LLM. 20% fewer tokens for coding agents, 60-95% fewer tokens for JSON, same answers. Library, proxy, MCP server.
Scrapling
88.2kπ·οΈ An adaptive Web Scraping framework that handles everything from a single request to a full-scale crawl! Don't be shy, join here: https://discord.gg/EMgGbDceNQ and follow here for daily tips and tricks: https://x.com/Scrapling_dev
crawl4ai
85.7kOpen-source web crawler and scraper for LLMs and AI agents: any website into clean, LLM-ready Markdown. Run it yourself, or use Crawl4AI Cloud with one key.
Languages
Trust signals
From repository metadata: license, adoption, age and documentation. Not a code audit β see the Safety scan above for what the skill file itself contains.
