GitLab Board Sync
Mirror local SDD planning/execution state onto existing GitLab issues. Does not create issues.
Prerequisites
- GitLab MCP available — follow
mcp-gitlab-usage for all tool calls
- If multiple GitLab MCP servers: ask human which to use
docs/context/gitlab-sync-config.md validated
- For post-planning batch:
gitlab-issue-feature-map.md exists
Configuration
Read references/gitlab-sync-config.template.md for expected fields:
projectid, milestoneid, assignee_default
statusbacklog, statusinprogress, statusdone, status_blocked
rflabelformat, basebranch, workbranch, mrtargetbranch
Discover unknown status labels via listprojectlabels — confirm with human.
Flow C — Pre-implementation read
When task lists GitLab issue IIDs:
read_issue for description + recent comments
- Non-blocking if inaccessible — log warning, continue
- Do not mutate issue in this flow
Flow A — Post-planning batch
Per issue in map (excluding exclude_issues):
- Validate milestone (project + group)
updateissue with milestoneid
- One
setissuelabels — removelabels + addlabels atomically (RF, Status, Equipe)
assign_issue
setissueestimate from linked task header (seconds) only if timestats.timeestimate is empty — never overwrite; skip values < 60
Flow B — Per-task execution sync (legacy 1:1)
Mutual exclusion: any issue_iid in delivery-units.md → do not run Flow B. Owner = ../ns-spec-driven/references/delivery-units.md GitLab status/spent (SSoT).
When task row maps 1:1 to its own GitLab issue (no delivery units file, or unpublished units + legacy gitlab-issue-feature-map.md):
Task start (before coding)
remove: status_backlog
add: status_in_progress
Record STARTTIME / STARTEPOCH when coding starts (for wall-clock addissuespent_time — see ../ns-execution-gitlab-issue/references/time-tracking.md).
Task complete (after validation)
Only if already statusinprogress:
remove: status_in_progress
add: status_done, RF: NNN
add_issue_spent_time
add_issue_comment (internal=true)
Never backlog → done in one step.
Flow D — Per delivery unit
Run only when SSoT row is Flow D (published issue_iid + local execute, no G). When G owns lifecycle → skip entire Flow D.
Unit start (before coding unit tasks)
remove: status_backlog
add: status_in_progress
Record STARTTIME / STARTEPOCH when coding starts for unit (wall-clock for unit-level spent).
Unit complete (after unit validation + review approved)
Only if already statusinprogress:
remove: status_in_progress
add: status_done
add_issue_comment (internal=true)
Local-only (SSoT Flow D row): include addissuespenttime once per unit (wall-clock, not estimatesum); set spent_posted = yes.
Never backlog → done in one step. Never addissuespent_time per task inside unit. Never Flow D when G owns the same issue.
Anti-patterns
| Wrong |
Right |
assignee on update_issue |
assign_issue |
| Two label calls for one transition |
Single atomic setissuelabels |
Manual Milestone: label |
milestoneid on updateissue |
setissueestimate for time spent |
addissuespent_time with wall-clock duration |
setissueestimate when estimate already set |
Skip — preserve existing |
Plan/estimate_seconds as spent duration |
Epoch delta only (time-tracking.md) |
| Public comment for internal notes |
internal: true |
References
| File |
When |
references/gitlab-sync-config.template.md |
Bootstrap config |
mcp-gitlab-usage |
Tool schemas and gates |
../ns-spec-driven/references/delivery-units.md |
GitLab status/spent (SSoT) |