---
name: versioned-artifacts
description: Never overwrite a file a human has already been given. Write the revision to a new, dated, version-numbered filename and hand back the new path, so the person reviewing yesterday's copy and the agent reading today's are never silently looking at different data under one name. Use this skill WHENEVER regenerating, re-exporting, correcting, enriching, re-running, fixing or otherwise re-editing any artifact that has already been shared, uploaded, linked, sent, published to a sheet, or referenced in a handoff — CSVs, review packets, exports, reports, label files, scored lists, spreadsheets. Use it BEFORE writing the file, not after, because the damage is done at the moment of overwrite and is not recoverable from the artifact itself. Use it even when the change seems tiny or purely additive ("just adding a column", "same data, one fix"), because a same-named file that has quietly changed shape is exactly what breaks a spreadsheet import, invalidates a half-finished review, and makes two people's numbers disagree with no way to tell which is stale.
---

# Versioned artifacts — the filename is a contract

The moment a file leaves the repo — uploaded, linked, sent, opened in a
spreadsheet — its name becomes a reference someone else holds. Overwriting it
breaks that reference without breaking anything visible.

The specific failure this exists to stop: a CSV is shared, the human starts
reviewing it, the agent regenerates it with a fix, and now the human's marks
refer to row positions and column names that no longer exist. Nothing errors.
The marks just quietly stop meaning what they say.

**The rule: a shared artifact is immutable. Revisions get a new name.**

## Onboarding — start here

### 1. What this skill does

Gives every regenerated artifact a new filename carrying its version and date,
keeps the previous one on disk, and writes a one-line pointer recording what
changed between them. The human's old copy stays valid; the new one is
unambiguously new.

It also covers the Google Sheets case, where the failure is worse: a re-uploaded
CSV does not update the sheet a reviewer already has open. It creates a second
file, or lands in Drive as an unopenable blob, and the reviewer keeps marking the
stale one.

### 2. What it can't do — say this before promising anything

| The user wants | Reality |
| --- | --- |
| To recover the version someone already reviewed | Only if it was never overwritten. That is the whole point — this skill is prevention, and there is no cure. Check git first; an uncommitted overwrite is gone. |
| Infinite versions with no cleanup | Versions accumulate. Prune deliberately at handoff time, and record which version each downstream number came from before deleting anything. |
| Versioning of derived caches and scratch files | Not those. Version what a **human** has been handed. A resumable cache like `data/.classify_cache.jsonl` is append-only machinery, not an artifact. |
| A live-updating spreadsheet from a re-run CSV | Sheets has no such thing via upload. Either write into the existing sheet through the API, or create a new sheet and say plainly that the old link is stale. |
| Version numbers that mean semantic versions | They do not. They are a monotonic counter plus a date, and their only job is to make two files distinguishable at a glance. |

### 3. Setup

None. No credentials, no dependencies. It is a naming discipline plus a pointer
file.

**Verify** you are about to overwrite something shared, before you write:

```bash
git log --oneline -1 -- data/the-file.csv 2>/dev/null && echo "TRACKED — check who has it" || echo "untracked"
```

### 4. How to invoke

It fires from its description whenever an artifact is being regenerated. Ask for
it directly with "version this properly" or "use versioned-artifacts".

### 5. Cost

Free. Disk only.

### 6. The rest of the skill

- `references/naming.md` — the naming scheme, the pointer file, and the Sheets case

---

## The procedure

### Step 1 — Before writing, ask whether this name has left the repo

It has left if it was: sent to the user, uploaded, pushed to a sheet, linked in a
message, or named in a handoff document. If any is true, do not write that name
again.

If unsure, assume it has. The cost of an extra version is a file; the cost of a
wrong overwrite is somebody's finished work.

### Step 2 — Name the new one so a human can order them at a glance

```
<base>-<n>.<ext>            icp-handcheck-11.csv
<base>-<n>-<yyyy-mm-dd>.<ext>   scored-leads-3-2026-08-14.csv
```

`n` increments; it never restarts and never gets reused. Include the date when
the artifact is regenerated on a cadence, so two versions from different days are
distinguishable without opening them.

Do not use `-final`, `-v2-real`, `-fixed`, `-new`, or an unsuffixed name beside a
suffixed one. Every one of those becomes ambiguous the second time it happens.

### Step 3 — Record what changed, in one line

A version number says two files differ. It does not say whether the difference
matters, and the reviewer holding the old one needs to know whether to restart or
carry on.

```
data/ARTIFACTS.md
- icp-handcheck-11.csv (2026-08-14) — added source_url + cached_page; mark split into
  checked/supported checkboxes. Supersedes -10. Marks from -10 do not transfer: columns moved.
```

State explicitly whether prior marks still transfer. That is the only thing the
reviewer actually needs from this line.

### Step 4 — For spreadsheets, update in place or say the link is dead

Re-uploading a CSV does **not** update an existing sheet. Two correct options:

1. **Write into the existing sheet** via the API, when the columns are unchanged
   and someone is mid-review. Their marks survive.
2. **Create a new sheet** when the shape changed, and say in the same breath that
   the old link is stale and any marks on it are lost.

The wrong option is handing over a CSV and asking them to import it — that is the
step that silently fails, and it is the reason this skill exists.

Record the sheet id and url next to the CSV (`<base>-sheet.json`) so the next
run can find the sheet it needs to update rather than making another one.

### Step 5 — Keep the old file

Do not delete the superseded version in the same breath as writing the new one.
It is the only evidence of what the human was looking at, and it costs kilobytes.

Prune at handoff time, deliberately, once nothing downstream cites it.
