Dev and Deploy

The canonical chain from spec to installed change: workspace release, block release without specs, push, pull all instances, install. Gates, non-gates and the MCP ops for every step.

This page is the process map for changes to Polycrate workspaces and blocks: from the spec to the installed change on the target system. It is the MCP view of the CANONICAL FLOW in polycrate spec manual; the concepts behind it are explained in Spec-Driven Development.

Polycrate versions *.poly files, runs actions and installs blocks. Git is not part of the process.

The chain

# Step CLI MCP (polycrate mcp) Hard fail when
1 Spec done spec update <id> --set status=done sdd op update_meta (status=done) structural drift; ## Open Questions not empty
2 Create workspace release release create X.Y.Z [--spec <id>…] workspace op release_create assigned spec not done/cancelled
3 Changelog + release note release update X.Y.Z --set type= --set message= --changelog-item --note-section highlights= workspace op release_update —
4 Finalize workspace release finalize X.Y.Z workspace op release_finalize message empty; highlights empty; drift or Open Questions in an assigned spec; a pre_action fails
5 Block changelog release --block <name> update X.Y.Z --set type= --set message= --changelog-item [--set app_version=] block op release_update no field passed
6 Finalize + push block release block-finalize <name> X.Y.Z [--app-version] [--no-push] block op release_finalize changelog entry missing or message/description empty; app_version empty although block.poly tracks one
7 Consume downstream block pull <registry/org/name>:X.Y.Z block op pull (version required) version missing
8 Install run <block> install action op run action fails

Steps 1–4 are the workspace part, 5–6 the block part, 7–8 the deploy part. If you only change a block, start at 5 (for a logic change with a workspace spec labelled block:<name>, step 1). If you only release the workspace, stop at 4.

--workspace / -w must be absolute. Relative (., .., ./ws) is a hard fail — without -w the current directory is used.

Complete example

A block hardening in the workspace ayedo-core receives a logic change; the workspace vivavis-prod-paz consumes it.

CORE=/home/me/.polycrate/workspaces/ayedo/ayedo-core
PROD=/home/me/.polycrate/workspaces/vivavis/vivavis-prod-paz

# 1. Spec in the host workspace (the label ties it to the block)
polycrate spec create --name "Configurable OpenSSH PerSourcePenalties" --type fix -w $CORE
polycrate spec update 12 --add-label block:hardening -w $CORE
# … write the spec, implement the block, spec lint/verify …
polycrate spec update 12 --set status=done -w $CORE

# 5–6. Block release (no release create, no block spec)
polycrate release --block hardening update 0.5.6 --set type=fix \
  --set message="Configurable PerSourcePenalties" \
  --changelog-item "Fix: exempt list for PerSourcePenalties" -w $CORE
polycrate release block-finalize hardening 0.5.6 -w $CORE   # sets block.poly version, pushes

# 2–4. Workspace release of the host workspace (optional, if the workspace itself carries a version)
polycrate release create 2.3.0 --spec 12 -w $CORE
polycrate release update 2.3.0 --set type=fix --set message="hardening 0.5.6" \
  --changelog-item "hardening 0.5.6: PerSourcePenalties" \
  --note-section highlights="- hardening 0.5.6" -w $CORE
polycrate release finalize 2.3.0 -w $CORE

# 7–8. Downstream
polycrate block pull cargo.ayedo.cloud/ayedo/linux/hardening:0.5.6 -w $PROD   # rewrites from: on all instances
polycrate run hardening install -w $PROD

A pure version bump of the block (dependency, image tag, no behaviour change) needs no spec: steps 5–6 only.

What happens at finalize

Workspace (release finalize): checks the gates from step 4, sets workspace.poly → version, runs config.release.pre_actions, then post_actions (e.g. build, image push, hub upload). No git tag, no commit.

Block (release block-finalize = release --block <name> finalize): checks the gates from step 6, sets block.poly → version (and app_version when passed), validates, pushes to the registry. Idempotent: if the tag already exists, the push is skipped (--force pushes again, --no-push skips it — then later block push <name>).

Pull (block pull <fqbn>:<version>): downloads the block and rewrites from: on every instance of that FQBN in workspace.poly. image_tag is neither written nor validated.

Gates and non-gates

Hard fail (exit ≠ 0): relative -w; invalid IDs; H1/H2 in a section body; structural drift on status=done and on workspace finalize of assigned specs; non-empty Open Questions in the same places; release create/update --spec with a spec that is not done/cancelled; empty changelog message; empty highlights; block finalize without a changelog entry or with empty message/description; missing app_version when block.poly tracks one; block pull without a version.

--force (with --force-reason, audited in .specs/.force-audit.log): on status=done bypasses drift and Open Questions; on release finalize only highlights.

Not a gate (warning or silent): red spec verify, missing spec review, unmet needs:, 0 specs on a release, dirty git tree, existing git tag vX.Y.Z, unpushed commits.

MCP

One server: polycrate mcp. Six tools, dispatched via op. No aliases, no session_id. Mutating ops need workspace as an absolute path.

Tool Ops
sdd list inspect create update_meta update_section lint format
docs schema (workspace/block/changelog/secrets, local) · guide (embedded) · get search (ayedo.de public API)
hub inspect_block list_versions list_blocks info cli_latest_version cli_list_versions cli_artifacts
workspace release_create release_update release_finalize release_status
block release_update release_finalize release_status push pull verify — no release_create (error with hint)
action run

sdd.update_section writes section bodies only (no H1/H2, no frontmatter). Direct file edits of section bodies remain allowed; both paths end in lint. docs op guide with name=dev_and_deploy returns this chain as embedded text; polycrate spec manual remains the SSOT.

Configuration and troubleshooting: MCP server page (German: /docs/polycrate/mcp/).

Docker registry auth

~/.docker/config.json is not mounted. Credentials come from the process environment into the action container:

  • DOCKER_REGISTRY_HOST
  • DOCKER_REGISTRY_USER
  • DOCKER_REGISTRY_PASSWORD

CARGO_* is playbook fallback only.

What Polycrate does not prescribe as process

  • Git tag as source of truth — released means: changelog entry + version file (workspace) or registry tag (block)
  • workspace sync or git commit/tag/push as a release step
  • block bump — does not exist; block-finalize sets the version
  • Block specs — blocks have no .specs/
  • CI-first — CI consumes the same chain
  • image_tag as a product check

Version control remains your habit, not the Polycrate process — see the Git integration page (German: /docs/polycrate/git/).

Next

  • Spec-Driven Development — specs, gates, agent integration in detail
  • Getting started
  • German-only reference pages: MCP server (/docs/polycrate/mcp/), Workspaces (/docs/polycrate/workspaces/), Blocks (/docs/polycrate/blocke/), CLI reference (/docs/polycrate/cli-referenz/)