# Product

<!-- impeccable:product-schema 1 -->

🤖 Product record for CONTRA. Confirmed with Paul, 2026-09-03. Everything
here is product truth, not visual direction — `AGENTS.md` holds the settled
decisions, `PROTOCOL.md` the cryptographic protocol, `DESIGN.md` the visual
system, `PLAN.md` what is built.

## Platform

adaptive

The web console is what exists today. `AGENTS.md` decision 6 fixes the build
order: rastrillo instance and client-shape web console first, then a native
Mac app as the *second* implementation of a settled contract, then the macOS
AutoFill Credential Provider extension, then iOS. Recorded as `adaptive`
because those native surfaces are the product, not ports of it — and because
the trust story differs by platform in a way design must not blur: the
at-rest promise holds everywhere, but "compromise the running server and
still get nothing" is only fully true where the code is signed and not
fetched per visit.

## Users

Two primaries, weighted equally. Neither may be traded off for the other.

- **A small team moving off a shared password manager.** Eleven is the first,
  and its secrets move in as soon as CONTRA is ready — with shared vaults
  working on day one, not as a later capability. Their situation: credentials
  that several people genuinely need, on infrastructure they control, without
  a multi-tenant operator holding anything that opens them.
- **A person leaving 1Password with their own vault.** Their job is getting
  everything across without a support article, and then trusting a thing whose
  recovery story is stricter than what they left. The `.1pux` file is opened,
  parsed and sealed in their browser; it never reaches the server.

An AI agent is a third, narrow actor rather than an audience: it may list a
vault, use a secret without receiving it, and add new secrets. It may not read
a value into its own context, and there is no setting that turns that on
(`AGENTS.md` decision 5).

## Product Purpose

A password manager where the server knows nothing about you. Not "we promise
not to look" and not "we encrypt at rest": the instance holding a vault cannot
open it, cannot tell one account from another by content, and does not know
the account's email address.

Success is that a stolen instance yields a pile of ciphertext and the times of
day somebody connected — and that a person who reads the trade-offs first
still chooses it.

## Positioning

Built to **CARLOS A1, host-blind** — the strictest class the family
publishes. What a neighbouring product cannot truthfully copy without
rebuilding on the same terms:

- **No content-derived identifiers at rest.** Item names, URLs, usernames,
  folder structure and vault names seal exactly like passwords, because a name
  is a secret too. All object identifiers are random, never content hashes:
  a content-derived identifier is both an A1 violation and an equality oracle.
- **There is no way back in that we control.** No reset link, no support
  override, no identity verification that restores a vault — because a server
  that could give your vault back could give it to someone else. Every
  competitor that can email you a way in has, by definition, a way in.
- **Sign-in is a signature, not a stored verifier.** The server holds only a
  public key and authenticates by signed challenge, so a fully compromised
  server holds something that cannot decrypt and cannot be replayed.
- **The honest trade-offs are on the front page**, not in a support article —
  including the ones competitors omit: that removing somebody from a shared
  vault cannot un-download what they already have, that the server learns
  transport shape, and that a browser trusts the server to send honest code.

## Operating Context

- **One instance per account**, on the owner's own deployment. A shared vault
  lives on its owner's instance and other members are identities there. That
  is what keeps membership an access-control list — transport shape — rather
  than a content-derived identifier, and the distinction is load-bearing.
- **The Emergency Kit is paper.** Two printed documents, generated in the
  browser at signup and never sent to the server: an **Account Key card** (a
  new device asks for it once; useless without the passphrase) and a
  **Recovery sheet** (the way back if the passphrase is forgotten; opens the
  vault on its own, and nobody can reissue it). They are stored differently on
  purpose — a drawer versus a safe — and the copy must keep saying so.
- **Getting onto a new device** is a three-rung ladder that must never
  dead-end: a handoff from an already-enrolled device, scanning the card's QR,
  or typing its code. Once a device holds the Account Key, the passphrase
  alone unlocks it — the everyday case.
- **Migration is a file, not an integration.** 1Password `.1pux`, opened
  client-side. Passkeys stored in 1Password cannot be exported by anyone, so
  those are re-created by hand and the product must show which ones.

