Skip to content

feat(marius-mode): babysit and ship GitLab MRs - #10

Merged
tacheshun merged 1 commit into
mainfrom
feat/forge-gitlab-babysit-ship
Sep 30, 2026
Merged

tacheshun merged 1 commit into
mainfrom
feat/forge-gitlab-babysit-ship

Conversation

@tacheshun

Copy link
Copy Markdown
Owner

Why

After #9, opening an MR on GitLab worked, but babysitting and landing it still followed GitHub steps. Babysit, Shipping, and Autopilot-stack now resolve the forge through references/forge.md, and the reference covers GitLab status, threads, CI, replies, and merge.

Scope

  • references/forge.md: new "Babysit and ship" table with status, threads, watch CI, reply, merge now, and merge when ready for Origin, GitHub, and GitLab. Also the GitLab MR fields that decide merge-ready and failure (detailed_merge_status, state, head_pipeline.status, merge_when_pipeline_succeeds).
  • playbooks/babysit.md: GitLab stop condition, reply and thread-resolve path, and glab mr merge added to the do-not-merge rule. Bugbot threads get resolved after the reply. Human threads stay open.
  • playbooks/shipping.md: merge and retarget go through the reference. A new GitLab watch-and-fail rule sits in step 8. Step 6 now covers GitLab auto-merge.
  • playbooks/autopilot-stack.md and SKILL.md: forge sentences replaced with the reference.
  • Out of scope: scripts/watch-pr and scripts/worktree-audit.sh stay GitHub-only. On GitLab, the playbooks poll with glab instead.

Tradeoffs

  • No GitLab watch-pr port. Polling glab mr view --output json and glab ci status --wait covers the same stop conditions without a second watcher to maintain.

Blast Radius

Only marius-mode babysit and ship runs. GitHub and Origin commands and verdicts are unchanged. On GitLab, merge now passes --auto-merge=false, because glab mr merge would otherwise arm auto-merge without asking.

