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_HOSTDOCKER_REGISTRY_USERDOCKER_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 syncorgit commit/tag/pushas a release stepblock bump— does not exist;block-finalizesets the version- Block specs — blocks have no
.specs/ - CI-first — CI consumes the same chain
image_tagas 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/)