Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 29 additions & 1 deletion .github/workflows/release-preflight.yml
Original file line number Diff line number Diff line change
Expand Up @@ -374,8 +374,36 @@ jobs:
shell: bash
run: |
set -euo pipefail
# cargo package must rewrite path+version dependencies to
# registry-resolvable versions during its manifest-prepare phase,
# before any verification build runs -- --no-verify does not skip
# this. So packaging a crate whose dependency is another
# manifest-declared sibling that hasn't been published yet always
# fails here, even though the real `cargo publish` step (which runs
# for real, in manifest publish_order) will succeed once that
# sibling is actually live. Treat that specific, identified failure
# as non-blocking; any other cargo package failure still fails this
# step.
mapfile -t manifest_packages < <(python3 .github/scripts/release_artifacts.py list-publish-plan --manifest "${RELEASE_ARTIFACT_MANIFEST}" | cut -d'|' -f1)
while IFS='|' read -r package _; do
cargo package -p "$package" --locked --allow-dirty
if ! output="$(cargo package -p "$package" --locked --allow-dirty 2>&1)"; then
skip=false
for sibling in "${manifest_packages[@]}"; do
[[ "${sibling}" == "${package}" ]] && continue
if grep -qF "no matching package named \`${sibling}\`" <<<"${output}"; then
skip=true
break
fi
done
if [[ "${skip}" == true ]]; then
echo "::warning::cargo package -p ${package} failed only because manifest sibling crate has not published yet (expected for a new intermediate crate's first release; the real cargo publish step runs in manifest publish_order and will succeed). Treating as non-blocking."
echo "${output}"
continue
fi
echo "${output}" >&2
exit 1
fi
echo "${output}"
done < <(python3 .github/scripts/release_artifacts.py list-publish-plan --manifest "${RELEASE_ARTIFACT_MANIFEST}")

