Platform ingestion and rendering
Platform behavior has two owners: Core acquires and normalizes content; Web
renders canonical resources. Shared source imports carry the ResourceKind and
ResourcePlatform contracts, while each Worker owns its runtime behavior.
Core ingestion
Section titled “Core ingestion”source cron or saved URL -> ingest/acquisition.ts -> ResourceProcessingV2Workflow -> ingest/platforms/* -> canonical resources/resource_translations -> AI Search syncRelevant files:
workers/core-worker/src/index.ts: cron dispatch;workers/core-worker/src/ingest/acquisition.ts: saved-URL detection and acquisition routing;workers/core-worker/src/ingest/platforms/: platform-specific durable processing;workers/core-worker/src/ingest/stored-resource.ts: stored-resource reads, row projection, and processability gates;workers/core-worker/src/ingest/resource-persistence.ts: enrichment graph projection into the app-ownedDOMAIN.persistResolvedResourcetransaction sink.
Keep the ingest axes independent:
- monitored
Source.platform: RSS, Twitter, or YouTube; - monitored
Source.kind: blog or news feed/editorial classification; Resource.kind: blog, forum, post, video, paper, image, or file;Resource.resourcePlatform: Hacker News, Twitter, YouTube, or null;- representation:
file_typeMIME plus optionalstorage_key; - provenance: nullable
source_id; - user lifecycle:
user_resources, optionalresource_placements, and minimaluser_filesraw-blob ownership.
The valid (kind, resourcePlatform) identities are blog / null,
forum / hackernews, post / twitter, video / youtube, paper / null,
image / null, and file / null. Source.kind remains
separate: both blog and news sources render resources through the blog shell,
and the Article content-kind filter groups both source kinds. The source kind remains
editorial provenance rather than a second presentation identity.
PDF acquisition adds neither a platform nor a PDF-specific kind. Academic
enrichment promotes an identified work to paper; an unresolved readable PDF
falls back to file with file_type='application/pdf'. HN/Twitter carriers stay carrier Resources and
link a separately resolved target through subject_resource_id.
To add a platform:
- implement durable processing in
ingest/platforms/; - add an acquisition branch when saved URLs should resolve to it;
- add only the required cron line when it has a monitored source;
- normalize provider facts into common creators, versioned kind metadata, exact identifiers, and an optional immediate subject;
- add its locator, valid identity pair, and narrowed kind adapter;
- keep profile saves/locations in
user_resources/resource_placements, raw-blob ownership inuser_files, and monitored provenance inresources.source_id.
There is no Core platform registry to update.
Web rendering
Section titled “Web rendering”Web receives canonical resource cards from the shared read layer and switches
exhaustively on persisted kind. Readers consume canonical creators, kind
metadata, identifiers, file facts, and subject facts; they never interpret
provider JSON or resolve target URLs.
web-tanstack/src/lib/resource/presentation.tsfor labels and source policy;web-tanstack/src/components/feed/ResourceCardBody.tsxandcards/for kind-owned card rendering;web-tanstack/src/components/resource/readers/for kind-owned detail layout;web-tanstack/src/components/resource/{hackerNewsDiscussion,postPresentation,videoPresentation}.tsfor canonical kind metadata projection;web-tanstack/src/lib/resource/file.tsfor the few file labels shared by cards and readers.
Card and reader composition is exhaustive over every product kind;
resourcePlatform supplies only platform presentation policy. PDF preview is
layered on readable-document/paper presentation from the MIME representation. Source.kind
remains in the source domain and is intentionally absent from resource
presentation DTOs.
Dispatch product presentation only from canonical kind plus optional
resourcePlatform.
Verification
Section titled “Verification”- Run Core lint/typecheck for every ingest change.
- Use
resyncResourceto exercise acquisition → enrichment for an existing resource whose source changed. - Use
wrangler dev --test-scheduledto exercise cron discovery and batch error isolation; resync does not cover cron. - Tail logs and compare
enrichment_status='failed'counts before and after production smoke tests.