Prepare scoped npm prerelease - #12
Conversation
Technical reviewCorrecting my own check on #11I reported that the name was still free, based on this: A 404 means nobody has published it. It does not mean npm will let you. The registry applies a similarity check at publish time, and that is what rejected The collision is real. Everything in the verification list reproducesCloned the branch and ran it: The 15 paths are the same allowlist as before, so the rename did not disturb the packed contents. I also checked the dotted scope, since So the name is syntactically fine, and Bumping to Finding: the failure that killed alpha.1 is still outside the verification listThis is the same gap, one level up. Every listed check runs locally:
Two registry-side conditions remain unverified, and both fail at the same late point: The The scoped name must clear the same similarity policy. Scoping usually settles it, since the check is scoped-aware, but "usually" is what the last attempt relied on. Both are answerable in seconds with an authenticated Finding: the pull request body is malformedThe description contains 22 literal Cosmetic, and worth fixing because this body is the record of why the name changed. Someone reading it in six months to understand the alpha.1 failure will be reading one long line. Two findingsVerify the org and scoped name against the registry before tagging, and re-render the description. |
Lesson: "nobody has it" is not "you can have it"I made this mistake on the previous pull request, so it is a fair one to teach. The question was whether a package name was available on npm. I checked the obvious way: Not found. Available, surely. npm refused it. There is a package called The 404 was accurate. It just answered "has anyone published this?" when the question was "will you accept this?" The general shapeChecking for absence tests availability. It does not test permission. These come apart wherever a namespace has policy attached, which is most places worth naming something: npm blocks typosquat-adjacent names, as above. RubyGems has similar protections, and additionally will not let you reclaim a name that was published and then yanked. DNS will happily tell you a domain is unregistered while a trademark holder is entirely willing to take it from you afterwards. GitHub organizations hold reserved words and names tied to dormant accounts that no API will report as taken. S3 buckets are globally unique, so a name free in your account may be held silently in someone else's. Database uniqueness, which is the version every Rails developer has already met: if User.where(email: email).none?
User.create!(email: email) # racy, and the constraint is the real authority
endThe check and the write are separate operations, and something can change in between. This is why the unique index exists and why Local validation is not server acceptance eitherThe same PR shows the second half of the pattern. The release process runs: That builds the tarball, validates the name syntactically, and prints exactly what would be sent. It is a genuinely useful check, and it passed for the rejected name too, because it never contacts the registry to ask. A dry run tells you your request is well-formed. It does not tell you it will be accepted. The same gap appears in What to do about itClaim the namespace before you build the process around it. Publishing a placeholder version, or just registering the org, converts an assumption into a fact. Here the name was assumed through an entire release workflow, a protected tag, and an approval environment, and failed at the last step. Make the cheap authoritative check part of the checklist. For npm that is asking the registry whether you may publish, not whether something exists. Where the authoritative check needs credentials, that is a hint it is the one that matters, because it is the one the server actually evaluates. When a check comes back negative, ask what question it answered. A 404 is a fact about the registry's contents. Whether you may add to those contents is a different question with a different answer, and the two look identical until the moment they do not. |
npm rejected the unscoped package name as too similar to an existing package. Publish the next immutable candidate in the firstdraft.com organization while preserving the firstdraft executable. Canonicalize the bin target so npm no longer warns while normalizing it, and record the scoped bootstrap, trusted-publisher transition, and alpha.1 recovery history.
2a28688 to
8f53c9f
Compare
|
Addressed both hosted findings in 8f53c9f.
The checklist deliberately states the evidence boundary: the checks prove scope authority and package absence. npm exposes no non-mutating registry endpoint that guarantees admission. Publishing under an owned scope is the documented remedy for the unscoped similarity rejection, and the workflow continues to require public access explicitly. Verification on the exact pushed tree:
Hosted CI is rerunning on 8f53c9f. |
Follow-up on
|
Summary
Context
npm rejected the unscoped firstdraft name as too similar to the existing first-draft package before creating a registry package. The protected v0.1.0-alpha.1 Git tag remains immutable, so this uses the next version and leaves the old tag untouched.
This PR only prepares reviewed source. It does not create v0.1.0-alpha.2 or publish to npm.
Verification