package manager: login, logout, owner and yank commands #22
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Goal
The write service of packages.torb.dev already has accounts, scoped tokens, owners and yank over
/api/1(
tools/registry), buttorbcan only publish. Add the client commandstorb login,torb logout,torb ownerand
torb yank, so an owner manages a package without writingcurlcalls.torb deprecateis split out to #279.Source
yank,ownerandloginas commands over the API that exists" is the open item--undo), 7.1 (owners and roles), 7.6 (tokens, second factor,Torb-Code), 7.13 ("Not built" list), 2 (registry readiness)tools/registry/README.md(the API and itsTorb-Coderules, #274/#275),compiler/src/package/upload.trb(the client's HTTP helper and token lookup),compiler/src/package/user-config.trb(the torb home files)Design (decided by the loop, see the comment below for the reasons)
publish:torb login,torb logout,torb owner list|add|remove,torb yank--registry <url>first; else the registry the package's (or owner's) owner is bound to by aregistryline when run inside a project; else the public registry (registryOf). Never through a mirrortorb login [--registry <url>]GET /api/1/tokensbefore storing it, so a wrong or expired token is refused and nothing is writtencredentials.trbin the torb home ($TORB_CREDENTIALSoverrides, like$TORB_CONFIG), a receiver script of literal linestoken "<registry url>", value: "torb_..."read statically and never evaluated. A separate file fromconfig.trbsoconfig.trbstays shareable. Created with mode0600before the secret is written (read-only attribute on Windows, which is the profile's ACL otherwise). A project never holds a tokenTORB_TOKEN, then the stored token of that registry, then trusted publishing (publish only). A stored token is returned only forhttps:or a loopbackhttp:registry. The token never appears in an argument or a log linetorb logout [--registry <url>]torb ownerlist <owner>(GET /owners/<owner>),add <owner> <account> [--role owner|publisher](defaultpublisher, the least privilege),remove <owner> <account>.addandremovesendTorb-Codefrom--code <code>or$TORB_CODE(an authenticator app or recovery code) when the account has a second factor, and print the registry's own refusal otherwisetorb yank <owner/name> <version> --reason "..."and--undo--undo. On afile:registry the command appends theyankorunyankline itself (aspublishappends a release) and is refused when that registry signs its index; there are no accounts on a directory, sologinandownerrefuse afile:registry in wordsNot in this issue: step-up by passkey for
owner add\|remove(a passkey-only account) anddeprecate, split into #279 and #280.Acceptance criteria
torb loginstores a verified token thattorb publish,ownerandyankthen use;TORB_TOKENstill wins; a token the registry refuses stores nothingcredentials.trbis created0600on POSIX, read statically (a malformed line is an error at its line), holds one line per registry, and a secondloginreplaces the line of its registry;torb logoutremoves ithttp:to a non-loopback host, never to a mirror, never printed, and never in a process argument (test the argument list and the output)torb owner list|add|removeandtorb yank [--undo]work against/api/1, print the registry's answer, and print its refusals in its words (403,409, theTorb-Coderules)torb yank [--undo]on afile:registry appends the record andreadIndexthen excludes or re-admits the version;loginandowneron afile:registry are refused with a sentence--undowith--reason, yank without--reason, unknown role) exit 2 with a sentence;torb --helpandusage.trblist the new commandsfile:yank) incompiler/tests; the network commands intools/registry/testsagainst the registry over loopback with afile:storage and a temporary database, asclient.test.trbdrivestorb publish(a full round: operator account,login,owner add,publish,yank,yank --undo,owner remove,logout). No production registry is toucheddocs/tooling/torb-login.md,torb-logout.md,torb-owner.md,torb-yank.md,torb-publish.md's token section points atlogin,docs/tooling/index.mdandthe-torb-command.mdlist them; RELEASE.md 7.13 "Not built" and 7.11 "Not built yet", ROADMAP.md's package-manager item andtools/registry/README.md"Not built yet" no longer nameyank,ownerandlogin;skills/regenerated (torb docs skill docs skills)Design record point
RELEASE.md sections 7.3 (
torb yank acme/http 1.2.4 --reason "...",--undo) and 7.6 (tokens scoped and stored by the client), ROADMAP milestone 8 "the package manager's remaining commands". The storage file is new and is recorded in RELEASE.md 7.13 as part of this change.Seed impact
None. TorbScript only in
compiler/src/cli,compiler/src/packageandtools/registry/tests: no syntax change, no new native (File.setPermissionsand thecurl/wgethelper ofupload.trbexist), no driver flag, no std name the compiler looks up by string. One PR, no seed refresh.Size
One PR landing as two Conventional Commits:
feat(package): torb login and logout with stored registry tokens(credentials file, token lookup shared withpublish, registry resolution, tests, docs)feat(package): torb owner and torb yank over the registry API(the two commands,file:yank, tests, docs, design-record updates, regenerated skills)Related
deprecate: registry endpoint, index record and client) and #280 (passkey step-up forowner add|remove), both depend on this issueTorb-Coderules this client follows[loop:torbscript] intake: in scope (author orion, label loop). Client commands against the registry API per RELEASE.md readiness; tests against a local or
file:registry, no production registry touched. Likely adds new subcommands, so command names and token storage may need an owner decision, to settle in refine. Release freeze for 0.1.0 (2026-10-06) holds new PRs, next: refine (queued)[loop:torbscript] refine: still queued behind the intake order. next: waiting (ready buffer full: #4, #163, #164, #223 are ready) until 2026-10-10T04:00:00Z
[loop:torbscript] claim refine by session:loop-torbscript-20261009 until 2026-10-10T00:30Z (ready buffer holds only 3 ready issues, 2 of them waiting on a seed, so refine is allowed; the earlier "buffer full" marker was stale)
torb deprecate: flag a whole package as deprecated #279torb owner --step-up: approve owner changes with a passkey #280package manager:to package manager:login,owner,yankanddeprecatecommandslogin,logout,ownerandyankcommands[loop:torbscript] refine: ready (claim 2839 released). Decided by the loop, from RELEASE.md 7.3/7.6/7.13, the registry README and
upload.trb; the issue body now holds goal, criteria, seed impact (none) and size (one PR, two commits).publish:login,logout,owner list|add|remove,yank [--undo];logoutadded as the inverse oflogin. Reason: existing commands are flat, the issue and RELEASE.md 7.3 use these words.credentials.trbin the torb home ($TORB_CREDENTIALS), a statically read receiver script likeconfig.trb, mode0600, never in a project. Reason:config.trbis meant to be shared and mirrors never get secrets; reusing the receiver-script format needs no new native (File.setPermissionsexists). Lookup:TORB_TOKEN, stored token, trusted publishing; stored tokens only forhttps:or loopbackhttp:.logininput: token from standard input only, verified withGET /api/1/tokensbefore it is stored. Reason: a flag would leak into shell history and process lists; the API has no device flow to mint one from the client.--registry, else the owner'sregistrybinding, else the public registry;owner/loginrefusefile:,yankappends to afile:registry (gives the local-registry test the issue asks for).owner add|removetake--code/$TORB_CODE(app or recovery code). Passkey step-up is split to #280 because it needs an interactive approval loop.deprecatehas no registry API, no index record and no stored flag, so it is a registry plus index plus client change of its own: #279 (readers skip unknown index words, so it is not a break of the published index; verified by a test there).next: implement
[loop:torbscript] claim implement by session:loop-torbscript-20261009 until 2026-10-10T04:30Z
torb deprecate: flag a whole package as deprecated #279torb owner --step-up: approve owner changes with a passkey #280[loop:torbscript] implement: PR #283 open, CI green
6622ea59feat(package): torb login and logout with stored registry tokens,6f9d340bfeat(package): torb owner and torb yank over the registry API.tools/registry/tests/commands.test.trb(login, owner add, publish, yank, yank --undo, owner remove, logout; the token in no curl argument and no output) passes in the registry job.login/logoutalways default to the public registry (there is no owner to bind);owner listsends no token;wgetnow reads headers from a--configstartup file too, and header files are written 0600.next: waiting (merge gate review of PR #283)
torb deprecate: flag a whole package as deprecated #279torb owner --step-up: approve owner changes with a passkey #280torb deprecate: flag a whole package as deprecated #279torb owner --step-up: approve owner changes with a passkey #280[loop:torbscript] close: landed via PR #283 by the merge gate as
6622ea596eand6f9d340b68, main CI green on6f9d340b. Issue closed. Unblocked: #279 (waits for PR #282), #280 (in implementation). next: done