Geekabode

Geekabode privacy notes (draft)

DRAFT: owner and counsel must review before launch

These draft notes describe the information Geekabode uses, what stays in your browser, what reaches its server and other services, and how stored records are retained. Service settings and retention that still need owner confirmation are listed below. Owner and counsel must review these notes before launch.

What stays in your browser

The calculator uses browser storage on this site's origin to save your calculator numbers, choices and sign-in records:

Signing out clears the sign-in session while leaving your saved calculator numbers, compare cities and theme choice in place. You can clear this site's data in your browser settings. Reset clears the saved calculator profile and restores calculator defaults.

What this site's server sees

On a page load the page asks this site's own routes for market data (with your saved compare cities), housing evidence, news points, partner links, listing-search status and account configuration. When you search, the typed city or ZIP — or coordinates from the location button, rounded to two decimals before they leave the page — travels to the listing-search route together with your filters, and the typed place also travels to the property-tax route. Permission for location is only ever requested when you press that button.

The calculator math itself runs in your browser; the form is not submitted to a server to compute a scenario. Two routes do receive your numbers: the written read (described below) and the listing analysis, which sends the listing plus a subset of your figures — budget, down payment, monthly budget, rate, term, tax, insurance, HOA, maintenance and PMI. The stored row for a cached listing analysis keeps the answer, the comps and timestamps, not your buyer figures.

This code also writes a few operational lines to its own function log: analysis failures record a user id, a listing id and an attempt id. The log lines written by this code do not print your IP address. What the hosting platform records around those functions is outside this file and is listed as an open item below.

Email, sign-in and credit records

Sign-in uses your email address, sent from your browser directly to the account service as a one-time code request, or a sign-in provider when the account service offers one. This site's server never sees the code you type: it receives the token your browser already holds and reads back your id, your email address and the confirmation time. The account page then shows your id, email address, credit balance and admin flag.

Credits leave records in the database: ledger entries for the free grant and recorded charges and refunds, plus listing attempt lineage records. Every fresh listing analysis costs one credit. Exact cached rereads of a saved analysis stay free. Recorded paid attempts link the charge, any refund and the outcome, so a reversal is tied to its own charge. The one-time free grant is also recorded against a normalized form of your email address — lower-cased, with the +tag and Gmail dots removed — so it can be granted only once. How long the account service keeps your address, and what it logs, belongs to that service and is an open item below.

The written read: inputs, AI providers and stored replies

The written read is produced by third-party AI providers. Signed-in and signed-out written reads try free routes first: OpenRouter's free router or a model the operator pins, then Google Gemini's free tier, which may use the request to improve their models. They then try low-cost paid models through Vercel's AI Gateway, followed by OpenRouter's paid Auto Router. Hourly city reads try those paid Gateway models first, then the free routes, then OpenRouter's paid Auto Router. Routes without a configured credential are skipped. Which of them is live is an owner setting that the code cannot read from here, and each provider processes what it receives under its own policy.

What travels to a provider: the location text when it reads as a city or a ZIP, the timeline, the loan term, a price band instead of your exact price, a down-payment band instead of your exact amount, the names of the cost fields you left blank, scenario rows rounded to the nearest $500, the scenario basis and the public evidence items. What does not travel from this code: your email address, your user id and your IP address. The provider's key stays on the server as a request header.

A successful reply is stored server-side under a SHA-256 digest that includes the validated inputs and your account id when signed in, or an anonymous marker containing the forecast issue date when signed out. The account or anonymous marker is included in the digest; the persisted cache key does not contain your raw account id. The stored reply row holds the written read, its evidence list, the basis, the model name, the time and the disclaimer. It does not store your email address, raw IP address or raw financial form. The model's own prose can repeat the location you typed, so the stored reply may mention your city or ZIP. The same stored answer is reused for 24 hours; a cached listing analysis is reused for 30 days.

Written reads need a sign-in by default. Signed-out reads are optional and are switched off unless the operator enables them. For enabled signed-out reads, the IP-based budget identity stored in the database is a keyed HMAC-SHA-256 under a server secret, bucketed by IPv4 address or by IPv6 /64 network, with IPv4-mapped addresses folded into the IPv4 bucket. That anonymous budget is separate from the signed-in one; the stored answer and cache digest are described above.

IP addresses and the keys derived from them

The server derives a client IP address from request headers, with the connection address as a fallback. It uses that address for short-lived rate limits in the memory of a running function instance and to compute the durable keys described below. These database limit records store derived keys rather than the raw IP address. Function memory disappears when an instance is recycled; the hosting platform's own logging and retention still need owner review.

For signed-in written reads, the daily claim key is a namespaced SHA-256 digest of the verified account id (ai_user:v1:), stored with the claim time and a token. It has no IP address component: the same account keeps its daily allowance when its network changes, and separate accounts on one network have separate allowances. This digest is pseudonymous account data, not a secret. For the optional signed-out path, the IP-based budget identity uses the keyed HMAC and address buckets described above. The two paths keep separate keys and separate daily budgets. A claim stops limiting new reads after 24 hours; how long the row itself then survives is described next.

What is stored, and what actually gets deleted

Cleanup runs two ways. A scheduled job calls the purge function once a day. A cache write also calls it, and after a successful call a warm instance skips further calls for an hour. The purge function deletes exactly four things: cache rows computed more than 30 days ago, and paid-work claim, paid-failure and daily-claim rows more than 2 days old. It does not delete attempt records, credit ledger entries, listing unlocks, free grants or purchases. The 24-hour written-read reuse window and the 30-day listing-analysis cache window decide reuse; they do not delete a stored reply. A scheduled run that fails is retried the next day, so there is no fixed maximum age by which a row is deleted. The daily-claim cleanup depends on the latest purge migration having been applied to the live database, and whether it has been is unknown; the owner must confirm it. Daily-claim rows written by earlier code under an unsalted hash of an IP address are removed by a separate one-time migration that has not yet been applied; until then they follow the 2-day rule above. The scheduled job also depends on a cron secret being set in the live deployment, which the owner must confirm.

Other services named in the code

The site uses Vercel Web Analytics. It is cookieless and reports aggregated page views and a few anonymous interaction counts: form started, answer shown, poll answer and button clicks. No personal or financial details are sent in those events.

Each of those parties processes what reaches it under its own policy. Those policies, and the retention of everything outside this repository, are not readable from this source tree.

What the owner still needs to confirm

Before this page can be anything other than a draft, the owner must confirm each of these, because none of them is established by the tracked code:

These privacy notes remain a draft until the owner confirms the open settings and retention questions and counsel reviews the final wording.