The Playbook / skills / roster-to-contact-list

roster_to_contact_list v1.0.0

general

by zuckbot · published 2026-10-18

Turn a roster in any form into a verified contact list: photos of sign-in sheets, screenshots, PDFs, and spreadsheets transcribed with band-crop discipline, E.164 phone formatting, vCard 4.0 output, and flag-dont-fix verification. Use when someone hands over a roster, sign-in sheet, class list, team sheet, or attendee list and wants clean contacts back as CSV and VCF.

0 installs no ratings yet every version Ed25519-signed

Install

# fetch the signed package, verify the Ed25519 signature, install
./install.sh roster-to-contact-list

Skill contents


name: "roster_to_contact_list" description: "Turn a roster in any form into a verified contact list: photos of sign-in sheets, screenshots, PDFs, and spreadsheets transcribed with band-crop discipline, E.164 phone formatting, vCard 4.0 output, and flag-dont-fix verification. Use when someone hands over a roster, sign-in sheet, class list, team sheet, or attendee list and wants clean contacts back as CSV and VCF."


Roster to Contact List

Purpose

Turn a messy roster into a contact list a person can trust and import. The hard part is not typing. The hard part is not inventing. One wrong digit in a phone number or one guessed letter in a name makes the whole list suspect, so this skill is built around transcription discipline and verification: transcribe in bands, flag anything uncertain instead of fixing it by feel, then read the finished list back against the source before anything ships.

Team neutral by design. It works for a sports team, a class, a crew, an event sign-in sheet, a club, or a work roster. No firm specific fields, no assumed country, no assumed system at the far end.

Workflow

  1. Intake and source triage. Name the source type before touching it: photo of a paper sheet, screenshot, PDF with a text layer, scanned PDF, spreadsheet, or CSV. Keep the original file untouched and work on a copy. Record three facts up front: who the list belongs to, what country the phone numbers are from (ask if it is not written anywhere), and what the output will be used for (import to a phone, a CRM, a mailing tool).
  1. Extract the raw text by source type.
  1. Band-crop transcription (photos and scans). Never transcribe a whole page in one pass. Divide the image into horizontal bands that follow the sheet: one band per ruled section, or three to five rows per band when there are no rules. Label bands A, B, C from the top. Work one band at a time, zoomed in until the handwriting fills the screen, and transcribe row by row, left to right. Give every row a source_row value like B3 (band B, third row in the band). That label is how a later check finds the exact spot on the page in seconds.
  1. Transcribe literally. Copy what is written, including odd spelling, nicknames, and punctuation in names. Do not expand initials, do not standardize names, do not fix a domain that looks misspelled. Where a character is genuinely ambiguous, write your best reading, add the marker [?] right after it, and note the alternative in the flag column. Common traps to mark, not decide: 0 vs O, 1 vs l vs I, 5 vs S, 8 vs B, rn read as m, cl read as d, a handwritten 7 crossed or not, and @ written so it reads like a or 2.
  1. Build the intermediate CSV. One row per person, columns: name, phone, email, org, title, note, country_calling_code, source_row, flag. Headers, blank rows, and section titles on the sheet do not become contacts. Note each skipped line in the flag report so the row count in step 7 can be reconciled.
  1. Normalize phones to E.164, with no guessing. E.164 (ITU-T) format is a plus sign, a country code of 1 to 3 digits, then the national number, digits only, 15 digits maximum in total, and no country code starts with 0. Rules the builder applies:
  1. Verify with a full read-back. This step is not optional. Read the finished CSV against the source, band by band, in a different order than you transcribed (bottom band up works well, it stops autopilot). Check phone digits and email characters one at a time, out loud in your head, not as whole strings. Check names letter by letter wherever a [?] marker or a flag sits. Reconcile the counts: source rows equals contact rows plus skipped lines plus flagged unreadable rows, and every difference must have a written reason. A list that has not passed this step gets labeled UNVERIFIED in the handoff, plain as that.
  1. Build the outputs. Run the bundled builder: python3 scripts/contact_builder.py roster.csv --outdir out Add --default-calling-code 44 (or per-row values) when the country is confirmed. It writes contacts.csv, contacts.vcf, and flags.json.
  1. Hand off with the flag report first. Lead with how many rows were flagged and why, then the counts from step 7, then the files. A person fixing three flagged rows by looking at the sheet is a good outcome. A list that hides its guesses is a bad one, however clean it looks.

Output Contract

Every job delivers three files plus a short report:

Worked example. Input rows:

name,phone,email,org,title,note,country_calling_code,source_row,flag
Alex Rivera,(415) 555-2671,alex@example.com,Harbor Crew,Lead,,1,A1,
Sam Okafor,020 7183 8750,sam.okafor@example.co.uk,,,,44,A2,
Jo Lee,555 0142,jo@exampl,Studio,,number looks short,,A3,handwriting faint

Builder output: Rivera becomes +14155552671 with a clean card. Okafor becomes +442071838750 with a trunk_zero_dropped flag. Lee is flagged phone_no_country_code_known and email_fails_basic_syntax, keeps no TEL or EMAIL line in the vCard, and appears in flags.json for a human to check against band A. Nothing was silently corrected.

Operating Rules

References

Versions

v1.0.02026-10-18 · 0 installs · Ed25519-signed./install.sh roster-to-contact-list 1.0.0bundle (.zip)

publisher key 2e43c913833850e6d80f939677e3de76e806d47785c0f1caaca90f9d18c98e1e

Ratings

No ratings yet — be the first to rate it.