Use this checklist to decide when a Kismet-powered site is ready for guests. It
collects every check from the SDK tooling, the guides, and real launches into
one list. Coding agents should treat it as the definition of done.
Stages and rows marked (if used) apply only when your site uses that feature.
A check passes only with proof: an exit code, an HTTP status, a screenshot, or a
quoted value. A green build, a 200, a merged pull request, or a passing preview
proves only its own layer. None of them proves the interface or the live site.
If you skip a check, record the reason and an owner in the pull request.
Never submit a payment against live data while testing. Quotes and bookings reach
the property manager’s real reservation system. Prove end-to-end booking with the
TEST booking request instead.
Vendored or supplied packages match their manifest
Each tarball’s SHA-256 and source commit match the supplied manifest, and the installed version string matches the pin
A3
Old package tarballs are removed and no longer referenced
npm ci --dry-run is clean
A4
Types
npm run typecheck (tsc --noEmit) exits 0
A5
Lint
npm run lint exits 0 with no new suppressions
A6
Production build
npm run build exits 0 and emits pages for every live property and group
A7
Unit tests
npm test exits 0
A8
Pre-commit gate
npm run check:precommit exits 0 (starters run it on every commit)
A9
Agent instructions are current
npx kismet init --check exits 0
A10
Framework upgrade notes reviewed
Breaking changes for your framework version are checked before you change code
A11
Runtime provides fetch
No env/no-fetch error (Node.js 18 or newer)
A12
No calls to removed Kismet API paths
Search the source for retired endpoints; your SDK version is the release that removed them
A13
Server and browser render the same package versions
No hydration mismatch (React #418/#425) in the console
A14
Negative controls fail when they should
check:negative-controls makes the expected recipe fail
A15
Element labels
check:element-labels shows each Element’s label, and the negative control fails when a label is removed
A16
Page contracts
test:page-contracts: every page uses Kismet.Page or is exempt, the marker and canonical URL are present, Accept: text/markdown returns Markdown with a Canonical: line, foreign origins return 404, private Markdown returns 404, unlisted pages return 200, and llms.txt lists only public pages
A17
Sort navigation
test:sort-navigation: ?sort= is honored on the server, the labelled control defaults to recommended, reload and Back keep the choice, and hostile values fall back
A18
Robots by environment
Staging and preview disallow crawlers; KISMET_ENVIRONMENT takes precedence over the host’s environment; production welcomes crawlers
A19
Structured data on the running server
check:structured-data:running-server passes, crawls at least one page, and finds one marker, one @graph, and every required path
The live key shows recent use after deploy, and unused keys are revoked
Credential list
B21
The exact site host is an allowed installation origin, a registered collection domain, and an authorized collection domain
Otherwise requests fail with ORIGIN_NOT_AUTHORIZED or ORIGIN_MISMATCH, and content links render empty
B22
Development origins: private development hosts are accepted, production requires HTTPS, partial-host matches are rejected, and the framework allows the development host
Unit test
B23
Credential values never appear in logs, pull requests, chat, or commits
Review
B24
Staging uses TEST and production uses LIVE in one hosting project: staging is served from its own branch with TEST settings, never from the production deployment
--env is required; a missing or invalid value fails with
env/invalid-environment. The command exits 0 when there are no errors.
Warnings are reported but never change the exit code. Fix each diagnostic and
re-run until it exits 0. npx kismet verify --env production runs this check
together with the recipe tests.
The collection homepage shows the collection name and every property, read from the API; no static headings or single reads
E2
The property page shows the name, description, images, and nightly-from price on its route, with VacationRental JSON-LD and a hasReviews link; the price is not only in JSON-LD
E3
Reviews show the author and text of every review from the API; nothing is stale or hard-coded
E4
AI-readable surfaces use Kismet.llmsTxt and Kismet.aiRobots, with zero checker issues
E5
Curated rows show exact group membership, without flattening or leaking members between groups
E6
A single-rental key produces a complete site without inventing a parent collection
E7
Group pages show exact membership with images near links, and CollectionPage.mainEntity.itemListElement matches exactly
E8
Results match exactly: ItemList count, order, positions, names, and URLs
E9
The property card shows its marker, image, property link, and price
E10
The search bar submits canonical checkIn, checkOut, and guests
E11
The blog index and posts come from article.list and article.get
E12
Nightly rates show every date and price, labelled indicative, without quote language
E13
Structured data includes type, additional type, URL, images, rooms, occupancy, location, rating, and offer
E14
Every property has a Markdown version with a canonical line
E15
Availability echoes the request, treats unknown as different from unavailable, and avoids “Book now” or “Guaranteed”
E16
Natural-language results keep the ranked order and show the query
E17
Policies are crawlable links, with an honest empty state
E18
Fixture plans show exact manifest fields and are labelled as not live
E19
Guest authentication runs in server handlers; tokens never reach the browser
E20
Guest saves go through the server; raw guest tokens and visitor IDs stay out of client code
E21
TEST booking requests are labelled sandbox and use an idempotency key; the client never sets price, card, or status
E22
Live mode reads live data and throws on failure; it never falls back to fixtures
E23
The blog index pages through every post and category
E24
Blog relations show the exact related and featured sets, never the post itself
E25
The group index lists every group once, with no invented counts
E26
Filters, sort, map, and quick view stay consistent and show only approximate locations
E27
Group landing pages show FAQs, reviews, stories, sibling groups, and empty states without leaking members
E28
Checkout URLs carry property, check-in, check-out, and guests, and Kismet re-quotes the stay
E29
Shared links are the same from Web Share and copy, Open Graph agrees, and no personal data or exact coordinates are exposed
E30
Every operation works with a scoped TEST credential
E31
Loading, empty, denied, unavailable, and expired-session states all render truthfully
E32
HTML, structured data, Markdown, and navigation agree on names, prices, and links
E33
Content the property manager edits is read from Kismet, never copied into code, and no counts or entities are hard-coded
E34
Each page has exactly one h1 at desktop and mobile widths
Conformance does not prove live inventory, complete pricing, or working payments.
The Elements bundle base is set before Elements loads (window.Kismet.bundleBase)
The checkout bundle returns 200
F2
(Next.js) The app exposes window.React, window.ReactDOM, and createRoot for the checkout bundle
The drawer mounts
F3
(Next.js) Checkout requests to /api/vr-reservations/*, /api/booking-attempts/identify, /api/identity/resolve, the payment-provider route, and /api/collection/* are proxied same-origin to Kismet, without shadowing your own API routes
Each returns 200 on your origin
F4
Fixtures styles load before your global styles, so its CSS reset does not change your typography
Visual comparison shows no change
F5
Desktop: pick dates and select Reserve; the bundle, quote (with a price), and payment provider return 200; the drawer shows the summary, guest form, and card form; the console is clean
Screenshot and network log
F6
Mobile: select dates and Book now; the same calls and result
Screenshot and network log
F7
The payment iframe actually mounts, not only the drawer
DOM check
F8
“Payment form unavailable” never appears; the card form loads on three consecutive attempts, and a failure lets the guest retry
Three runs
F9
The drawer and payment host stay in the light DOM
DOM check
F10
The drawer total matches the quote, and fees, taxes, and the cancellation policy are shown
Compare values
F11
Cards and the detail page reach the same checkout with identical fields
configured-checkout recipe
F12
Malformed dates are handled truthfully
Test case
F13
Invalid guest counts are handled
Test case
F14
Unavailable inventory is handled
Test case
F15
Changed prices are handled
Test case
F16
A reload mid-checkout is handled
Test case
F17
A missing checkout integration is handled
Test case
F18
Fixture prices are never substituted for real ones
Review
F19
The configured-checkout recipe passes against your URL
npx kismet recipes test --recipe configured-checkout --url <url>
F20
The integration’s TEST flow and server-confirmed checks pass before any LIVE pilot
Evidence
F21
A changed price or term shows the new offer; a copied total is never submitted
Test case
F22
An unavailable stay keeps the guest’s selection and never books another property
Test case
F23
A pending or unknown result shows pending; a redirect or event is not proof
Test case
F24
Confirmation comes only from the authoritative reservation result; payment is not a booking
Test case
F25
Retries follow idempotency, with no second payment after a timeout
Test case
F26
The client never authors totals or says “confirmed” before confirmation
Review
F27
A /booking-confirmation page exists, is noindex, renders from the redirect’s parameters, and shows a helpful fallback when they are missing
npx kismet check (site/booking-confirmation)
F28
Links back to a property from checkout resolve to your own property pages
Redirect returns 200
F29
Testing never submits a payment against live data; end-to-end booking is proven with a TEST booking request (201, labelled sandbox)
Pull request states “payment not submitted”
F30
The call to action prefers the drawer, then the handoff, then the not-configured state
Render test
F31
Prices read as “$X × N nights” with a subtotal, a taxes note, and one total; unpriced stays say “Price at the next step”
Screenshot
F32
(Group pricing) Requests use ISO dates with check-out after check-in, stay length 1–90, guests 1–100, a registered host, groupType=building, and repeated group and neighborhood slugs; errors are never shown as empty or sold out
Sign-in runs over HTTPS (localhost is allowed only with TEST); development uses an HTTPS tunnel registered as a development domain
H5
The flow completes: challenge, verify (200), then the guest profile request (200)
H6
TEST challenges return 202 without sending email; real codes require a verified host without a port
H7
An end-to-end sign-in on staging receives a real code and loads the guest profile
H8
Domain verification serves /.well-known/kismet-domain-verification as plain text with no redirect, verifies within 30 minutes, and does not change origins or grants
H9
Sign-in does not fail with IDENTITY_ANCHOR_NOT_FOUND
H10
Unknown errors show “Sign-in isn’t available” and log the problem code
H11
Server-side authentication uses HttpOnly cookies, CSRF protection, and origin checks; no tokens reach the browser
H12
(Google) The return page is public and same-origin, completes once, removes the fragment before any request, never logs the code, and restarts on bad parameters; cancelling creates no session
H13
(Google) The proxy preserves cookies, origin, CSRF header, method, and body, forwards every Set-Cookie, marks auth responses no-store, and keeps the opener
H14
Each documented sign-in error (401, both 403 cases, 409, expired return, 503, and a popup that closes signed out) is handled
H15
Saved homes round-trip and link to your own property pages
H16
Each preference state behaves as documented, TEST states never grant real benefits, and LIVE is enabled only after TEST
H17
Each documented preference error is handled, and retries are safe
H18
Contact capture passes the phone constraints, and a valid format is not treated as consent
H19
An accepted test email is not treated as delivered, and clicks are not treated as consent
npx kismet init has written the Kismet check workflow
L2
CI installs Chromium and runs npx kismet verify --env production on every push and pull request
L3
A deterministic fixture gate is required on pull requests
L4
A separate, bounded smoke test runs with a TEST key
L5
Deterministic checks cover membership, links, provenance, operations, structured data, Markdown, llms.txt, browser errors, and flow state; a model judge grades only qualitative criteria, with a visible rubric
L6
CI also runs type checks, lint, the build, and tests; any disabled step is documented with a tracking issue
L7
CI is green on the main branch
L8
CI fetches the main route of every page type and checks for a 200 response and JSON-LD
The public HTML, Markdown versions, llms.txt, and links are inspected on production
N2
A smoke test returns 200 for /, the results page, one property, one group, /llms.txt, /robots.txt, /sitemap.xml, and /booking-confirmation, and checkout returns a quote for an available stay
N3
F5 and F6 pass on production, stopping before payment
N4
Runtime logs show no new server errors for 30 minutes
N5
The key shows recent use, with no authentication errors
The pull request explains why, shows before and after screenshots, lists what changed, and maps each check ID to its result
P2
The verification section names the exact commands, the commit, each exception with its file, error, reason, and tracking issue, and the main branch’s state
P3
Only an authorized owner merges, and only after approval
P4
The main branch is protected: required review, no force push or deletion, and resolved conversations
P5
No secrets appear in commits, pull requests, logs, or chat
P6
The handoff notes record state, tested behavior, links, open gaps with owners, and where credentials live (never their values)
P7
Someone outside your team can complete the flow using supported APIs