Build a project handover checklist with owners, locations, and open issues
Turn project handover notes into a structured checklist that records what must be transferred, who owns it, where it is stored, and what remains unresolved. A small synthetic example shows how to detect missing owners, locations, and open-issue details before handover.
Content checked 2026.09.20Hand-checked example
Show contents
Who this is forThis guide is for teams transferring a project between people and needing a checklist that makes ownership, file locations, and unresolved work explicit.
What you need
Python 3.12 and a terminal command that starts that version.
A text editor or spreadsheet program that can save UTF-8 CSV files.
A working folder where the script can create a new folder beneath outputs.
Only the Python standard library is required: csv and pathlib.
01Define what every handover item must answer
A useful handover checklist should tell the next person what the item is, who is responsible for it, where the relevant material is located, whether the item is complete, and what remains unresolved. A note such as files are on the drive is usually not specific enough for someone joining the project later.
This example uses six fields: item_id, handover_item, owner, location, status, and open_issue. status may be READY or OPEN. READY items must have an empty open_issue field. OPEN items must explain what remains unresolved.
02Create a synthetic project handover checklist
The following checklist is synthetic and was written specifically for this article. Save it as handover_items.csv. It contains five handover items, with two deliberate problems that should be caught before the checklist is accepted.
csv
item_id,handover_item,owner,location,status,open_issue
H001,Source code,Min,repo/main,READY,
H002,Test dataset,Jae,shared-drive/project/data,READY,
H003,Calibration procedure,Min,shared-drive/project/docs/calibration.pdf,OPEN,Final approval is still pending
H004,Supplier contact list,,shared-drive/project/admin/suppliers.csv,READY,
H005,Open bug list,Jae,,OPEN,Two export bugs remain under review
H001 through H003 are structurally complete. H004 has no owner even though it is marked READY. H005 describes an open issue but has no location for the bug list. The example therefore contains two validation problems.
03Review the checklist by hand first
item_id
Expected result
Reason
H001
PASS
Owner and location are present; READY has no open issue
H002
PASS
Owner and location are present; READY has no open issue
H003
PASS
OPEN item includes owner, location, and unresolved issue
H004
FAIL
Missing owner
H005
FAIL
Missing location
The expected totals are 5 checklist items, 3 valid items, and 2 invalid items. There are 2 OPEN items, H003 and H005, and both contain non-empty issue descriptions. The problems in this example are therefore not missing issue text; they are missing responsibility and location information.
This distinction matters because a project can have legitimate open issues and still be ready for handover if the unresolved work is clearly described, assigned, and locatable.
04Validate the handover checklist with Python
Save the following script as check_handover.py. It checks required columns, duplicate IDs, owners, locations, allowed status values, and whether the open_issue field is consistent with the status. It writes a review report without changing the original checklist.
python
import csv
from pathlib import Path
SOURCE = Path("handover_items.csv")
OUTPUT_DIR = Path("outputs") / "handover_check_result"
REPORT = OUTPUT_DIR / "handover_review.csv"
REQUIRED_COLUMNS = [
"item_id", "handover_item", "owner", "location", "status", "open_issue"
]
VALID_STATUS = {"READY", "OPEN"}
def add_issue(issues, row_number, item_id, issue):
issues.append({
"row_number": row_number,
"item_id": item_id,
"issue": issue,
})
def main() -> None:
if not SOURCE.is_file():
raise FileNotFoundError(f"Source CSV not found: {SOURCE}")
if OUTPUT_DIR.exists():
raise FileExistsError(f"Output folder already exists: {OUTPUT_DIR}")
issues = []
seen_ids = set()
item_count = 0
open_count = 0
with SOURCE.open("r", encoding="utf-8-sig", newline="") as stream:
reader = csv.DictReader(stream)
if reader.fieldnames != REQUIRED_COLUMNS:
raise ValueError(
f"Header mismatch. Expected {REQUIRED_COLUMNS}, got {reader.fieldnames}."
)
for row_number, row in enumerate(reader, start=2):
item_count += 1
item_id = row["item_id"].strip()
handover_item = row["handover_item"].strip()
owner = row["owner"].strip()
location = row["location"].strip()
status = row["status"].strip()
open_issue = row["open_issue"].strip()
if not item_id:
add_issue(issues, row_number, item_id, "MISSING_ITEM_ID")
elif item_id in seen_ids:
add_issue(issues, row_number, item_id, "DUPLICATE_ITEM_ID")
seen_ids.add(item_id)
if not handover_item:
add_issue(issues, row_number, item_id, "MISSING_ITEM_NAME")
if not owner:
add_issue(issues, row_number, item_id, "MISSING_OWNER")
if not location:
add_issue(issues, row_number, item_id, "MISSING_LOCATION")
if status not in VALID_STATUS:
add_issue(issues, row_number, item_id, "INVALID_STATUS")
elif status == "OPEN":
open_count += 1
if not open_issue:
add_issue(issues, row_number, item_id, "MISSING_OPEN_ISSUE")
elif open_issue:
add_issue(issues, row_number, item_id, "READY_HAS_OPEN_ISSUE")
OUTPUT_DIR.parent.mkdir(parents=True, exist_ok=True)
OUTPUT_DIR.mkdir()
with REPORT.open("x", encoding="utf-8", newline="") as stream:
writer = csv.DictWriter(
stream,
fieldnames=["row_number", "item_id", "issue"],
)
writer.writeheader()
writer.writerows(issues)
affected_items = len({row["item_id"] for row in issues})
print(f"Checklist items: {item_count}.")
print(f"Open items: {open_count}.")
print(f"Validation issues: {len(issues)}.")
print(f"Affected items: {affected_items}.")
print(f"Report: {REPORT.as_posix()}")
if __name__ == "__main__":
main()
05Compare the expected review report
Because the CSV header is row 1, H004 is physical row 5 and H005 is physical row 6. The review report should contain exactly two issue rows.
Confirm that every item has one clearly named owner, even if ownership will change after handover.
Open each listed location and verify that the next person can actually access it.
For OPEN items, state the unresolved issue, current status, and next expected action.
Check that READY items do not hide unresolved work in comments, chat messages, or private notes.
Record credentials through an approved password or access-management process rather than placing secrets in the checklist.
Run the script again without changing OUTPUT_DIR. It should stop with FileExistsError instead of replacing the previous review.
A path can be syntactically present but still useless if permissions are missing or the referenced file is outdated. The checklist should therefore be reviewed by the receiving person, not only by the person leaving the project.
07Recognize common handover failures
Weak handover entry
Why it is insufficient
Owner: Team
Responsibility is unclear if no person or defined role is accountable.
Location: Drive
The receiving person still has to search for the actual file or folder.
Status: Done
Done is ambiguous unless the team's definition of completion is clear.
Open issue: Needs work
The problem and next action are not specific enough.
Credentials included in CSV
A general handover checklist is not an appropriate place for passwords or secrets.
Do not mark an item READY simply because a file exists. A usable handover also depends on access, current documentation, ownership, and whether the receiving person understands unresolved decisions.
08Expand the checklist for larger projects
A real project may need additional fields such as receiving_owner, due_date, repository branch, access_required, last_verified_date, dependency, contact person, equipment location, approval status, and next milestone. Add fields only when they improve transfer clarity.
This script validates completeness and internal consistency, not whether a location is reachable or an open issue description is technically correct. Access checks, file freshness, repository state, equipment condition, and knowledge transfer require separate review.
The checklist should be versioned or dated and retained with the project records. After the receiving person verifies the handover, record that acceptance separately instead of silently rewriting the original transfer state.
Execution and verification record
2026-09-20 · hand-checked example · target: Python 3.12 · standard library: csv, pathlib · no execution
Manually counted 5 synthetic handover items and 2 items with OPEN status.
Manually checked H001, H002, and H003 as structurally valid.
Identified H004 as missing its owner and H005 as missing its location.
Confirmed that both OPEN items contain non-empty open_issue descriptions.
Derived the expected physical CSV rows as row 5 for H004 and row 6 for H005.
Inspected the script for required headers, duplicate IDs, owner and location checks, status consistency, output collision protection, and preservation of the original CSV.
Verification limits
The code was not executed by the author of this response; no review CSV was created.
The script does not test whether listed paths are accessible, current, or correct.
The synthetic owners, locations, and issues are examples and do not describe a real project.
Secrets, permission transfer, repository state, equipment condition, and actual knowledge-transfer quality were not tested.
The official documentation URLs were provided from known documentation locations but were not checked live.
Define a simple team filename convention, test it on a synthetic folder, and write a review report without renaming or deleting anything. The checker separates structural errors, invalid dates, and unsupported extensions.
Turn raw release notes into a changelog entry that separates changes from required user actions and verification steps. A synthetic software update shows how to make a release note useful to someone who did not make the change.
Instead of stopping at another summary of the meeting, separate agreed work from open items. Turn synthetic meeting notes into a list with owners, due dates, deliverables, and evidence of completion, and write an AI request that assists with the same task.
Manage each article as one row and separate drafting, review, approval, and publishing. Covers importing a local CSV, dropdowns, filter views, sharing permissions, and version history, and sets up a flow for manually updating site files after approval.