docs(ingest): document the post-first migration contract at the native seam (#857)
CI / lint (push) Successful in 3s
CI / frontend-build (push) Successful in 18s
CI / backend-lint-and-test (push) Successful in 26s
CI / integration (push) Successful in 3m16s

Milestone #67 step 3. Spell out, at the IngestCore.run seam resolution, that
post_record_key + write_post_record are the post-first contract a platform
implements when migrating onto the native core ingester — the post-record owns
the body/links, the per-media sidecar carries image identity only. The import
side is already self-enforcing via uses_native_ingester → importer.post_first.
Durable directive recorded as FC project rule #120.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-15 10:20:03 -04:00
parent 8b99dc9b81
commit 41aa8fe39e
+12 -3
View File
@@ -141,9 +141,18 @@ class Ingester:
# tick has no resumable backfill state.
checkpoint = mode in ("backfill", "recovery", "recapture")
ledger_key = self._ledger_key
# Optional seams (Patreon native ingester): capture pure-text posts that
# have NO downloadable media so the artist archive is complete. Absent on
# stub clients/downloaders (unit tests) → media-less posts skipped as before.
# POST-FIRST CONTRACT (milestone #67): these two optional seams make a
# platform "post-first" on the native core ingester — the post-record is
# the single authoritative writer of the post body/links/metadata, and the
# per-media sidecar carries image identity only (download_service flips
# importer.post_first via uses_native_ingester, so the import side follows
# automatically). A platform migrating off gallery-dl onto the native core
# adopts post-first by implementing BOTH:
# client.post_record_key(post) -> (ledger_key, post_id) | None (gate)
# downloader.write_post_record(post, artist_slug) -> PostRecordOutcome
# Absent on stub clients/downloaders (unit tests) and on not-yet-migrated
# platforms → media-less posts are skipped as before and the body still
# comes from the per-media sidecar (gallery-dl path). See [[post-first-ingest-contract]].
post_record_key = getattr(self.client, "post_record_key", None)
write_post_record = getattr(self.downloader, "write_post_record", None)
start = time.monotonic()