agentsclimarketplace

Ferpa deid

Skill chaz-clark/canvas-toolbox/.claude/skills/ferpa-deid

Use for the de-identification / re-identification WORKFLOW — building the course-wide de-id master, de-identifying submissions or a gradebook (docx/pdf/xlsx/jupyter/databricks/text/comments) before anything reaches the LLM, re-identifying keyed results back to students, and scanning for name leaks. Load this when preparing student artifacts for AI processing or turning keyed results back into a named report. The FERPA *discipline* (never read Zone-2 files) is constitutional and always applies; this skill is the *how* of the de-id machinery.From its SKILL.md

Install
npx -y skills add chaz-clark/canvas-toolbox --skill ferpa-deid

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 2 stars2 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

SKILL.md

3.9 KB, as published. Nobody here has run it

FERPA de-identification / re-identification

The machinery that lets student work be processed by an LLM without a name ever reaching cloud context: strip identity → opaque keys → process → map keys back locally.

The constitution (AGENTS.md) is the law: the name-bearing files (.deid_master.csv, .keymap.json, .known_names.txt, .review.csv, submissions_raw/, feedback/_grader*.csv) are FERPA Zone-2 and are never read or displayed — verify with wc -l/ls, never cat/head/grep. This skill runs the de-id tools; it never bypasses that rule.

The two-zone flow

raw submissions (names) ──deidentify──▶ opaque keys ──▶ LLM / analysis
        ▲                                                     │
        └────────── reidentify (BY KEY, local) ◀──────────────┘
  • Zone 1 (cloud-safe): de-identified keys + grades. Fine for the LLM.
  • Zone 2 (local only, gitignored): the keymap/master that links keys ↔ names.

Building the master

build_deid_master.py builds the course-wide .deid_master.csv — one row per student, keyed by user_id, with a stable opaque deid_code = sha256(user_id)[:6]. It dedups multi-section students (a student in S1+S2 is otherwise returned twice) and auto-derives .known_names.txt (the scrub roster). Run --force to refresh from current enrollment. This is the identity surface every keyed tool and accommodation consumes.

De-identifying artifacts (before the LLM)

grader_fetch.py de-identifies submissions automatically, dispatching to the right format adapter. The standalone adapters exist for direct/one-off use:

ArtifactTool
Word docsgrader_deidentify_docx.py
PDFsgrader_deidentify_pdf.py
Excelgrader_deidentify_xlsx.py
Jupyter notebooksgrader_deidentify_jupyter.py
Databricks exportsgrader_deidentify_databricks.py
Plain textgrader_deidentify_text.py
Canvas submission commentsgrader_deidentify_comments.py
A gradebook exportgrader_deidentify_gradebook.py

Re-identifying results (BY KEY — never by sort order)

  • grader_reidentify.py maps key → user_id via .keymap.json, and is duplicate-aware (user_id → [keys]): one student legitimately has many keys across submission batches (e.g. final-review_* + fpr_*). Never map by row position / sort order — that misattributes results. If two batches share user_ids, that's expected; the keymap disambiguates.
  • grader_reidentify_gradebook.py re-identifies a de-identified gradebook.
  • Re-identified output is Zone-2 — write it outside any cloud-synced or git-tracked path (e.g. ~/Downloads/), never back into the repo.

Verifying no leak

grader_name_leak_check.py scans keyed/de-identified artifacts for any name that slipped through the scrub (against .known_names.txt). Run it before handing de-identified material to the LLM if you're unsure the scrub was complete.

Quick command map

AskCommand
"Rebuild the de-id master / student list"build_deid_master.py --force
"De-identify these submissions"(usually automatic via grader_fetch.py)
"Turn the keyed results back into names"grader_reidentify.py --challenge-dir grading/<name>
"Check nothing leaked a name"grader_name_leak_check.py …

Keep looking

Skills are one crate of 627,801. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.