feat(workflows): compose workflows with a unified execution tree - #4764
Open
markuswondrak wants to merge 1 commit into
Open
markuswondrak wants to merge 1 commit into
markuswondrak wants to merge 1 commit into
Conversation
Keep invocation results and workflow bindings on the same execution occurrence. Isolate fan-out contexts and resume persisted expansions through one executor. Assisted-by: OpenCode (model: gpt-6-astra, autonomous)
7 tasks
Contributor
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
Child step implementation exceptions are incorrectly converted into ordinary workflow failures and may be swallowed by continue_on_error.
Review effort: Balanced
Findings: 1
What changed in this PR
Introduces composable workflows backed by a unified, persisted execution tree.
Changes:
- Adds scoped workflow calls with typed inputs and declared outputs.
- Unifies execution, resume, fan-out, and nested-state persistence.
- Adds CLI reporting, documentation, and regression coverage.
| File | Description |
|---|---|
src/specify_cli/workflows/_commands.py |
Reports nested scopes and gates. |
src/specify_cli/workflows/_execution.py |
Implements tree-based execution. |
src/specify_cli/workflows/__init__.py |
Registers workflow steps. |
src/specify_cli/workflows/command_resume.py |
Documents crash recovery. |
src/specify_cli/workflows/command_status.py |
Displays composed scopes. |
src/specify_cli/workflows/composition.py |
Handles workflow boundaries. |
src/specify_cli/workflows/engine.py |
Integrates persistence and execution. |
src/specify_cli/workflows/step/gate/__init__.py |
Normalizes gate messages. |
src/specify_cli/workflows/step/workflow/__init__.py |
Defines the workflow step. |
tests/specify_cli/workflows/test_command_status.py |
Tests composed CLI lifecycle. |
tests/workflows/test_composition_execution.py |
Covers composition and resume. |
design/workflow-step.md |
Updates execution guidance. |
docs/reference/workflows.md |
Documents composition semantics. |
workflows/ARCHITECTURE.md |
Describes the execution tree. |
workflows/PUBLISHING.md |
Adds workflow-step validation guidance. |
workflows/README.md |
Lists the new step type. |
💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Comment on lines
+486
to
+492
| outcome, error = self.run( | ||
| node["children"][0], | ||
| child_context, | ||
| (*ancestry, target), | ||
| path=(*path, "workflow"), | ||
| public=False, | ||
| ) |
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Summary
Reimplements workflow composition from main (
c00dc055) with one persisted execution tree and one executor. Replaces #4724 and implements the scoped single-run contract approved in #4680 (comment).Closes #4680.
Included workflows receive private, strictly bound inputs and return only declared outputs alongside workflow/status/error metadata. Targets must exactly match safe, installed, enabled IDs in the current project. Bound overlay-resolved definitions survive resume, cycles are path-based, and included depth is limited to 16.
Why replace #4724
The previous implementation accumulated separate scope identities, result keys, cursor state, snapshot files, and execution paths. Its latest review identified a real fan-out isolation bug: nested calls had distinct scope keys but shared the caller-result alias.
Each execution occurrence now owns its result, children, and workflow binding. Authored step IDs are local expression aliases; concurrent items have independent contexts. Persistence and resume follow the same tree.
The replacement includes 702 added test lines. Existing tests on main are retained.
Architecture and compatibility
_execution.pyowns tree traversal, resume, control flow, workflow scope entry, validation, and reporting projections.composition.pyowns target resolution and typed boundaries, reusing existing input coercion.engine.pykeeps public lifecycle and RunState persistence, replacing the previous execution loops with thin adapters.Evidence
test_concurrent_nested_calls_keep_downstream_aliases_localwas run against #4724 commit7ece7a16using an isolated import path. It failed with consumed outputs{1: 1, 2: 1}instead of{1: 1, 2: 2}. The same case passes here.45 focused cases cover concurrent downstream consumption, scoped outputs, frozen branch/custom expansion resume, loops and fan-out, terminal sibling reuse, stable definitions, strict target/input/output rejection, cycles/depth, output-finalization retry, malformed checkpoints, checkpoint/log failures, and legacy adaptation. A CLI integration case exercises run → nested gate status in JSON and human formats → resume.
Test selection reasoning
Results
.venv/bin/python -m pytest tests -q: 8,435 passed, 212 skipped, 4 failed in 328 seconds. All four failures also reproduce against clean mainc00dc055: preset-update missing-argument wording and three checksum tests expecting English FAILED under a German locale. All workflow tests pass in the full run.git diff --checkpasses.AI disclosure
Implemented and submitted on behalf of @markuswondrak by OpenCode, model gpt-6-astra (
github-copilot/gpt-6-astra), in autonomous mode with user-directed scope. AI assistance covered decision-history research, planning, source code, tests, documentation, regression reproduction, automated validation, commit/push, and this fully AI-drafted PR description. Human line-by-line review or manual testing is not attested. This rewrite incorporates requirements and findings from the AI-assisted implementation and review history in #4724.