Build1 distinct publisher2 min readUpdated
The app shows one shareable page. The record layer shows twenty-two writes for a twenty-person pack, and no safe way to run them twice.
The Engineer · Build desk
Compiled by The EngineerSomething wrong?How this is made
The idempotency in this design sits in exactly one place. `putRecord` against a known rkey overwrites in place, so a rename or a feed swap leaves the same share URL standing [7]. Nothing on the create path behaves that way. Each `createRecord` mints a fresh rkey, and the protocol dedupes on no natural key such as a title, so a second run of a creation script yields a second pack, live and indexed, whose URL is not the one your script now reports [6]. None of this needs a privileged API: it is ordinary `com.atproto.repo` calls against your own PDS [8].
Count the writes. A twenty-person pack is one list record, twenty listitems and one starterpack record, so twenty-two writes before anything is shareable [1]. Filled to the documented cap of 150 people it is 152 sequential creates [2], and 150 of those carry the membership the artifact exists to express. The team behind the dev.to writeup says it slices to remaining capacity in its own code and has never pushed a list past the cap to see what the record layer does [12].
Retry safety therefore has to live in the read rather than the write. According to the writeup, the add-members path takes the existing list's AT-URI, fetches current members through `app.bsky.graph.getList` while paginating on the cursor, dedupes the incoming batch against that fetched set and against itself, slices to remaining capacity, and only then loops the listitem creates [10]. The cursor is the load-bearing detail. Dedupe against page one alone and every member past that boundary looks absent, so the retry that was supposed to be safe writes duplicates [10].
The error contract follows from the same mechanism. If member 14 of 24 fails, thirteen listitems are already committed in the repo, and raising an exception reports that nothing happened when something did; the pipeline instead returns the added-so-far result alongside the error and lets the next run's dedupe absorb the overlap [11].
One more consequence of the reference structure is worth naming, because it is where the public identity gets decided. The share URL is not returned by the API. It is derived: your handle plus the rkey tail of the starterpack record's AT-URI [5]. That means the name a pack is known by comes out of the one call in the pipeline that cannot be repeated. Everything downstream of it can be corrected with `putRecord`. The create cannot.
Follow any of these and your For You feed starts watching them — no settings page required.
Ranked by verification strength, evidence, and original report placement.
A Bluesky starter pack is backed by an ordinary Bluesky list record (app.bsky.graph.list) with purpose app.bsky.graph.defs#referencelist; the list record holds metadata such as name, purpose and createdAt plus optional description and avatar, while members live elsewhere.
Membership is stored as app.bsky.graph.listitem records, one per member, each holding the member's DID and the list's AT-URI; there is no batch add call in the record layer, so twenty members means twenty listitem creates.
The app.bsky.graph.starterpack record is what makes the share page exist; per the lexicon name, list and createdAt are required, list is the AT-URI of the referencelist, the name is capped at 50 graphemes, and optional feeds can attach custom feeds.
The official limits are up to 150 people and up to 3 feeds per starter pack.
The share URL is derivable rather than returned: https://bsky.app/starter-pack/{your-handle}/{rkey}, where rkey is the tail of the starterpack record's AT-URI.
Every createRecord mints a fresh rkey, so running a create-starter-pack script twice produces two packs with two URLs, both live and both indexed, and the one already shared is not the one the script now reports; there is no natural key such as a title that the protocol dedupes on.
Evidence-backed comparisons of source perspectives and observed adoption signals. Read the methodology
Which Builder, Operator, and Investor concerns the observed source mix emphasized—not a truth score.
Evidence, demonstrated adoption, hype gap, incentives, and confidence are assessed independently, each on its own current evidence. How these are measured.
Detailed first-hand account, single source, no external citation
The mechanics are specific and internally consistent — named lexicon types, required fields, the derivable share URL, and the createRecord/putRecord asymmetry — and they come from someone who says they run the flow. But the cluster contains exactly one article from one publisher, the stated limits (150 people, 3 feeds, 50 graphemes) are attributed to 'the lexicon' and 'official limits' without a linked spec, and nothing independently confirms the non-idempotency behaviour or the orphaned-record cleanup claim.
One self-reported pipeline, no third-party usage
The only adoption signal is the authors' own disclosure that the pipeline runs in an automated outreach flow for Rulestack with packs published from @ai-shop.bsky.social. There are no counts of packs, members, other teams using the pattern, or any external deployment, so the measured level is deliberately low rather than zero.
Modestly stated relative to the detail supplied
The framing stays close to what is shown: the piece promises a record decomposition and one non-idempotency trap and delivers both, and its strongest generalisation — that curation quality rather than API access becomes the bottleneck — is a limited claim. Mild negative rather than zero because the concrete failure mode (two live, indexed packs after a double run) is arguably more consequential for anyone automating packs than the low-key how-to presentation suggests.
Disclosed vendor promotion attached to a how-to
The post closes by naming the authors' product (Rulestack, rule and skill packs for AI coding agents) and directing readers to @ai-shop.bsky.social to see the output, and the pipeline described exists to serve an automated outreach effort. The promotional interest is real and would bias toward presenting the approach as sound, though it is disclosed openly and the technical content includes unflattering details such as never having tested the 150 cap.
Coherent but uncorroborated single-publisher account
Confidence is capped by cluster shape: one publisher, one article, no contradicting or confirming source, and a mix of checkable protocol mechanics with unverifiable team practices. The specificity of the record types, field requirements and failure handling raises confidence above the floor for the technical core, while the self-reported operating rules and adoption disclosure remain single-party assertions.
build
The git part is not the part doing the work: JSONL ledgers as an agent's state layer1 distinct publisher
build
Bluesky names its infrastructure, and puts a token on the archive1 distinct publisher
build
Buy transactional email on recovery controls, not send price1 distinct publisher
build
Four Clocks, One Timeout: Why Long-Audio Transcription Needs a State Machine1 distinct publisher
Distinct publishers with included, body-backed reporting in this cluster.
dev.to
1 article · August 22, 2026