Imported from nextstage-brasil/skills (
skills/ns-execution-gitlab-issue/SKILL.md). Install upstream withnpx skills add nextstage-brasil/skills --skill ns-execution-gitlab-issue. Copyright stays with the author (Apache-2.0).
Execute GitLab Issue
Entry priority 1 for external GitLab ISSUE_URL. SDD unit mode (below) when delivery-units.md supplies unit + issue_iid — not an external URL. Full routing: ../../ns-harness/references/code-skill-routing.md.
Routing (read first)
Entry priority 1. Harness table: ../../ns-harness/references/code-skill-routing.md. Trigger phrases: references/entry-triggers.md.
| Handoff | Target |
|---|---|
| Phase 2 execution (external, single unit) | coder-agent → ns-coder in existing worktree — skip ns-autonomous (planning-decision.md single-unit; spawn gate) |
| Phase 2 execution (external, multi-unit) | ns-autonomous (Engine mode) |
| Phase 2 execution (SDD unit) | ../../ns-coder/references/run-implementation.md (unit tasks only) |
| MR / status / time / comments | mcp-gitlab-usage |
| Phase 4 review gate | reviewer-agent → ns-reviewer; then ns-judge in-session only if Code Review: Approved |
| Rejected fix loop (external, single unit) | coder-agent / ns-coder (same worktree; no A) |
| Rejected fix loop (external, multi-unit) | ns-autonomous → C2 (same worktree; no re-entry to this skill from A/C2) |
| Rejected fix loop (SDD unit) | coder-agent → ns-coder / run-implementation (same worktree; no ns-autonomous) |
G remains single GitLab lifecycle owner until delivery. External multi-unit under A must not re-open this skill. External single-unit + SDD unit Phase 2 skip A.
Session boot
See ../../ns-harness/references/session-boot.md. Complete Session boot (blocking) there before any MCP call. Read mcp-gitlab-usage after Session boot.
Inputs
| Variable | Required |
|---|---|
ISSUE_URL |
Yes for external issue mode |
unit + issue_iid |
Yes for SDD unit mode (from delivery-units.md) |
SOURCE_BRANCH |
No — resolved by Gate 1 if omitted |
External issue mode (priority 1 unchanged): single worktree, single branch, single MR, single commit per issue:
WORKTREE_ROOT = .worktrees/{ISSUE_ID}WORK_BRANCH = work/{ISSUE_ID}-{ISSUE_SLUG}
SDD unit mode — when ns-spec-driven dispatches a published delivery unit:
- Input:
unitid (e.g.unit-001) +issue_iidfromdelivery-units.md— not externalISSUE_URL WORKTREE_ROOT = .worktrees/{unit}WORK_BRANCH = work/{unit}-{slug}perdelivery-units.md/source-branch-resolution.mdSOURCE_BRANCH= version-resolved branch recorded indelivery-units.mdheader (Gate 1 uses same rules; skip re-discovery when header set)- Phase 2 coding:
../../ns-coder/references/run-implementation.mdfor unit tasks only — notns-autonomousEngine - Status/spent: this skill owns lifecycle (First act + Phase 3). Skip Flow D. Cite
../ns-spec-driven/references/delivery-units.mdGitLab status/spent (SSoT) add_issue_spent_timeonce per unit at Phase 3 (wall-clock) — not per task, not estimate sum
Phase 0 — Context (boot before MCP)
- Session boot (blocking) — complete
../../ns-harness/references/session-boot.mdbefore any MCP call. - Ensure
.worktrees/is gitignored (seereferences/worktree-setup.md). - Read
mcp-gitlab-usagebefore the first MCP call. - Mode detect: external
ISSUE_URL→ external issue mode.unit+issue_iidfromdelivery-units.md→ SDD unit mode — setWORKTREE_ROOT,WORK_BRANCH,ISSUE_IDsubstitutes below. - Incomplete acceptance (optional pre-step): AC missing, conflicting, or too thin for autonomous coding → run
/ns-requirements-enricherfirst. Do not start Phase 1 (nostatus_in_progress, no coding) until enricher done or human explicitly skips.
Phase 1 — Prepare
First act (mandatory, before any gate)
Apply status_in_progress (Em andamento) to the issue via MCP. If this call fails, abort immediately and wait for human intervention — nothing below runs on an issue that isn't marked in progress.
Gate 0 — Existing branch/MR reuse
An issue may already have a work branch (e.g. returned by a human reviewer). Detect it before Gate 1 so you never open a duplicate branch/MR:
External issue mode:
list_issue_merge_requests— look for an open MR whosesource_branchmatcheswork/{ISSUE_ID}-*; record itssource_branchandtarget_branch.git ls-remote --heads origin "work/{ISSUE_ID}-*"as a second signal.
SDD unit mode:
list_issue_merge_requests— open MR withsource_branchmatchingwork/{unit}-*.git ls-remote --heads origin "work/{unit}-*".mr_urlindelivery-units.mdrow when present — prefer reuse.
Both modes (reuse decision):
- Found →
REUSE_MODE = true,WORK_BRANCH = {existing branch},SOURCE_BRANCH = {existing MR target}. SkipWORK_BRANCHderivation below and skip Gate 1 (only re-validate the branch still exists on the remote). - Not found →
REUSE_MODE = false, proceed to Gate 1.
Gate 1 — SOURCE_BRANCH (mandatory, blocking; skipped when REUSE_MODE = true)
SDD unit mode: when delivery-units.md header already records SOURCE_BRANCH, use it — do not re-run discovery unless human overrides this run.
External issue mode: resolve only via references/source-branch-resolution.md (priority order: human → issue text → product rule → milestone/version discovery → mandatory develop fallback).
- Never infer from the current checkout or ad hoc heuristics.
- Never auto-use any branch except a discovered version-relative
develop_*/develop-*or thedevelopfallback — other bases (homolog,release/*,main,master, etc.) require explicit human confirmation this run. main/masterare allowed asSOURCE_BRANCHonly with express human authorization this run — never auto; issue text naming them alone is not enough (ask once).
After resolution, validate on the remote (fetch, ls-remote, _ ↔ - alternates) per the same reference. When the mandatory develop fallback is missing on the remote → abort with the exact error; ask the operator once.
Gate 1.5 — Single worktree (monorepo)
Create WORKTREE_ROOT per references/worktree-setup.md:
- External issue mode:
.worktrees/{ISSUE_ID} - SDD unit mode:
.worktrees/{unit}
Never under .cursor/. Abort if a worktree already exists for this id and is in use by another run, unless explicit resume. Never implement in main checkout or on main/master/SOURCE_BRANCH. If git worktree add fails → abort with exact error (no main-checkout fallback). Isolation is hard gate before Phase 2.
MCP setup
due_dateif empty: current date + 5 business days.- Do not set
START_TIMEhere — wall-clock for spent time starts at Phase 2 (seereferences/time-tracking.md).
Phase 2 — Execution (delegated)
External issue mode
- Read full issue payload via MCP (title, description, comments, attachments). Note
time_stats.time_estimatefor estimate gate below. - Set
START_TIME/START_EPOCHnow (UTC + Unix epoch) — immediately before first coding invoke. Seereferences/time-tracking.md. - Planning-depth gate — apply
../ns-autonomous/references/planning-decision.mdheuristic on issue payload before calling A:- Single unit (≤5 files / one-paragraph AC, no real DAG): skip
ns-autonomous. MUST dispatchcoder-agentwhen available (elsens-coder) insideWORKTREE_ROOT/WORK_BRANCH. Dispatch: implement only; defer review to Phase 4 (../../ns-harness/references/subagent-dispatch.mdReview once per closure). - Multi-unit (Requirements+tasks path): invoke
ns-autonomousEngine mode, passing issue payload,WORKTREE_ROOT,WORK_BRANCH,SOURCE_BRANCH. Engine plans depth, doubt protocol, dispatches units — seens-autonomousreferences/routing.md.
- Single unit (≤5 files / one-paragraph AC, no real DAG): skip
- Estimate (first invocation only): call
set_issue_estimateonly iftime_stats.time_estimateempty (0/ missing) and worker/engine returnedestimate_seconds≥ 60. Estimate already exists, or value < 60 — skip; never overwrite, never write 1-second estimate. Full rules:references/time-tracking.md. - Doubt escalation contract — engine never mutates GitLab state. When Engine returns destructive-doubt event (multi-unit path only):
- Record
PAUSE_STARTepoch (exclude wait from spent time). - Apply
status_blocked(Em Impedimento). - Post comment mentioning issue author (
@{author.username}fromread_issue) with questions, options, recommended default. - Mirror same question in interactive chat and wait.
- On answer (chat and/or issue comment): add pause duration to
PAUSED_SECONDS, set status back tostatus_in_progress(Em andamento), re-invoke engine with resolved doubt appended.
- Record
- No intermediate confirmations otherwise — this loop only pause until Phase 4 review gate.
SDD unit mode
read_issueforissue_iid— execution + review checklists in description.- Set
START_TIME/START_EPOCHbefore first task in unit. - Run
../../ns-coder/references/run-implementation.mdscoped to unit tasks insideWORKTREE_ROOT— handoff rows stay per task; no Flow D here (G owns status/spent). - Skip
ns-autonomousEngine. Skip per-taskadd_issue_spent_time. - Estimate at publish time = sum of task estimates (
delivery-units.mdestimate_sum) — do not re-estimate per task.
Phase 3 — Delivery
- Squash to one Conventional Commit before push (
<type>(#{issue_iid}): <imperative description in English>, types: feat/fix/refactor/test/docs/chore). External mode may useISSUE_IDin message when that is the issue identifier. Squash internal checkpoint commits to preserve one-commit-per-delivery atomicity. See../../ns-harness/references/agent-git-identity.mdfor attribution. - Push
WORK_BRANCH. - Run Phase 4 (review gate). Do not set
END_TIME, spent time, or Dev 100% until Phase 4 returns bothCode Review: ApprovedandDelivery Review: Approved. - On
Approvedonly — close the clock and board (same instant):- Set
END_TIME/END_EPOCHnow. add_issue_spent_timewithduration = ELAPSED_SECONDSfromreferences/time-tracking.md(epoch delta minusPAUSED_SECONDS). Never useestimate_secondsor any plan estimate asduration. Single spent owner when this skill runs full lifecycle — setspent_posted=yesondelivery-units.mdrow; Flow D must not double-post.- Status →
status_done(Dev 100%). - Internal delivery comment (
internal: true) usingreferences/delivery-report.template.md.
- Set
Phase 4 — Review gate (blocking, bounded fix loop)
Canonical rules: ../ns-reviewer/references/review-gate-workflow.md.
- MUST invoke
reviewer-agentwhen available (elsens-reviewer) in Issue review mode — passISSUE_URLorproject_id+issue_iid(SDD unit mode). Bridge/skill loadsAGENTS.mdthen reviewer workflow. Read-only code gate; posts internal GitLab comment. Does not parse ACs /requirements.md. Forbidden: Task subagents (senior-tech-lead-reviewer,bugbot,security-review) or substitute unless human explicitly requests this run. Allowed: harnessreviewer-agent. See../../ns-harness/references/subagent-dispatch.md. Reviewer MUST NOT dispatch judge. - Code loop =
review-gate-workflow.mdCode ordered contract (max 3;Approved= 10). One coder target per map — never split:- Call 1 / call 2
Rejectedwith rounds left → pass map verbatim to external single-unit:coder-agent/ns-coder(same worktree); external multi-unit:ns-autonomous(same worktree) as one fix unit (no map split); SDD unit:coder-agent/run-implementation(same worktree). Next reviewer prompt =delta+ prior map IDs viareviewer-agent(MUST when available; elsens-reviewer). KeepSTART_TIME; no spent/Dev 100% yet. No judge. - Call 3 only after that second coder (delta found residual and/or introduced Critical). Call 3 not score 10, or
Blocked, or rounds exhausted →status_blocked(Em Impedimento), post findings, stop. No coder onBlocked. NoEND_TIME, spent, or Dev 100%. No judge.
- Call 1 / call 2
- On
Code Review: Approvedonly: read../ns-judge/SKILL.mdin-session (--mode issue --ac-filefrom synthesis). Python optional.Delivery Review: Approvedonly at 10. Judge Rejected: fix map; product files changed → code review again (must Approved) then judge again. Max 3 judge rounds. - Both Approved → Phase 3 step 4 (END + spent + Dev 100% + delivery comment).
- Final output:
Fatto!+MR_URLS+Code Review: {verdict}+Delivery Review: {verdict}— exact strings returned.
Stop and ask the human
| Condition | Action |
|---|---|
Gate 1: develop fallback missing on remote |
Stop — ask once |
Gate 1: non-default base (main/master/homolog/…) without express human confirmation this run |
Stop — ask once |
| Worktree conflict (same issue, another run) | Stop unless explicit resume |
| Ambiguous or conflicting acceptance criteria | Stop — /ns-requirements-enricher first; do not start Phase 1 coding |
| MCP unavailable or auth failure | Stop — state blocker |
project_id trio not confirmed |
Stop per mcp-gitlab-usage |
Work on protected/base branch per gitlab-sync-config.md |
Stop |
| Destructive ops (issue delete, force-push main/master) | Stop — require explicit human |
| Product decision not stated in the issue | Stop — ask once |
| Engine reports a destructive doubt | Pause/resume per Phase 2 step 4 — not a hard stop |
See mcp-gitlab-usage for MCP tool contracts and confirmation gates.
Related skills
| Skill | Role |
|---|---|
/ns-requirements-enricher |
Optional pre-step when AC incomplete — before Phase 1 |
mcp-gitlab-usage |
All GitLab tools |
ns-gitlab-board-sync |
Status label semantics |
ns-reviewer |
Phase 4 code gate (MUST reviewer-agent when available) |
ns-judge |
Phase 4 delivery proof in-session after Code Review: Approved |
ns-autonomous |
Phase 2 Engine when multi-unit only |
ns-coder |
External single-unit + SDD unit coding; non-GitLab ad-hoc |
References
| File | When |
|---|---|
references/source-branch-resolution.md |
Gate 1 — milestone/version discovery, develop fallback, remote validation |
references/worktree-setup.md |
ISSUE_ID → run_id override (canonical mechanics in ns-harness) |
references/mr-conventions.md |
MR title, draft, linking, reuse note |
references/delivery-report.template.md |
Phase 3 internal delivery comment |
references/time-tracking.md |
Estimate fill-if-empty; spent-time wall-clock + pause rules |
