carlos / movement Public

Product truth, before any of it gets designed

Three answers from Paul that the repository could not have supplied: the
audience is builders and contributors *and* people serious about changing
how software is delivered, not a choice between them; a signup earns
occasional updates about CARLOS and nothing more; and the page is about
both CARLOS and the ethics, with the tension as the message rather than a
problem to resolve in favour of one.

That last one settles the headline mismatch flagged in the spec's Open
section.

Recorded as absences too, because they are the ones most likely to get
invented later: no testimonials, no customers, no user counts, no press,
and no community to invite anyone into. The offer is updates.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Paul Campbell aa59645d71de6cbf5f3041dcbeb864faabb287e9 parent cdb4c0e
1 file changed, +202 −0
  • PRODUCT.md +202 −0
diff --git a/PRODUCT.md b/PRODUCT.md
new file mode 100644
index 0000000..fd70577
--- /dev/null
+++ b/PRODUCT.md
@@ -0,0 +1,202 @@
+# Product
+
+<!-- impeccable:product-schema 1 -->
+
+## Platform
+
+web
+
+## Users
+
+**Primary: builders and contributors who are serious about changing how
+software gets delivered.** Confirmed by Paul, 2026-09-01, as a deliberate
+combination rather than a choice between two groups — people who would write
+CARLOS apps or contribute to the framework, *and* people whose contribution is
+the argument, the accountability, and the shared position rather than code.
+The signup form asks how someone can help because the answer is genuinely
+open.
+
+Their situation: they have arrived from carlosframework.com or a link someone
+sent, they are deciding whether this is a thing they want to be associated
+with, and the decision is partly technical and partly ethical. They are being
+asked to state a position on AI in public-ish terms before they are asked for
+anything else.
+
+**Secondary: Paul, as the only reader of what comes in.** He reads the
+confirmed list and what people wrote about themselves, and decides what to do
+with it. There is no second admin today.
+
+## Product Purpose
+
+Recruit people into the movement around CARLOS by collecting email addresses,
+while sorting those people by their stance on AI — and doing the sorting
+*before* the email, so the stance is a considered choice rather than a
+checkbox after the fact.
+
+Three positions are offered. All three can sign up and all three are invited
+to say why they are interested and how they could help. Each gets a different,
+honest response to the position they picked.
+
+**The middle group is the target.** People who are curious about AI and
+ethically sceptical of it are the ones this is built to find. The other two
+paths exist so that the middle one means something: a form where everybody is
+welcome equally sorts nobody.
+
+Success is a confirmed list of people in that middle group who wrote something
+substantive about themselves — not a large list.
+
+## Positioning
+
+**The sorting is the mechanism, and it costs conversions on purpose.** A
+neighbouring signup page maximises the number of addresses it captures. This
+one asks a question that will lose it people, tells two of the three groups
+that they may not be the right fit, and treats a smaller and more considered
+list as the better outcome. That trade is not a growth tactic with a
+conscience bolted on; it is the product.
+
+**CARLOS is the proof, and the ethics is the point — both, and the page says
+so.** Ruled by Paul, 2026-09-01, against the alternative of leading with one
+and treating the other as a filter. The claim is that infrastructure built a
+particular way, by people who thought about why, produces different software —
+and CARLOS is what that looks like when somebody actually builds it. The
+tension between the two subjects is the message rather than a problem to be
+resolved in favour of one.
+
+## Operating Context
+
+Someone arrives at a single page, reads a short statement about CARLOS with a
+link out to carlosframework.com, and is offered three positions on AI. Picking
+one takes them to that position's own page, where they read a response written
+specifically to it and find the signup form beneath.
+
+They give an email address and write something about why they are interested
+and how they can help. They receive an email and click a link in it, and only
+then are they on the list. Until they do, nothing about them is counted,
+exported, or shown to anyone.
+
+Paul reads the confirmed list and exports it. There is no team, no queue, and
+no workflow beyond that.
+
+## Capabilities and Constraints
+
+**Built and settled** — the full record is
+`docs/superpowers/specs/2026-09-01-movement-design.md`, whose §1 is the
+settled-decisions table.
+
+- One Go binary on the rastrillo framework (Go 1.25, rastrillo v0.23.0, chi,
+ GORM, cgo-free SQLite), server-rendered `html/template`, hand-written ES
+ modules, no bundler and no build step, no CDN. Deployed on CARLOS at
+ `movement.bdj.oncarlos.com`; no custom domain for v1.
+- Double opt-in. An address is on the list only after a click from inside that
+ inbox, and confirmation happens on a POST so that mail-scanning gateways
+ cannot confirm somebody who never clicked.
+- Anti-abuse: a proof of work bound to the submitted address, an HMAC-sealed
+ challenge with single-use nonces, a honeypot, and persisted mail budgets.
+- Every response to the signup form is identical whether an address is
+ unknown, pending, or already confirmed. The page must never become a way to
+ check who is on the list.
+- Admin is a magic link restricted to an allowlist, and shows confirmed rows
+ only. Pending rows are counted, not displayed.
+- Transactional email is sent through the CARLOS platform's own facility. No
+ third-party provider.
+
+**Deliberately not built yet**, each with the trigger that would change that:
+pushing into mailing-list software (a CARLOS-family mailing list app exists);
+self-service unsubscribe and deletion (before the first bulk send); changing
+one's stance after confirming (someone asks).
+
+**Open, and not to be invented:**
+
+- **The three stance labels and their URL slugs.** Paul's drafts were "Never
+ AI", "AI curious, ethically skeptical", and "Love AI, never thought about
+ its ethical issues". The third is known to be broken as written: it asks
+ someone to volunteer that they have not thought about something, so the
+ people it describes will pick the middle option instead and pollute the one
+ signal this product exists to isolate. It needs a label that group would own
+ willingly, with the diagnosis living in Paul's reading of the bucket rather
+ than in the words on the button.
+- **Whether "Movement" is the public name** or only the repository and app
+ name. Not asked, not assumed.
+
+## Brand Commitments
+
+- **CARLOS is real and its own positioning is fixed.** carlosframework.com
+ leads with "Lower your costs. Raise your security, resilience, privacy and
+ sovereignty", and describes per-person processes and encrypted databases,
+ with idle apps sleeping into a bucket and waking in milliseconds. A visitor
+ who follows the link meets that page, so nothing here may describe CARLOS in
+ terms it would contradict.
+- **AI is a guest with a name tag.** The family's authorship doctrine, carried
+ in every sibling's AGENTS.md: 🤖 and 👨 markers, `Co-Authored-By` trailers,
+ published prompt and carbon ledgers, opt-in and disclosed. A page recruiting
+ people on the strength of their AI ethics has to hold itself to it visibly.
+- **Honesty about what the software can and cannot see.** The house pattern is
+ to state the limits of a privacy claim rather than imply a stronger one. Here
+ the true and narrow claim is that the public surface reveals nothing about
+ who is on the list — not that the list is private from us. The server reads
+ every address.
+- **House voice**, from the sibling repositories: declarative, specific,
+ unhedged, willing to name what was rejected and why. It does not sell.
+
+## Evidence on Hand
+
+- **CARLOS is running in production.** amadan.net itself is served by it, and
+ the console at console.carloku.com is live. This is a real platform, not a
+ proposal.
+- **Sibling projects exist**: Sheets, Home and Pegamento, in the same family.
+ Most are specifications rather than shipped software today. Describing them
+ as available products would be false.
+- **carlosframework.com** is quotable in full.
+
+**Absences that must not be filled in.** There are no testimonials, no named
+customers, no user counts, no benchmarks, no press, no funding story, and no
+case studies. There is no existing community, forum or group to invite anyone
+into. Nothing may imply that other people have already signed up, that the
+list is large, or that anyone notable is on it.
+
+**What a signup actually earns**, confirmed by Paul, 2026-09-01: occasional
+updates on CARLOS. Not early access, not membership of anything, not a date.
+The page may promise that and nothing more.
+
+## Product Principles
+
+1. **A smaller, more considered list beats a larger one.** Every design
+ decision that trades reach for signal is the correct one here, and the
+ sorting question is the first of them.
+2. **Say the unflattering thing.** Two of the three paths tell people they may
+ not be the right fit. That is the product working, and the copy should not
+ soften it into a welcome.
+3. **Promise only what exists.** Occasional updates about CARLOS is the whole
+ offer today. There is no community to join yet, and inventing one would be
+ the exact failure this audience is being selected for noticing.
+4. **State limits rather than imply strength.** Where a privacy or security
+ claim is narrow, say how narrow. The audience is chosen for scepticism.
+5. **Nobody is told a different story than anybody else.** The response to a
+ submission is the same regardless of who is asking, because the alternative
+ turns a recruitment page into a register of people's political positions.
+
+## Accessibility & Inclusion
+
+**Signing up requires JavaScript, and this is a known exclusion.** The proof
+of work is mandatory and runs in the browser; Paul chose this on 2026-09-01
+over a fallback that would have let non-JavaScript visitors through, with the
+trade-off stated. The obligation that follows is honesty at the point of
+failure: the form renders with its submit disabled and an explanation inside
+`<noscript>`, and the module enables it once loaded — so a visitor who cannot
+sign up learns that immediately and from us, rather than meeting a form that
+looks live and silently does nothing.
+
+**The honeypot must not catch real people.** It is hidden visually, so it
+needs `aria-hidden`, `tabindex="-1"`, `autocomplete="off"`, and a field name
+browsers will not autofill. A screen-reader user or a password manager filling
+that field would have their signup silently discarded behind a cheerful
+success page, which is the same "looks live, does nothing" failure the
+`<noscript>` rule exists to prevent.
+
+**The proof of work runs in a Worker**, because several hundred thousand
+hashes on the main thread freezes a low-end phone, and its difficulty is to be
+calibrated on real mid-range hardware at p95 and p99 rather than on an
+average — a mean-calibrated challenge hangs for one visitor in a hundred.
+
+No formal conformance standard has been set for this project. Not asked, not
+assumed.