.gitbay/wiki/Parity.org

ca02f30bc09194b796e456c746a08421359b58d4
gitbay/.gitbay/wiki/Parity.org rendered · source · history · blame · raw

289 lines · 14039 bytes

  1#+title: Parity
  2
  3Which surface can do what. The CLI is meant to be the complete
  4interface: every capability exists over SSH, and the other surfaces
  5dispatch the same control commands rather than reimplementing them, so
  6they cannot drift. This page is updated in the merge request that
  7changes a row.
  8
  9Three surfaces now: the CLI over SSH, the web, and the iOS client
 10(krz/gitbay-ios). A =no= in the cli column is a defect, not a
 11preference — it means some surface reached around the registry and
 12stranded a capability where only it can reach.
 13
 14* Rule
 15
 16A capability lands over SSH first. If it belongs to the
 17triage/review/respond loop, it lands on the web in the same merge
 18request. Anything whose input is a credential — secrets, mirror
 19tokens, API tokens — stays SSH-only by design: the web dispatcher
 20refuses =SSHOnly= commands outright. Session minting is not one of
 21them: what a browser submits to ask for a login link is a username or
 22an address, and the credential it gets back travels by mail.
 23
 24Rows are one page or one action each. Grouped rows hide gaps, twice
 25now: "browse, log, blame, search" read as covered while blame had no
 26command at all, and "build list, log" read as covered while the job
 27list a trigger can name had none (krz/gitbay#50), leaving the picker
 28browser-only and the iOS build screen unable to say more than the log.
 29
 30* Merge requests
 31
 32| capability             | cli | web | ios |
 33|------------------------+-----+-----+-----|
 34| read, diff, commits    | yes | yes | yes |
 35| review and check times | yes | yes | yes |
 36| who resolved it, when  | yes | yes | yes |
 37| comment                | yes | yes | yes |
 38| edit title and body    | yes | yes | yes |
 39| review (approve etc.)  | yes | yes | yes |
 40| resolve a thread       | yes | yes | yes |
 41| comment on a diff line | yes | yes | yes |
 42| merge (all strategies) | yes | yes | yes |
 43| close                  | yes | yes | yes |
 44| create                 | yes | yes | yes |
 45| draft, ready           | yes | yes | no  |
 46| search title and body  | yes | yes | no  |
 47| create from a fork     | yes | no  | yes |
 48| retarget               | yes | yes | no  |
 49| milestone              | yes | yes | yes |
 50| choose body markup     | yes | no  | no  |
 51| stacked merge requests | yes | yes | no  |
 52
 53Reviews and checks carry the time they last said something, and a
 54=ci/<job>= check carries how long its build ran, so a merge request
 55reads without opening the build. Statuses posted through =status set=
 56have no build and report only the time. A merged or closed merge
 57request names who resolved it and when; a row without that stamp — a
 58=migrate= import, or one merged before krz/gitbay!137 with no
 59=mr.merged= event to backfill from — says neither rather than
 60inventing a time.
 61
 62A merge request whose target is another open merge request's source
 63branch is stacked on it: =mr show= and the page say so both ways, and
 64when the lower one merges, everything stacked on it is retargeted onto
 65what it merged into with its reviews kept. A squash or rebase merge is
 66refused while anything is stacked on the merge request, since it would
 67rewrite the commits the stack builds on. The iOS client renders the
 68retarget but has no stack view yet.
 69
 70A draft merge request is open but not asking: it does not merge, and it
 71does not appear in anyone's review queue. Draft is a flag rather than a
 72fifth state, so every =state = 'open'= rule still means what it did.
 73Batched review and range-diff (krz/gitbay#111) are not built.
 74
 75Nothing asks a *particular* person for a review. The review queue is
 76computed from involvement — what you own, are granted, or reach through
 77an org or team — so a collaborator with write access who has not touched
 78a thread hears nothing until they do (krz/gitbay#145).
 79
 80Creating from a fork works anywhere the source can be typed as
 81=owner/name:branch=; only the web lacks it. Retargeting moves an open
 82merge request onto another branch of the same repository and stales the
 83reviews, since an approval was of the diff against the old branch.
 84
 85* Issues
 86
 87| capability          | cli | web | ios |
 88|---------------------+-----+-----+-----|
 89| read, list, filter  | yes | yes | yes |
 90| filter by label, assignee, author, milestone | yes | yes | no |
 91| search title and body | yes | yes | no |
 92| create              | yes | yes | yes |
 93| comment             | yes | yes | yes |
 94| edit title and body | yes | yes | yes |
 95| close and reopen    | yes | yes | yes |
 96| labels, assignees   | yes | yes | yes |
 97| milestone           | yes | yes | yes |
 98| milestone list      | yes | yes | yes |
 99| labels: list, colour | yes | yes | no  |
100| choose body markup  | yes | no  | no  |
101
102Labels are created on the fly by =issue label --add= and managed by
103=label list=, =label set <label> --color rrggbb= and =label remove=,
104which takes the label off every issue. The web paints the stored colour
105on every chip and derives one from the name when none is set. The set
106itself is at =/<owner>/<repo>/labels=, linked from the issue list:
107create, recolour and remove, dispatching the same commands.
108
109Issue, MR and release bodies, and their comments, carry the markup they
110were written in — =--format md|org= on create, comment and edit, stored
111alongside the text so changing a preference later cannot reinterpret
112prose that already exists. Every surface *renders* the stored format;
113the =no= above is the absence of a picker on the web form and in the iOS
114composer, both of which write markdown. Diff-line comments have no
115format column and are always markdown.
116
117* Repositories
118
119| capability                  | cli | web | ios |
120|-----------------------------+-----+-----+-----|
121| browse files                | yes | yes | yes |
122| read a file                 | yes | yes | yes |
123| commit log                  | yes | yes | yes |
124| commit log at a ref         | yes | yes | yes |
125| one commit with its patch   | yes | yes | yes |
126| blame                       | yes | yes | yes |
127| search file contents        | yes | yes | yes |
128| compare two refs            | yes | yes | no  |
129| branches and tags           | yes | yes | yes |
130| wiki (read)                 | yes | yes | yes |
131| download an archive         | yes | yes | n/a |
132| edit a file                 | yes | yes | yes |
133| create                      | yes | yes | yes |
134| pin                         | yes | yes | yes |
135| watch, mute                 | yes | yes | no  |
136| settings, protection        | yes | yes | yes |
137| topics, website             | yes | yes | yes |
138| visibility                  | yes | yes | yes |
139| archive (read-only flag)    | yes | yes | yes |
140| release list, show          | yes | yes | yes |
141| release create, edit        | yes | yes | yes |
142| build list                  | yes | yes | yes |
143| build show (one build)      | yes | yes | yes |
144| build log                   | yes | yes | yes |
145| build jobs                  | yes | yes | yes |
146| build trigger               | yes | yes | yes |
147| build cancel                | yes | no  | no  |
148| dependency checks on/off    | yes | yes | no  |
149| dependency status           | yes | no  | no  |
150| delete, transfer            | yes | no  | no  |
151| release delete              | yes | yes | no  |
152
153No row is web-only any more. Blame, file editing, log at a ref,
154archive, the public listing and the wiki were all in that state — a
155handler reading git or the store directly instead of dispatching a
156command — until krz/gitbay!99, !101 and !102 gave them commands.
157
158=build cancel= withdraws a queued build, or ends a running one: the
159server closes the runner's log session and the runner kills the step
160within a couple of seconds. Cancelling a duplicate of a commit that
161already passed the job puts that result back on the commit. No button
162on the build page yet.
163
164Dependency checks are off until a repository's admin turns them on: the
165check tells a public registry what the repository depends on. =repo deps
166status= lists what is behind and has no web view because the report
167itself is an issue the worker opens, rewrites and closes, which every
168surface already reads.
169
170The wiki row covers reading. A wiki lives at =.gitbay/wiki/= on the
171default branch, so editing one is editing a file in the repository —
172a push, or =repo commit-file= — and there is no wiki-specific edit row
173to have parity on. The web editor reaches it on any repository that
174permits server-authored commits; one requiring verified signatures
175does not, because the server signs nothing on a user's behalf, so
176those wikis are push-only.
177
178=n/a= marks a capability deliberately absent from a surface rather than
179missing from it. Archive download is =n/a= on iOS: the read API carries
180a command's stdout as a JSON string, so a gzip stream cannot survive it,
181and the app has nowhere useful to put a tarball — the brief rules out
182local git, so there is no clone, checkout or build to feed. The web's
183route stays the way to get one.
184
185A README or wiki page's org renders per surface: the web through
186go-org, the iOS client through the shared OrgSwift package
187(=krz/org-swift=). OrgSwift is held to orgo's output by the
188=krz/org-conformance= corpus — golden renderings from orgo, itself
189diffed against Emacs =ox-html= — so constructs the iOS client used to
190approximate (tables, footnotes, timestamps, heading tags, nested lists)
191now render the way the reference does. go-org is not yet on the corpus.
192
193* Discovery
194
195| capability                       | cli | web | ios |
196|----------------------------------+-----+-----+-----|
197| search repositories              | yes | yes | yes |
198| search issues and merge requests | yes | yes | no  |
199| browse all public repositories   | yes | yes | yes |
200| profile page                     | yes | yes | yes |
201| profile about and links          | yes | yes | no  |
202| activity feed                    | yes | yes | yes |
203| command reference                | yes | no  | n/a |
204
205=explore= is the listing without a query; =repo search= is the one with.
206=search= is both plus the title and body of every issue and merge
207request the caller can read, over FTS5; the web serves it at =/search=
208with a field in the rail, and an anonymous visitor gets the public rows
209from the same query. =issue list --search= and =mr list --search= narrow
210one repository. What someone types is quoted term by term, so an FTS5
211operator — =c++=, =AND=, a lone quote — is a word to match and never a
212syntax error. =repo grep= remains the per-repository file-contents
213search.
214
215About text renders as markdown or org-mode per the =about_format= it
216was stored with. The iOS =Profile= decoder lists its keys explicitly,
217so it ignores =about= and =links= rather than breaking on them.
218
219=help= lists the command registry. Bare it is an index, one line per
220command, sorted. With a prefix (=help mr=) it adds each command's
221argument syntax, which is the only place flags are written down;
222=gitbay <cmd> --help= asks the server for the same thing, and =--json=
223returns ={path, summary, usage}=. No web page renders it, and a native
224client has no use for one (krz/gitbay#57).
225
226* Accounts
227
228| capability                  | cli | web | ios |
229|-----------------------------+-----+-----+-----|
230| SSH keys: list, add, remove | yes | yes | yes |
231| PGP keys: list, add, remove | yes | yes | yes |
232| email add and verify        | yes | yes | yes |
233| dashboard aggregate         | yes | yes | yes |
234| notification inbox          | yes | yes | no  |
235| API token mint              | yes | no  | no  |
236| account export bundle       | yes | yes | no  |
237| profile set                 | yes | no  | no  |
238| request a login link        | n/a | yes | no  |
239
240Notifications land in an inbox row per recipient whether or not the
241instance sends mail, and mail is the second half when SMTP is
242configured. =notifications list= reads it, unread by default;
243=notifications read <id>... | --all= clears it; the dashboard and the
244web rail carry the unread count. =repo watch= adds you to a
245repository's notifications and =repo unwatch= mutes it, and a mute wins
246over owning the repository or having written the thread.
247
248A login link is requested from the login page by username or verified
249address, and arrives by mail: it works once and expires in fifteen
250minutes. The row is =n/a= for the CLI because a terminal with a
251registered key runs =web login=, which mints a link directly and needs
252no mail. It exists because an account with no SSH key had no way into
253the web at all (krz/gitbay#155). The page offers the form only when the
254instance has SMTP configured; there is no separate switch. The response
255never says whether the account exists.
256
257=profile set= carries description, website, about and links. It is not
258=SSHOnly= — nothing about a bio is a credential, and the JSON API runs
259it — but no surface has ever offered a form, so the =no= above is
260missing UI rather than a rule.
261
262* Organizations
263
264| capability                | cli | web | ios |
265|---------------------------+-----+-----+-----|
266| read members and teams    | yes | yes | yes |
267| members add, remove, role | yes | yes | yes |
268| teams create, delete      | yes | yes | yes |
269| team members              | yes | yes | yes |
270| team repo grants          | yes | yes | yes |
271| create, rename, delete    | yes | no  | no  |
272
273* Pagination
274
275=issue list=, =mr list=, =repo list=, and =feed= take =--limit <n>=
276and =--cursor <c>=. Cursors are opaque; each page carries the next
277one. Without the flags a list stays complete, so existing scripts are
278unchanged. The web pages the issue and merge request lists at fifty
279with the same cursors; iOS pages with them too.
280
281* SSH only, by design
282
283Build secrets, mirror configuration and tokens, custom domain claims,
284API token minting, deploy keys, account and instance administration. Deleting or transferring a repository is also
285CLI-only: both want a typed confirmation, not a button.
286
287These are the only rows where a =no= is intended. Everywhere else a
288=no= is work outstanding, and =n/a= means a surface cannot usefully
289carry the capability at all — see the archive note above.