- id: github_release_permissions
Expand Down
16 changes: 8 additions & 8 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ members = ["crates/sc-composer", "crates/sc-composer-beads", "crates/sc-compose"
resolver = "2"

[workspace.package]
version = "1.5.0"
version = "1.6.0"
authors = ["Randlee"]
edition = "2024"
license = "MIT"
Expand All @@ -24,8 +24,8 @@ serde = { version = "1", features = ["derive"] }
serde_json = "1"
serde_yaml = "0.9"
quick-xml = "0.41"
sc-sha = { path = "crates/sc-sha", version = "1.5.0" }
sc-composer = { path = "crates/sc-composer", version = "1.5.0" }
sc-sha = { path = "crates/sc-sha", version = "1.6.0" }
sc-composer = { path = "crates/sc-composer", version = "1.6.0" }
sha2 = "0.10"
similar = "2"
time = { version = "0.3", features = ["formatting", "macros"] }
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ handoff requirements.
| Any (Rust) | crates.io | `cargo install sc-compose` |
| Any (Python) | PyPI | `pip install sc-compose` |
| Any (source) | cargo | `cargo build --release -p sc-compose` |
| Rust lib | Cargo.toml | `sc-composer = "1.5.0"` |
| Rust lib | Cargo.toml | `sc-composer = "1.6.0"` |

Bundled examples are guaranteed in Homebrew, Scoop, Winget, and GitHub Release
installs. `cargo install` ships the binary only — set `SC_COMPOSE_DATA_DIR` for
Expand All @@ -186,11 +186,11 @@ examples.

| | |
|---|---|
| Version | 1.5.0 |
| Version | 1.6.0 |
| MSRV | Rust 1.94.1 |
| Rust edition | 2024 |
| Platforms | macOS, Linux, Windows |
| Stability | stable 1.5 release line |
| Stability | stable 1.6 release line |

---

Expand Down
2 changes: 1 addition & 1 deletion bindings/python/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ crate-type = ["cdylib", "rlib"]

[dependencies]
pyo3 = "0.29"
sc-composer = { path = "../../crates/sc-composer", version = "1.5.0" }
sc-composer = { path = "../../crates/sc-composer", version = "1.6.0" }
serde_json = "1"
serde_yaml.workspace = true

Expand Down
2 changes: 1 addition & 1 deletion bindings/python/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "maturin"

[project]
name = "sc-compose"
version = "1.5.0"
version = "1.6.0"
description = "Python bindings for sc-compose composition APIs"
readme = "README.md"
requires-python = ">=3.11"
Expand Down
2 changes: 1 addition & 1 deletion bindings/sc-composer-beads-python/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ python-extension = ["pyo3/extension-module"]

[dependencies]
pyo3 = "0.29"
sc-composer-beads = { path = "../../crates/sc-composer-beads", version = "1.5.0" }
sc-composer-beads = { path = "../../crates/sc-composer-beads", version = "1.6.0" }
serde_json.workspace = true

[lints]
Expand Down
2 changes: 1 addition & 1 deletion bindings/sc-composer-beads-python/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "maturin"

[project]
name = "sc-composer-beads"
version = "1.5.0"
version = "1.6.0"
description = "Typed Python adapter for host-neutral Beads formula composition"
requires-python = ">=3.11"
license = { text = "MIT" }
Expand Down
2 changes: 1 addition & 1 deletion bindings/sc-sha-go/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ crate-type = ["staticlib", "cdylib", "rlib"]
doctest = false

[dependencies]
sc-sha = { path = "../../crates/sc-sha", version = "1.5.0" }
sc-sha = { path = "../../crates/sc-sha", version = "1.6.0" }
thiserror.workspace = true
uniffi.workspace = true

Expand Down
2 changes: 1 addition & 1 deletion bindings/sc-sha-python/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ python-extension = ["pyo3/extension-module"]

[dependencies]
pyo3 = "0.29"
sc-sha = { path = "../../crates/sc-sha", version = "1.5.0" }
sc-sha = { path = "../../crates/sc-sha", version = "1.6.0" }

[lints]
workspace = true
2 changes: 1 addition & 1 deletion bindings/sc-sha-python/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "maturin"

[project]
name = "sc-sha"
version = "1.5.0"
version = "1.6.0"
description = "Python adapter for deterministic sc-sha file and composition identities"
requires-python = ">=3.11"
license = { text = "MIT" }
Expand Down
4 changes: 2 additions & 2 deletions crates/sc-compose/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ mimalloc = { version = "0.1" }
serde.workspace = true
serde_json.workspace = true
serde_yaml.workspace = true
sc-composer = { path = "../sc-composer", version = "1.5.0" }
sc-composer-beads = { path = "../sc-composer-beads", version = "1.5.0" }
sc-composer = { path = "../sc-composer", version = "1.6.0" }
sc-composer-beads = { path = "../sc-composer-beads", version = "1.6.0" }
sc-observability.workspace = true
sc-observability-types.workspace = true
time.workspace = true
Expand Down
1 change: 1 addition & 0 deletions site/announcements/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
<h1>Announcements</h1>
<p>Press releases and release announcements for sc-compose.</p>
<ul>
<li><a href="sc-compose-v1.6.0.md">sc-compose v1.6.0</a> — Beads Composition Engine, Renderer Hardening, Release Consolidation</li>
<li><a href="sc-compose-v1.5.0.md">sc-compose v1.5.0</a> — Hermes Runtime, sc-publish migration, Go distribution, release hardening</li>
</ul>
</body>
Expand Down
49 changes: 49 additions & 0 deletions site/announcements/sc-compose-v1.6.0.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# sc-compose v1.6.0 — Beads Composition Engine and Renderer Hardening

**Released:** August 28, 2026 · **Install:** `cargo install sc-compose` (Rust), `pip install sc-compose` (Python ≥3.11)

[Changelog](https://github.com/randlee/sc-compose/blob/main/CHANGELOG.md) · [Release notes](https://github.com/randlee/sc-compose/releases/tag/v1.6.0)

---

## Beads Alchemist

**As a beads alchemist, I want to compose and instantiate beads formulas — workflow, expansion, aspect, and convoy — through sc-compose, so that I can express a recurring multi-step agent workflow once and pour it across projects.**

v1.6.0 ships the Phase R Beads composition integration (ADR-0021 accepted). sc-compose can now render `.formula.toml.j2` / `.formula.json.j2` templates into beads formula files that `bd cook` / `bd mol pour` then compile. The new host-neutral composition engine keeps sc-compose from knowing anything about `bd`'s internals — `bd` stays the sole validator and state-owner — while sc-compose supplies the templating and rendering half of the workflow.

A pinned binary integration path and a JSON-protocol CLI adapter round out the runtime: formulas composed in sc-compose flow into `bd` through a stable request/response protocol rather than ad-hoc CLI scraping. Hardening lands alongside the happy path — TOML escaping is selected at the caller boundary, invalid variable argv values are rejected, render-failure details are preserved, and rendered output is capped so a runaway formula can't flood a terminal.

---

## Release & Ops Engineer

**As a release/ops engineer, I want to compose service configs from shared fragments and generate compliance/sprint reports, so that configs stay DRY and reports are reproducible.**

The release pipeline gets a consolidation pass in v1.6.0: registry status is centralized into one component, the build ref is emitted once from a resolved main SHA, and published-channel recovery is manifest-driven and idempotent. Homebrew keyed release assets are preserved across retries, and Windows GNU release executables are packaged correctly for the first time.

These are the fixes that make the 1.6.0 bump itself reliable: unpublished-sibling package-check failures no longer block a release, and the redundant isolated verification build is skipped in preflight.

---

## Python Developer

**As a Python developer, I want Python bindings and pytest-fixture generation, so that I can drive composition from Python and generate test stubs from a list of test names.**

The Beads integration arrives with its Python half: `beads-python` gains a PyO3 adapter scaffold, wheel tests, and release metadata, plus an in-process sdist parity test that pins the Python and Rust rendering paths together. The existing `sc-compose` PyPI bindings are otherwise unchanged — this is additive.

---

## Library Consumer (Rust)

**As a Rust library consumer, I want the `sc-composer` crate with a stable API, so that I can embed composition in my own tooling.**

Renderer robustness is the Rust story this release. Three confirmed renderer bugs from the adversarial fuzz campaign are pinned as permanent regression tests, legacy JSON null serialization is made consistent, and unused escape APIs are removed. No public API break: the `sc-composer` crate surface stays stable while rendering gets measurably more correct at the edges.

> The AI-Agent Profile Author and Task-Template Author personas are unchanged this release — the renderer fixes above benefit their rendering paths indirectly, but no new profile or template surface ships in v1.6.0.

---

## What's Next

With Phase R landed, subsequent work extends the beads composition surface and continues the adversarial-fuzz hardening loop.
4 changes: 2 additions & 2 deletions tests/fixtures/sc-lint/bootstrap/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading