Git compatibility live
It is just git. Clone, branch, commit and push with the git you already have. Pushing a
bean/<name> branch submits a change; the verdict comes back on the
push and as a ref anyone can fetch. Nothing is installed on the client beyond a
credential.
Push a change, read the verdict
$ git clone https://gitstalk.dev/acme/api.git && cd api $ git switch -c add-truncate origin/sprout # edit, then $ git commit -am "Add truncate(text, n)" $ git push -o wait origin HEAD:refs/heads/bean/add-truncate remote: gitstalk: new bean add-truncate received at 3f9a1c2: "Add truncate(text, n)" remote: gitstalk: pre-land check started: your change is merged onto the sprout and the whole suite runs on that tree remote: gitstalk: LANDED: add-truncate passed its pre-land check and is on the sprout as 8d41e07 remote: gitstalk: it moves to the stalk once CI validates the sprout; git fetch origin sprout stalk
-o wait holds the push open until the bean has a verdict. Without it the
push returns as soon as the bean is received.
When a bean comes back red, the push says what broke, and which landed beans it collided with:
$ git push -o wait origin HEAD:refs/heads/bean/tax-in-total remote: gitstalk: RED: tax-in-total was not landed. Merged onto the sprout, these tests failed: remote: gitstalk: - test/discount.test.js remote: gitstalk: it collided with these landed beans (accepted behaviour; keep both): remote: gitstalk: - add-discount "Add percentage discounts" remote: gitstalk: intent: discounted(items, rate) takes rate off the cart total. remote: gitstalk: output: remote: gitstalk: not ok 1 - discounted takes 10% off a 100.00 cart remote: gitstalk: expected 90, got 99 remote: gitstalk: fix: git fetch origin sprout && git rebase origin/sprout remote: gitstalk: then fix, commit and git push -f origin HEAD:refs/heads/bean/tax-in-total remote: gitstalk: and keep working; git push -o bean=tax-in-total origin HEAD:refs/wait/any waits for its next verdict
Every refusal and verdict message is explained, keyed by its exact text, in Troubleshooting.
URLs
A repository is cloned from the web host, where its page is, with a GitHub-style URL
(the .git suffix optional). The repository page shows it:
git clone https://<host>/<owner>/<repo>.git
The older gateway URL,
https://<gateway host>/git/<owner>/<repo>.git, still
works. A repository you may not see answers 404, exactly as a missing one does, on every
transport.
SSH planned
Git over SSH is built, not public yet. SSH on port 22 needs a paid Cloudflare feature
(Spectrum), so it is not offered. It has been tested end to end on a staging stack.
HTTPS works today. What is live: you can register an SSH key in
Settings (/gitstalk:setup does it for you), which approves your machine,
but the git remote it sets is an HTTPS URL. Once SSH is public, remotes will look like
ssh://git@<ssh host>/<owner>/<repo>.git and follow the
same rules as HTTPS in every row below.
Push is submit
| You push | What happens |
|---|---|
refs/heads/bean/<name>, a new name |
A new bean. Its title is the commit subject, its intent the message. A
Task: <id> trailer links a task.
|
| the same bean after a red or a conflict | The fix: the new head is checked again. Force-push after a rebase is expected. |
| a new commit to a bean still in check | Refused: its verdict comes first. The message says how to wait for it. |
| a bean that already landed, or is parked or dropped | Refused: push the work again as a new bean. |
sprout, stalk, main |
Refused: landing is never a push. Only the engine moves these lines. |
| any other ref, a deletion, two beans at once | Refused, with the rule. |
Refusals happen inside the git protocol, before anything reaches storage, so git prints
a normal ! [remote rejected] line with the reason rather than an HTTP
error. Bean names start with a letter or digit, then use letters, digits,
., _ and -, up to 32 characters in all.
Push options
| Option | Effect |
|---|---|
-o wait |
Hold the push until the verdict: landed, red, conflict, parked or dropped. Progress lines as the engine reports them and a keepalive every 15 s; gives up after 600 s and says where the verdict will be. |
-o wait=<seconds> |
The same, up to 1,800 s. |
-o task=<id> |
Links a task (overrides the trailer). |
-o intent=<text> |
The bean's intent and title, instead of the commit message. |
-o bean=<name> |
On a push to a wait ref (below): a bean to wait for. Repeat it for several. |
An unknown option is ignored, and the push says so.
What the push prints
Every line starts remote: gitstalk:. The ones you will meet:
| Line starts | Meaning |
|---|---|
new bean … received |
The push was accepted as a bean (or a new push to a bean you already had). |
pre-land check started |
Your change is merged onto the sprout and the whole suite runs on that tree. |
LANDED |
It passed and is on the sprout. It moves to the stalk after validation. |
RED |
The merged tree failed. Failing tests, collided beans and the fix commands follow. |
CONFLICT |
It does not merge onto the sprout. Conflicting hunks follow. |
PARKED / DROPPED |
It needs a person (parked), or fell off (dropped), with the reason. |
validated: on the stalk |
The sprout commit passed validation and reached the stalk. |
changes protected paths, approval rules |
What protected paths and approval rules decided. |
Status refs
| Ref | What |
|---|---|
refs/heads/sprout |
The staged line: every landed bean. |
refs/heads/stalk |
The stable line: validated sprout commits. |
refs/heads/bean/<name> |
The bean's pushed head. |
refs/beans/<name>/status |
An annotated tag: <phase>: <reason>, then the verdict's
lines.
|
| Phase | Meaning |
|---|---|
checking |
The pre-land check is running. |
waiting |
Reserved. Waits count it as checking, but a git push does not write it today (the Changes tab shows waiting for a bean held on a decision or on a red sprout). |
landed |
On the sprout. |
green |
Validated: on the stalk. |
red |
The merged tree failed its checks. |
conflict |
It does not merge onto the sprout. |
parked |
It needs a person. |
dropped |
It fell off. |
git fetch origin '+refs/beans/*:refs/beans/*'
git for-each-ref 'refs/beans/' --format='%(refname:lstrip=2) %(contents:subject)'
git cat-file -p refs/beans/add-total/status
Waiting without polling
An agent that has pushed several beans and run out of work makes one blocking call that the first verdict wakes. A push to a wait ref stores nothing:
git push -o bean=a -o bean=b origin HEAD:refs/wait/any # returns at the first verdict
git push -o bean=a -o bean=b origin HEAD:refs/wait/all # returns when none is checking
git push origin HEAD:refs/wait/all # every bean in flight pushed with my credential
It holds up to 9 minutes by default, under the 10-minute limit of an agent's shell tool,
and prints each verdict as it arrives. -o wait and MCP
bean_wait use the same wait: the verdict wakes them, nothing polls. Why it
exists:
agents replaced blocking pushes with sleep loops.
Importing and leaving
Any public git URL can be imported when you create a repository. Importing a private
repository and two-way sync with another forge are
planned. Your history stays plain git: clone it, and
push it anywhere else. Branch names other than bean/*,
sprout and stalk are not accepted on push today, and tag
pushes are refused.