---
title: "MyLimb engagement — Case study — Thoughtful Robots"
description: "MyLimb is a community platform for the international limb-loss community — its engagement layer decides who to reach, with what, and how often, and treats staying quiet as a first-class decision."
source: "https://thoughtfulrobots.ai/work/mylimb-engagement"
---
# One invitation at a time. Often, none at all.#
MyLimb is a community platform for the international limb-loss community — patients, families and the clinicians around them. Its engagement layer decides who to reach, with what, and how often. Most of the time it decides to say nothing.
Designed and built for MyLimb · the topic layer, the participation signals and the promise watchdog run in production · the invitation card is built and dark · the For You feed is specified
Research → Three concepts → One built → Four review rounds before merge
Silence loses them. Prompting loses them faster.
a health-adjacent community · no points · no streaks · no leaderboards
## Engagement here cannot be growth-hacking.#
The member who has gone quiet is the hardest person a community serves. A platform that says nothing loses them; one that keeps prompting loses them faster — and here the second failure is the worse one, because every hollow notification teaches a member that the place built to understand them is chasing its numbers like everything else.
So the design began in the peer-support research rather than in a growth playbook, and it began by ruling things out. What survived is a single question, asked afresh each time a member opens the app: is reaching out worth it right now, or is silence the better move?
## A layer that can name its reasons.#
The engagement layer reads only what members do in the open — the posts they write, the replies they give, the interests they name on their first day. It never watches them read.
What it is allowed to offer is deliberately small: one invitation at a time and never a stack, a dial the member owns, and a feed in which every card carries the signal that put it there.
Someone asked about walking on uneven ground, and no one has answered yet.
You’ve written about this before.
This is the only invitation you’ll see today.
How often should we invite you?
You can change this at any time. Off takes effect straight away.
Topic match · an interest named on day one
Topic match · read and replied to lately
Curated · the magazine lane, woven in
Fill · newest — never labelled personal
Three surfaces, drawn — (01) The card is pull-only: it exists because a member opened the feed, and nothing about it ever pushes. Accepting deep-links to the real post or composer; declining is one tap with no reasons asked, and it rests that kind of ask rather than that person. (02) The dial is a member setting, not a budget the product spends — and “Off” is honoured with no confirmation ask and no copy that argues back. (03) Every For You card carries a machine-readable reason and its plain-language label, so the feed cannot place a card it cannot explain; the magazine lane is woven in rather than ranked, a fill card from the newest posts is never dressed up as personal, and no two cards in a row may carry the same reason.
Most days the right number of cards is zero.
Five shapes · one live card · never the same ask twice
## The model supplies words. Code decides who gets asked.#
Who to reach, with what, how often — every decision a member can feel is made by code that can be read, tested and argued with. The model’s whole job is to say what a post is about, in a vocabulary it did not write.
The vocabulary — A published post is chunked, embedded and matched against a curated catalogue of 125 limb-loss topics. Hybrid retrieval shortlists forty candidates and the prompt closes the world to that list, so an invented topic is not discouraged — it is unreachable. What comes back is a slug the model was handed, a confidence and a short quoted line of evidence. Two thresholds then split the result three ways, and the middle one is the interesting one: a topic the model is only fairly sure of is stored, shown to an administrator, and excluded from every downstream signal until a person accepts it. The system would rather know less than be confidently wrong.
#### The dial
#### The live card
#### The budget
#### Five shapes
The dial, the live card, the budget, the shapes — in that order, and no other. The dial — the member’s own setting, read first. Off returns nothing, silently. The live card — re-checked, not replaced. One at a time is a constraint, not a policy. The budget — twelve hours, then one a day and three a week. Spent is spent. Five shapes — walked in a fixed order, and that order is the entire ranking. Tomorrow it runs again — against caps that have moved on and shapes that may be resting.
Three of the four gates can end the pass in silence — only the last one mints a card
One pass, gate by gate — (01) The dial is read before anything is computed, so a member who said no costs nothing to serve. (02) A card already standing is re-checked rather than replaced — still visible, still unanswered, less than five days old — and one live card per member is a database constraint. (03) The budget is absolute: nothing in the first twelve hours, then at most one a day and three a week, one a week on “Fewer”. (04) The five shapes are walked in a fixed order and that order is the entire ranking — no scores, no optimiser, no model. A resting shape is skipped, and declining rests the shape rather than the person, so a decline teaches the system without costing the member anything. Clinicians are walked through a shorter pool: they are only ever asked to give.
## Nothing sent from memory. Nothing welcomed by a bot.#
Restraint is a promise, and a promise needs infrastructure behind it. The one thing this system does push is an alert to staff — and it is written down before it is sent, so an outage can delay it but cannot drop it and cannot repeat it.
The warmest moment is the one deliberately left to people. When a newcomer’s first hello is still unanswered near the end of the day the community promised it, the platform does not post a reply. It emails the crew.
Delay Possible
Silent drop Impossible
Duplicate Impossible
An infrastructure failure delays an alert; it cannot silently drop or repeat one.
One first post, hour by hour — The sweep runs hourly in production and looks only at an author’s first public post: an introduction between twenty and twenty-four hours old, a question between forty and forty-eight, and still unanswered by anyone but its author. The windows sit inside the promise on purpose, so a person still has hours to act. Detection writes one ledger row per post, ever, with the subject, the body and the idempotency key frozen at that moment — the fix that came out of a real incident, where a payload recomputed per attempt made two retries different enough to be rejected once and duplicated later. At delivery the premise is checked one last time; if the post has been answered in the meantime, the row closes and nobody is emailed.
## Engagement, engineered as restraint.#
The discipline here is structural rather than aspirational. One live card is a unique index. The permanent no-repeat is a unique index. The dial is read before the work is done rather than after it. The selector and the feed can each name the reason for anything they show — and the only thing the whole system pushes is an email asking a person to go and be one.
> We designed an engagement system, read the research, and removed the model from the decision. **No scores. No ranking. No model call anywhere in the selector.**
Stack — Rails · Postgres + pgvector · SvelteKit · OpenAI — every model call a background job, none in a member’s request path