SkillAgentSearch skills...

punch-list-manager

Digital punch list management for construction project closeout. Track deficiencies, assign corrections, photo documentation, and completion verification.

Install / Use

npx skills add datadrivenconstruction/DDC_Skills_for_AI_Agents_in_Construction --skill punch-list-manager

Installs into whichever agent you are using.

About this skill
📄

SKILL.md

Installable skill definition

Quality Score

89/100

Supported Platforms

Universal

Our assessment of punch-list-manager

punch-list-manager scores 89/100 on our quality scale, 572nd of 1,180 Content & Media skills we index (top 49%).

Its SKILL.md is 22 KB long, split into 7 sections with 4 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.

Substance
30/30
Structure
18/20
Description
15/15
Adoption
11/20
Freshness
15/15

Maintenance, license and trust

  • The repository was last updated about 2 months ago, so punch-list-manager 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.

Safety scan

No issues found

Our scan of the whole file found no instruction hijacking, hidden characters, credential access, data exfiltration or destructive commands.

Automated pattern scan on 2026-10-17. It catches known dangerous patterns, not every risk — read a skill before letting an agent act on it.

punch-list-manager compared with similar skills

All 4 of these similar skills score higher than punch-list-manager; compare them before choosing.

SkillScoreStarsUpdatedFormat
punch-list-manager (this skill)by datadrivenconstruction8933356d agoSKILL.md
Agent-Reachby Panniantong10098.3k2d agoCLAUDE.md
headroomby headroomlabs-ai10075.5ktodayCLAUDE.md
Scraplingby D4Vinci10088.2ktodayMCP Server
crawl4aiby unclecode10085.7k2d agoMCP Server

Frequently asked questions

How do I install punch-list-manager?
Run npx skills add datadrivenconstruction/DDC_Skills_for_AI_Agents_in_Construction --skill punch-list-manager. The install tabs above show the steps for each supported agent.
Which AI agents does punch-list-manager 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 punch-list-manager safe to use?
Our scan of the whole file found no instruction hijacking, hidden characters, credential access, data exfiltration or destructive commands. 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 punch-list-manager still maintained?
The repository was last updated about 2 months ago, so punch-list-manager is actively maintained.

name: "punch-list-manager" description: "Digital punch list management for construction project closeout. Track deficiencies, assign corrections, photo documentation, and completion verification." homepage: "https://datadrivenconstruction.io" metadata: {"openclaw": {"emoji": "🏗️", "os": ["darwin", "linux", "win32"], "homepage": "https://datadrivenconstruction.io", "requires": {"bins": ["python3"]}}}

Punch List Manager for Construction Closeout

Complete system for managing construction punch lists from creation through final acceptance.

Business Case

Problem: Punch list management is inefficient:

  • Paper lists get lost or outdated
  • Difficult to track completion status
  • Photos disconnected from items
  • Back-charges delayed due to poor documentation
  • Multiple walks create duplicate items

Solution: Digital punch list system that:

  • Creates items with photos and location markup
  • Assigns to responsible parties with deadlines
  • Tracks completion with before/after photos
  • Generates back-charge documentation
  • Provides real-time completion dashboards

ROI: 50% faster closeout, 80% reduction in disputed back-charges

Punch List Workflow

┌──────────────────────────────────────────────────────────────────────┐
│                      PUNCH LIST WORKFLOW                              │
├──────────────────────────────────────────────────────────────────────┤
│                                                                       │
│   CREATION            ASSIGNMENT          COMPLETION                 │
│   ┌─────────┐         ┌─────────┐         ┌─────────┐               │
│   │ Walk    │────────►│ Assign  │────────►│ Correct │               │
│   │ Site    │         │ Items   │         │ Items   │               │
│   └─────────┘         └─────────┘         └─────────┘               │
│       │                   │                   │                      │
│       ▼                   ▼                   ▼                      │
│   ┌─────────┐         ┌─────────┐         ┌─────────┐               │
│   │ Log     │         │ Notify  │         │ Submit  │               │
│   │ Items   │         │ Parties │         │ Photo   │               │
│   └─────────┘         └─────────┘         └─────────┘               │
│       │                   │                   │                      │
│       ▼                   ▼                   ▼                      │
│   ┌─────────┐         ┌─────────┐         ┌─────────┐               │
│   │ Photo   │         │ Set     │         │ Mark    │               │
│   │ + Tag   │         │ Deadline│         │ Complete│               │
│   └─────────┘         └─────────┘         └─────────┘               │
│                                               │                      │
│                                               ▼                      │
│   VERIFICATION        CLOSEOUT           ┌─────────┐               │
│   ┌─────────┐         ┌─────────┐        │ Verify  │               │
│   │ Re-walk │◄────────│ Accept  │◄───────│ Work    │               │
│   │ Site    │         │ Items   │        └─────────┘               │
│   └─────────┘         └─────────┘                                   │
│       │                   │                                          │
│       ▼                   ▼                                          │
│   ┌─────────┐         ┌─────────┐                                   │
│   │ New     │         │ Final   │                                   │
│   │ Items?  │────NO──►│ Accept  │                                   │
│   └────┬────┘         └─────────┘                                   │
│        │YES                                                          │
│        └──────────────► Back to CREATION                            │
│                                                                       │
└──────────────────────────────────────────────────────────────────────┘

