Skip to content

Releases: Wave-Engineering/mcp-server-sdlc

v4.0.0

Choose a tag to compare

@github-actions github-actions released this 01 Aug 19:33
59da5b8

What's Changed

  • fix(pr_wait_ci)!: wait for checks to register before declaring none by @bakeb7j0 in #511

Full Changelog: v3.0.0...v4.0.0

v3.0.0

Choose a tag to compare

@github-actions github-actions released this 27 Jul 07:09
0a2840f

What's Changed

  • chore(wave): parameterize the kahuna branch name, drop trunk-defaulting target_branch by @bakeb7j0 in #505
  • chore(release): v3.0.0 — target_branch is required, no trunk default by @bakeb7j0 in #507

Full Changelog: v2.1.2...v3.0.0

v2.1.2

Choose a tag to compare

@github-actions github-actions released this 20 Jul 03:00
8dcd231

What's Changed

  • chore(release): bump package.json to 2.1.1 to match the released tag by @bakeb7j0 in #499
  • chore: bump package.json version to 2.1.2 for v2.1.2 tag by @bakeb7j0 in #501

Full Changelog: v2.1.1...v2.1.2

v2.1.1

Choose a tag to compare

@github-actions github-actions released this 19 Jul 22:45
8a0efb1

Fixes two defects where the tooling reported success it had not achieved

GitLab merges failed with 400 SHA must be provided when merging

pr_merge and pr_merge_wait were a hard block on affected GitLab projects — the MR was left open, waiting for a human, with no MCP fallback. /scpmmr completed MR-create and CI, then died at merge.

Why it started happening, and why it will keep happening: GitLab's merge endpoint rejects an unguarded merge when the project's namespace has require_sha_for_merge, and GitLab now defaults that ON for newly-created groups. This is an upstream environment change, not a regression here — which is why newly-created nested groups failed while older projects that had always merged kept working. Expect it on every new subgroup.

The adapter now resolves the MR's source-branch HEAD and passes it as --sha.

pr_status reported zero checks for PRs with passing checks

pr_status returned checks: none for GitHub PRs that had passing checks — on every GitHub PR, permanently, on any host running gh 2.45 (what Ubuntu 24.04 LTS ships). It ran gh pr checks --json, a flag that does not exist on that version, and treated the resulting non-zero exit as "no checks configured".

Checks are now read from statusCheckRollup on the existing gh pr view call — one subprocess instead of two.


Behaviour changes (not just fixes)

Both change what callers observe. Neither should break correct usage, but they are worth knowing before the upgrade.

1. --auto-merge=false is now forced on GitLab merges. A pending pipeline now merges or fails — it no longer silently enrols (merge-when-pipeline-succeeds) while the tool reports merge_method: "direct_squash" and a completed merge. Anyone who was relying on the enrolment behaviour will see a difference; that behaviour was reporting success for a non-merge.

2. pr_status now fails closed. A checks query that fails returns {ok: false, code} instead of ok: true with a zeroed summary. Callers that treated an empty summary as "this PR has no checks" will now see an error — that is the point, and it is not a regression. A genuine zero (a PR with no checks configured) still returns ok: true with summary: "none"; the two are now distinguishable.


Also in this release

  • -R <repo> is shell-escaped in the GitLab merge path (was the one caller-supplied field interpolated raw).
  • Stale-head 409 handling is anchored to the HTTP status rather than a bare 409 match — glab echoes the request URL, which contains the MR IID, so merging MR !409 previously matched on its own number and misclassified genuine failures as races.
  • --sha and --auto-merge added to the real-CLI flag-shape gate. --auto-merge is itself a rename of the older --when-pipeline-succeeds; the mocked unit suite cannot catch a glab that rejects either flag.
  • Adapter errors now surface a code through the pr_status handler.

Validation

Both fixes were validated live as paired experiments — the defect reproduced first on the same fixture, then the fix applied — rather than on green unit tests alone:

  • GitLab merge: reproduced 400 SHA must be provided when merging on a real require_sha_for_merge namespace, then merged. Confirmed by reading MR state back from the API, including merge_when_pipeline_succeeds: false to prove a real merge rather than an armed auto-merge.
  • pr_status: gh pr checks --json exits 1 on gh 2.45 (what produced none), then the new path reported total 4, passed 4, all_passed on the originally-reported PR.

Full suite: 2416 tests, 0 failures, 78/78 runtime smoke, trivy 0 HIGH/CRITICAL.

Upgrade: curl -fsSL https://raw.githubusercontent.com/Wave-Engineering/mcp-server-sdlc/main/scripts/install-remote.sh | bash — then restart Claude Code so the MCP subprocess picks up the new binary.

v2.1.0

Choose a tag to compare

@github-actions github-actions released this 14 Jul 10:37
dcd058a

v2.1.0 adds one new MCP tool (branch_guard) and hardens several existing ones against silent false-positive gate results — the dominant theme this cycle is "a compliance/trust check returned a confident ok:true/success when it shouldn't have." ci_wait_run gains a merge-result anchor to stop grading the wrong pipeline; ibm and branch_guard stop guessing repo/branch pairings; work_item stops leaking type::epic onto Plans. Also: three wave-engine handlers stop hardcoding main as the mainline, a deploy-freshness startup check was added, and two HIGH CVEs were patched. CHANGELOG.md was retired in this range (#459) — GitHub Releases notes (this document) are now the authoritative changelog; there is no in-repo file to check.

New tools

  • branch_guard (#469, refined #471, #485) — Guards against basing on / merging into the wrong mainline. Input: role ('base'|'target'), optional branch, optional repo. Resolves the git host's live default branch and verdicts whether the checked branch is "protected" by name (main or release/* — a shared pattern with ibm, not a live host protection query as originally shipped in #469 and reworked in #471). Returns {verdict: 'pass'|'warn', reason, default_branch, checked_branch, is_protected, is_sandbox}; kahuna/* sandboxes always pass. Warns when a protected-by-name branch is neither the live default nor a sandbox (e.g. a stale release/0.0.1 after the default moved to release/1.0.0). Call it before basing/merging to catch drift against a moved default branch. As of #485, role:'base' with an explicit repo but no branch is refused rather than pairing the server cwd's current branch with a possibly-unrelated foreign repo.

Changed

  • ci_wait_run (#478, #484) — New optional params require_merge_result: boolean and pr_number: number (required together via a zod .refine). Set require_merge_result: true to accept only a run that validated the actual merge result for the PR/MR's current head — GitHub: a pull_request run whose head_sha matches the PR head; GitLab: the pipeline GitLab reports as the MR's head_pipeline (a detached /head or merge-train /train pipeline no longer counts). A non-qualifying run now yields final_status: "not_merge_result" instead of a misleading success. Also: the "no run has appeared yet" grace window is now decoupled by call shape — require_merge_result still gets the full timeout_sec (merged-results pipelines are slow to appear), but a plain expected_sha wait is now bounded to min(timeout_sec, 180s) instead of silently consuming the entire timeout on a transient first-poll miss. Phase-2 (polling a run once it has appeared) is unaffected either way.
  • ibm (#481) — New optional repo param, threaded through both the issue lookup and the PR/MR lookup. Pass it whenever the branch being checked is not the one checked out in the server's cwd. Behavior change: an unrecognized branch with no repo given is now refused (ok:false) rather than silently resolved against the cwd's repo — previously this could match a same-numbered but unrelated issue in the wrong repository and return a false ok:true compliance pass. The response envelope now echoes the repo actually checked.
  • work_item (#479) — type enum gains 'plan' (applies type::plan); previously /issue plan was documented but not creatable. Behavior change: the auto type::<type> label is now suppressed whenever the caller already supplies any type::* label (both platforms) — previously it was always prepended, which was only safe on GitLab by accident (scoped-label eviction); on GitHub the same call could produce an issue tagged with both type::epic and type::plan. Caller-supplied labels are also now trimmed/normalized once before both the suppression check and the platform argv, and a GitHub --label failure on a non-existent label now names the remedy (label_create) in the error message.
  • wave_init — the kahuna bootstrap's implicit base_branch no longer defaults to the literal 'main'; when the plan omits base_branch it now resolves the repo's live default branch via the adapter (#473).
  • wave_finalizetarget_branch changed from z.string().min(1).default('main') to z.string().min(1).optional(). An explicit value still wins; when omitted, it now resolves the repo's live default branch instead of silently targeting main (#473). Matters for any repo whose default branch isn't main (e.g. release/1.0.0).
  • Internal-only, no signature/output change: fetch-ci-trust-signal-github's branch-protection probe (backs wave_ci_trust_level) now probes the live default branch instead of a hardcoded main (#473). FlightDeck event emission was wired into commutativity_verify, drift_check_path_exists, drift_check_symbol_exists, drift_files_changed, ci_wait_run, pr_wait_ci, wave_ci_trust_level, pr_merge, and wave_finalize (#464) — fire-and-forget telemetry to ~/.claude/status/events.jsonl/FlightDeck ingest; every emit runs after the handler's normal work and never alters the response or control flow.
  • Server startupSERVER_VERSION now derives from the injected build tag (git describe, e.g. 2.1.0) instead of a hardcoded '1.0.0'; uncompiled dev runs report 0.0.0-dev. A new one-time, non-blocking deploy_freshness check compares the running binary's embedded build SHA against the server's own latest GitHub release and emits a single warn-level log line if the binary is stale (#482, closes #447) — network-optional, degrades silently if gh/network/releases are unavailable, and answers initialize in ~150ms even while the freshness check is in flight.

Fixed

  • ci_wait_run / wave trust gate (#478) — Fixed a live false-pass: GitLab skips the branch pipeline on a merge commit, and the status mapping treated skipped as success, so a kahuna merge commit's gate could report final_status: "success" for a pipeline that never ran. Also closed a "freshness by absence" gap where a green merge-result run for a previous commit could satisfy the gate for a PR/MR whose head had since moved — the run is now re-validated against the anchor before grading.
  • ci_wait_run (#484) — Fixed a silent full-timeout_sec hang: with expected_sha set, a transient miss on the first CI-run poll used to consume the entire (typically 1800s) timeout with zero partial output before failing; now bounded to ~180s with an actionable error.
  • ibm (#481) — Fixed a false compliance pass where a branch not checked out in the server's cwd got its issue number looked up against the cwd's repo, matching an unrelated same-numbered issue in the wrong repository.
  • work_item (#479) — Fixed a GitHub-only taxonomy leak where an issue created with type: 'epic' plus a caller-supplied type::plan label ended up carrying both labels (GitHub has no scoped-label mutual exclusion, unlike GitLab).
  • branch_guard (#480, shipped in #485) — Fixed the same cwd-branch/foreign-repo pairing trap as the ibm fix, scoped to role:'base': a repo given without a branch no longer infers the cwd's current branch and resolves it against a repository it may not belong to.
  • Security (#468, #450, shipped in #485) — fast-uri bumped to ^3.1.2 (resolves 3.1.3) and hono to ^4.12.25 (resolves 4.12.30), patching CVE-2026-6321, CVE-2026-6322, and CVE-2026-54290. trivy fs --severity HIGH,CRITICAL: 0 findings.

v2.0.3

Choose a tag to compare

@github-actions github-actions released this 23 Jun 05:24
623cb9f

What's Changed

  • fix(ibm): distinguish unrecognized-prefix from missing-issue errors by @bakeb7j0 in #451
  • fix(wave_finalize): root PR find/create at args.root, not the session project by @bakeb7j0 in #454

Full Changelog: v2.0.2...v2.0.3

v2.0.2

Choose a tag to compare

@github-actions github-actions released this 08 Jun 08:45
8a4fa0a

What's Changed

  • fix(install): handle PEP 668 in commutativity-probe install by @bakeb7j0 in #433
  • fix(epic_sub_issues): parse nested-bullet refs in Phase checklists by @bakeb7j0 in #436
  • fix(gitlab-api): URL-encode branch names in resolveBranchSha API path (#437) by @bakeb7j0 in #441
  • fix(wave_init): normalize devspec-upshift plan shape before persist (#438) by @bakeb7j0 in #442
  • fix(wave_init): expose force param to allow plan overwrite (#439) by @bakeb7j0 in #443
  • fix(pr-merge-gitlab): silently drop skip_train instead of returning platform_unsupported (#423) by @bakeb7j0 in #444
  • fix(test): standardize ci-run-logs-gitlab fixture to org/repo (release flake) by @bakeb7j0 in #446

Full Changelog: v2.0.1...v2.0.2

v2.0.1

Choose a tag to compare

@bakeb7j0 bakeb7j0 released this 14 May 03:57
d5a705b

Fixes

  • fix(routing): getAdapter uses repo slug depth to infer platform — 3+ segment slugs route to GitLab regardless of server cwd (#426)
  • fix(gitlab-api): treat empty stdout from glab list endpoints as empty collection, not error — fixes intermittent ibm() failure during precheck (#428)
  • fix(pr_comment): add target: "issue" | "mr" param to disambiguate GitLab issue vs MR commenting (#430)

v2.0.0

Choose a tag to compare

@github-actions github-actions released this 27 Apr 23:11
1639948

What's Changed

  • chore(phase-3): close retrofit — MV-05 verified, MV-06 partial, VRTM populated (#325) by @bakeb7j0 in #369
  • feat(wave_init)!: accept kahuna: { plan_id, slug }; remove legacy epic_id by @bakeb7j0 in #370
  • feat(wave_finalize)!: accept plan_id; title pattern plan(#N) by @bakeb7j0 in #371
  • docs(wave-finalize): correct stale epic_id comment by @bakeb7j0 in #372
  • chore(changelog): aggregate P2W2 entries by @bakeb7j0 in #373
  • feat(wave-reconcile): Prime(post-wave) reconciliation handler + Category B drift-halt by @bakeb7j0 in #374
  • feat(devspec-finalize): require depends_on field on every Story by @bakeb7j0 in #375
  • chore(changelog): aggregate P2W3 entries by @bakeb7j0 in #376

Full Changelog: v1.8.1...v2.0.0

v1.8.1 — Platform Adapter Retrofit (Phase 2 + Phase 3)

Choose a tag to compare

@github-actions github-actions released this 27 Apr 02:37
5b2be29

Platform Adapter Retrofit — Phase 2 + Phase 3 complete

Internal refactor. All 25 platform-aware handlers are now migrated to the PlatformAdapter pair (GitHubAdapter, GitLabAdapter). Gate-greps enforce the adapter boundary across the full handler tree; lib/glab.ts has been removed.

Version note: v1.8.0 shipped the Phase-1-close milestone earlier today (2026-04-26 AM). v1.8.1 completes the retrofit (Phase 2 + Phase 3) as a single coherent follow-on release. The bump is non-destructive to the v1.8.0 pinning already in the wild.

What users see

No behavioral changes. Every MCP tool call emits the same I/O contract as v1.8.0. lib/glab.ts is no longer exported (internal-only change).

What changed internally

  • MIGRATED_METHODS: 10/25 → 26/26
  • scripts/ci/migration-allowlist.txt: 31 entries → 0 (empty — gate-greps now enforce against ALL handlers)
  • lib/glab.ts: deleted (all helpers migrated to adapters)
  • Test suite: 1466 → final count (green on every migration PR)
  • Bugs closed en route: #280, #281, #282, #283

Links

Install / upgrade

SDLC_VERSION=v1.8.1 ./install-remote.sh

Binaries attached below (sdlc-server-linux-x64, sdlc-server-darwin-arm64, sdlc-server-darwin-x64) per DM-07.