On your Mac
Your prompts, replies, models and recordings never leave your Mac. The app sends no analytics and no telemetry.
- Conversations
- Your prompts, the model's replies, any rating you give a reply, and the summaries a model writes of a long conversation's oldest turns: in data/cycast.db, in CyCast's folder in ~/Library/Application Support.
- Recorded runs
- What each run recorded: its settings, its events and the tensors it captured, in data/runs. When the finished runs together pass 20 GiB, the oldest are removed.
- Calibrations
- Each model's trait calibration, in data/traits.
- Models
- CyCast reads models from folders already on your Mac: the Hugging Face cache, LM Studio's and Atomic Chat's model folders, and any folder named in CYCAST_MODEL_DIRS. When you download a model from the model list, the app fetches its files from Hugging Face into the Hugging Face cache. It uploads no model and no file.
- Preferences
- Your sampling and display settings, in the app's own storage in the same folder. prefs.json keeps the first-launch model choice, the EULA version you accepted and the update versions whose notices you dismissed.
- Sign-in
- The account's sign-in token, encrypted with a key macOS keeps in your keychain, in account.json in the same folder.
The engine host that runs the models listens only on 127.0.0.1, this Mac's own address, so no other computer can reach it, and it starts with the Hugging Face libraries' offline and no-telemetry switches on. Downloads run in a separate process, only when you start one.
What the Mac app sends
The app talks to CyCast's account server over HTTPS, and to Hugging Face when you download a model (below). Creating an account sends your name, email and password; signing in sends your email and password. Both also send a digest of the Mac's hardware UUID and the Mac's computer name. After that, each call carries the sign-in token and that digest. Changing the password or deleting the account sends the password you type.
The app needs this server to run. It checks the account when it opens, when its window comes back into view, and about once a minute while it is open. It keeps a signed licence for this Mac, including the paid subscription end, covered version limit and the next online check deadline. The app and engine host check it independently. An offline or failed network check keeps a valid licence usable for up to 30 days since the last successful licence issue. After that, a new engine start needs an online check; a run already in progress can finish. Explicit sign-out or removal of this Mac ends its access. Cancelling renewal keeps versions covered by paid periods and their patches.
Hugging Face
The app connects to Hugging Face only when you start a download from the model list, and only huggingface.co, hf.co and hosts under them, over HTTPS; a redirect to any other host is refused. It asks for each of the model's files at the revision this version of CyCast pins.
Each request carries the headers Host, Accept, Accept-Encoding, Connection and User-Agent, and Range, when it resumes a file. The User-Agent is always cycast-download/1. It keeps no cookie a Hugging Face host sets, so none is sent back. Hugging Face also sees your Mac's IP address, as every server the Mac connects to does. No request carries a token, account data or any identifier of you or of your Mac.
Hugging Face can count downloads on its side, from its own server logs, and Hugging Face's own privacy policy applies to those requests.
On CyCast's server
To sign in, CyCast keeps your email, name, a hashed password and the Macs you use it on. Payments are handled by Stripe. Table by table, its database holds this.
Your account
One row per account.
- The email address you sign in with.
- Name
- The name you gave when you created the account.
- Password
- Only a hash of your password (scrypt, with a salt of its own). The password itself is not kept.
- Verified
- The verified email address and when email verification succeeded; a changed address needs verification again.
- Created
- When the account was created.
- Account id
- A random account id, which ties the rows below to the account.
Email verification and reset
One active challenge per account and purpose.
- Account
- The account id and the email address the challenge was sent to.
- Credential
- A digest of the verification code or reset token, bound to the account; never the code or token itself.
- Purpose
- Whether it verifies email, confirms an email change, or resets a password.
- Expiry
- When it expires: 15 minutes for a verification code, 30 minutes for a reset token.
- Attempts
- How many incorrect verification attempts were made; five ends the code's use.
A successful use deletes the challenge. A new request replaces it; account deletion removes it.
Subscription renewals
One row per Stripe subscription, to manage yearly renewal.
- Stripe
- The subscription id, originating Checkout Session id, customer id and Stripe Price, in live or test mode.
- Account
- The account id it belongs to.
- Renewal
- The subscription status, whether it cancels at period end, the current period end, and when its state was updated.
- Discount
- Whether the U of T discount is applied, so eligibility can be checked before renewal.
Paid subscription periods
Each paid year that grants version coverage, kept even after cancellation.
- Stripe
- The invoice id, subscription id, Checkout Session id and payment id, in live or test mode.
- Account
- The account id it belongs to.
- Period
- The paid period start and end; when it was paid, with its amount and currency.
- Reversal
- When it was refunded or revoked, and why; partial refunds keep coverage.
Kept subscription records
Paid years kept after account deletion, without the email, name or account id.
- Stripe
- The invoice id, subscription id, Checkout Session id and payment id, in live or test mode.
- Period
- The paid period start and end; when it was paid, with its amount and currency.
- Reversal
- When it was refunded or revoked, and why; later Stripe reversals update this record.
- A salted hash of the email, made separately for each record, which cannot be read back.
- Deleted
- When the account was deleted.
Signed-in Macs
One row for each Mac signed in to the account. One account covers 2 Macs at once, and these rows are how they are counted.
- The Mac
- A digest of its hardware UUID, made on the Mac, so the UUID itself never leaves it. A Mac whose UUID cannot be read sends a random id it keeps instead.
- Its name
- The Mac's computer name, so the account can show which Mac is which.
- Last seen
- When the app on that Mac last checked the account. The app checks when it opens and repeatedly while it is open (about once a minute); only the latest time is kept.
- Sign-in
- A digest of the sign-in token (the token itself is kept only on the Mac), and when the sign-in expires: 180 days after it was last used.
- Account
- The account id it belongs to.
A Mac's row goes when it signs out, when another Mac of the account signs it out, when you sign out everywhere or change the password (every Mac but the one that changed it), and when the account is deleted. Signing in again on the same Mac replaces its row. Once a Mac's sign-in has expired, its row is removed the next time any Mac signs in or creates an account.
Website sign-ins
One row for each sign-in on this website.
- Sign-in
- A digest of the sign-in token, whose token itself is in your browser's cookie, and when the sign-in expires: 180 days after it was last used.
- Account
- The account id it belongs to.
A row goes when you sign out on the website, when you sign out everywhere or change the password in the app, and when the account is deleted. Expired rows are removed whenever anyone signs in or creates an account on the website.
Purchases
One row for each Stripe Checkout the account starts, in the app or on this website, and one for each item CyCast's admin grants the account without a checkout (with an id of its own and no Stripe Price or payment).
- Checkout
- Stripe's Checkout Session id, the Stripe Price it was made with, whether it was made in Stripe's live or test mode, and when it was started.
- Consent
- The checkout mode (subscription or payment), terms version, when consent was given, and whether the U of T discount was applied.
- What it sells
- Whether it is for the app, a paid update or a feature, with the version it sells or the feature's id.
- Payment
- Stripe's payment id, when it was paid, and the amount and currency Stripe reported.
- Afterwards
- As they happen: when a checkout closed unpaid; when its payment was refunded; when access from it was ended without a refund, and why (a lost chargeback, or CyCast's admin ending an order that had nothing to pay); and, for a second payment by an account that already held CyCast, the purchase it repeats and the id of its refund.
- Account
- The account id it belongs to.
No card or bank details: those go to Stripe alone.
Kept purchase records
When an account is deleted, one row for each purchase it paid for through Stripe, kept without its email, name or account id, so a refund or tax question about it can still be answered.
- Checkout
- Stripe's Checkout Session id, the Stripe Price it was made with, whether it was made in Stripe's live or test mode, and when it was started.
- Consent
- The terms version and when consent was given.
- What it sold
- Whether it was for the app, a paid update or a feature, with the version it sold or the feature's id.
- Payment
- Stripe's payment id, when it was paid, and the amount and currency Stripe reported.
- Afterwards
- When its payment was refunded; when access from it was ended without a refund, and why; and, for a second payment, the purchase it repeats and the id of its refund. A refund or lost chargeback Stripe reports after the account was deleted is written here too.
- A salted hash of the email (scrypt, with a salt of its own for each row), which cannot be read back: only someone who already knows an address can check whether it matches, as CyCast's admin does to answer a question about a purchase.
- Deleted
- When the account was deleted.
A grant by CyCast's admin, which Stripe never saw, is not kept.
Payment notes
Stripe events the server refused, set aside, or acted on in a way CyCast's admin should know about (a dispute, an automatic refund), and payments it learnt of late, noted for the admin to look up in Stripe.
- Event
- Stripe's event id and event type.
- Object
- The id of the Stripe object it concerns, such as a Checkout Session or a payment.
- Why
- The reason, in words, and when it was noted.
A note never names the account, its email or an amount.
Early refunds
A full refund or a lost chargeback Stripe reported for a payment the server has no record of: the payment may still be on its way, its account may have been deleted, or it may not be a CyCast payment. It is kept so that, if the payment arrives, it unlocks nothing.
- Payment
- Stripe's payment id it concerns.
- What
- Whether it was a refund or a lost chargeback, Stripe's event id, and when it was noted.
A row goes when its payment is recorded, or after 7 days, at the next Stripe event the server receives. It never names the account, its email or an amount.
Daily counts
Two counters for each UTC day.
- Site views
- How many times the website's front page was loaded.
- Downloads
- How many times the installer was downloaded.
Known bots and command-line fetches are not counted. Nothing about who visited is kept.
Weekly counts
One counter for each ISO week (from Monday, UTC).
- Licence checks
- How many licences the server issued in the week, to every account together.
Nothing about who asked is kept.
Besides these, the server keeps the sign-in of CyCast's one admin, the site's owner: a password hash, a sign-in code secret and the admin's sign-ins. They hold nothing about you.
Only in memory
To slow down and then block password guessing, the server counts sign-in attempts by IP address and by email, and failed and successful account creations by IP address, over 15 minutes, the website and the app together. Entering the password to change it or to delete the account counts as a sign-in attempt. These counts are never written to the database, and a restart of the server clears them.
Request logs
Like any web server, CyCast's server and its host, Railway, keep request logs, which include the IP address each request came from. The server's log also carries the payment notes above and any errors.
Stripe
You pay on Stripe's own Checkout page. Card and bank details go to Stripe and never reach CyCast. When it starts a checkout, CyCast gives Stripe the account's email and account id; Stripe tells CyCast whether the order was paid, with the amount and currency. Changing the CyCast sign-in email does not change Stripe's billing email for an existing subscription. Stripe keeps its own record of every payment.
Transactional email
Resend receives your email address and a verification code or password reset link to deliver messages requested by the account, including verification of a proposed new email address. The server logs the provider's delivery receipt id without the recipient, code, or message contents. No marketing email is sent; open and click tracking are disabled in the sender's configuration. Replies to these messages are kept in centram's Google Workspace mailbox. Stripe sends its own receipts, renewal reminders and cancellation notices.
Cookies
The website sets two cookies of its own: one keeps you signed in until 180 days pass without a visit, and one protects its forms. It loads nothing from other sites.
Deleting your account
Any account can be deleted on this website's account page, bought or not; once CyCast is bought, the Mac app's account settings can delete it too. Either asks for the account's password. CyCast first stops its subscriptions at Stripe without a prorated charge or refund, and closes any checkout still open, so nothing can be paid for an account that no longer exists; while a payment is still being completed, or Stripe cannot be reached, the account is not deleted yet. Then, together, it deletes:
- Your account: its email, name and password hash
- Email verification and reset: every challenge
- Subscription renewals: every renewal record, after stopping renewal at Stripe
- Paid subscription periods: every paid period, once kept apart below
- Signed-in Macs: every one
- Website sign-ins: every one
- Purchases: every record of the account's checkouts and payments, once each paid purchase is kept apart without the email or name (below)
It keeps:
- Kept subscription records, which hold no email, name or account id
- Kept purchase records, which hold no email, name or account id
- Payment notes, which name no account
- Early refunds, which name no account
- Daily counts, which name no one
- Weekly counts, which name no one
- Request logs, as the host keeps them
- Stripe's own record of any payment, with the email given to Checkout
What is on your Macs stays there; only their sign-ins end. A purchase does not carry over to a new account.