Data Structure

from dataclasses import dataclass, field
from datetime import datetime, date
from enum import Enum
from typing import List, Optional
import uuid

class PunchItemStatus(Enum):
    OPEN = "Open"
    ASSIGNED = "Assigned"
    IN_PROGRESS = "In Progress"
    READY_FOR_VERIFICATION = "Ready for Verification"
    VERIFIED = "Verified"
    REJECTED = "Rejected"
    ACCEPTED = "Accepted"

class PunchItemPriority(Enum):
    CRITICAL = "Critical"     # Life safety / code compliance
    HIGH = "High"             # Affects occupancy
    MEDIUM = "Medium"         # Standard punch
    LOW = "Low"               # Minor / cosmetic
    OBSERVATION = "Observation"

class TradeCategory(Enum):
    GENERAL = "General Contractor"
    ELECTRICAL = "Electrical"
    PLUMBING = "Plumbing"
    HVAC = "HVAC"
    FIRE_PROTECTION = "Fire Protection"
    DRYWALL = "Drywall/Painting"
    FLOORING = "Flooring"
    MILLWORK = "Millwork/Casework"
    GLAZING = "Glazing"
    ROOFING = "Roofing"
    SITEWORK = "Sitework"
    LANDSCAPING = "Landscaping"
    CONTROLS = "Controls/BMS"
    OTHER = "Other"

@dataclass
class PunchItem:
    item_id: str
    punch_list_id: str
    description: str
    location: str
    trade: TradeCategory
    priority: PunchItemPriority

    # Location details
    building: str = ""
    floor: str = ""
    room: str = ""

    # Assignment
    assigned_to: str = ""
    assigned_date: date = None
    due_date: date = None

    # Documentation
    photo_before: str = ""
    photo_after: str = ""
    drawing_markup: str = ""
    spec_reference: str = ""

    # Status tracking
    status: PunchItemStatus = PunchItemStatus.OPEN
    created_by: str = ""
    created_date: date = field(default_factory=date.today)

    # Completion
    completed_by: str = ""
    completed_date: date = None
    completion_notes: str = ""

    # Verification
    verified_by: str = ""
    verified_date: date = None
    verification_notes: str = ""

    # Back-charge
    back_charge: bool = False
    back_charge_amount: float = 0.0
    back_charge_ref: str = ""

    # History
    history: List[dict] = field(default_factory=list)

@dataclass
class PunchList:
    list_id: str
    project_id: str
    name: str
    walk_date: date
    walk_attendees: List[str]

    items: List[PunchItem] = field(default_factory=list)
    status: str = "Active"  # Active, Complete
    created_by: str = ""
    created_date: date = field(default_factory=date.today)

    area: str = ""  # Building/floor/zone covered
    list_type: str = "Punch"  # Punch, Pre-Punch, Final

Python Implementation

import pandas as pd
from datetime import datetime, date, timedelta
from typing import List, Dict, Optional
from collections import defaultdict

