Appearance
GitLab: import and origin labels
You'll learn how an issue in a connected GitLab becomes a GAIA ticket, and how the ticket's progress is mirrored back onto that issue as a label your customer can see.
GAIA keeps its own canonical tickets — it never works in GitLab. The integration is two one-way bridges: import brings an issue in and remembers where it came from as the ticket's origin; origin labels write the ticket's state back onto that issue.
The connector
An administrator configures a connector on the control plane, one per GitLab instance: its base URL and an API token with access to the projects you want to import from. Nothing else about GitLab lives on the control plane — no labels, no webhooks. With import_interval at 0 the connector imports on demand only.
Import an issue
The import is one JSON:API action on the control plane; it needs the import gaia tickets permission:
sh
curl -X POST "$BASE_URL/jsonapi/gaia_ticket/import" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/vnd.api+json" \
-d '{"data":{"attributes":{"url":"https://git.example.com/group/repo/-/issues/42"}}}'The response is the ticket as a JSON:API document: 201 when the issue was new to GAIA, 200 when it had been imported before and the ticket was updated instead. Source identity is deterministic, so re-importing the same issue never creates a second ticket.
What the ticket gets: the issue's title and description (as Markdown), the raw GitLab assignee username, origin set to the issue URL — and a starting state from the issue's type label:
| Issue label | Workflow | Enters at |
|---|---|---|
bug | gaia_bug | diagnose |
chore | gaia_chore | coding |
feature | gaia_feature | spec |
| any of those, issue already closed | as above | done |
| no type label | none yet | no state — unclassified |
An imported issue therefore skips qualification: the label already said what it is. An unclassified import has no workflow and no state, and any conductor of the project may claim it to qualify it. From there on the origin plays no part in dispatch.
Origin labels — the state, mirrored back
Whenever an agent step transitions a ticket that has an origin, it writes one label onto the origin issue and removes the others of the same family. The default chain needs no configuration:
| Ticket state | Label on the issue |
|---|---|
qualification, spec, coding, review | doing |
done | review |
Read it from the customer's side: doing while GAIA works, review when the result is ready for them to look at.
Your customer's vocabulary
If the labels your customer expects differ, add one bullet to the repository's WORKFLOW.md, under ## Loaded skills, with an origin_labels.data map:
md
## Loaded skills
- @gaia/publish-origin-status
origin_labels.data: |
qualification: in progress
spec: in progress
coding: in progress
review: in progress
done: ready for reviewKeys are GAIA states; a <workflow>:<state> key such as gaia_feature:done wins over the bare done, because done means "the project manager tests it now" on a feature and "the customer can have it" on a PM-test ticket. The values are the label family GAIA owns on the issue: exactly one of them is present at a time, the others are removed, and a label outside the map is never touched. An empty value, an empty map or a state with no key writes nothing.
How the write happens
The label is written by the agent, in its own session, with that machine's credentials — one glab issue update call. So glab must be installed and authenticated on every machine that runs a conductor for the project, and the control plane holds no GitLab credentials beyond the importer's token.
Two consequences to accept up front:
- Only a transition made by an agent step is mirrored. A state changed by hand in the cockpit, by the importer, or by a bare
dropsh updateis not mirrored until the next agent step transitions the ticket. - Pre-create the labels in the GitLab project with a colour and description, so GitLab does not auto-create them in random colours on first use.
Next
- Create a ticket — the import beside the three other creation paths.
- Author WORKFLOW.md — where the
origin_labels.dataoverride lives. - The ticket lifecycle — the states the chain maps.