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
Notice.Decide.Invite once.Stay quiet.
The tension
Silence loses them. Prompting loses them faster.
a health-adjacent community · no points · no streaks · no
leaderboards
01 — The tension
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?
02 — What the member meets
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.
The member’s surfaces — three moments
01 · The invitation
An invitation
Someone asked about walking on uneven ground, and no one has answered yet.
You’ve written about this before.
Answer itNot nowFewer of these
This is the only invitation you’ll see today.
02 · The dial
Settings · Invitations
How often should we invite you?
NormalAt most one at a time. Never required.
FewerAt most one a week.
OffWe won’t ask again.
You can change this at any time. Off takes effect straight away.
03 · For You
For You · every card with its reason
Topic match · an interest named on day one
Back on the trail — three small things that made long walks easierRen T. · Staying Active
Topic match · read and replied to lately
Flying next month — my airport routine, start to finishMarisol V. · Travel & Getting Around
Curated · the magazine lane, woven in
Questions worth asking when you choose a clinic teamFrom the editors · Guide
Fill · newest — never labelled personal
New here. Mostly reading for now — helloDev A. · Introductions
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
03 — How it decides
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.
01
The dial
the member’s own setting, read first
02
The live card
one at a time, re-checked rather than replaced
03
The budget
twelve hours, then one a day and three a week
04
Five shapes
a fixed order, and the order is the whole ranking
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.
04 — The safety margin
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.
What the ledger guarantees
DelayPossible
Silent dropImpossible
DuplicateImpossible
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.
05 — What this proves
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
Let's find the work AI should be doing in your organization.
Whether you are exploring an idea or improving a system already in use,
we’ll help you decide what is worth doing next.