tools: distinguish "captured in time" from "still alive"

analyze_media_age.py claimed age was ruled out because an image from
2025-11 was saved while one from 2026-08 was not. That conclusion does not
follow. "Saved" means some earlier run downloaded it, not that ChatGPT
still holds it — an image captured in June looks saved forever after, even
if it died in July. A month with no losses shows the exports were timely,
not that the assets survived.

- probe_survival_by_month.py: sample images already on disk, grouped by
  their conversation's month, and ask /files/{id} whether each still
  exists today. Old months still 200 → no expiry, and cadence did not save
  them. Old months now 404 → uploads do expire and cadence is the whole
  ballgame.
- analyze_media_age.py: stop asserting the unsupported verdict; say what
  the number does and does not show, and point at the probe.

One signal there is immune to the confound and survives: 2026-07-09 kept
38 images and lost 12. Same conversation, same day, opposite outcomes —
no retention policy does that, so at least part of this is per-asset.
This commit is contained in:
JesseMarkowitz
2026-08-17 08:53:54 -04:00
parent 04191eed8c
commit b9e8896b33
2 changed files with 174 additions and 3 deletions
+21 -3
View File
@@ -20,6 +20,15 @@ grouping outcomes by month and by source distinguishes the hypotheses:
* Neither → deaths scattered across months, or concentrated in a
few conversations while their neighbours survive.
IMPORTANT — what "saved" does and does not mean. It means the image was
downloaded by *some* run at *some* point, not that ChatGPT still holds it. An
image captured in June looks saved forever after, even if it died in July. So
a month with no losses shows the exports were timely; it cannot show the
assets survived. Use probe_survival_by_month.py to ask the API what is still
live today. The one signal here that is immune to this confound is a single
conversation that both kept and lost images: same age, same chat, opposite
outcomes means the cause is per-asset, not retention.
Run from the project root:
python tools/analyze_media_age.py
@@ -123,12 +132,21 @@ def main() -> None:
print(f" dead range : {old_d or '—'} … {new_d or '—'}")
if old_s and new_d and old_s < new_d:
print(
f" → an asset from {old_s} survived while one from "
f"{new_d} did not: age alone does not explain the loss."
f" → an asset from {old_s} was captured while one from "
f"{new_d} was not."
)
print(
" This does NOT disprove expiry: 'captured' means some "
"run got it in time,"
)
print(
" not that it is still on ChatGPT today. Run "
"probe_survival_by_month.py to tell"
)
print(" those apart.")
elif old_s and old_d and old_s > old_d:
print(
f" → everything dead is older than everything alive "
f" → everything lost is older than everything captured "
f"(cutoff between {old_d} and {old_s}): consistent with expiry."
)
print()