Online community — the model build-off
Four models, one byte-identical planner package — same source hash, same generator — so every difference below is the model, not the brief. A community looks like the easiest product in the catalogue: spaces, posts, a member list, some events. What decides it is who may read what about whom. The members are strangers to each other, moderators judge reports about people they know, and the member directory is a list of real people's contact details. So the question is not whether the app has a directory. It is whether one member can read another's email address, whether the export of that list is guarded as tightly as the list itself, whether a reported member can find out who reported them, and whether someone removed from the community can still read it. One of the four guarded the export and left the list wide open. The other three closed that gap — and none did it because a check in its own test suite asked.
How the builds ranked.
Hearthside
Best OverallThe one to copy. It got the directory right by design, not by accident.
- Best at
- Treating the member directory as the confidential record it is. The directory query never selects an email address at all, and the same visibility rule is applied at four separate surfaces — the list, a profile opened by its id, a member's connections and search — so there is no second door into what the first one withholds. A member who hides from the directory returns not-found rather than forbidden, so nobody can confirm they exist. The members table and its export are refused to ordinary members and hosts alike, and the moderation queue and its export agree the same way. We created a second community to test separation between them and found none leaking. Its demo sign-in is double-locked: in production it stays off even if the setting that enables it is left on. And its own suite of 115 checks re-ran cleanly against the database it shipped.
- Watch for
- No login throttling. Ten wrong passwords went through in under three seconds with no lockout, no backoff and no refusal. Two things genuinely soften it: every attempt costs a quarter of a second of password hashing, and an unknown address fails in the same time with the same message as a real one, so it cannot be used to discover accounts. But nothing stops a patient attacker, and nothing tells the operator an account is under attack.
Gatherwell
Best HardeningThe most defended build in the programme. It arrived with two operational faults.
- Best at
- Defences the others did not build. It is the only one of the three with working login throttling — twelve attempts, then a refusal. It also enforces cross-site request protection: every change must come from its own origin or it is refused. Retried requests are recognised and replayed rather than applied twice, concurrent edits are caught instead of silently overwriting each other, and every audit entry is written in the same transaction as the change it records. The directory problem is closed structurally: the member list and its export are literally the same request, so they cannot drift apart. A demo visitor gets not-found for the real community, not forbidden, so they cannot even learn it exists. Its reply-level reporting is defended inside the database itself, which refuses to store a report whose recorded source disagrees with the reply it names.
- Watch for
- Two operational faults. Deleting its database to start fresh left the application unable to start at all, because a leftover file told it the tables already existed. And its own verification could not be reproduced against the build it delivered — 64 of 76 checks passed in our hands, the rest depending on data from its own build session. Smaller: it answered only on the machine it ran on, so it could not be put on a hosted address without changing code; its login limit counted per email address only; and a member who hid from the directory vanished even for the moderators responsible for them.Fixed since audit — all of it was repaired against our findings and re-verified, and it was rescored 92 → 97. Every database starting point we tried now boots — deleted, empty, populated, and imported. Its full suite passes 76 of 76 twice in a row with no preparation, and when we deliberately broke a permission check in our copy, the suite caught it. Hosting is now configurable while staying local-only by default, a second login limit per source was added, and staff can now see hidden members, clearly labelled as hidden.
Northline
Leanest StackIt kept email addresses private and escaped every page — then let removed members keep reading.
- Best at
- Getting the vertical's headline question right with no framework at all. Signed in as an ordinary member, the directory carried no email address anywhere, not even in the page source, and the member list and its export both refused. It runs on zero dependencies, yet every value it writes into a page goes through its own escaping helper, so the markup injection that sank another build here cannot happen. Passwords are hashed with scrypt, sessions are stored only as a hash and expire after twelve hours, and email and push are honestly shown as pending rather than sent. Its own 58 checks re-ran cleanly in our hands.
- Watch for
- Removing someone from the community removes nothing. We removed a member and the moderator: both could still sign in, the member could still read the discussions, and the moderator could still open the moderation queue, which names who filed each report. And a community manager's backup is a copy of every community on the server. Northline's manager downloaded a file holding the other community's manager account and every password hash, and restoring a backup rolls every community back. Invited people are never given a way to sign in, and joining with an invited address crashes with a server error. The demo sign-in can't be switched off, there is no login throttling, and the session cookie is not marked secure. Its own suite could not have caught any of this: each feature's three checks share one pass or fail from its working path, so none of its denial checks runs on its own.
No public demo for this build.
CrowdCraft
Fast-Tier BuildModeration done right — and any member's display name could run code in the manager's browser.
- Best at
- Getting the vertical's usual failure right. The moderation queue is closed to ordinary members and to hosts, while filing a report stays open to every member, which is exactly the right split, and the export of the member list is locked down even more tightly than the queue. Every privileged surface we tried refuses an anonymous visitor, sign-out revokes the session on the server, and passwords are properly hashed. It runs on four production dependencies with a clean audit. Its own 44 checks re-ran cleanly in our hands.
- Watch for
- Its pages write names, posts and titles into the screen as raw markup, and nothing in the application escapes them. A member who set their display name to a snippet of script had it run in the community manager's browser the moment the manager opened the member list — and, riding the manager's session, the script promoted that member to community manager. Any member could also send any other member a notification whose link ran script when clicked, and the sign-in page would forward to whatever address it was handed, another site included. The member list handed every signed-in member everyone's email address, the community manager's among them, while its own export of the same list refused even a moderator. A host could cancel, publish or export the attendee list of events other people run. And the demo sign-in could not be switched off, there was no login throttling, and the session cookie was not marked secure.Fixed since audit — the model's own repair closed the member list, made the demo sign-in switchable and off by default, added login throttling and marked the cookie secure — but left the script injection, two more routes that still handed out email addresses, and the event and notification holes. We repaired those: every value written into a page is now escaped, stored links must be web addresses, only staff can notify other members, sign-in only returns to pages on the site, and a host manages only their own events. With attack text planted in every text field, 60 page loads and 154 opened panels ran it zero times, against 5,573 times before the repair, and the build's own 46 checks still pass. The score stays the as-found one.
Models tested: Claude Fable 5.1, GPT-6 Astra, Grok 4.7 and Gemini 3.8 Flash — all four from the same planner package, so all four numbers are directly comparable. Scores are as found at audit, after each build had run its own acceptance pass. Test data that a build's own QA runs left behind in its delivered database is reported back to the build but not scored, and all four builds were treated the same way on that. GPT-6 Astra was later repaired against our findings and re-verified (92 → 97); that is described under the build, but the score stays the as-found one, because that is what the model produced unaided. Gemini 3.8 Flash was re-audited on 2026-09-23 and rescored from 88 to 68: our first pass missed that it writes names and posts into its pages as raw markup, which let any member take over the community manager's account. Fable 5.1 and Astra render their pages through React, which escapes text by default, and we confirmed neither writes user text into a page as raw markup. Grok 4.7 uses no framework, but passes every value it writes into a page through its own escaping helper. Grok 4.7 was audited on 2026-09-26 on an isolated copy, and its decisive findings were reproduced by hand. Fable 5.1, Astra and Gemini are published as live demos; Grok 4.7 is not. The Gemini demo is the repaired build, without unrelated experiments that were later added to its folder. These grade correctness and security, not visual design or workflow usability.