This repo is in release execution.
The goal is production-ready release of:
sc-composersc-compose
This document is the authoritative release plan. It replaces the earlier implementation-history view with one sprint sequence that contains all work required to ship.
The post-release Beads formula-composition integration is planned separately in Phase R — Beads Formula Composition Integration. It is an additive adapter track: it does not reopen or redefine this release plan's core renderer contract. ADR-0021 and the Phase R pre-source boundary gate are authoritative for that work.
requirements.md,architecture.md, and this plan are the release source of truth.- No sprint may leave a known release blocker unassigned.
- A later sprint may start only after the prior sprint exit gate passes, unless the authoritative phase plan explicitly declares independent tracks; in that case, the sprint's own plan gate and declared dependency conditions govern its start.
- Deferred work is allowed only when it is explicitly out of scope for the initial release and does not reduce production readiness.
sc-composerremains a pure library.sc-composemay depend onsc-composer,sc-composer-beads, and standalone observability crates only.bindings/pythonis a Python-facing adapter package that may depend onsc-composeronly.bindings/pythonmust not depend onsc-compose,sc-observability, or ATM-specific crates.sc-composermust not depend onbindings/python.sc-composer-beadsmay depend only onsc-composer, workspace serde/error dependencies, and the approvedprocess-wrapplatform-containment dependency. It must not depend on the CLI, a foreign-language adapter, Beads source/database libraries, or ATM/runtime code.bindings/sc-composer-beads-pythonmay depend only onsc-composer-beadsplus approved PyO3/maturin/serde dependencies; it must not depend on the CLI,sc-composer, Beads source/database libraries, or ATM/runtime code.- No ATM-specific runtime assumptions may enter code or manifests.
Current known release blockers:
| ID | Blocker | Status | Sprint | Closure condition |
|---|---|---|---|---|
| RB-01 | Final release command surface and JSON contracts are not yet locked as an implementation baseline. | Closed | Sprint 1 | requirements.md, architecture.md, and project-plan.md define one consistent command and schema contract. |
| RB-02 | The local observer contract and event conventions are not yet fully implemented in sc-composer. |
Closed | Sprint 2 | Observer API, event fields, and no-op behavior are fixed in docs and then implemented in code. |
| RB-03 | sc-compose does not yet wire the concrete sc-observability::Logger integration path. |
Closed | Sprint 2 | CLI startup constructs the logger, adapts it into the observer path, and exposes observability-health. |
| RB-03a | CliObserver still uses a bespoke sink path instead of sc-observability::Logger. |
Closed | Sprint 2 | Replace the bespoke observer sink with sc-observability::Logger construction and adapter wiring. |
| RB-03b | --json console sink suppression is not yet wired through the observer/logger path. |
Closed | Sprint 2 | Console sink suppression is enforced through the sc-observability::Logger construction path whenever --json is active. |
| RB-03c | Graceful logger shutdown is not yet called before process::exit(). |
Closed | Sprint 2 | The CLI calls logger.shutdown() before process exit so pending events flush cleanly. |
| RB-04 | Production logging safeguards are not yet proven. | Closed | Sprint 3 | Tests prove --json cleanliness, shutdown/flush behavior, sink degradation behavior, and event coverage. |
| RB-05 | Any non-observability release blocker found during audit must be closed before release. | Closed | Sprint 3 | Every audit finding is either closed or explicitly moved to a later sprint in this plan before Sprint 1 exit. |
| RB-06 | Final release validation, QA approval, and cutover readiness were incomplete before Sprint 4 closeout. | Closed | Sprint 4 | End-to-end smoke tests, QA review, design review, and release approval all pass; closure evidence includes crates/sc-compose/tests/cli/observability.rs::release_smoke_covers_render_pipeline_and_observability_health. |
Inventory rules:
- Sprint 1 owns this inventory.
- Any blocker discovered during Sprint 1 must be added to this table with an assigned sprint before Sprint 1 can exit.
- No blocker may be removed from this table until its closure condition is met.
Branch:
feature/release-contract-closure->develop
FRs addressed:
- FR-7
- FR-8a
- FR-9
- FR-10
- FR-11
Deliverables:
- update the
Release Blocker Inventorysection in this document so it lists every known release blocker and its assigned sprint - final normative updates in:
docs/requirements.mddocs/architecture.mddocs/project-plan.md
- final command surface for the initial release, including:
renderresolvevalidatefrontmatter-initinitobservability-health
- final logging-only observability contract, including:
sc-composerlocal observer hook model- CLI-owned command lifecycle events
- pipeline event emission points
- stable event
messageconventions - no-op fallback behavior
--jsonconsole suppressionobservability-healthcommand behavior- graceful shutdown behavior
- explicit initial-release scope statement that keeps:
- structured logging and health reporting in scope
sc-observeandsc-observability-otlpout of scope
Acceptance criteria:
- the
Release Blocker Inventorysection lists every known release blocker and assigns each one to a sprint in this plan requirements.md,architecture.md, andproject-plan.mdare mutually consistent- the logging contract is precise enough to implement without inventing new behavior during coding
- the initial-release command surface is final
observability-healthis fully specified as a release command rather than a placeholder- no unresolved contradiction remains around the local observer model, logger
wiring, command lifecycle events, event
messageconventions, or no-op behavior
Exit gate:
quality-mgrcross-document consistency review passes- req-qa and arch-qa find no blocking document mismatch
- the
Release Blocker Inventorysection is accepted as complete
Branch:
feature/release-logging-integration->develop
FRs addressed:
- FR-9
- FR-10
- FR-11
Deliverables:
crates/sc-composer/src/observer.rsimplementing the local observer contract, including:ObservationEventObservationSinkCompositionObserver- built-in no-op observer path
compose_with_observer(...)as the end-to-end library injection entry pointcompose()andRendererdefault behavior that remains functional when no observer is injectedsc-observabilitydependency and logger construction insc-compose- CLI-owned adapter from the local
sc-composerobserver model tosc-observability::Logger - command lifecycle logging for:
- command start
- command completion
- command failure
- pipeline-stage logging for:
- resolve
- include-expand
- validate
- render
observability-healthcommand implementation- console sink suppression in
--jsonmode - logger shutdown wiring on process exit
Acceptance criteria:
sc-composerdoes not depend onsc-observability-typessc-composerdoes not depend onsc-observabilitysc-composeconstructsLoggerand adapts it into the library observer path- command lifecycle events and composition-stage events are emitted through the documented mapping
observability-healthreturns the documentedLoggingHealthReport--jsonmode remains machine-readable- shutdown flushes sinks on exit and does not break command behavior
Exit gate:
cargo test --workspacepassescargo clippy --all-targets --all-features -- -D warningspassescargo fmt --all --checkpassesquality-mgrimplementation review finds no blocking contract mismatch
Branch:
feature/release-production-hardening->develop
FRs addressed:
- FR-1 through FR-11 where production behavior requires hardening
Deliverables:
- focused tests for:
- observer injection and no-op defaults
- command lifecycle logging
- resolve/include-expand/validate/render event coverage
- event
messageguidance and stable target/action naming observability-healthtext outputobservability-health --jsonobservability-healthprocess-local behavior without daemon dependency--jsonconsole suppression and stdout cleanliness- graceful shutdown and flush behavior
- sink failure degradation behavior
- failure-path coverage for logging integration
- closure of every non-observability release blocker identified in Sprint 1
- updates to release notes, migration notes, and cutover notes where changed behavior affects downstream consumers
Acceptance criteria:
- no release blocker from Sprint 1 remains open
- logging support is production-ready for:
- CLI use
- consuming applications that extend logging through the documented observer hook model
- all documented logging behaviors are covered by automated tests
- no command emits console log noise that corrupts machine-readable stdout
- health reporting and shutdown behavior are proven by tests rather than by documentation alone
Exit gate:
cargo test --workspacepasses with the full logging and hardening suitescargo clippy --all-targets --all-features -- -D warningspassescargo fmt --all --checkpasses- no Priority 1 or Priority 2 QA finding remains open
Branch:
feature/release-gate->develop
FRs addressed:
- FR-1 through FR-11 release validation
Deliverables:
- final release-readiness checklist for both crates
- final migration and cutover notes for downstream consumers
- final verification of standalone boundary rules
- automated repo-boundary verification covering forbidden ATM env/import/manifest references
- final end-to-end smoke tests
- final QA and design review pass
- branch prepared for merge to
develop, then release merge tomain
Acceptance criteria:
- all FR-1 through FR-15 behavior is implemented and covered by automated tests
- all release blockers are closed
- all required docs match shipped behavior
- downstream cutover notes are accurate
- standalone boundary verification passes with no forbidden ATM runtime references or dependencies in source/manifests
- release workflow prerequisites are satisfied
Exit gate:
cargo test --workspacepassescargo clippy --all-targets --all-features -- -D warningspassescargo fmt --all --checkpasses- full end-to-end smoke test passes using includes, vars, frontmatter, and observability-health
quality-mgrfull QA passteam-leadfinal design review pass- branch approved for merge to
develop - release approved for merge to
main
- FR-1 through FR-6:
- already specified in the normative docs
- revalidated in Sprint 3 and Sprint 4 where release blockers or integration changes touch them
- FR-1b:
- Sprint S7 broadens render inputs from scalar-only to scalar values plus arrays of scalars
- Sprint S7 validates empty-array acceptance and list iteration support
- FR-1d:
- Sprint S7 defines flat bundled examples, per-template user directories,
and the
TemplateStore-based lookup model
- Sprint S7 defines flat bundled examples, per-template user directories,
and the
- FR-2:
- Sprint S7 extends precedence handling to include template
input_defaults
- Sprint S7 extends precedence handling to include template
- FR-7:
- Sprint 1 finalizes the command surface
- Sprint 2 implements
observability-health - Sprint 3 hardens command behavior
- Sprint 4 validates release behavior
- Sprint S7 adds
examples list,examples <name>,templates list,templates add, andtemplates <name> - Phase D adds multi-pass
render --all, pass-scoped--pass N/--vargroups,verify, andtemplate-init - Phase D also lands delimiter hardening for custom variable delimiters:
Renderer::with_delimitersis now fallible on invalid delimiters and ships in1.3.0under the narrow ADR-0010 stability exception
- FR-7b:
- Phase D assigns
verifydrift to exit code1 - Phase D keeps render and validation failures on
2 - Phase D keeps usage and configuration failures, including
template-initliteral-miss cases, on3
- Phase D assigns
- FR-22:
- PR #396 defines the shipped conceptual-help command, its static bundled manual registry, topic coverage, parser collision rules, and text/JSON output schemas
- the
help_topicsregistry remains exclusively owned bysc-compose, with topic names resolved only within the explicithelpcommand namespace
- FR-8 and FR-8a:
- Sprint 1 finalizes command and health schemas
- Sprint 2 implements the logger-facing command output
- Sprint 3 hardens JSON and failure-path behavior
- Sprint 4 validates release behavior
- Sprint S7 adds
examples list --json,templates list --json, andtemplates add --json
- FR-9:
- Sprint 1 finalizes the logging-only integration contract
- Sprint 2 implements the logging path
- Sprint 3 hardens and validates it
- Sprint 4 validates release behavior
- FR-10:
- Sprint 1 finalizes the local observer contract
- Sprint 2 implements it
- Sprint 3 hardens and validates it
- Sprint 4 validates release behavior
- FR-11:
- Sprint 1 finalizes CLI logger behavior
- Sprint 2 implements it
- Sprint 3 hardens and validates it
- Sprint 4 validates release behavior
- FR-12:
- Sprint H1 adds structured object input support
- FR-13:
- Sprint H2 adds arrays of objects and loop-body discovery support
- FR-14:
- Sprint H3 adds HTML template output as a bundled report example track
- FR-15:
- Sprint H3 ships the
sprint-report-htmlbundled example
- Sprint H3 ships the
- FR-12 through FR-15 (H4):
- Sprint H4 extends wrapper integration across FR-12–FR-15 and finalizes source-of-truth documentation; introduces no new functional requirements
- FR-16 and Phase H:
- Phase G establishes the known-template XML-first extraction contract and its scalar-only boundaries
- Phase H.1 owns the contract amendments for issue #193's JSON, YAML, and TOML extensions and plans the migration of format-neutral value matching from the XML path into a shared raw-text core
- Phase H.2 through H.8 own implementation, cross-surface parity, corpus, adversarial hardening, and phase-ending remediation for those accepted amendments
- XML mixed-content, XML dirty-prefix tolerance, and customer-facing
raw-text mode remain outside Phase H; they are now planned as Phase I
work in
docs/phase-I/phase-I-plan.md, not retroactively claimed as H behavior
- FR-17 through FR-21 and Phase I:
- I.1 accepts the raw-text, XML recovery, loop-context, and YAML merge-key contracts in ADR-0013 and the synchronized requirements/architecture docs
- I.2 through I.6 own runtime implementation, cross-surface parity, and evidence for those accepted requirements; I.1 adds no executable code
Release is complete only when all numbered Phase-H sprints have passed and all of the following are true:
- no release blocker remains open
requirements.md,architecture.md, andproject-plan.mdmatch the shipped behavior- all FR-1 through FR-15 behavior is implemented and covered by automated tests
cargo test --workspacepassescargo clippy --all-targets --all-features -- -D warningspassescargo fmt --all --checkpasses- full end-to-end smoke coverage passes
quality-mgrcompletes a full QA passteam-leadcompletes a final design review- release is approved for merge to
main
Status:
- complete: C.1 through C.3 landed the Python adapter, API surface, and release
train; the current workspace publishes the adapter at
1.4.1
Sprint entries:
- Sprint C.1 — Maturin Python Bindings Foundation
- Sprint C.2 — Python API Surface
- Sprint C.3 — Python Release Train And Packaging Hardening
- Phase C README
- Maturin Bindings Investigation
These sprint plans define the first implementation path for a Python-facing
adapter package that depends on sc-composer while keeping sc-composer a
pure Rust library and keeping reporting plus observability APIs out of the
initial Python scope.
Status:
- complete: all eight D-track sprints and the phase-ending fixes passed QA and merged into the main development line
Sprint entries:
- Sprint D.1 — Multi-Pass Library Foundation
- Sprint D.1-py — Python Bindings — Multi-Pass Library Foundation
- Sprint D.2 — Multi-Pass Composition Pipeline
- Sprint D.2-py — Python Bindings — Multi-Pass Composition Pipeline
- Sprint D.3 — Multi-Pass CLI Surface
- Sprint D.3-py — Python Bindings — Multi-Pass CLI Surface Parity Check
- Sprint D.4 — template-init + verify
- Sprint D.4-py — Python Bindings — template-init + verify
- Phase D README
These sprint plans define the first implementation path for multi-pass
stacked-header template rendering in sc-composer and sc-compose,
closing 10 of the 11 gaps identified in the prototype gap analysis
(prototype/multipass/docs/gaps.md). GAP-4 (Renderer::with_delimiters)
was already closed by Phase C.2.
Status:
- complete: B11 through B15 cleanup sprints landed and their findings are
closed in
docs/issues-inventory.md
Sprint entries:
- Sprint B11 — Contract-Alignment
- Sprint B12 — JSON Surface Hardening
- Sprint B13 — Observability Panic Removal
- Sprint B14 — CLI Extraction
- Sprint B15 — Reporting Runtime Cleanup
- Issues Inventory
These sprint plans target integrate/phase-B follow-on cleanup work. They do
not change the completed Phase B execution record; they capture the next
implementation slices needed to close the remaining production-readiness gaps.
The accepted cleanup findings and sprint ownership are tracked in
docs/issues-inventory.md.
Status:
- complete: E.1 through E.3 delivered recursive structured inputs and the adversarial rendering validation workflow
Sprint entries:
- Phase E plan
- Sprint E.1 — Recursive Structured Input Support
- Sprint E.2 — Adversarial Fuzzing Workflow
- Sprint E.3 — First Adversarial Campaign And Regression Closure
- Sprint 157 — Multi-Agent Fuzz-Session Report Template
- Sprint — Top-Level Report Shell Template
- Sprint — Per-Report Artifact Subdirectory Layout
E.1 changes the runtime input contract, E.2 defines the multi-agent QA workflow, E.3 proves that workflow against the expanded contract, and Sprint 157 defines the single-page multi-panel report package emitted by a session.
Status:
- complete on
integrate/phase-fat0360fb790fdc52541d6ff4e3faebd0618b2ff370; PRs #174-#178 are merged and format, clippy, manifest-validation, workspace tests, and Python-wheel CI checks are green on macOS, Ubuntu, and Windows.
Sprint entries:
| ID | Sprint | Status | Branch | Worktree |
|---|---|---|---|---|
| F.1 | CLI Input Parsing and JSON Capability Seams | complete | sprint/f-1-cli-input-parsing |
/Users/randlee/Documents/github/sc-compose-worktrees/sprint/f-1-cli-input-parsing |
| F.2 | Main Dispatch Runner and Process Boundary | complete | sprint/f-2-main-dispatch-runner |
/Users/randlee/Documents/github/sc-compose-worktrees/sprint/f-2-main-dispatch-runner |
| F.3 | CLI Integration Test Decomposition | complete | sprint/f-3-integration-test-decomposition |
/Users/randlee/Documents/github/sc-compose-worktrees/sprint/f-3-integration-test-decomposition |
| F.4 | Var-File Decode and Validation Split | complete | sprint/f-4-var-file-decode-split |
/Users/randlee/Documents/github/sc-compose-worktrees/sprint/f-4-var-file-decode-split |
| F.5 | Observer Typed Event Builder | complete | sprint/f-5-observer-event-builder |
/Users/randlee/Documents/github/sc-compose-worktrees/sprint/f-5-observer-event-builder |
F.1 through F.5 convert the five findings from the read-only Repowise review into one-file-or-boundary-owned implementation sprints. They preserve the sc-composer pure-library boundary, the Python adapter boundary, and the standalone observability dependency direction.
Required Phase F merge order:
F.1 -> F.2 -> F.4 -> F.5 -> F.3- F.2, F.4, and F.5 must rebase onto the preceding sprint's merged
developstate before implementation. F.3 is deliberately last because it decomposes the sharedtests/cli.rsandtests/json_cli.rssuites after all earlier sprints' test additions have landed.
Unnumbered Phase F follow-on work:
- Add a text/JSON equivalence matrix after F.3; it is intentionally not part of F.3's closed decomposition scope or acceptance gate.
- The canonical
.claude/skills/codex-orchestration/sprint-plan.md.j2tooling defect was fixed by the follow-on FIX-238 sprint. The parser now preserves adjacent rendered-document frontmatter containing Jinja syntax as template body, and the canonical template validates and renders end to end.
Status:
- complete: a known-template, XML-first
sc-compose extractfeature informed by prior reverse-extraction research, with Python as a first-class customer surface. G.1 through G.7 landed; the G.6 adversarial-evidence campaign reports all required gates PASS with no unresolved candidates.
Sprint entries:
- Phase G plan
- Sprint G.1 — Extraction Contract and Analysis Model
- Sprint G.2 — Deterministic XML Extraction Engine
- Sprint G.3 — Python Extraction Bindings
- Sprint G.4 — CLI Extract Surface
- Sprint G.5 — Corpus and Regression Closure
- Sprint G.6 — Adversarial Evidence and Hardening
- Sprint G.7 — Reject Dotted Extraction Expressions
Phase G is intentionally narrower than a general inverse-Jinja feature. It starts with known-template XML extraction, gives the first customer a Python binding over the same library semantics, reports unsupported or ambiguous constructs instead of fabricating values, and leaves unknown-template identification, JSON/Markdown adapters, loop reconstruction, and typed-value recovery as separately planned follow-on work.
Status:
- complete closure of the in-scope real-customer reverse-extraction gaps recorded in issue #193; H.1's contract and H.2 through H.8 implementation, parity, corpus, hardening, and closure gates are complete
- H.7 owns the promoted JSON/YAML depth-diagnostic hardening and the related release-registry documentation updates
- H.8 owns the phase-ending remediation and production-readiness gate for the remaining YAML, TOML, diagnostic, documentation, and evidence findings
Sprint entries:
- Phase H plan
- Sprint H.1 — Reverse Extraction Format Contract
- Sprint H.2 — JSON Extraction Core
- Sprint H.3 — JSON Cross-Surface Parity
- Sprint H.4 — YAML Extraction
- Sprint H.5 — TOML Extraction
- Sprint H.6 — Cross-Format Corpus and Adversarial Closure
- Sprint H.7 — Alias and Input-Limit Hardening
- Sprint H.8 — Phase-Ending Review Remediation
Disambiguation: the completed Phase HTML-Report (H1-H4) section above uses
undotted H1/H2/H3/H4 labels for the HTML-Report feature family. The Phase H
section here uses dotted H.1–H.8 identifiers for reverse-extraction extension
sprints; these are separate phases and sprint sequences.
Status:
- completed Phase I work for the remaining XML extraction gaps from issue #193, the strict-validation loop-context gap in issue #167, and the YAML var-file merge-key safety gap in issue #166;
- I.1 Contract, Raw-Text Semantics, and Traceability: complete/accepted on
sprint/i-1-contract-and-traceabilityat6604de7(docs-only contract gate); - I.2 Customer-Facing Raw-Text Mode: complete/accepted on
sprint/i-2-customer-raw-text-modeatac6d62f, with Rust, CLI, Python, and Markdown/text evidence; - I.3 XML Block and Mixed-Content Extraction: complete/accepted on
sprint/i-3-xml-block-mixed-contentata3c0ce1after the QA remediation pass; - I.4 XML Dirty-Prefix Normalization: complete on
sprint/i-4-xml-dirty-prefixatf3dca07, with Rust, CLI, Python, and boundary evidence; - I.5 Jinja Loop-Context Built-ins: complete/accepted on
sprint/i-5-loop-context-builtinsat8cde64d, with QA-2 PASS 10/10 and strict validation evidence; - I.6 YAML Merge-Key Var-File Safety: complete on
sprint/i-6-yaml-merge-key-safetyate62cfea/1232c8d, with fail-closed Rust/CLI coverage, JSON and alias controls, and source-located diagnostics; - Phase I also makes the shared H raw-text matcher customer-facing for known Markdown/text templates because raw text is the product use case that the format adapters alone do not provide;
- I.1 is the contract and traceability gate. I.2 through I.6 are independent implementation tracks after that gate except that I.3 depends on I.2's public matcher seam. Independent sprint QA may proceed in parallel; no sprint is required to wait for an unrelated sprint's QA result.
Sprint entries:
- Phase I plan
- Sprint I.1 — Contract, Raw-Text Semantics, and Traceability
- Sprint I.2 — Customer-Facing Raw-Text Mode
- Sprint I.3 — XML Block and Mixed-Content Extraction
- Sprint I.4 — XML Dirty-Prefix Normalization
- Sprint I.5 — Jinja Loop-Context Built-ins
- Sprint I.6 — YAML Merge-Key Var-File Safety
- Phase I Backlog Cleanup
Status:
- all four behavior-preserving maintainability decomposition sprints are
merged into
integrate/phase-j(J.1 PR #228, J.2 PR #229, J.3 PR #230, and J.4 PR #231) - J.1 is independent; J.2 precedes J.3; J.4 follows J.2 and J.3
- all four are full implementation sprints with the complete Phase J validation checklist, not planning/design sprints
Sprint entries:
- Phase J plan
- Sprint J.1 — CLI Argument and Pass-Input Seams
- Sprint J.2 — Validation State and Context Assembly
- Sprint J.3 — Validation Policy and Required-Path Diagnostics
- Sprint J.4 — Frontmatter Parser and Normalizer Split
Status:
- complete: all eight behavior-preserving decomposition sprints from the
Repowise hotspot review in issue #311 (
sc/repowise-update2, 2026-08-07) are merged intointegrate/phase-kat2c2b875; - K.1, K.2, K.3, K.4, K.7, and K.8 are independently reviewable tracks; K.5 and K.6 are separately gated and should follow K.4 when practical;
- an out-of-order K.5 or K.6 start requires the sprint owner to record the K.4 export-stability check and the plan-gate reviewer to accept that evidence;
- if K.7 finds no safe seam, its QA-approved abandon-evidence record is the Phase K exit contribution in place of a merged decomposition, without a decomposition-completion claim;
- gate status: critical-plan-review (STEP3-R3) passed at
96c219cand the quality-mgr plan-gate review passed after consistency hardening ateacbd08; the phase-ending review and integrated validation passed at2c2b875; - closeout record: the four phase-status artifacts self-reference
final_commit: 2c2b875, the actual tip ofintegrate/phase-k; - the Python package metadata is aligned with the workspace release at
1.4.1; future releases should keepbindings/python/pyproject.tomlsynchronized withCargo.tomlthrough a release or CI consistency check; - all eight are implementation sprints, not planning/design sprints, and each requires full behavior-preserving validation regardless of gate status.
- issue disposition is tracked as
PHK-CLEANUP-001indocs/issues-inventory.md; the architecture decision and boundary artifacts are ADR-0015, phase-k-boundary-contract.md, and phase-k-boundaries.json.
Sprint entries:
- Phase K plan
- Sprint K.1 — XML Extraction Decomposition
- Sprint K.2 — Compose Command Orchestration
- Sprint K.3 — Var-File Decoding and Validation
- Sprint K.4 — Diagnostic Schema and Envelope
- Sprint K.5 — Error-Family Modules
- Sprint K.6 — Include Expansion Seams
- Sprint K.7 — Template Discovery Seams
- Sprint K.8 — Report Output Materialization
Status:
- complete: all seventeen sc-lint integration sprints are merged into
integrate/phase-lat904d8dd; - L.1 (PR #329, fix #330) bootstrapped the pinned sc-lint 0.4.0 release, canonical package boundaries, and the reusable CI setup contract; L.2 (PR #331, cleanup #332) landed the shared sc-lint runner, reporting contract, and Just integration that every later target sprint reuses;
- L.3 through L.11 (PRs #333, #335, #336, #337, #340, #338, #341, #342, #343) integrated the sc-boundary, sc-portability, sc-runtime, line-counts, identity-literals, view-findings, check-native, check-xwin, and clippy-native targets independently, each following the L.2 runner contract;
- L.12 through L.16 (PRs #344, #345, #346/#350, #348, #349) integrated the
clippy-xwin target and the lint-fast/lint-full/lint-ci/ci composite
profiles; this group surfaced and closed out the phase's recurring
cross-cutting defect classes: incomplete
PYTHON_TOOLSfixture lists insc_lint_lint_full.rs(QM-L14-002, QM-L14-004), a macOS PEP 668 externally-managed-Pythonpip install codespellregression shared by L.13/L.15 (QM-L13-002, QM-L15-002), and a windows-latest raw-string escaping compile failure insc_lint_ci.rs'swrite_fake_cargo()(QM-L16-003); - L.14's original PR #346 auto-closed as merged when its head branch
converged with PR #349's identical commit; its actual closing fix
(QM-L14-004) landed via the follow-up PR #350 opened directly against
integrate/phase-l; - L.17 (PR #351) is a documentation/external-coordination-only sprint —
cargo test --workspaceis explicitly not a closure gate for it — and producedsc-lint-script-packaging-inventory.mdplus randlee/sc-lint#86, scoped against the pre-existing randlee/sc-lint#83; - every merge in this phase required an explicit quality-mgr QA PASS with live-CI re-verification (not local-review-only) before merge, per the standing merge-gate rule; no sprint bypassed this gate.
Sprint entries:
- Phase L plan
- Sprint L.1 — sc-lint Repository and Tool Bootstrap
- Sprint L.2 — sc-lint Just and Report Integration
- Sprint L.3 — sc-boundary
- Sprint L.4 — sc-portability
- Sprint L.5 — sc-runtime
- Sprint L.6 — Line Counts
- Sprint L.7 — Identity Literals
- Sprint L.8 — View Findings
- Sprint L.9 — Check Native
- Sprint L.10 — Check Xwin
- Sprint L.11 — Clippy Native
- Sprint L.12 — Clippy Xwin
- Sprint L.13 — Lint Fast
- Sprint L.14 — Lint Full
- Sprint L.15 — Lint CI
- Sprint L.16 — Top-Level CI
- Sprint L.17 — sc-lint Script Packaging
Status:
- complete: M.1 (merged at
de2ade8) and M.2 (merged at47572e9) delivered the standalonesc-shacrate, thesc-sha-pythonadapter, and thesc-composerintegration; - ADR-0018 and the corresponding boundary rules are accepted, and the
implementation is present under
crates/sc-sha/andbindings/sc-sha-python/;sc-composerdelegates hashing tosc-sha.
Sprint entries:
- Phase M plan
- Sprint M.1 — sc-sha Core Crate
- Sprint M.2 — sc-compose Integration
- Sprint FIX-373 — Diamond Frontmatter Dedup
- Sprint FIX-374 — sc-sha Digest Error Code
- Sprint FIX-375 — ScShaError str
- Sprint FIX-385 — Template-Init JSON Round Trip
- Sprint FIX-390 — Clap Usage Exit Code
- Sprint FIX-SIMP-001 — Shared Template Suffix Helper
- Sprint FEAT-HELP-MANUAL-CORE — Core Help Manuals
- Sprint FEAT-HELP-MANUAL-TOPICS-1 — Group 1 Help Manuals
- Sprint FEAT-HELP-MANUAL-TOPICS-2 — Help Manuals: Workspace and Reports
Status:
- complete on
feat/help-manual-topics-1at73c68f7
Sprint entry:
FEAT-HELP-MANUAL-TOPICS-1 adds the six group-one feature manuals for render, resolve, validate, verify, extract, and template-init. Each document is embedded in the CLI's ordered help-topic registry and is also linked from the repository manual index.
Status:
- complete on
feat/help-manual-topics-2atfeb7ca6
Sprint entry:
FEAT-HELP-MANUAL-TOPICS-2 adds bundled manuals for frontmatter-init,
init, examples, templates, and reports, registering each page in the
CLI's deterministic help-topic index with matching command-level sanity tests.
Status:
- complete on
feat/help-manual-coreat final PR branch commit1d016d4; implementation and QA fixes are included in its history; the post-merge JSON-envelope deduplication follow-up is included in this branch. - CI checks for PR #397 are green for final branch commit
1d016d4, including the workspace and platform-specific checks; closeout evidence is recorded in the sprint document.
Sprint entry:
FEAT-HELP-MANUAL-CORE adds the CLI-owned bundled manual registry, the initial
exit-codes manual, and the sc-compose help discovery surface. Follow-on
feature sprints can add one markdown manual and one ordered registry entry at a
time.
Status:
- complete on
developafter PRs #397, #398, #399, and #396 merged. - N.1 established the CLI-owned
help_topicsregistry and initial manual; N.2 and N.3 added the remaining command manuals; PR #396 finalized the FR-22 requirement, parser collision rules, and text/JSON output schemas. - The merged registry now ships manuals for
exit-codes,render,resolve,validate,verify,extract,template-init,frontmatter-init,init,examples,templates,reports, andobservability-health. - Validation for the completed sequence passed
cargo fmt --all --check,cargo clippy --all-targets --all-features -- -D warnings, andcargo test --workspace.
Sprint entries:
- Sprint N.1 — Help-Manual Core Scaffolding (PR #397); complete.
- Sprint N.2 — Help-Manual Content, Group 1 (PR #398); complete.
- Sprint N.3 — Help-Manual Content, Group 2 (PR #399); complete.
- Follow-on plan gate — CLI Conceptual Help Manuals (PR #396); complete.
Status:
- complete: JSON escape-mode compatibility and fail-closed rendered-output validation, including the Phase O fix-sprint sequence through the 1.4.1 release metadata follow-up
- O.1 is the infrastructure sprint; O.2 and O.3 may execute in parallel after O.1 merges; O.4 migrates the six in-repo templates; O.5 is the release-corpus and fuzz closeout sprint. O.5 cross-repository migration disposition remains open under the documented release waiver.
- target:
integrate/phase-o
Sprint entries:
- Phase O plan
- Sprint O.1 — JSON Mode Contract
- Sprint O.2 — Checked Render Contract
- Sprint O.3 — Template Lint and Repository Target
- Sprint O.4 — Six-Template Migration and Compatibility Fixtures
- Sprint O.5 — Cross-Repository Release Corpus and Fuzz Gate
Status:
- complete: generated Go bindings for the standalone
sc-shacrate under issue #510, including the P.3 release-preparation metadata and consumer documentation; - P.1 establishes the pinned UniFFI /
uniffi-bindgen-goadapter, typed two-operation contract, generator-drift CI, and boundary amendments; - P.2 follows P.1 to publish the Go submodule/native artifact contract and
hand off integration evidence to
sc-doltand atm-core; - P.3 closes the Phase P release preparation by documenting the Go consumer
surface, bumping the workspace to
1.5.0, and closing the release metadata and boundary-rule gates; - Go bindings for
sc-composerand all rust2go work are explicitly estimated follow-ons, not Phase P delivery.
Sprint entries:
- Phase P plan
- Sprint P.1 — Generated sc-sha Go Adapter Contract
- Sprint P.2 — Go Module Distribution and Consumer Handoff
- Sprint P.3 — Phase P Release Preparation
Status:
- complete: Q.1 (sc-publish package parity), Q.2 (installed the canonical
publishing agents, workflows, scripts, actions, and channel templates),
Q.3 (consumed a further sc-publish develop update), and Q.4 (consumed the
release-candidate provenance update); sc-compose remains a consumer of
sc-publish, not its owner, and consumer updates do not modify internal sc-publish probe, workflow, or install logic; - in progress: Phase Q closeout resolves its final duplicate-logic QA
findings before
integrate/phase-qmerges todevelop; - production publication remains blocked until the installed package renders a complete manifest with the released sc-compose renderer and passes final preflight.
Sprint entries:
- Phase Q plan
- Sprint Q.1 — sc-publish Package Parity
- Sprint Q.2 — sc-compose Install and Publish Cutover
- Sprint Q.3 — Consume sc-publish Develop Update
- Sprint Q.4 — Consume sc-publish Release-Candidate Provenance Update
Status:
- in progress: Phase R is the ADR-0021-gated, host-neutral Beads formula-composition track; R.1 is complete and R.2 and R.3 may proceed in parallel;
- R.1 pre-source gate: ADR-0021 is accepted; the architecture, CLAUDE, and
sc-lint boundary inventories must record and enforce
sc-compose -> sc-composer-beads -> sc-composerandbindings/sc-composer-beads-python -> sc-composer-beadsbefore R.1 source is authored; - target:
integrate/phase-r
Sprint entries:
- Phase R plan
- Sprint R.1 — Beads contract and execution engine
- Sprint R.2 — Bead CLI and JSON protocol
- Sprint R.3 — Beads Python bindings
- FIX-BEADS-FUZZ-OUT-001 — Orphaned descendant output-cap containment
Status:
- planned: Phase S is the behavior-preserving hotspot remediation track based
on issue #572 and repowise evidence; it partitions safe private refactors
from intentionally vendored
sc-publishrelease-package copies; - target: one linear
gh stackrooted atintegrate/phase-s; the draft phase-integration PR is the only Phase S PR targetingdevelopand merges atomically with the reviewed sprint layers at phase close.
Sprint entries:
- Phase S plan
- Sprint S.1 — Extractor Internal Seams
- Sprint S.2 — Template Lint Seams
- Sprint S.3 — Checked Validation Seams
- Sprint S.4 — JSON Capability Seams
- Sprint S.5 — Boundary Invariant Guardrails
- Sprint S.6 — Diagnostics Facade Contract
- Sprint S.7 — Path Normalization Contract
- Sprint S.8 — Beads Runner Reliability
- ARM64.1 — ARM64 Linux CLI and Python Wheel Support Plan
- ARM64.2 — ARM64 Linux implementation (in review, PR #593): native
ubuntu-24.04-armCLI andsc-composewheel delivery, with Zig-basedmanylinux2014_aarch64wheel packaging and a separate non-sc-lint ARM64 validation job. Branch:feature/arm64-linux-support-impl.
Status:
- implementation complete on
fix/sc-lint-bootstrap-fixture-version-driftatc558613; awaiting PR #554 merge intodevelop
Sprint entry:
FIX-554 regenerates the sc-lint bootstrap fixture lockfile from the current
workspace patches and verifies that the committed lockfile matches an offline
Cargo metadata regeneration. It also hardens temporary Beads workspace cleanup
against transient Windows sharing violations.
Status:
- complete on
integrate/phase-oat4d37280via PR #438
Sprint entry:
FIX-O13 synchronizes the 1.4.1 README and changelog metadata and records the Phase O status accurately: implementation and fix-sprint work is complete, while the six-root O.5 migration disposition remains open under the release waiver.
Status:
- implementation complete on
fix/o15-composer-directive-inspection-api; awaiting PR and integration intointegrate/phase-o
Sprint entry:
FIX-O15 adds the narrow, parser-validated sc-composer API required by
atm-core to classify include, import, and from-import statements with exact
UTF-8 byte spans. It deliberately leaves target resolution and CLI/binding
surfaces to their owning consumers.
Status:
- complete on
integrate/phase-oatfda36d5via PR #434
Sprint entry:
FIX-434 added the O.6 CI template-contracts gate and its cross-platform validation coverage for the repository-level template lint target.
Status:
- in progress on
fix/491-hermetic-fixture-discoveryat22b8593, targetingdevelop
Sprint entry:
FIX-491 confines shared sc-lint integration-test utility discovery to an
explicit SC_LINT_SOURCE_ROOT or the repository-local pinned runtime. It
eliminates machine-dependent ancestor-checkout discovery while preserving the
CI provisioning contract.
Status:
- complete on
fix/390-clap-exit-code-fr7bat6528f67
Sprint entry:
FIX-390 aligns clap-originated usage failures with FR-7b by returning exit code
3 in both JSON and plain-text modes, while preserving exit code 0 for
--help and --version display requests.
Status:
- complete on
fix/390-followup-exit-code-source-of-truthatb045594
Sprint entry:
FIX-390-FOLLOWUP removes the duplicate exit-code computation from the clap parse-error path and synchronizes the FIX-390 completion commit reference.
Status:
- complete on
fix/simp-001-shared-suffix-helperat60c6df6
Sprint entry:
FIX-SIMP-001 centralizes the .j2, .jinja2, and .jinja suffix stripping
used by renderer auto-escape classification and template-init JSON detection
in the pure sc-composer crate, eliminating the duplicated heuristic without
changing either caller's behavior.
Status:
- complete on
fix/simp-001-followup-architecture-doc
Sprint entry:
FIX-SIMP-001-FOLLOWUP adds the template_ext module to docs/architecture.md
Section 4's module list, closing the ATM-QA-003 finding from FIX-SIMP-001 QA.
Status:
- complete on
fix/390-print-rendered-helperat8a014e9
Sprint entry:
FIX-390-PRINT-RENDERED-HELPER extracts a shared print_rendered helper in
report_cli_parse_error, removing the duplicated stderr/stdout print block
flagged by simplification-reviewer on FIX-390-FOLLOWUP QA (PR #393).
Status:
- complete on
fix/373-diamond-frontmatter-dedupatcc828b8
Sprint entry:
FIX-373 deduplicates the missing-frontmatter diagnostic for a
frontmatter-less leaf shared through a diamond-shaped include graph. The
existing is_new gate now covers resolved_files, source_texts, and
frontmatters, so the diagnostic is emitted once per canonical file while
distinct graph edges remain preserved.
Status:
- complete on
fix/375-scshaerror-stratb06b07d
Sprint entry:
FIX-375 gives ScShaError a readable string representation while preserving
the separate .code attribute used for error-code dispatch. Python callers
now receive the human-readable message from str(error) instead of the raw
(code, message) argument-tuple representation.
Status:
- complete on
fix/252-varfile-missing-dir-misclassifiedatbd8a748
Sprint entry:
FIX-252 routes missing and directory --var-file open failures through
ERR_CONFIG_READ with an InspectPath recovery hint, while preserving
ERR_CONFIG_PARSE for malformed content that was successfully read.
Status:
- complete on
fix/370-371-include-path-error-swallowingatf76700e
Sprint entry:
FIX-370-371 makes include resolution fall back from a relative candidate only for a genuine not-found error. Permission-denied and other filesystem errors now retain their original diagnostic and actual candidate path, preventing silent substitution from a same-named root-relative decoy.
Status:
- complete on
fix/frontmatter-parser-adjacent-delimiterat226ebbc
Sprint entry:
FIX-238 closes the canonical sprint-plan template regression in which an
adjacent rendered-document --- block containing Jinja syntax was incorrectly
parsed as a second YAML config block. Plain-YAML stacked headers remain
supported, while the canonical template now validates and renders with the
conditional worktree field both set and unset.
Status:
- complete on
fix/246-strict-ignores-custom-delimitersat0c7d90c
Sprint entry:
FIX-246 threads active custom variable delimiters through strict undeclared-
token validation. Literal default-delimiter text remains inert under custom
delimiters, while undeclared variables referenced through the active custom
delimiters now fail closed with ERR_VAL_UNDECLARED_TOKEN.
Status:
- complete on
fix/243-frontmatter-silent-data-lossat01a1e5c
Sprint entry:
FIX-243 preserves adjacent plain-YAML blocks with unrecognized top-level keys as template body while retaining recognized-key multi-pass stacking and the FIX-238 Jinja-syntax break behavior.
Status:
- complete on
fix/244-whitespace-control-phantom-dashatac7c139
Sprint entry:
FIX-244 strips delimiter-adjacent Jinja whitespace-control markers before token discovery without changing kebab-case variable support.
Status:
- complete on
fix/245-opening-delimiter-trailing-whitespaceat61aadec
Sprint entry:
FIX-245 accepts spaces and tabs after an opening --- delimiter before LF,
CRLF, or EOF, while preserving strict closing-delimiter matching and the
resulting ERR_CONFIG_PARSE for trailing-whitespace closing lines.
Status:
- complete on
fix/247-expand-file-stack-overflowat49cf5ad
Sprint entry:
FIX-247 caps the effective recursive include depth at 128 inside
expand_includes, preserving the public IncludeDepth API while ensuring
unreasonably deep include chains return ERR_INCLUDE_DEPTH instead of
overflowing the native stack.
Status:
- complete on
fix/251-io-error-collapse-not-foundat5f4b05e
Sprint entry:
FIX-251 distinguishes permission-denied, directory-target, and filesystem
symlink-loop failures from genuine not-found results at include and explicit
template resolution boundaries, while preserving existing invalid-data,
confinement, and not-found behavior. The follow-up also centralizes the
filesystem classification and makes directory-target handling independent of
Windows io::ErrorKind mappings.
Status:
- complete on
fix/248-err-config-parse-leaks-raw-yamlatc65ba50
Sprint entry:
FIX-248 removes the raw serde_yaml source attachment from frontmatter
syntax errors on the CLI text path while preserving the stable diagnostic
message, recovery hint, JSON envelope, and all other configuration-error
source handling.
Status:
- complete on
fix/249-path-confinement-existence-oracleat6aa2912
Sprint entry:
FIX-249 makes out-of-root resolver diagnostics independent of whether the
candidate exists, while preserving the normal not-found diagnostic for
lexically in-root missing paths. The implementation also handles macOS
/var//private/var temporary-directory aliases without weakening
confinement.
Status:
- complete on
fix/268-xml-format-autoescape-not-appliedat19953ad
Sprint entry:
FIX-268 preserves the existing filename-extension auto-escape convention on
the default single-pass, multi-pass, and custom-delimiter render paths. XML
and HTML templates now escape interpolated markup while non-markup templates
and the public in-memory render_all() API retain their unescaped behavior.
Status:
- complete on
fix/269-json-stdout-content-lossat352c91f
Sprint entry:
FIX-269 makes non-dry-run render --json stdout content observable through
the optional body payload field while preserving file-output and dry-run
payload shapes.
Status:
- complete on
fix/272-format-aware-escapingat0ccff88
Sprint entry:
FIX-272 adds filename-aware JSON escaping plus opt-in cdata_escape and
turtle_escape filters, while preserving existing HTML/XML behavior. The
plan-hardening CDATA fields now opt into safe CDATA splitting.
Status:
- complete on
fix/270-dict-get-method-unsupportedat6e61f7c(squash-merged via PR #281 todevelop)
Sprint entry:
FIX-270 adds a narrow project-owned Minijinja unknown-method callback for map
.get(key[, default]) calls. Missing keys return Undefined or the supplied
default, while unrelated methods, value kinds, and arities retain the original
unknown-method behavior.
Status:
- complete on
fix/242-undeclared-token-false-positivesateed3369(squash-merged via PR #282 todevelopat8992ad0)
Sprint entry:
FIX-242-271 removes false undeclared-token diagnostics for numeric
subscripts/slices, binary operator fragments, Jinja filter names, and simple
{% set %} locals while preserving real filter-argument references and
loop-context diagnostics outside active loops.
Status:
- complete on
fix/278-control-chars-survive-escape-filterat388c6d8
Sprint entry:
FIX-278 makes the shared HTML/XML/XHTML escaping formatter XML-character-safe
for forbidden C0 controls, adds the opt-in xml_char_safe filter, and covers
the XHTML filename dispatch alongside explicit and implicit escaping paths.
Status:
- complete on
fix/274-spoofed-frontmatter-delimiterat2145245
Sprint entry:
FIX-274 adds an opt-in frontmatter_safe filter for interpolated values in
frontmatter-shaped Markdown output. Standalone --- and ... lines are
neutralized without changing ordinary text or mid-line delimiter sequences;
the codex-orchestration sprint-plan template applies the filter to its title
fields.
Status:
- complete on
fix/275-markdown-table-pipe-escapeatb5d225c
Sprint entry:
FIX-275 adds the explicit md_table_safe filter for Markdown table cells. It
escapes literal pipes as \|, collapses embedded line breaks to spaces, and
leaves all other characters unchanged. The filter is opt-in so ordinary
Markdown text and existing auto-escape behavior remain unchanged.
Status:
- complete on
fix/273-array-typed-vars-accept-scalarsatcca8486
Sprint entry:
FIX-273 rejects present scalar and object values when a top-level required variable is consumed by a conservative bare-identifier for-loop, while preserving existing dotted-path validation and non-loop behavior.
Status:
- complete on
fix/276-yaml-colon-space-unescapedat75e51d9
Sprint entry:
FIX-276 adds the explicit yaml_safe filter for caller-controlled YAML
mapping values. It emits a double-quoted scalar with scoped escaping for
backslashes, quotes, and line-control characters, and applies the existing
frontmatter_safe delimiter protection before YAML quoting in the sprint-plan
template.
Status:
- complete on
fix/277-bytes-written-off-by-oneat07e4ca0
Sprint entry:
FIX-277 corrects JSON stdout render metadata to include the trailing newline emitted by the equivalent plain-mode stdout path. File output and dry-run metadata remain unchanged.
Status:
- complete on
fix/checked-render-format-normalization-parity
Sprint entry:
FIX-POSTMERGE-02 unifies JSON template-path classification across rendering, checked output validation, diagnostics, template lint, and template-init. The shared helper removes all recognized template suffixes case-insensitively so stacked suffixes and case variants receive the same JSON contract.
Status:
- complete
Sprint entry:
Branch:
refactor/render-request-real-module->develop
This completed cleanup replaces the render-request monolith with focused blocks, mode, request, vars, and test modules. The full workspace suite and standard Rust validation checks pass; the refactor is ready for independent regression QA.
Status:
- complete
Sprint entry:
Branch:
refactor/publish-manifest-real-module->develop
This completed cleanup replaces the publish-manifest monolith with focused archive, error, files, model, report, write, and test modules. The full workspace suite and standard Rust validation checks pass; the refactor is ready for independent regression QA.
- Undeclared-token diagnostics currently attribute the warning or error to the resolved root template path. Per-include-file attribution is deferred because it does not block correct render or validation behavior in the initial release.
ObservationSink::emit()remains an external extension point for host-owned sinks and adapters. Internal composition dispatch uses the typedCompositionObservercallbacks directly.- Release determinism is covered by the stable rendering pipeline and golden output tests, but the repo does not yet carry a dedicated two-invocation byte-for-byte integration test.
- CLI-to-log-file emission is covered by command and observer integration tests, but there is not yet a standalone seam test that asserts every command event reaches the final sink file on disk.
- Multi-panel HTML/XHTML report composition, wrapper-level open/app selection,
and any reusable post-render hook design remain follow-on work documented in
docs/html-sprint-report-plan.md. The shipped
Phase HTML-Report scope is limited to the structured-input model, the
bundled single-panel
sprint-report-htmlexample, and wrapper-owned HTML rendering integration.
GitHub issue #360 identified
the limits of the original content-only SHA model: identical content at
different canonical paths and transitive include changes needed distinct
identities. Phase M delivered the versioned composition fingerprint contract
with a deterministic dependency manifest and root composition_sha derived
from canonical paths, exact source bytes, ordered include edges, repeated
occurrences, and relevant render context. The implementation is owned by
sc-sha and consumed by sc-composer; no follow-on claim remains for the
original issue scope.
Status:
- planned
Branch:
TBD
Goals:
- unify the default examples and user-template directories under one stable
user-owned root:
~/.sc-compose/ - preserve
SC_COMPOSE_DATA_DIRandSC_COMPOSE_TEMPLATE_DIRoverride behavior exactly as it exists today - make installer-created directories and first-run diagnostics match the new unified user-data contract
Deliverables:
crates/sc-compose/src/template_store.rspub(crate) fn data_dir() -> Result<PathBuf>- preserves
SC_COMPOSE_DATA_DIR - changes the default fallback from install-relative
../share/sc-composeto~/.sc-compose
- preserves
pub(crate) fn user_templates_dir() -> Result<PathBuf>- preserves
SC_COMPOSE_TEMPLATE_DIR - changes the default fallback from the platform-specific user-data root to
~/.sc-compose/templates
- preserves
fn platform_user_data_dir() -> Option<PathBuf>- is simplified or removed if it no longer owns the examples/templates default-resolution path
release/homebrew/sc-compose.rb.j2- adds a
post_installblock that:- creates
~/.sc-compose/examples - copies bundled examples from
#{share}/sc-compose/examples/into~/.sc-compose/examples/ - creates
~/.sc-compose/templates
- creates
- adds a
- equivalent installer/runtime planning notes for other distribution paths so Homebrew is not treated as the only installer owning the unified user-data contract
- unit and integration tests covering:
- new default examples resolution
- new default templates resolution
- preserved env-override precedence
- clear first-run error messaging when the expected user-data dirs are absent
- docs updated so the default user-facing examples/templates locations point to
~/.sc-compose/
Explicit non-closure:
- no change to the meaning of
SC_COMPOSE_DATA_DIR - no change to the meaning of
SC_COMPOSE_TEMPLATE_DIR - no runtime writes into package-managed install prefixes
- no implementation of publish/reporting behavior in this sprint
Acceptance Criteria:
sc-compose examplesresolves bundled examples fromSC_COMPOSE_DATA_DIR/exampleswhenSC_COMPOSE_DATA_DIRis set- without
SC_COMPOSE_DATA_DIR,sc-compose examplesresolves from~/.sc-compose/examples sc-compose templatesresolves fromSC_COMPOSE_TEMPLATE_DIRwhenSC_COMPOSE_TEMPLATE_DIRis set- without
SC_COMPOSE_TEMPLATE_DIR,sc-compose templatesresolves from~/.sc-compose/templates - if the unified user-data dirs are missing on first run,
sc-composeemits a clear error that points users to~/.sc-compose/ - the Homebrew install path creates
~/.sc-compose/examples, populates it from packaged bundled examples, and creates an empty~/.sc-compose/templatesdirectory - no runtime fallback remains on install-relative
../share/sc-compose/examples/for default bundled-example discovery - tests cover the new defaults and the preserved env overrides on macOS, Linux, and Windows path conventions
Required Validation:
cargo fmt --all --checkcargo test --workspacecargo clippy --all-targets --all-features -- -D warnings
Status:
- completed
Branch:
chore/version-bump-1.0.0->develop
Goals:
- finalize the first standalone
1.0.0release path forsc-composerandsc-compose - add release-control infrastructure that prevents accidental duplicate publish
- make Homebrew,
winget, and packaged GitHub Release installs match the documented examples-discovery contract
Deliverables:
- completed as specified in docs/publishing.md
Acceptance Criteria:
- workspace and crate manifests are updated to
1.0.0 - release workflow archives ship
bin/sc-composeandshare/sc-compose/examples/... .github/scripts/release_artifacts.pyenforces release ancestry plus unpublished-version checks- release preflight verifies unpublished crate versions before release
- release workflow publish steps are idempotent when crates are already live
- Homebrew automation updates
randlee/homebrew-tapfrom the checked-in formula template wingetautomation and supporting docs are present forrandlee.sc-compose- publishing docs and operator guidance are aligned with the first standalone
1.0.0release path
Exit Gate:
SC-RELEASE-ENG-QA-001passed as the Sprint S8 exit gate
Status:
- completed
Branch:
feat/examples-command->develop
Goals:
- ship a small, reviewable starter set of bundled example files with the tool
- add a user-managed templates surface in the same sprint so created or custom templates are immediately usable
- support short named-render UX through command namespaces rather than a longer explicit render subcommand
- broaden the input model enough to support array/list-driven examples without expanding into hooks or manifest-owned execution logic
Deliverables:
- repo-root
examples/directory with flat starter example files:hello.md.j2frontmatter-demo.md.j2service-config.yaml.j2agent-task-branching.xml.j2pytest-fixture.py.j2
- user templates stored as one subdirectory per template under the user templates root
- optional
template.jsonfor user template directories carrying only:descriptionversioninput_defaults
sc-compose examples list- discovers bundled example files through
SC_COMPOSE_DATA_DIR/examplesfirst - falls back to install-relative
../share/sc-compose/examples/ - lists bundled example files in text or JSON form
- discovers bundled example files through
sc-compose examples <name>- implicitly renders the flat example file matching the requested name
- uses the same render flags and output behavior as
render
sc-compose templates list- lists user template packs from
SC_COMPOSE_TEMPLATE_DIRor the platform user-data directory joined withsc-compose/templates/
- lists user template packs from
sc-compose templates add <src> [name]- adds a user template pack from either a single file or a directory source
- uses
[name]when provided - otherwise uses the source directory name for directory input or the normalized template filename for file input
- fails if the destination pack name already exists
sc-compose templates <name>- implicitly renders the single root-level
*.j2file in the named user pack
- implicitly renders the single root-level
- a lightweight
README.mdin the user templates root documenting:- where user templates live
- the one-template-per-directory convention
- the
templates addandtemplates <name>workflow
- input-model expansion from scalar-only values to:
- scalar values
- simple arrays/lists of scalar values
- precedence updates so named-render pack defaults merge as:
- explicit input variables
- environment-derived variables
- user-template
template.jsoninput_defaults - frontmatter defaults
- packaging/install documentation for:
- Homebrew
#{prefix}/share/sc-compose/examples/ - Windows and other system installs using the same relative share layout
- manual
SC_COMPOSE_DATA_DIRoverride for CI and custom installs - the default user template root and
SC_COMPOSE_TEMPLATE_DIRoverride
- Homebrew
- tests for:
- bundled example root resolution
- user template root resolution
- examples/templates listing
- templates add
- named render for single-template packs
- array/list inputs through frontmatter defaults, user-template
template.jsoninput_defaults, and--var-file
Example design rules:
- examples should be immediately understandable without reading the source code
- each example should remain understandable from frontmatter, filename, and minimal inline guidance when needed, without polluting the primary rendered output
- the starter set should cover:
- minimal rendering
- frontmatter/defaults/validation behavior
- practical multi-variable configuration generation
- branching task/agent prompt generation
- code-generation scaffolding for pytest
- the pytest example should exercise real array/list inputs rather than a scalar text-block workaround
- v1 named render resolves flat example files by stem and user templates by
the single root-level
*.j2file inside the named template directory
Explicit deferral:
- do not add
prepare-hook,post-render-hook, or any other pack-executed hook model - do not add manifest-owned entrypoint selection, hook declarations, or other
code-driving fields to
template.json - do not add template deletion, update, sync, or remote registry features
- do not add implicit named render for packs with multiple root-level
*.j2candidates
Acceptance criteria:
- all five starter example files exist and are review-ready
sc-compose examplesauto-finds bundled example files from install-relative share layout orSC_COMPOSE_DATA_DIR/examplessc-compose templatesauto-finds the user template root fromSC_COMPOSE_TEMPLATE_DIRor the platform user-data directory joined withsc-compose/templates/examples list,examples <name>,templates list,templates add, andtemplates <name>work on macOS, Linux, and Windows path conventions- the user templates root includes a concise
README.mddescribing the supported workflow and directory convention - array/list inputs work through
--var-file, frontmatter defaults, and user-templatetemplate.jsoninput_defaults template.jsonremains a user-facing metadata/defaults file rather than a manifest that drives alternate execution logictemplates addstores file sources as<user-template-root>/<pack-name>/<original-file>and directory sources as<user-template-root>/<pack-name>/...- packager instructions are explicit enough for system package installs and user-template discovery
Status:
- completed
Phase goal:
- broaden
sc-composeinto a strong structured HTML report generator without moving wrapper-owned browser/display behavior into the core tool.
Release blocker inventory:
| ID | Blocker | Status | Sprint | Closure condition |
|---|---|---|---|---|
| HRB-01 | The current input model cannot express structured records such as PR objects and nested field access. | Closed — PR #45, 2280bd1. All 11 H1 acceptance tests pass including frontmatter_defaults_accept_object_value (crates/sc-composer/src/lib.rs:166), render_accepts_object_values_in_json_var_file (crates/sc-compose/tests/cli/render.rs:2165), and template_json_object_input_defaults_obey_precedence (crates/sc-compose/tests/cli/templates.rs:634). |
H1 | Object/map input values render end-to-end with stable field-path diagnostics. |
| HRB-02 | The current input model cannot express repeated report sections as arrays of structured records. | Closed — H2 implements arrays-of-objects ingress and loop-body discovery; E.1 removes the historical nested-array restriction with recursive validation and regression coverage. | H2/E.1 | Recursive arrays and arrays of objects render, validate, and support loop-body discovery end-to-end. |
| HRB-03 | There is no bundled HTML report example proving sc-compose can generate a useful clickable report artifact. |
Closed — H3 adds examples/sprint-report-html.html.j2, realistic sample vars, and named-render coverage for sprint-report-html.html.j2 -> sprint-report-html.html. |
H3 | sprint-report-html renders a self-contained HTML report from realistic structured input. |
Description:
- expand the value model from scalars and arrays of scalars to include object/map values with string keys.
FRs addressed:
- FR-12
Deliverables:
- object/map values accepted through
--var-fileJSON and YAML input - object values accepted in frontmatter defaults
- object values accepted in
template.jsoninput_defaults - nested field access documented for Jinja templates
- stable diagnostics for malformed objects and missing nested fields:
ERR_VAL_OBJECT_SHAPEERR_VAL_SHAPE_MISMATCHERR_VAL_MISSING_NESTED_FIELD
- explicit top-level replacement semantics for structured defaults; no deep merge
- explicit top-level extra-variable policy for structured inputs
- the former negative-shape tests were replaced by recursive acceptance coverage:
crates/sc-composer/src/types.rs::validate_input_value_accepts_recursive_arrays_and_objectscrates/sc-compose/tests/cli/render.rs::render_accepts_recursive_values_in_yaml_var_filecrates/sc-compose/tests/cli/render.rs::render_accepts_recursive_values_in_frontmatter_defaultscrates/sc-compose/tests/cli/templates.rs::templates_named_render_accepts_recursive_values_in_template_json_defaults
Acceptance Criteria:
- object values render end-to-end through
--var-file - object values work through frontmatter defaults and
template.jsoninput_defaults - missing nested fields reference stable field paths such as
pr.number - structured defaults are replaced, not merged, at the top-level boundary
- unit tests (
sc-composer) cover:validate_input_value_accepts_serde_json_objectinput_value_from_yaml_mapping_becomes_objectfrontmatter_defaults_accept_object_valuerequired_variable_path_pr_number_is_satisfied_by_object_inputmissing_nested_field_reports_err_val_missing_nested_fieldshape_mismatch_reports_err_val_shape_mismatchstructured_defaults_replace_without_deep_mergeextra_nested_fields_are_ignored_by_top_level_extra_input_policy
- integration tests (
sc-compose) cover:render_accepts_object_values_in_json_var_filerender_accepts_object_values_in_yaml_var_filetemplate_json_object_input_defaults_obey_precedence
Exit Gate:
- object-input behavior is specified in
requirements.mdandarchitecture.md - automated tests covering object input paths pass
- no open blocker remains against FR-12
quality-mgrsprint_review passes with no blocker findings
Description:
- extend the structured-input model so repeated report sections can be modeled as arrays of records.
FRs addressed:
- FR-13
Deliverables:
- arrays of objects accepted through
--var-file - arrays of objects accepted in frontmatter defaults
- arrays of objects accepted in
template.jsoninput_defaults - loop-body field access in Jinja templates
- scope-tracker chosen over a MiniJinja AST dependency for loop-body
discovery; the decision is documented in
architecture.mdsection 21.5 - frontmatter-init discovery for nested references inside loop bodies
- the historical H2 nested-array restriction is superseded by ADR-E1; the current phase index names the implementation Sprint E.1 to avoid colliding with the completed multi-pass Phase D identifiers
- unit and integration tests for arrays of objects
Acceptance Criteria:
- arrays of objects render end-to-end through Jinja loops
- frontmatter-init discovers loop-body variable references from array members
- recursive arrays, nested arrays of objects, and jagged arrays render through the E.1 recursive-value contract without emitting the reserved legacy code
- at least 10 tests cover arrays-of-objects behavior and failure cases
- the
sprint-report-htmlinput shape is representable by the implemented value model
Exit Gate:
- all H2 deliverables complete
- the loop-body discovery spike is documented in
architecture.mdsection 21.5 - automated tests covering arrays of objects pass
- no open blocker remains against FR-13
quality-mgrsprint_review passes with no blocker findings
Description:
- ship a self-contained single-panel HTML sprint report example that produces an immediately useful clickable artifact.
FRs addressed:
- FR-14
- FR-15
Deliverables:
- H3a (FR-14 implementation): reuse the existing
.j2suffix-stripping output path behavior already implemented bystrip_j2_suffix; H3 does not re-implement output-path logic - H3a adds:
- at least one integration test verifying
sprint-report-html.html.j2 -> sprint-report-html.html - an explicit safety note describing filename-aware automatic escaping and
limiting
| safeto trusted, pre-rendered HTML fragments
- at least one integration test verifying
- H3b (FR-15 content): bundled example at
examples/sprint-report-html.html.j2 - H3b keeps all template content inline in a single flat file; no
_includes/directory and no directory-based example pack - realistic sample vars file with PR and CI data
- self-contained HTML output with inline CSS and no external dependencies
- action links for:
- view PR
- view CI run
- merge URL
Acceptance Criteria:
sc-compose examples sprint-report-html --var-file examples/sprint-report-html.sample-vars.jsonworks end-to-end- rendered HTML is self-contained and browser-viewable
- rendered output includes working PR, CI, and plan/findings links from sample data
- the example clearly demonstrates why structured inputs are better than flattened prebuilt strings
Exit Gate:
- the bundled example renders successfully from realistic structured input
- design review confirms the example is a credible showcase artifact
- H3 remains a single flat example file with no bundled-example layout change
- no open blocker remains against FR-14 or FR-15 for the single-panel scope
quality-mgrsprint_review passes with no blocker findings
Description:
- connect the shipped single-panel HTML example to the wrapper workflow without
moving open/display behavior into
sc-compose.
H4 introduces no new functional requirements. All H4 work extends FR-12, FR-13, FR-14, and FR-15 with wrapper integration and final source-of-truth documentation. This is intentional.
Deliverables:
/sprint-reportskill update that selects the shipped HTML artifact and writes or optionally opens it from wrapper logic- architecture/docs update describing the wrapper-owned orchestration pattern
- explicit scoping language that multi-panel XHTML composition and any reusable post-render hook remain follow-on work, not H4 deliverables
Acceptance Criteria:
/sprint-report --htmlproduces the HTML report through wrapper-owned render orchestration- the wrapper path opens or writes the output without requiring hook execution
in
sc-compose - H4 keeps the bundled HTML artifact as the shipped single-panel example and does not redefine it into a multi-panel report
Exit Gate:
- wrapper integration works without changing
sc-composeinto a workflow orchestrator - quality review confirms the final single-panel HTML report flow is usable and maintainable
- all HTML-Report phase blockers are closed
quality-mgrsprint_review passes with no blocker findings
docs/traceability-matrix.mddocs/error-code-registry.mddocs/test-strategy.mddocs/html-sprint-report-plan.md
The current plan is the authoritative release plan for 1.4.1. Additional
post-1.4.1 design exploration must not silently rewrite the shipped contract.
The current follow-on design track is:
docs/html-sprint-report-plan.md- multi-panel HTML/XHTML sprint-report exploration beyond the shipped single-panel artifact,
- wrapper-level output viewing behavior such as
--openor application selection, - possible post-render-hook design exploration that remains outside the core
sc-composerenderer boundary unless explicitly accepted in a later phase.
docs/phase-A/phase-A-plan.md- reusable report-pack planning for multi-output bundles, shared XHTML panel
chrome, latest/archive output policy, publish-manifest handoff, and
sc-observability1.1.0adoption planning for the CLI logging layer
- reusable report-pack planning for multi-output bundles, shared XHTML panel
chrome, latest/archive output policy, publish-manifest handoff, and
docs/phase-A/sprint-A6.md- the sixth executable Phase A sprint, which defines latest/archive output
policy and the shared
just reportsaggregation and verification behavior
- the sixth executable Phase A sprint, which defines latest/archive output
policy and the shared
docs/phase-A/sprint-A7.md- the seventh executable Phase A sprint, which defines the machine-readable publish-manifest handoff from generated artifacts to CI or wrapper-owned publication steps
docs/phase-A/sprint-A1.md- the first executable Phase A sprint, which defines the generic report artifact contract and report catalog before any later report-family or panel-specific planning work closes out
docs/phase-A/sprint-A3.md- the third executable Phase A sprint, which defines the generic source-driven rendering contract for collection discovery, metadata extraction, render-many, and generated manifests
docs/phase-A/sprint-A4.md- the fourth executable Phase A sprint, which defines the typed semantic report-spec contract so Mermaid becomes one renderer or migration input instead of the long-term semantic source model
docs/phase-A/sprint-A8.md- the cross-use-case proof sprint, which demonstrates that the shared
reporting model must serve both
atm-corestyle multi-panel state-machine/SQL-query reports andsc-lintstyle lint/test/smoke evidence reports without changing the shared discovery or verification contract
- the cross-use-case proof sprint, which demonstrates that the shared
reporting model must serve both
docs/phase-A/sprint-A2.md- the second executable Phase A sprint, which defines the standard producer
command contract and reserves
just reportsfor shared aggregation, verification, and opening/viewing
- the second executable Phase A sprint, which defines the standard producer
command contract and reserves
docs/phase-A/sprint-A5.md- the fifth executable Phase A sprint, which defines shared template families, repo-local override points, and shared panel chrome with stable copy-action behavior
docs/phase-A/sprint-A9.md- the observability follow-on sprint, which upgrades
sc-composetosc-observability1.1.0, keeps direct logger integration, and adopts logger-managed retained-log maintenance defaults
- the observability follow-on sprint, which upgrades
Any follow-on sprint added after this plan must preserve the standalone boundary defined by:
docs/requirements.mddocs/architecture.mddocs/git-workflows.mddocs/publishing.md
docs/sprints/fix-beads-toml-formula-escaping.mddocs/sprints/fix-beads-legacy-json-null-depth.mddocs/sprints/fix-homebrew-publish-asset-shape.mddocs/sprints/cleanup-293-frontmatter-yaml-filter-chain.mddocs/sprints/cleanup-298-path-containment-centralize.mddocs/sprints/cleanup-294-validate-lint-mode.mddocs/sprints/cleanup-295-296-expansion-reuse.mddocs/sprints/cleanup-299-json-integer-guard-dedup.mddocs/sprints/cleanup-301-yaml-merge-key-scan.mddocs/sprints/cleanup-297-bare-loop-discovery.mddocs/sprints/cleanup-300-include-depth-wrapper.mddocs/sprints/fix-250-varfile-object-wording-inconsistent.mddocs/sprints/fix-252-varfile-missing-dir-misclassified.mddocs/sprints/fix-253-doubled-delimiter-error-message.mddocs/sprints/fix-254-varfile-negative-boundary-i128.mddocs/sprints/fix-283-unbound-variable-policy-noop.mddocs/sprints/fix-372-chained-ternary-dynamic-classification.mddocs/sprints/fix-386-cli-json-envelope-clap-bypass.mddocs/sprints/fuzz-beads-integration-campaign.mddocs/sprints/fix-beads-render-error-message.mddocs/sprints/fix-beads-nul-byte-argv-misattribution.md
The current follow-on implementation track is:
docs/phase-B/phase-B-plan.md- the implementation phase that turns the Phase A reporting contracts into a runnable shared system
docs/phase-B/sprint-B1.md- report artifact runtime and catalog
docs/phase-B/sprint-B10.md- built-in render context variables injected into every render context
- added during Phase B hardening to make render-context precedence and template metadata injection explicit before implementation dispatch
docs/phase-B/sprint-B2.md- producer recipes, report-init scaffold, and
justcommand surface
- producer recipes, report-init scaffold, and
docs/phase-B/sprint-B3.md- source collection, metadata extraction, and render-many runtime
docs/phase-B/sprint-B4.md- template families and shared panel chrome
docs/phase-B/sprint-B5.md- latest/archive output policy and reports aggregator
docs/phase-B/sprint-B6.md- publish manifest and CI handoff
docs/phase-B/sprint-B7.md- semantic diagram-spec runtime
docs/phase-B/sprint-B8.md- cross-use-case proof by implemented examples
docs/phase-B/sprint-B9.md- complete:
sc-observability1.2uplift landed and Phase B closeout docs/tests track the shipped surface
- complete:
docs/sprints/b11-contract-alignment.md- follow-on cleanup sprint for normative doc/API drift between Phase B
source-of-truth docs and the shipped
sc-composerAPI
- follow-on cleanup sprint for normative doc/API drift between Phase B
source-of-truth docs and the shipped
docs/sprints/b12-json-surface-hardening.md- follow-on cleanup sprint for remaining JSON and JSONL forward-slash path normalization plus Windows-sensitive coverage
docs/sprints/b13-observability-panic-removal.md- follow-on cleanup sprint for removing panic paths from production
observability code after the
sc-observability 1.2uplift
- follow-on cleanup sprint for removing panic paths from production
observability code after the
docs/sprints/b14-cli-extraction.md- follow-on cleanup sprint for oversized CLI module extraction and command ownership cleanup
docs/sprints/b15-reporting-runtime-cleanup.md- follow-on cleanup sprint for dead reporting seams, duplicated helper removal, and report-runtime scope tightening