Files
turnstone/docs/releasing.md
T
Patrick Buckley 471d1a3311 docs: audit documentation for 1.4 / 1.5 state
Systematic pass over every doc under docs/, the root-level README /
QUICKSTART / CONTRIBUTING, and the PlantUML diagrams.  Memory and docs
had drifted against the code since 1.2 — this catches them up to the
1.4.0 release and the 1.5.0a1 experimental line.

User-facing fixes
- README: fix broken docs/mcp.md link (→ mcp-registry.md); channel
  gateway entry reflects shipped Discord + Slack adapters instead of
  "Slack/Teams planned"; diagrams table mentions both.
- QUICKSTART: docs/*.md relative links were wrong from the repo root;
  wizard version bumped from 0.5.4.
- CONTRIBUTING: add dev extra plus the ruff / mypy / pytest commands
  we actually expect before push.

Reference docs
- architecture.md: 19 tool schemas (was 15), 18 admin tabs (was 14),
  turnstone-bootstrap added to entry-points table, OpenAI provider
  file split (chat/responses/common) documented, 38 SDK event
  dataclasses (was 27 and referenced deleted mq/protocol.py), Slack
  adapter + multi-adapter gateway, plan_agent/task_agent naming,
  governance admin-panel rewrite.
- api-reference.md: full attachment endpoints (POST/GET/content/
  DELETE on /v1/api/workstreams/{ws_id}/attachments) plus the
  multipart mode on POST /v1/api/workstreams/new.
- channels.md: Slack Setup section (Socket Mode app creation, OAuth
  scopes, tokens), Slack CLI/env reference in config table, combined-
  adapter architecture diagram.
- console.md: 18-tab listing (was 13) with Channels/Models/Nodes/TLS
  descriptions and ConfigStore live-edit note.
- docker.md: Slack env vars block; image entry-point list now
  includes turnstone / turnstone-bootstrap.
- sdk.md: attachments methods on the server client, attachments
  example (upload-then-send and at-creation), event count fixed.
- releasing.md: four-track table (stable/1.0, 1.3, 1.4 + main 1.5);
  promotion workflow uses 1.5 / 1.6 numbering.
- settings.md: plan_model / task_model / plan_effort / task_effort
  overrides section.
- governance.md: skill naming (/skill, `skill` field — not /template),
  Prompts/Judge tabs called out.
- security.md: two-token-types wording; src claim values match the
  AuthResult source strings actually emitted.
- mcp-registry.md: SDK package name is @turnstone/sdk.
- tools.md: plan / task renamed to plan_agent / task_agent in the
  section headings and summary table; primary-key table matched.
- design/consistent-hash-ring.md: dead direct-http-transport.md
  pointer redirected to architecture.md.

Diagrams
- 02-package-structure: drop phantom chat.py entry point, add admin
  and bootstrap, add slack/bot.py, rename channels/gateway.py →
  channels/cli.py.
- 16-channel-architecture: Slack is no longer "(future)", add a
  SlackBot class and the slack-bolt Socket Mode edges; wire the new
  bot into ChannelService.  PNGs regenerated from both puml sources.
2026-04-16 16:01:24 -07:00

3.1 KiB

Release Process

Turnstone ships several parallel release tracks from a single PyPI package.

Release Tracks

Track Versions Branch Docker tags PyPI install
Legacy 1.0 1.0.x stable/1.0 :1.0.x, :1.0 pip install 'turnstone==1.0.*'
Stable 1.3 1.3.x stable/1.3 :1.3.x, :1.3 pip install 'turnstone==1.3.*'
Stable 1.4 1.4.x stable/1.4 :1.4.x, :1.4, :stable, :latest pip install turnstone
Experimental 1.5.0aN main :1.5.0aN, :experimental pip install turnstone --pre
  • Stable tracks receive bugfixes only. The most-recent stable minor owns the :stable / :latest Docker tags and the default PyPI install.
  • Experimental (always on main) receives new features. May be rough around the edges.
  • When experimental matures, it is promoted to a new stable minor via a stable/X.Y branch; older stable branches continue to receive security fixes until explicitly retired.

Version Scheme

PEP 440 pre-release suffixes on a single package:

  • 1.0.0 — stable release
  • 1.1.0a1 — alpha (experimental)
  • 1.1.0b1 — beta (experimental, more stable)
  • 1.1.0rc1 — release candidate (experimental, nearly stable)
  • 1.1.0 — promoted to stable

Releasing an Experimental Version (from main)

scripts/release.sh 1.5.0a2 --push

This bumps pyproject.toml + turnstone/__init__.py, regenerates uv.lock, commits, tags v1.5.0a2, and pushes. CI runs, then publish + Docker workflows fire automatically.

Releasing a Stable Patch (from stable/X.Y)

git checkout stable/1.4
git cherry-pick <commit-hash>    # bugfix from main
scripts/release.sh 1.4.1 --push

Promoting Experimental to Stable

When main is ready for a stable release:

# 1. Tag the stable release on main
scripts/release.sh 1.5.0 --push

# 2. Create the stable maintenance branch from that tag
git branch stable/1.5 v1.5.0
git push origin stable/1.5

# 3. Start the next experimental cycle on main
scripts/release.sh 1.6.0a1 --push

The previous stable branch (stable/1.4) continues to receive security-only patches; older tracks (stable/1.0, stable/1.3) are retired when they fall out of support.

CI/CD Pipeline

All releases are gated on CI success:

  1. git push with v* tag triggers CI (lint, typecheck, test, test-postgres, lock-check, security audit)
  2. On CI success, Publish to PyPI fires via workflow_run
  3. On CI success, Publish Docker Image fires via workflow_run

Pre-release tags (a, b, rc suffixes) produce:

  • PyPI: pre-release version (not installed by default)
  • GitHub Release: marked as pre-release
  • Docker: :experimental alias + exact version tag

Stable tags produce:

  • PyPI: stable version (default pip install)
  • GitHub Release: full release
  • Docker: :stable, :latest, :X.Y, :X.Y.Z tags

Dependency Updates

Renovate targets main (experimental) only. Stable branches receive manual dependency updates via cherry-pick when security-relevant.