v1.6 / 03 August 2026

How protcul works

Running version 0.0.5 · Production review: `0.0.5`

This is the public, plain-language explanation of how protcul handles your data and where its privacy boundaries are. It describes consequences first and implementation details second. For legal information about processing, retention, and your rights, read the privacy policy.

Availability

Availability: protcul is still being built. Guest mode and local-only storage shipped in 0.0.1. Password-protected export shipped in 0.0.2. Natural-language quick entry shipped in 0.0.3. Multiple separate pillboxes shipped in 0.0.4. Registered accounts and end-to-end encrypted sync shipped in 0.0.5; an account remains entirely optional, and guest mode is still the default path. The page at /tech shows the running app version so you can tell which description applies.

What is available at 0.0.5

A capability is described as available only from the release that ships it.

  • Guest mode, with no accountAvailable
  • Local-only storage in this browserAvailable
  • Offline use after the first loadAvailable
  • Full-dataset plaintext export and importAvailable
  • Password-protected exportAvailable
  • Natural-language quick entryAvailable
  • Multiple pillboxes (Profiles)Available
  • Registered accountsAvailable
  • Encrypted sync across devicesAvailable

The short version

Guest modeRegistered mode
Account requiredNoYes — but only to sync across devices; the complete app works without one
Working copyStored in this browser, unencryptedStored in this browser, unencrypted
Medication data sent to usNoneEncrypted records only
Works offlineYes, after the first successful loadYes; synchronization waits until the device is online and unlocked for sync
What protects the local copyYour device login, disk encryption, and browser-profile access controlsYour device login, disk encryption, and browser-profile access controls
What protects the server copyThere is no server copyEnd-to-end encryption; the data key exists only on your devices
RecoveryExport your data regularlyKeep your handle, passphrase, and exports; protcul cannot recover the handle or passphrase

In both modes, the browser database is the working source of truth. Taps are saved locally first, the app remains useful without a network connection, and export is the portable backup and migration path.

Where your data goes

Guest

You → this browser's local database

Protocols, Profiles, and Completions stay in the browser. Doses are calculated from Protocols when needed rather than stored as a separate history. After the first successful application load, the cached application shell and local database make the pillbox usable offline.

Guest health data is not sent to protcul. Clearing this browser's site data, removing the browser profile, or losing the device can remove the only copy, so export matters. A browser can also evict local data on its own when it is short of space; protcul does not currently ask for the exempt storage some browsers offer, so nothing is reducing that chance on your behalf. Export is what protects you from it.

Registered

You → local plaintext database → encryption on this device → ciphertext mailbox → decryption on your other device

Registered mode adds synchronization; it does not replace the local-first model. A change is committed to the browser database first and encrypted before upload. Another signed-in device downloads ciphertext and decrypts it locally. The server is a mailbox for encrypted records, not a medication database.

The local working copy is still unencrypted. End-to-end encryption protects data while it travels and while it is stored by protcul, not against someone who can use your device or browser profile.

How encryption works

Your passphrase is processed on the device. It never reaches protcul, and neither do the resulting master secret or data-encryption key.

The server receives an authentication value derived from the authentication key and stores only a further one-way hash of it. It never receives the data key. The passphrase and in-memory keys are not persisted by the app; after a reload, the local registered vault remains usable, but the passphrase must be entered again before synchronization can resume.

Changing the passphrase re-encrypts the server mailbox under a new key generation and revokes other device sessions. There is no passphrase reset: protcul cannot decrypt the mailbox to recover it for you.

Publishing the algorithms does not weaken this design. The protection comes from the passphrase-derived secret, fresh randomness, and correct implementation—not from hiding how the system works.

Algorithm-level detail

The design uses:

  • Argon2id to make a 256-bit master secret from the normalized passphrase and an account-specific salt. The deliberately expensive derivation slows passphrase guessing.
  • HKDF-SHA-256 to derive separate authentication and data keys. A key used to prove account access is not the key used to encrypt records.
  • AES-256-GCM to encrypt each synchronized record independently. Every write uses a fresh random nonce, and authenticated associated data binds ciphertext to the account handle, record type, and record key so it cannot be silently moved to another slot.
  • Independent export encryption. Each password-protected export gets a fresh random salt and its own derived key. The file records the versioned algorithms and parameters needed for future compatible imports.

What the server can and cannot see

For a guest, protcul receives no health data.

For a registered account, the server can hold:

  • the normalized, user-chosen handle, which is pseudonymous but intentionally not secret;
  • authentication and session material, never the passphrase;
  • encrypted Profile, Protocol, revision, lifecycle, and Completion-operation records;
  • opaque record identifiers, record types, tombstones, counts, sizes, and update timing;
  • small account bookkeeping: a random internal identifier for the account, the date it was created, the version of the encryption settings it was set up under, and a counter of how many times its passphrase has been changed;
  • temporary encrypted staging records while a passphrase change is in progress; and
  • short-lived, hashed handle- and IP-derived counters used to limit abusive account attempts.

