Reusable scaffold for Boundline framework-adapter binaries.
This repository now exposes the initial stdio contract surface used by the
host for describe, preflight, execute-stage, and emit-hook. The
scaffold stays intentionally generic: it emits a placeholder adapter identity,
declares one sample plan stage override, and returns stable happy-path JSON
payloads that downstream adapters can replace with framework-specific logic.
For the Boundline-to-adapter exchange, expected stdin and stdout payloads,
and a Mermaid sequence diagram of the one-shot stdio flow, see
STDIO Contract.
The executable assertions for that contract live in tests/contract.rs and can be rerun with:
cargo test --test contractThe crate now pins the released shared protocol package directly:
[dependencies]
boundline-adapters = { git = "https://github.com/apply-the/boundline", tag = "0.66.0" }It also re-exports boundline_adapters::framework_protocol and
boundline_adapters::framework_catalog so downstream adapters can reference the
host-owned typed contract surface from the same released Boundline line.
Current scaffold guarantees:
- the repository builds as a standalone Rust crate
- the binary speaks the
framework-adapter-v1protocol over JSON stdin/stdout - every stdio command returns the standard success envelope on stdout
describedeclares the supported V1 transport explicitly as JSON over stdin/stdout- the library exposes reusable helpers for required setup fields plus ready and blocked preflight examples
- smoke tests cover happy-path
describe,preflight,execute-stage, andemit-hookbehavior - the library exposes typed serde models for the scaffold protocol payloads
For the corrected Spec 066 line, keep the scaffold generic but align examples
to the shipped stage map used by the concrete Speckit adapter: goal remains
host-owned, plan may map to workflow ID speckit-planning, run may map to
workflow ID speckit-implementation, and host visibility surfaces remain
native to Boundline. The concrete bridge executes split workflow assets under
.specify/workflows/speckit/planning.yml and
.specify/workflows/speckit/implementation.yml; this template remains the
reusable bounded subprocess scaffold rather than hard-coding those workflow
paths.
GitHub Actions mirrors the local validation scripts shipped with this scaffold:
ci.ymlruns the baseline format, test, and clippy jobs togetherlint.ymlexposes the dedicated format and clippy checks as a separate quality signalvulnerabilities.ymlrunscargo auditagainst the workspace lockfilequality.ymlruns./scripts/coverage.sh, uploadslcov.infoto Codecov, and publishes the same report to SonarCloud
Rerun the same checks locally with:
cargo fmt --all --check
./scripts/test.sh
./scripts/clippy.sh
./scripts/coverage.shDescribe the scaffold capabilities:
cargo run -- describeExample response:
{
"success": true,
"data": {
"protocol_line": "framework-adapter-v1",
"adapter_id": "template-scaffold",
"adapter_version": "0.1.0",
"supported_boundline_range": ">=0.66.0,<0.67.0",
"supported_transports": [
{
"transport": "stdio",
"encoding": "json",
"request_channel": "stdin",
"response_channel": "stdout"
}
],
"declared_stage_overrides": ["plan"],
"declared_hook_subscriptions": ["stage_completed", "stage_failed"],
"required_config_fields": []
}
}Adapters that need guided setup can switch from the empty required_config_fields
default to describe_response_with_setup(...) plus sample_required_setup_fields().
Those helpers expose a bounded example schema for template_repo and
adapter_repo, including prompt text, help text, and non_interactive_policy = fail.
Validate a happy-path preflight request:
printf '%s' '{"boundline_version":"0.66.0","workspace_ref":"../tmp/example-workspace","non_interactive":false,"config_values":[]}' | cargo run -- preflightExample response:
{
"success": true,
"data": {
"status": "ready",
"normalized_config_values": [],
"warnings": []
}
}If your adapter needs to block before stage claim, the scaffold now exposes two preflight helpers:
ready_preflight_response(...): returnsstatus = readywith normalized valuesblocked_preflight_response(...): returnsstatus = blockedwithreason = missing_required_config,missing_fields, andrecovery
Example blocked response:
{
"success": true,
"data": {
"status": "blocked",
"normalized_config_values": [],
"warnings": [],
"reason": "missing_required_config",
"missing_fields": ["template_repo"],
"recovery": "boundline adapter add custom --workspace <workspace>"
}
}execute-stage and emit-hook are also wired and return the same stdout
envelope shape with data.status values of succeeded and delivered.
Structured stderr remains optional and is reserved for trace enrichment rather
than control flow.
The library exposes a few reusable helpers so downstream adapters can model partial stage ownership and hook observation without copying raw literals:
sample_partial_override_stage_keys(): returns a bounded example override set ofplanplusrunsample_hook_observer_subscriptions(): returns the scaffold hook observer set ofstage_completedplusstage_faileddescribe_response_with_overrides(...): wraps those stage and hook lists into a fulldescribepayloadfailed_execute_stage_response(...): returns a stablestatus = failedclaimed-stage example withfailure_class = adapter_runtimefailed_hook_observer_response(...): returns a stable failed hook-observer example
Example library usage:
use boundline_framework_template::{
blocked_preflight_response, describe_response_with_setup,
sample_hook_observer_subscriptions, sample_partial_override_stage_keys,
sample_required_setup_fields,
};
let describe = describe_response_with_setup(
sample_partial_override_stage_keys(),
sample_hook_observer_subscriptions(),
sample_required_setup_fields(),
);
let blocked = blocked_preflight_response(
vec!["template_repo".to_string()],
"boundline adapter add custom --workspace <workspace>".to_string(),
);
assert_eq!(describe.declared_stage_overrides, vec!["plan", "run"]);
assert_eq!(blocked.status, "blocked");These helpers keep the template generic while still giving adapter authors a concrete example of how to advertise selective lifecycle ownership, collect required setup inputs, and surface claimed-stage, blocked-preflight, or hook-only failures inside the standard success envelope.
When adapting the scaffold to a planning-aware bridge, keep the same V1 constraints: standard success or error envelopes on stdout, optional structured stderr for trace enrichment only, no graceful shutdown, and any planning readiness loop kept explicitly bounded by the adapter implementation rather than hidden behind the transport.
The corrected 2026-06-01 compatibility validation reran:
cargo test --test contract
cargo fmt --all --check
cargo clippy --all-targets -- -D warningsThat validation stayed green and reconfirmed the scaffold's released compatibility line:
- the crate now pins
boundline-adaptersto the released Boundline0.66.0git tag for sibling-repo compatibility tracking - the published dependency pin remains on
0.66.0because no newer Boundline release tag exists yet; corrected Spec 066 semantics are therefore recorded in host and siblingUnreleasednotes instead of fabricating a new tag - the scaffold remains compatible with downstream adapters that execute split
workflow assets by local YAML path while reporting semantic workflow IDs such
as
speckit-planningandspeckit-implementation describestill declaresframework-adapter-v1plus the V1 stdio JSON transport (stdin -> stdout)describe,preflight,execute-stage, andemit-hookstill return the standard stdout success envelope used by the host- blocked preflight examples remain explicit and bounded instead of inventing a background recovery loop
- downstream planning-aware adapters may keep analyze or remediation logic in their bridge layer as long as the workflow asset is an explicit entrypoint and the operator-visible payload stays honest about ownership and bounded retries
- the validated command set is one-shot only; there is still no graceful- shutdown or long-lived daemon command in this release line
- the Boundline provider-catalog refresh remained a no-change result for this release, so no template-facing catalog delta was required beyond the host catalog update already landed on 2026-05-30