# Lathe Release

> Run Lathe release validation and publishing workflows. Use when the user asks to prepare, validate, cut, tag, publish, or ship a Lathe versioned release; runs the captured pre-release regression gate before tagging.

- **Type:** Skill
- **Install:** `agentstack add skill-lathe-cli-lathe-lathe-release`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [lathe-cli](https://agentstack.voostack.com/s/lathe-cli)
- **Installs:** 0
- **Category:** [AI & ML](https://agentstack.voostack.com/c/ai-and-ml)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [lathe-cli](https://github.com/lathe-cli)
- **Source:** https://github.com/lathe-cli/lathe/tree/main/.agents/skills/lathe-release

## Install

```sh
agentstack add skill-lathe-cli-lathe-lathe-release
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# Lathe Release

## Contract

Start read-only. Read repo-local instructions first: `AGENTS.md`, `CLAUDE.md`, `CONTRIBUTING.md`, release docs, Makefile, CI, and release config. Trust live code/config over old docs.

Default to validation only. Do not create tags, commits, pushes, PRs, or GitHub releases unless the user explicitly asks to cut/publish/release the target version.

Require a concrete target version before any publish step. If the version is missing or conflicts with existing tags/releases, ask one question.

Use ignored scratch paths for generated validation artifacts. Prefer `.local/regression-$VERSION/` and ignored release output such as `dist/`.

Use `rtk` for commands when available. If `rtk` blocks a command, run the command raw and report the fallback.

## Release Flow

1. Confirm target version and current baseline.
2. Check worktree cleanliness and current branch.
3. Fetch tags and verify the target tag does not exist locally or remotely.
4. Read release workflow config and CI status for `HEAD`.
5. Run the repo's declared local gate plus release-specific artifact dry-run.
6. Run product-specific end-to-end smoke tests.
7. Report `ready`, `blocked`, or `ready with skipped checks`.
8. Only if explicitly asked to publish: create the tag, push it, then monitor the release workflow.

Never claim a release is ready without fresh command output from this run.

## Lathe Pre-Release Gate

Use this section in `/Users/x/git/samzong/lathe` or another Lathe checkout. It captures the v0.4.3 regression shape and should evolve with Lathe's real release surface.

### Live State

```bash
git status --short --branch
git fetch origin --tags --prune
gh release list --limit 10
git tag --list 'v*' --sort=-v:refname | head -20
git ls-remote --tags origin "refs/tags/$VERSION"
gh run list --branch main --limit 6 --json databaseId,headSha,event,status,conclusion,workflowName,createdAt,updatedAt
```

Set the baseline to the latest GitHub release tag unless the user gives another baseline.

```bash
BASELINE=$(gh release list --limit 1 --json tagName -q '.[0].tagName')
git log --oneline --decorate --no-merges "$BASELINE"..HEAD
git diff --stat "$BASELINE"..HEAD
git diff --name-only "$BASELINE"..HEAD
```

Treat non-green `ci`, `codeql`, or `scorecard` on `HEAD` as a release blocker unless the user explicitly accepts the risk.

### Local Gates

```bash
make check
go test -race ./...
go build ./...
git diff --check
```

Run uncached targeted tests for Lathe's release-sensitive surfaces.

```bash
go test ./internal/sourceconfig ./internal/specsync -count=1
go test ./internal/codegen/render ./internal/overlay -count=1
go test ./internal/codegen/backends/... -count=1
go test ./pkg/runtime ./pkg/lathe -count=1
```

### Candidate Binary

```bash
ROOT=".local/regression-$VERSION"
rm -rf "$ROOT"
mkdir -p "$ROOT/bin"
COMMIT=$(git rev-parse --short HEAD)
DATE_UTC=$(date -u +%Y-%m-%dT%H:%M:%SZ)
go build -trimpath -ldflags "-X github.com/lathe-cli/lathe/pkg/lathe.Version=$VERSION -X github.com/lathe-cli/lathe/pkg/lathe.Commit=$COMMIT -X github.com/lathe-cli/lathe/pkg/lathe.Date=$DATE_UTC" -o "$ROOT/bin/lathe" ./cmd/lathe
"$ROOT/bin/lathe" version
CATALOG_SCHEMA=$(awk '/const CatalogSchemaVersion =/{print $4}' pkg/runtime/catalog.go)
REPO=$(pwd)
```

### Generated CLI E2E

Copy examples into scratch and rewrite their module replacement to the live checkout.

```bash
for EX in petstore richapi graphql; do
  cp -R "examples/$EX" "$ROOT/$EX"
  rm -rf "$ROOT/$EX/internal/generated" "$ROOT/$EX/skills" "$ROOT/$EX/bin" "$ROOT/$EX/go.sum"
  (cd "$ROOT/$EX" && go mod edit -replace github.com/lathe-cli/lathe="$REPO")
done
```

Petstore proves OpenAPI codegen, overlay shortcut, catalog, search, show, and schema.

```bash
cd "$ROOT/petstore"
../bin/lathe codegen -cache fixtures -overlay overlays
go mod tidy
go build -trimpath -o bin/petstore ./cmd/petstore
./bin/petstore --help | grep -F -- "pet-123" >/dev/null
./bin/petstore commands --json | jq -e --argjson schema "$CATALOG_SCHEMA" '.catalog_schema_version == $schema and (.commands[] | select(.path == ["pets","get"] and .http.method == "GET" and .http.path_template == "/pets/{id}" and .shortcuts[0].use == "pet-123"))' >/dev/null
./bin/petstore commands show pets get --json | jq -e '.path == ["pets","get"] and (.flags[] | select(.name == "id" and .required == true))' >/dev/null
./bin/petstore commands schema --json | jq -e --argjson schema "$CATALOG_SCHEMA" '.catalog_schema_version == $schema' >/dev/null
./bin/petstore search pet --json | jq -e 'length > 0' >/dev/null
cd "$REPO"
```

Richapi proves pagination, non-JSON body, body file help, long-running wait help, public auth, streaming hints, and search.

```bash
cd "$ROOT/richapi"
../bin/lathe codegen -cache fixtures
go mod tidy
go build -trimpath -o bin/richapi ./cmd/richapi
./bin/richapi commands --json | jq -e --argjson schema "$CATALOG_SCHEMA" '.catalog_schema_version == $schema and (.commands[] | select(.path == ["users","list"] and .output.pagination.strategy == "cursor" and .output.pagination.token_param == "page_token"))' >/dev/null
./bin/richapi commands show users upload-avatar --json | jq -e '.body.media_type == "application/octet-stream" and .body.required == true' >/dev/null
./bin/richapi users upload-avatar --help | grep -F -- "--file string" >/dev/null
./bin/richapi jobs create --help | grep -F -- "--wait" >/dev/null
./bin/richapi commands show system healthz --json | jq -e '.auth.required == false' >/dev/null
./bin/richapi commands show events stream --json | jq -e '.output.streaming.strategy == "sse"' >/dev/null
./bin/richapi search users --json | jq -e 'length > 0' >/dev/null
cd "$REPO"
```

GraphQL proves `/graphql`, request envelope merging, body-cursor pagination, required variables, and search.

```bash
cd "$ROOT/graphql"
../bin/lathe codegen -cache fixtures
go mod tidy
go build -trimpath -o bin/graphqlctl ./cmd/graphqlctl
./bin/graphqlctl commands --json | jq -e --argjson schema "$CATALOG_SCHEMA" '.catalog_schema_version == $schema and (.commands[] | select(.path == ["apps","list-apps"] and .http.method == "POST" and .http.path_template == "/graphql" and .body.merge_path == "variables" and .output.pagination.strategy == "body-cursor"))' >/dev/null
./bin/graphqlctl commands show apps list-apps --json | jq -e '.body.media_type == "application/json" and .body.merge_path == "variables" and .output.list_path == "data.listApps.nodes" and .output.pagination.token_param == "variables.after"' >/dev/null
./bin/graphqlctl commands show apps create-app --json | jq -e '(.flags[] | select(.name == "name" and .required == true))' >/dev/null
./bin/graphqlctl search apps --json | jq -e 'length > 0' >/dev/null
cd "$REPO"
```

If a JSON assertion fails, inspect the actual `commands show --json` output before calling it a product regression. Catalog shape can legitimately evolve with a schema bump.

### Skill Include Smoke

If `.local/skill-include-smoke` exists, copy it into the scratch root and run it against the candidate Lathe. Do not run its old `run-smoke.sh` blindly if it pins an older Lathe version.

```bash
rm -rf "$ROOT/skill-include-smoke"
cp -R .local/skill-include-smoke "$ROOT/skill-include-smoke"
cd "$ROOT/skill-include-smoke"
rm -rf internal/generated skills bin go.sum
go mod edit -replace github.com/lathe-cli/lathe="$REPO"
../bin/lathe codegen -sources specs/sources.yaml -cache .cache
grep -F 'This paragraph came from `skill.include`.' skills/smokectl/SKILL.md >/dev/null
grep -F 'This reference file was copied from `skill.include`.' skills/smokectl/references/local-runbook.md >/dev/null
go mod tidy
go build -trimpath -o bin/smokectl ./cmd/smokectl
./bin/smokectl commands --json | jq -e --argjson schema "$CATALOG_SCHEMA" '.catalog_schema_version == $schema and (.commands[] | select(.path == ["users","list"]))' >/dev/null
./bin/smokectl search users --json | jq -e 'length > 0' >/dev/null
cd "$REPO"
```

If the smoke fixture is missing, report it as skipped.

### GoReleaser Dry Run

```bash
goreleaser check
goreleaser release --snapshot --clean
(cd dist && shasum -a 256 -c *_checksums.txt)
SNAPSHOT_BIN=$(find dist -path "*/lathe" -type f | grep "$(go env GOOS)_$(go env GOARCH)" | head -1)
"$SNAPSHOT_BIN" version
```

Snapshot mode uses the previous tag in the version string. That is normal; the real version comes from the pushed release tag.

If GoReleaser is missing, report that artifact validation was not run.

## Publish Step

Only run this when the user explicitly asks to publish the target release and all required checks are green.

```bash
git status --short --branch
git tag "$VERSION"
git push origin "$VERSION"
gh run list --limit 5
```

Then monitor the release workflow and report the GitHub release URL or the failing job.

## Final Report

Report:

- release verdict: `ready`, `blocked`, or `ready with skipped checks`
- target version and baseline tag
- GitHub workflows checked for `HEAD`
- exact local commands that passed
- E2E surfaces that passed
- skipped checks and why
- worktree cleanliness
- whether tag, push, or release actions were performed

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [lathe-cli](https://github.com/lathe-cli)
- **Source:** [lathe-cli/lathe](https://github.com/lathe-cli/lathe)
- **License:** MIT

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/skill-lathe-cli-lathe-lathe-release
- Seller: https://agentstack.voostack.com/s/lathe-cli
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
