# Public feed contract v1.0

## Endpoints and schemas

- `/feeds/jobs.json` -> `/schemas/jobs.schema.json`
- `/feeds/listings.json` -> `/schemas/listings.schema.json`
- `/feeds/signals.json` -> `/schemas/signals.schema.json`
- `/feed.json` remains the existing homepage signal format; the normalized signals feed is derived from it.

All are static JSON GET resources, not queryable APIs. There is no POST, login, server-side filter, payment, or subscription endpoint. No private worker/crew database is public. Empty collections mean no reviewed records have been published, not zero real-world supply.

## Envelope

`schema_version` is `1.0`. `generated_at` is snapshot serialization time. `source_updated_at` is the source snapshot update time, not a freshness guarantee. `status` is `empty` or `snapshot`; `items` is an array. Per-record dates and verification times must be retained. Generation alone must never refresh `last_verified_at`. Check `expires_at`, source links and visible details before acting. Rebuild normalized signals after updating `/feed.json`; this is not automatic yet.

## Jobs

Required public fields include stable `id`, detail `url`, employer-authorized title/description, employer, city/region/country market, trade, employment type, original posting/expiry dates, start date (nullable), duration, compensation, per diem, housing, travel, application URL, source/rights, last verification time, status and paid-placement disclosure. Pay amounts are nullable and employer-provided only. Per diem is separate from base pay. Unknown is not zero. No applicant contact details or CVs.

These are onsite traveling jobs: a remote project is NOT a work-from-home role. Use genuine city/region/country; no confidential street/site address is required in this feed. `direct_apply` may be true only for an actual supported direct application flow. Do not mark a resume-intake page as an opening. No JobPosting JSON-LD on collection/empty pages.

## Inventory

`category` is space, sublease, gear, or housing. The matching typed `attributes` payload describes critical IT MW / sf / utility / power status, sublease term and consent, equipment ratings and condition, or housing terms. MW is critical IT load, not grid demand or generation nameplate. Capacity, area, prices, and dates can be null when genuinely unknown. Public locations are city/metro only. Blind contact goes through a desk page; private seller identity and exact addresses are excluded.

`price.amount = null` means no published amount, never free. Price model and currency explain units. Do not infer InStock or a commercial offer merely from a directory record. No Offer JSON-LD until a real, authorized offer with visible terms exists.

## Source rights and privacy

Allowed publication-rights labels are `employer_permission`, `owner_permission`, `licensed_feed`, or `original_reporting`. A public URL is not a republishing license. Do not fill the feed from competitor scraping. No user instructions, private contacts, resumes, payment identifiers, keys, or NDA material belong in these records. Validate against strict schemas before export; schema validation does not replace rights or confidentiality review.

## Discovery and caching

See `/llms.txt` and the custom discovery manifest. Hosting `_headers` sets public read-only CORS on normalized feeds and schemas, and revalidation caching. The local Python preview does not implement `_headers`; verify these on the chosen host before claiming CORS support. ETag/Last-Modified is host-dependent. Version breaking changes with a new schema URL/version rather than silently reinterpreting units.
