| 1 | # π€ PLAN β why CONTRA is shaped this way, and what lands when |
| 2 | |
| 3 | `PROTOCOL.md` is the spec. This is the reasoning and the order. |
| 4 | |
| 5 | ## Why build this at all |
| 6 | |
| 7 | 1Password is genuinely disappointing people. The complaints are not about |
| 8 | cryptography β they are about a product that grew away from the thing it |
| 9 | was for. That leaves an audience who already believe in password managers, |
| 10 | already pay for one, and are actively looking. They arrive with an export |
| 11 | file and a grievance, which is the easiest migration in software. |
| 12 | |
| 13 | The second reason is that the family needs it. The CARLOS apps keep |
| 14 | reaching for a password manager as the place recovery credentials live β |
| 15 | and every one of those references is a dependency on a product none of us |
| 16 | control. A family password manager closes that loop. |
| 17 | |
| 18 | ## The position |
| 19 | |
| 20 | Everything else in the category competes on features. CONTRA competes on a |
| 21 | sentence that its competitors structurally cannot say: **the operator sees |
| 22 | nothing at all** β not your vault, not your item names, not your email |
| 23 | address, not how many vaults you have. |
| 24 | |
| 25 | That sentence is only worth saying if it survives audit, which is why the |
| 26 | class is A1 strict and why the greps are merciless. The moment we need an |
| 27 | "exceptβ¦" clause, we are an A2 app competing on features again. |
| 28 | |
| 29 | ## Build order, and why this order |
| 30 | |
| 31 | **1 β Instance + client-shape web console.** |
| 32 | The crypto and the storage contract get proven exactly once, in the place |
| 33 | where they can be iterated fastest and reviewed on a canary the same day. |
| 34 | This surface is client-shape by force: sealing must happen where the keys |
| 35 | are, so a server-rendered vault is not a thing that can exist. Marketing |
| 36 | and settings pages stay server-shape beside it. |
| 37 | |
| 38 | Done when: signup, passphrase sign-in, recovery-code print, a working |
| 39 | vault, and the merciless greps green. |
| 40 | |
| 41 | **2 β Native Mac app.** |
| 42 | Fully native, and deliberately *second*. A second client written against a |
| 43 | settled contract is a port; a second client written against a moving |
| 44 | contract is two half-designs. Everything the Mac app needs from the server |
| 45 | already exists by then. |
| 46 | |
| 47 | **3 β AutoFill Credential Provider extension (macOS).** |
| 48 | This is where the product stops being a website. It is also where |
| 49 | distribution gets decided early rather than late: an |
| 50 | `ASCredentialProviderExtension` means a paid Apple developer account, code |
| 51 | signing, notarization, and a Sparkle-versus-App-Store call. That decision |
| 52 | constrains the Mac app, so it gets made at slice 2, not slice 3. |
| 53 | |
| 54 | **4 β iOS.** |
| 55 | Same contract, third implementation, plus its own AutoFill extension. |
| 56 | |
| 57 | ## Import |
| 58 | |
| 59 | 1PUX first, client-side, because that is where the users are coming from |
| 60 | and because an unsealed export touching the server would break the one |
| 61 | rule on day one. |
| 62 | |
| 63 | Bitwarden and Apple Passwords are wanted and deferred to discussions on |
| 64 | this repo. Passkeys need a documented manual path: 1Password will not |
| 65 | export them, so no importer can ever bring them across, and the honest |
| 66 | move is to tell the user exactly which ones need re-creating rather than |
| 67 | silently dropping them. |
| 68 | |
| 69 | ## Money |
| 70 | |
| 71 | A real free rung, then **β¬5/year**. |
| 72 | |
| 73 | Deliberately cheap, for a reason specific to this category: a password |
| 74 | manager somebody stops paying for is a password manager that loses their |
| 75 | data. Price it so lapsing is never the cheaper option. Shape follows |
| 76 | Slopbox β free rung that degrades generosity, never availability. |
| 77 | |
| 78 | Metering from the first write; integer cents. |
| 79 | |
| 80 | ## Deferred, with triggers |
| 81 | |
| 82 | The full list is in `AGENTS.md` under "Deliberately not built yet". The |
| 83 | two worth naming here: |
| 84 | |
| 85 | - **Cross-instance sharing (federation).** Not in v1, and the family has |
| 86 | already called this the biggest scope trap once. Single-instance sharing |
| 87 | gets proven first. |
| 88 | - **Breach and reused-password monitoring.** Every implementation sends |
| 89 | something derived from a password off the device. There may be an |
| 90 | A1-compatible design; until somebody writes it down, it is not sketched. |
| 91 | |
| 92 | ## Open questions |
| 93 | |
| 94 | - The recovery code's exact strength, alphabet and chunking β under review. |
| 95 | - Whether the daemon's `use` verb may make outbound requests itself or is |
| 96 | limited to injecting into a subprocess environment β under review. |
| 97 | - Namespace: `contra` is taken on npm and as a GitHub org, and the good |
| 98 | short domains are held. No password manager uses the name. See the |
| 99 | namespace note in the branch discussion. |
| 100 | |