Palm Engine

Sessions and consent

A first-party session cookie, a comment-section consent card, and a light view record. Still two endpoints.

Comments on this blog now wait for two things: the section in view, and a yes.

Until you accept, there is no request. Decline and the list stays hidden. Accept and the island fetches the comments. The Worker sets a first-party pe_session cookie, writes one view row, and returns the list.

The cookie is signed, HttpOnly, and lasts thirty days. It carries a session id. After you post, it also carries the name and email you submitted — for the Worker, not for the page.

The page never reads that cookie. Name and email in the form come from localStorage after a successful post. The next visit can skip the card if you already accepted.

We do not store a session row. The cookie is the session. Missing or invalid on GET mints a new one. Missing on POST is a 401. Writes are still Turnstile plus one comment per minute per address, and now five per hour per session.

What we record

One comment_views row per accepted load: session id, post slug, time, and the country Cloudflare already has on the request. That is the analytics. There is no site-wide banner and no third-party script.

A raw GET to /api/comments still mints a cookie and writes a view. The consent card is the human path. The Worker cannot see localStorage.

What did not change

Posts are still static files. The Worker still only answers /api/*. Same two endpoints. Email is still never in the public list. Replies still nest one level.

Search, a PWA, an admin UI, and media uploads stay named absences.

Comments

Comments load when this section is visible.