The encrypted mailbox is stored in Neon Postgres. The server cannot read Profile names, medication names, notes, schedules, quantities, anchors, or Completion content. It also cannot tell which encrypted Protocol belongs to which encrypted Profile. It can still observe metadata: for example, record counts and write timing can reveal an approximate rhythm of use even though content remains hidden. One record type gives away more than its identifier suggests, and the next section says which and why.

Vercel, the hosting provider, produces ordinary request and error logs containing technical request information such as an IP address, requested page, time, and browser type. Health content is not included because readable health records are not sent through those routes. protcul adds no analytics, advertising trackers, client telemetry, or automatic crash reporter.

What this design does not protect against

Privacy claims are incomplete without their limits:

  • Access to your device or browser profile. Local records are readable there in both modes.
  • A compromised device. Malware or a hostile browser extension can read what you can read.
  • A compromised or malicious application build. protcul is web-delivered, so the browser executes the code served for that release. A hostile build could read local data or capture keys before encryption. Public code, releases, and changelogs make builds auditable; they cannot cryptographically eliminate the delivery-channel risk.
  • A weak passphrase. Argon2id slows guessing but cannot turn a guessable passphrase into a strong one.
  • A lost passphrase or handle. There is no email address or recovery key held by protcul. An export is the recovery path.
  • Sync metadata. Encryption hides content, not the existence, type, size, count, or timing of encrypted records.
  • Automatic finish events. When a course closes on its own, the identifier of the record marking that is deliberately calculated from the Protocol it closes, the revision it was based on, the reason, and the date — so that two devices working out the same finish produce identical records instead of a conflict. The calculation runs one way only, but the server already holds the first two of those four ingredients as ordinary record identifiers, and the remaining two are a date and one of three reasons. That is few enough combinations to work through. A server that chose to do so could learn which Protocol finished, on what date, and for which of the three reasons. It could not learn the medication, the schedule, or anything else the record contains, and only automatic finishes are calculated this way — anything you do by hand is not.
  • Browser storage loss. A browser may evict local data when it is short of space, and protcul does not currently request the exempt storage that would make that less likely. Only an export protects against it.

Local database encryption is deliberately out of scope. Without a separate unlock secret it would not protect against the same browser profile, while requiring one would add friction every time the pillbox is used. The device's own access controls and disk encryption are the local protection boundary.

Your control

  • Guest mode requires no account and sends no health data to protcul.
  • Export is always available in a documented, versioned format. An export can be protected with a password, which is processed on your device and never stored — if it is lost, nothing can open that file. Exporting without a password requires an explicit warning first.
  • Import validates and previews the complete file before changing local data. It merges rather than silently overwriting newer history.
  • Guests can wipe their local vault. Registered users can delete their account, server ciphertext, handle, sessions, and that account's local vault.
  • Encrypted sync, shipped in 0.0.5, is opt-in and reversible. Creating an account is a deliberate choice, guest mode stays complete without one, and signing out leaves that account's local copy on the device untouched. What the account adds is the same pillbox on your other devices; what it does not add is any ability for us to read it. Changing your passphrase re-encrypts the whole mailbox and signs your other devices out; deleting the account removes its ciphertext, releases its handle, and removes that account's local vault after offering an export first. There is no recovery path for a lost passphrase, and a later registration of the same handle is a different account with no connection to the old one.
  • Separate pillboxes, shipped in 0.0.4, keep the medication of people you care for apart on your own device. Each pillbox has its own Protocols, agenda, and history; there is no combined view, and nothing is shared with anyone else. A pillbox can be exported on its own and imported by the person it belongs to — that export and import is the whole handoff, and it creates no ongoing link or access between the two devices. Deleting one pillbox erases only its own Protocols and Completions, after an export-first prompt, and the last pillbox cannot be deleted this way because wiping is the explicit way to erase everything.
  • Natural-language quick entry, shipped in 0.0.3, is a deterministic on-device parser over a fixed vocabulary. Your sentence is never sent to an LLM, a cloud parser, or any other service, and the same sentence always produces the same result. It only fills in the form for you: nothing is saved until you review that form and save it yourself, and anything it does not recognize is simply left blank for you to complete.
  • protcul has no analytics, notifications, ads, payments, or engagement tracking.

Check our work

The source repository is public and source-available under the PolyForm Noncommercial License 1.0.0. It is auditable by anyone, but it is not open source under an OSI-approved license.

Each release has one public changelog entry. The running application version and this page's last production-reviewed version make it possible to connect a claim to a specific release.

Ordinary bugs can be reported through the public issue flow, but security vulnerabilities must not be posted publicly. Follow the repository's private security-reporting instructions, and never include real health data in a report.