Verification

  • node scripts/check.mjs: ok (45 skills).
  • node --test scripts/*.test.mjs: 14 pass, 0 fail.
  • glab mr merge, mr view, ci status, mr note resolve, and the discussions notes API were checked against the GitLab CLI docs. Not run live, since glab is not installed here.

🤖 Generated with Claude Code

Babysit, Shipping, and Autopilot-stack resolve the forge through
references/forge.md. The reference gains status, thread, CI, reply, and
merge commands per forge, and the GitLab merge state that stops a
babysit or fails a ship.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 30, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-09-30T15:09:55.771933Z 482f841 PR opened
🔒 Security Review ✅ Completed 2026-09-30T15:16:27.326647Z 482f841 PR opened

Security findings

Advisory findings (1)

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

Base automatically changed from feat/forge-mr to main September 30, 2026 15:04
@tacheshun
tacheshun merged commit cdedf83 into main Sep 30, 2026
1 check passed
@tacheshun
tacheshun deleted the feat/forge-gitlab-babysit-ship branch September 30, 2026 15:05

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 482f84160a

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

| Operation | Origin | GitHub | GitLab |
| --- | --- | --- | --- |
| Status | `origin pr view <pr> --checks --comments` | `scripts/watch-pr/watch-pr` | `glab mr view <mr> --output json` |
| Threads | `origin pr thread list <pr>` | `scripts/watch-pr/watch-pr` | `glab mr view <mr> --unresolved --output json` |

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Replace the unsupported unresolved-thread command

glab mr view --help does not expose an --unresolved flag, so every GitLab babysit reaches this command and exits before it can determine whether discussions block the MR. Query the merge-request discussions endpoint with glab api and filter unresolved resolvable notes, which also supplies the discussion IDs needed by the reply flow.

Useful? React with 👍 / 👎.

| --- | --- | --- | --- |
| Status | `origin pr view <pr> --checks --comments` | `scripts/watch-pr/watch-pr` | `glab mr view <mr> --output json` |
| Threads | `origin pr thread list <pr>` | `scripts/watch-pr/watch-pr` | `glab mr view <mr> --unresolved --output json` |
| Watch CI | `origin pr checks <pr> --watch` | `scripts/watch-pr/watch-pr` | `glab ci status --branch <branch> --wait` |

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Use glab's live CI flag instead of --wait

glab ci status --help documents --live (-l) for watching until the pipeline ends, not --wait. In every GitLab babysit or shipping run, the prescribed command therefore fails immediately rather than waiting for CI, preventing the new workflow from reaching its merge-state checks.

Useful? React with 👍 / 👎.

7. **Classify CI before any retrigger.** Flake or infrastructure earns one fresh build, never a job retry. One retry only. An identical second failure means it was never flake, so reclassify and read the child logs instead of retrying blind. A failure in code the diff never touches means a stale base, so check with `git merge-base --is-ancestor` before assuming flake. Report a stale base as needing a rebase instead of burning retries. Only a failure in the diff's own code gets a commit.
8. **Bugbot is triaged skeptically, always.** Verify each claim against the code per `../references/bugbot-triage.md`. Fix real findings with a red-first proof in the lowest PR that owns the code, never at the tip unless the owning PR has merged. In that case, use step 4's sanctioned follow-up PR. Per step 2, upstack fixes wait for step 5's next frontier-driven push wave. Push that wave before replying so the reply cites the commit. On Origin, reply with `origin pr thread reply <thread-id> <pr> --body-file <reply-file>`. On GitHub, call `gh api --method POST "repos/<owner>/<repo>/pulls/<pr>/comments/<comment-id>/replies" --input <payload.json>` and put the reply body in the JSON file as data. Never interpolate comment text or a reply into a shell command. Dismiss noise with the concrete disproof on the thread. On GitHub, use the watcher's Bugbot pass count. On Origin, derive the pass count from `origin pr thread list` and the review history. From the third pass on, lean toward dismissing documented patterns, still escalating anything touching security, auth, billing, data, or migrations rather than dismissing it yourself. Never churn code to quiet a bot.
9. **Stop at the human's line.** Owner approval is a wait, not a blocker to fix. Babysitting never authorizes merging. Only an explicit request to merge, land, ship, or merge when ready does. Route that request to Shipping. Surface the escalation and keep working the rest. After GitHub reports `READY`, a queued `WAITING`/`merge-queue` stop, or `COMPLETE`, or after Origin reports the frontier merge-ready, sweep the run's triage decisions once. Offer any team-useful dismissal pattern as a candidate entry in the shared rubric (`../references/bugbot-triage.md`) and its own PR. Never keep it only in private memory.
8. **Bugbot is triaged skeptically, always.** Verify each claim against the code per `../references/bugbot-triage.md`. Fix real findings with a red-first proof in the lowest PR that owns the code, never at the tip unless the owning PR has merged. In that case, use step 4's sanctioned follow-up PR. Per step 2, upstack fixes wait for step 5's next frontier-driven push wave. Push that wave before replying so the reply cites the commit. Reply with the forge reference's reply command and the body in a file. Never interpolate comment text or a reply into a shell command. On GitLab, resolve a Bugbot thread with `glab mr note resolve <mr> <discussion-id>` after the reply lands, since unresolved threads can block the merge. Leave human reviewers' threads for them to resolve. Dismiss noise with the concrete disproof on the thread. On GitHub, use the watcher's Bugbot pass count. On Origin and GitLab, derive the pass count from the thread list and the review history. From the third pass on, lean toward dismissing documented patterns, still escalating anything touching security, auth, billing, data, or migrations rather than dismissing it yourself. Never churn code to quiet a bot.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Resolve GitLab discussions through the API

When a Bugbot discussion needs resolving, glab mr note resolve <mr> <discussion-id> is not a supported glab mr note form, so the babysit loop leaves the discussion unresolved and cannot reach the stated merge-ready condition. Use the GitLab discussions API to update the discussion with resolved=true after posting the reply.

Useful? React with 👍 / 👎.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛡️ Codex Security Review · Automatically triggered

Here are some automated security review suggestions for this pull request.

Reviewed commit: 482f84160a

ℹ️ About Codex security reviews in GitHub

This is an experimental Codex feature. Security reviews are triggered when:

  • You comment "@codex security review"
  • A regular code review gets triggered (for example, "@codex review" or when a PR is opened), and you’re opted in so security review runs alongside code review

Once complete, Codex will leave suggestions, or a comment if no findings are found.

| --- | --- | --- | --- |
| Status | `origin pr view <pr> --checks --comments` | `scripts/watch-pr/watch-pr` | `glab mr view <mr> --output json` |
| Threads | `origin pr thread list <pr>` | `scripts/watch-pr/watch-pr` | `glab mr view <mr> --unresolved --output json` |
| Watch CI | `origin pr checks <pr> --watch` | `scripts/watch-pr/watch-pr` | `glab ci status --branch <branch> --wait` |

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛡️ Codex Security Review · Automatically triggered

P1 Badge Security: Quote the GitLab branch before invoking the shell

When a lower-privileged GitLab contributor can choose an MR source branch, this watch command substitutes that attacker-controlled name into a shell command without quoting. Git accepts refnames containing shell metacharacters such as ; and $; a crafted branch can terminate the glab invocation and run a suffix with the operator's local permissions. Both Babysit and Shipping invoke this entry, while merge authorization and --sha do not protect the earlier CI watch. Pass the branch as one quoted argument and require quoting for every forge-derived placeholder.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant