Back to The Times of Claw

gstack Ship: The AI Release Engineer

gstack Ship automates the release process: sync main, run tests, audit coverage, push, and open a PR — all without manual intervention.

Mark Rachapoom
Mark Rachapoom
·6 min read
gstack Ship: The AI Release Engineer

gstack Ship: The AI Release Engineer

Shipping code should be boring. Not in the sense that it doesn't matter — it matters enormously — but boring in the sense that it's a well-defined process that executes predictably every time.

In practice, shipping is often the most anxiety-producing part of the development cycle. Did we run all the tests? Is main in a state that's ready to merge against? Did we update the changelog? Did we tag the release? Did we verify the deployment worked?

These aren't creative tasks. They're procedural. And they're exactly the kind of task that AI automates well.

gstack's Ship phase is the AI release engineer: the role responsible for making sure every release executes cleanly, completely, and without shortcuts.

What Release Engineering Actually Involves#

Before understanding gstack Ship, understand what good release engineering looks like:

Pre-release checks:

  • Is main up to date? (pull from upstream, resolve any conflicts)
  • Do all tests pass? (not just the ones in CI — run the full suite locally)
  • Is test coverage above the threshold? (no coverage regression allowed)
  • Are there known issues that should block this release?
  • Is the changelog current?

The release itself:

  • Create a clean commit with a clear message
  • Tag the release with the version number
  • Open a PR with a complete description (what changed, why, how to test)
  • Ensure CI passes before requesting review

Post-merge:

  • Verify the deployment completed successfully
  • Check for immediate errors in production logs
  • Verify the key feature works end-to-end in production

Each of these steps is well-defined and process-driven. Each is also the kind of step that gets skipped under time pressure.

What gstack Ship Does#

The Ship phase in DenchClaw's gstack workflow executes the full release process:

# What gstack Ship runs (simplified)
git fetch upstream
git checkout main && git pull upstream main
git checkout feature-branch
git rebase main
 
# Run tests
npm run test:full
 
# Check coverage
npm run test:coverage -- --coverageThreshold '{"global":{"statements":80}}'
 
# Lint check
npm run lint
 
# Build verification
npm run build
 
# If all checks pass:
git add -A
git commit -m "[clear commit message based on changes]"
git push origin feature-branch
 
# Create PR with AI-generated description
gh pr create \
  --title "feat: [descriptive title]" \
  --body "[AI-generated PR body with what changed, why, how to test, and screenshots if UI changes]"

Every step either passes or stops the process with a clear error message. No silent failures. No "I think CI is probably fine."

The PR Description#

One of the most neglected parts of the release process: the PR description. Most PRs have titles like "fix bug" or "update component." They contain no context about what changed, why it changed, or how to test it.

gstack Ship generates a structured PR description that includes:

Summary: What changed, in one paragraph. Written for a reader who hasn't been in the conversation.

Motivation: Why this change was made. What problem it solves.

Changes: A structured list of what was modified. Not just file names — what the changes do.

Testing instructions: Step-by-step instructions for how to verify the change works.

Screenshots/videos: For UI changes, visual evidence that the change looks right.

Related issues: Links to any bug reports, feature requests, or design docs that this PR addresses.

This level of description makes code review faster and makes the git history searchable. Six months from now, when you're trying to understand why a change was made, the PR description is the record.

Handling Pre-Release Blockers#

When gstack Ship detects a problem, it stops and reports clearly:

Test failures:

❌ Ship blocked: 3 tests failing
  - UserService.test.ts: createUser should handle duplicate email → assertion failed
  - ContactAPI.test.ts: POST /contacts should return 201 → received 500
  - ImportFlow.test.tsx: renders empty state → TypeError: Cannot read properties of null

Fix these failures before shipping.

Coverage regression:

⚠️ Coverage dropped below threshold
  - Statements: 74% (threshold: 80%)
  - New uncovered code: src/services/enrichment.ts lines 45-67

Add tests for the uncovered code or adjust the threshold with justification.

Merge conflict:

⚠️ Rebase conflict detected in src/api/contacts.ts
  Your changes and main changes both modify the same lines.
  Resolve the conflict and re-run Ship.

Each blocker is specific and actionable. Not "something is wrong" — "this specific thing is wrong, here's what to do."

Release Notes and Changelog#

Part of the Ship phase: updating the changelog.

gstack reads the git log since the last release, summarizes the changes by category (features, fixes, improvements, breaking changes), and updates CHANGELOG.md with a structured entry.

## [1.4.0] - 2026-03-26
 
### Features
- Added calendar integration for Google Calendar event sync
- Added export functionality to CSV and Parquet formats
 
### Fixes
- Fixed duplicate contact creation when email normalization differs
- Fixed mobile layout overflow on Safari
 
### Improvements
- Improved import validation error messages
- Reduced bundle size by 15% through code splitting
 
### Breaking Changes
- None

This changelog update is part of the Ship commit. Documentation doesn't fall behind.

Auditing Test Coverage#

Test coverage is a lagging indicator of code quality, but it's a useful floor to maintain. gstack Ship enforces coverage thresholds before allowing a release.

The audit produces:

  • Overall coverage percentage by type (statements, branches, functions, lines)
  • New code that was added without tests
  • Coverage trend (going up, flat, or declining)

Declining coverage trend is a process health signal. If every release reduces coverage slightly, something structural is wrong — new code isn't being tested, test debt is accumulating.

Frequently Asked Questions#

How does gstack Ship interact with existing CI/CD pipelines?#

gstack Ship is designed to work alongside CI/CD, not replace it. The Ship phase runs pre-commit checks that catch issues before they reach CI. CI still runs after the PR is opened and serves as the final gate before merge.

What if tests pass locally but fail in CI?#

This is a real problem: environment differences between local and CI. gstack Ship checks for common causes (environment variables, dependency versions, seed data) and flags them. When it happens, gstack Investigate is the right next step.

Should every developer run gstack Ship, or just a designated release engineer?#

Every developer should run the Ship phase before opening a PR. The "designated release engineer" model creates bottlenecks and makes releases batch up. When every developer can ship cleanly, you can ship more frequently.

How does gstack handle hotfixes vs. planned releases?#

The Ship phase handles both. For hotfixes, the rebase target is the current production tag rather than main. The process is otherwise identical — tests still run, coverage is still checked, the PR description is still generated.

What's the Ship phase's relationship to semantic versioning?#

gstack Ship can automatically determine the semantic version bump based on the changes in the PR (breaking changes → major, new features → minor, bug fixes → patch). This automates the version decision that often leads to debates or inconsistency.

Ready to try DenchClaw? Install in one command: npx denchclaw. Full setup guide →

Mark Rachapoom

Written by

Mark Rachapoom

Building the future of AI CRM software.

Continue reading

DENCH

© 2026 DenchHQ · San Francisco, CA