class PunchListManager:
    """Construction punch list management system"""

    def __init__(self, project_id: str, storage_path: str = None):
        self.project_id = project_id
        self.storage_path = storage_path or f"punch_{project_id}"
        self.punch_lists: Dict[str, PunchList] = {}
        self.items: Dict[str, PunchItem] = {}

    def create_punch_list(
        self,
        name: str,
        walk_date: date,
        attendees: List[str],
        area: str = "",
        list_type: str = "Punch",
        created_by: str = ""
    ) -> PunchList:
        """Create new punch list from walk"""

        list_id = f"PL-{datetime.now().strftime('%Y%m%d%H%M%S')}"

        punch_list = PunchList(
            list_id=list_id,
            project_id=self.project_id,
            name=name,
            walk_date=walk_date,
            walk_attendees=attendees,
            area=area,
            list_type=list_type,
            created_by=created_by
        )

        self.punch_lists[list_id] = punch_list
        return punch_list

    def add_item(
        self,
        punch_list_id: str,
        description: str,
        location: str,
        trade: TradeCategory,
        priority: PunchItemPriority = PunchItemPriority.MEDIUM,
        building: str = "",
        floor: str = "",
        room: str = "",
        photo_before: str = "",
        drawing_markup: str = "",
        spec_reference: str = "",
        created_by: str = ""
    ) -> PunchItem:
        """Add item to punch list"""

        if punch_list_id not in self.punch_lists:
            raise ValueError(f"Punch list {punch_list_id} not found")

        # Generate item ID
        punch_list = self.punch_lists[punch_list_id]
        item_num = len(punch_list.items) + 1
        item_id = f"{punch_list_id}-{item_num:04d}"

        item = PunchItem(
            item_id=item_id,
            punch_list_id=punch_list_id,
            description=description,
            location=location,
            trade=trade,
            priority=priority,
            building=building,
            floor=floor,
            room=room,
            photo_before=photo_before,
            drawing_markup=drawing_markup,
            spec_reference=spec_reference,
            created_by=created_by
        )

        # Add history entry
        item.history.append({
            'date': datetime.now(),
            'action': 'Created',
            'by': created_by,
            'notes': ''
        })

        self.items[item_id] = item
        punch_list.items.append(item)

        return item

    def assign_item(
        self,
        item_id: str,
        assigned_to: str,
        due_date: date = None,
        assigned_by: str = ""
    ) -> PunchItem:
        """Assign item to responsible party"""

        item = self.items.get(item_id)
        if not item:
            raise ValueError(f"Item {item_id} not found")

        if due_date is None:
            # Default due dates by priority
            days = {
                PunchItemPriority.CRITICAL: 1,
                PunchItemPriority.HIGH: 3,
                PunchItemPriority.MEDIUM: 7,
                PunchItemPriority.LOW: 14,
                PunchItemPriority.OBSERVATION: 30
            }
            due_date = date.today() + timedelta(days=days.get(item.priority, 7))

        item.assigned_to = assigned_to
        item.assigned_date = date.today()
        item.due_date = due_date
        item.status = PunchItemStatus.ASSIGNED

        item.history.append({
            'date': datetime.now(),
            'action': 'Assigned',
            'by': assigned_by,
            'notes': f'Assigned to {assigned_to}, due {due_date}'
        })

        # Trigger notification
        self._notify_assignment(item)

        return item

    def mark_complete(
        self,
        item_id: str,
        completed_by: str,
        photo_after: str = "",
        completion_notes: str = ""
    ) -> PunchItem:
        """Mark item as completed by trade"""

        item = self.items.get(item_id)
        if not item:
            raise ValueError(f"Item {item_id} not found")

        item.completed_by = completed_by
        item.completed_date = date.today()
        item.photo_after = photo_after
        item.completion_notes = completion_notes
        item.status = PunchItemStatus.READY_FOR_VERIFICATION

        item.history.append({
            'date': datetime.now(),
            'action': 'Completed',
            'by': completed_by,
            'notes': completion_notes
        })

        return item

    def verify_item(
        self,
        item_id: str,
        verified_by: str,
        accepted: bool,
        notes: str = ""
    ) -> PunchItem:
        """Verify completed item"""

        item = self.items.get(item_id)
        if not item:
            raise ValueError(f"Item {item_id} not found")

        item.verified_by = verified_by
        item.verified_date = date.today()
        item.verification_notes = notes

        if accepted:
            item.status = PunchItemStatus.ACCEPTED
            action = 'Accepted'
        else:
            item.status = PunchItemStatus.REJECTED
            action = 'Rejected'
            # Re-assign for rework
            item.assigned_date = date.today()
            item.

Truncated for display — read the full file on GitHub.

Related Skills

View on GitHub
GitHub Stars333
CategoryContent
Updated1mo ago
Forks82

Languages

Python

Trust signals

100/100

From repository metadata: license, adoption, age and documentation. Not a code audit — see the Safety scan above for what the skill file itself contains.

No cautions