Sign in

Search issue titles and bodies, change requests and comments. Private repositories you cannot read are not included.

vole
Clone

Read only, no credentials:

https://rodent.software/git/vole.git

Write over SSH with a registered key:

git clone ssh://git@0.0.0.0:2222/vole.git

A free and open-source forge that lives in your Git repo.

Phase 7: the CLI knows who you are and where you wrote it

a63475ce8a689107f6572150d7c58be1d623f6f0 · Keenan Nemetz · 17d ago · parent 79c88d72

Phase 7: the CLI knows who you are and where you wrote it

Three things a first-time user hit in a row, all measured against a live
instance before they were fixed.

1. Identity was guessed. Every issue and request was stamped with a name from
   `git config user.name`, sanitised: "Keenan Nemetz" became `keenan-nemetz`, an
   account that does not exist, and nothing complained — the issue page showed it,
   and the assignee rule accepted it because that rule only checks the shape.
   `vole-whoami` is a new SSH verb, and `vole whoami` is the CLI command that
   reads it: the instance is the only place a key maps to an account, and it is
   one call on the connection already open. `vole issue` and `vole request` stamp
   the account's current name and id, and `--author` is gone from both, because a
   name you can type is a name you can get wrong. Read commands still need no
   identity — `issue list` and `issue show` keep working with the instance
   unreachable — and the git-config guess survives only as a warned fallback for
   `--no-push`.

2. `--remote ssh://…` did not fetch. `fetch` checked for a configured remote name,
   so a URL was skipped: the first write in a fresh repository succeeded (nothing
   to fast-forward from) and every later one pushed from a tip that had never been
   updated, was rejected, and then retried as a "lost race" that never happened,
   reporting `already exists`. A URL is now fetched like a named remote, so
   `git init` plus a URL is the real no-clone filing path the roadmap described.

3. A command answered with an id and stopped. `new` and `comment` now print the
   page they wrote, and a comment link lands on that comment: the instance reports
   its own `public_url` in the same whoami reply (new optional config key), and the
   web puts an `id="c-<ulid>"` anchor on every comment. Empty states on the issues
   and requests pages print the command that fills them, because four of the five
   things a reader wants to do are writes the web cannot take, and "no comments
   yet" is a dead end.

Verified live, not only in tests: `vole whoami` in a clone whose `user.name` is
"Keenan Nemetz" printed `keenan` while the issue it then filed carried
`author: keenan` on the branch; two repositories that never clone both wrote
through the URL (the exact case that failed before); and a comment printed a
`#c-01M5N3M0…` permalink whose anchor is on the served page. Tests:
TestWhoAmIAnswersFromTheInstance (including `--author` now being an unknown
option), TestReadCommandsNeedNoIdentity (closes the SSH listener, then lists),
TestRequestAuthorComesFromTheKey, TestAURLRemoteIsFetchedBeforeWriting,
TestEmptyStatesPrintAWorkingCommand, and the comment-empty-state assertion added
to TestIssuePushedThenRendered. scripts/ci.sh green (gofmt, vet, build, markdown
links, go test -race ./...).

README.md +25−3

@@ -99,6 +99,13 @@ git clone http://127.0.0.1:8080/git/demo.git # read only, no credentials
99 99 Repositories are private by default. A private repo is a `404` on the web and
100 100 over HTTP — not a `403` — so the read-only surface never confirms that it exists.
101 101
102 Nothing in the configuration knows where the instance is reachable from outside,
103 so tell it once if the web is served through a proxy or another address:
104
105 ```toml
106 public_url = "https://forge.example.com" # optional; the CLI prints links to it
107 ```
108
102 109 ## Filing an issue
103 110
104 111 An issue is one file on the `vole` branch. No client tooling is required:
@@ -145,6 +152,7 @@ The id must be a ULID (26 characters, Crockford base32 — uppercase, no `I`, `L
145 152 Or use the CLI, which is the same thing with the paperwork done:
146 153
147 154 ```sh
155 vole whoami # which account your key is; no guessing
148 156 vole issue new --title "Nothing renders on the docs page" -m "Steps..." -l bug -a wilbur
149 157 vole issue comment -m "Also affects search" 01M5JR2JK29KKMAA1T9MDNTPBP # prints the comment id
150 158 vole issue edit-comment 01M5JR2JK29KKMAA1T9MDNTPBP 01M5N1PRC4GJPZNEEG8PR8J4D6 -m "Corrected."
@@ -171,9 +179,23 @@ Options come before arguments — `vole issue comment -m text <id>`, not the oth
171 179 way round — and a usage mistake exits 129, as git does.
172 180
173 181 The CLI writes the files, commits to the `issues` branch, validates locally and
174 pushes. `#<ulid>` in a body links to that issue, and commits whose message
175 mentions an id are listed as backlinks on the issue. The list page filters by
176 state and label and searches titles and bodies.
182 pushes. Its author is the account your key resolves to — the CLI asks the instance
183 once (`vole-whoami`) instead of trusting `git config user.name`, which on a normal
184 machine is a real name that is not an account name. There is no `--author` flag to
185 get wrong.
186
187 A repository with no configured remote works too: `git init` in an empty directory
188 and pass the URL.
189
190 ```sh
191 git init bug-report && cd bug-report
192 vole issue new --title "the docs page is blank" --remote ssh://git@forge.example.com/demo.git
193 ```
194
195 `#<ulid>` in a body links to that issue, and commits whose message mentions an id
196 are listed as backlinks on the issue. The list page filters by state, label and
197 assignee, and searches titles and bodies. When `public_url` is set, `new` and
198 `comment` print the page they wrote, and the comment link lands on that comment.
177 199
178 200 A comment is `issues/<id>/comments/<ulid>.md` with `author` and `created`
179 201 frontmatter. Closing an issue is editing `state` to `closed`. The push is