## Capabilities and Constraints

- **Crypto is byte-identical across implementations**, pinned by shared golden
  vectors generated by neither of them. Changing a pinned value is changing
  the protocol.
- **Sealing happens where the keys are**, which makes a server-rendered vault
  impossible rather than merely discouraged: the server has never seen a title
  and could not render one.
- **A new storage surface lands with its canary or it does not land.** Canary
  strings are pushed through every write path and the raw database bytes
  searched for them.
- **Recovery, stated plainly:** lose the kit *and* the passphrase and the data
  is gone. Lose the kit while a device is still enrolled and it reprints — the
  Account Key card exactly, the recovery sheet only by regenerating, which
  invalidates the old one.
- **Accepted residue**, published rather than hidden: the sharing graph (which
  accounts share a vault, never what is in it), item count, per-item write
  timing, and sign-in timing.
- **Money:** a genuine free rung, then €5/year. Cheap on purpose — a password
  manager people cannot afford to keep is one that loses their data. Integer
  cents; a float never touches an amount.
- **Terminology that must stay stable:** Account Key, recovery code, Emergency
  Kit, vault, item, member, drop box, instance, handoff.
- **Explicitly undecided / not built:** Bitwarden and Apple Passwords
  importers, passkey migration out of 1Password, cross-instance sharing
  (federation — never in v1), breach monitoring, one-off sharing links, agent
  mutation of an existing item. Each has a written trigger in `AGENTS.md`.

## Brand Commitments

- **Name:** CONTRA. A CARLOS app.
- **Voice:** plain, specific, and unapologetic about consequences. It states
  the cost of a decision in the same breath as the decision, and does not
  soften a limitation into a feature. "That is the product, not a gap in it."
- **AI authorship is disclosed.** Machine-authored text carries 🤖 where it
  surfaces; a person marker (👨/👤/🧑) certifies human text an LLM must not
  rewrite, rephrase, condense or delete. AI features are opt-in, always
  disclosed, and every path works with AI switched off.
- **No dark patterns around loss.** The product nags toward a second device
  and a reprinted kit because both are real protection — never to manufacture
  urgency.

## Evidence on Hand

- **Pre-alpha. Nothing to sign up for yet.** There are no customers, no
  testimonials, no press, no benchmarks and no pricing page in market. None
  may be invented.
- Real artefacts that do exist: the deployed canary
  (https://contra.bdj.oncarlos.com), the golden vectors
  (`vectors/contra-v1.json`), `README.md`'s trade-offs section, `AGENTS.md`'s
  nine settled decisions, `PROTOCOL.md`'s protocol and compromise matrix, and
  `PLAN.md`'s built/not-built state with a trigger per deferral.
- The two kit documents are generated by the product itself
  (`internal/contra/static/crypto/kit.js`) and are the only real "assets".

## Product Principles

1. **Say the cost where the promise is made.** Trade-offs belong on the front
   page and beside the button, not in a support article. The recovery rule,
   the sharing residue and the browser-trust boundary are stated in the copy
   that precedes the action.
2. **Never dead-end a person who still has a way through.** Every screen that
   needs a key offers every rung that can work, and the last one always can.
3. **The server is a hostile witness.** Design as though the instance is
   already stolen: nothing it holds may name, rank, group or identify content.
4. **Sealed by default, everywhere a name could hide.** If a person typed it,
   it is a secret — titles, URLs, usernames, vault names included.
5. **Paper is a feature, and it is asked for honestly.** The kit exists so
   that a chosen passphrase cannot cap how safe a vault can be; the product
   explains that rather than assuming compliance.

## Accessibility & Inclusion

**WCAG 2.2 AA**, binding.

Two places where that is more than a checklist and design must treat it as a
product constraint:

- **The printed kit is an accessibility surface.** Contrast, type size and the
  QR's quiet zone have to survive real paper and a phone camera, at the worst
  moment somebody will ever use this product.
- **Recovery paths must not assume a mouse, a camera, or a steady hand.** The
  device ladder's typing rung is the one that always works, and it self-heals
  a single mistyped character rather than only rejecting it.
