|
| 1 | +Feature: Subflow Transition Overhaul |
| 2 | + |
| 3 | + The subflow mechanism (push/pop stack for nested flows) is completely |
| 4 | + non-functional for real flows due to two critical bugs in path resolution |
| 5 | + and exit handling. Additionally, the `next` command hides critical |
| 6 | + navigation information — trigger names, guarded transitions, and evidence |
| 7 | + requirements — making autonomous agent navigation impossible. |
| 8 | + |
| 9 | + This feature fixes the subflow mechanism, enhances `next` to show the |
| 10 | + complete navigation picture, and improves session command robustness. |
| 11 | + |
| 12 | + Depends on: session-management (core), session-management-extended. |
| 13 | + |
| 14 | + Status: ELICITING |
| 15 | + |
| 16 | + Rules (Business): |
| 17 | + - Flow references without `.yaml` extension are resolved by appending `.yaml` if the bare path doesn't exist |
| 18 | + - Subflow exit resolves through the parent flow's transition map, not by using the exit name directly |
| 19 | + - Subflow chaining: after exiting one subflow, if the resolved target enters another subflow, the stack is pushed again |
| 20 | + - `session init` auto-enters the initial subflow if the first state has a `flow:` field |
| 21 | + - `next` always shows ALL transitions including blocked/guarded ones, with status markers |
| 22 | + - `next` output shows trigger→target mapping with inline condition requirements |
| 23 | + - `next` JSON output uses `transitions` array of objects with `trigger`, `target`, `status`, `conditions` |
| 24 | + - `check --session <target>` correctly shows transition conditions |
| 25 | + - `states --session` and `validate --session` resolve the current flow from session |
| 26 | + |
| 27 | + Constraints: |
| 28 | + - Non-session commands remain backward compatible |
| 29 | + - `next` JSON output is a breaking change: `next` array of strings replaced with `transitions` array of objects |
| 30 | + - Domain layer (Session, SessionStackFrame) changes are minimal — fixes are in CLI/transition logic |
| 31 | + |
| 32 | + ## Questions |
| 33 | + |
| 34 | + | ID | Question | Status | Answer / Assumption | |
| 35 | + |----|----------|--------|---------------------| |
| 36 | + | Q1 | Should `next` show all transitions or require `--all` flag? | Resolved | Always show all — agents need the full picture | |
| 37 | + | Q2 | Should `next` JSON preserve backward compatibility? | Resolved | No — clean break, replace `next` array with `transitions` objects | |
| 38 | + | Q3 | Should `set-state` support crossing flow boundaries? | Open | Phase 3 — may add `--flow` flag for recovery scenarios | |
| 39 | + |
| 40 | + ## Changes |
| 41 | + |
| 42 | + | Session | Q-IDs | Change | |
| 43 | + |---------|-------|--------| |
| 44 | + | 2026-05-05 S1 | Q1-Q3 | Created: subflow resolution, exit handling, next overhaul, session robustness | |
| 45 | + |
| 46 | + Rule: Subflow Path Resolution |
| 47 | + As a flowr user |
| 48 | + I want flow references without file extensions to resolve correctly |
| 49 | + So that I can use clean flow names in YAML definitions |
| 50 | + |
| 51 | + @id:sf-001 |
| 52 | + Example: Flow reference without .yaml extension resolves correctly |
| 53 | + Given a flow YAML with `flow: discovery-flow` referencing a file `discovery-flow.yaml` |
| 54 | + When the CLI resolves subflows |
| 55 | + Then the subflow is loaded successfully |
| 56 | + |
| 57 | + @id:sf-002 |
| 58 | + Example: Flow reference with .yaml extension still works |
| 59 | + Given a flow YAML with `flow: child.yaml` referencing a file `child.yaml` |
| 60 | + When the CLI resolves subflows |
| 61 | + Then the subflow is loaded successfully |
| 62 | + |
| 63 | + Rule: Subflow Exit Resolution |
| 64 | + As a flowr user |
| 65 | + I want subflow exits to correctly resolve through the parent flow's transitions |
| 66 | + So that my session lands on the correct next state after completing a subflow |
| 67 | + |
| 68 | + @id:sf-003 |
| 69 | + Example: Subflow exit resolves parent transition target |
| 70 | + Given a session inside discovery-flow with stack frame pointing to main-flow/discovery |
| 71 | + And discovery-flow exits with `complete` |
| 72 | + And main-flow/discovery maps `complete → architecture` |
| 73 | + When the user transitions with the exit trigger |
| 74 | + Then the session pops the stack and lands at main-flow/architecture |
| 75 | + |
| 76 | + @id:sf-004 |
| 77 | + Example: Subflow chaining enters next subflow after exit |
| 78 | + Given a session exiting discovery-flow back to main-flow |
| 79 | + And the resolved target `architecture` has `flow: architecture-flow` |
| 80 | + When the subflow exit resolves to architecture |
| 81 | + Then the session pushes a new stack frame and enters architecture-flow |
| 82 | + |
| 83 | + @id:sf-005 |
| 84 | + Example: Subflow exit with invalid parent state produces error |
| 85 | + Given a session inside a subflow with a corrupted stack frame |
| 86 | + When the subflow exit cannot find the parent state |
| 87 | + Then the CLI prints a clear error indicating the parent state is invalid |
| 88 | + |
| 89 | + Rule: Session Init Enters Subflow |
| 90 | + As a flowr user |
| 91 | + I want session init to automatically enter the initial subflow |
| 92 | + So that I can start working immediately without an extra transition step |
| 93 | + |
| 94 | + @id:sf-006 |
| 95 | + Example: Session init auto-enters subflow when initial state has flow field |
| 96 | + Given a flow whose initial state has `flow: discovery-flow` |
| 97 | + When the user runs flowr session init main-flow |
| 98 | + Then the session is created inside discovery-flow with a stack frame pointing to main-flow |
| 99 | + |
| 100 | + @id:sf-007 |
| 101 | + Example: Session init without subflow works as before |
| 102 | + Given a flow whose initial state has no `flow:` field |
| 103 | + When the user runs flowr session init simple-flow |
| 104 | + Then the session is created at the initial state with no stack |
| 105 | + |
| 106 | + Rule: Next Shows Full Transition Map |
| 107 | + As a flowr user |
| 108 | + I want to see all transitions with trigger names, targets, and condition requirements |
| 109 | + So that I can navigate without reading raw YAML files |
| 110 | + |
| 111 | + @id:sf-008 |
| 112 | + Example: Next shows trigger→target mapping for all transitions |
| 113 | + Given a session at a state with transitions `needs_full_discovery → event-storming`, `needs_scope_only → scope-boundary` |
| 114 | + When the user runs flowr next --session |
| 115 | + Then the output shows each trigger name alongside its target state |
| 116 | + |
| 117 | + @id:sf-009 |
| 118 | + Example: Next shows blocked guarded transitions with condition hints |
| 119 | + Given a session at a state with a guarded transition requiring `committed_to_main_locally=verified` |
| 120 | + When the user runs flowr next --session without evidence |
| 121 | + Then the blocked transition appears with a marker showing the required evidence |
| 122 | + |
| 123 | + @id:sf-010 |
| 124 | + Example: Next shows passing guarded transitions |
| 125 | + Given a session at a state with a guarded transition requiring `committed_to_main_locally=verified` |
| 126 | + When the user runs flowr next --session --evidence committed_to_main_locally=verified |
| 127 | + Then the transition appears as passing/open |
| 128 | + |
| 129 | + @id:sf-011 |
| 130 | + Example: Next JSON output uses transitions array with full details |
| 131 | + Given a session at a state with transitions |
| 132 | + When the user runs flowr next --session --json |
| 133 | + Then the output contains a `transitions` array where each entry has `trigger`, `target`, `status`, and `conditions` |
| 134 | + |
| 135 | + Rule: Check Session Shows Conditions |
| 136 | + As a flowr user |
| 137 | + I want to check transition conditions from session mode |
| 138 | + So that I know exactly what evidence to provide |
| 139 | + |
| 140 | + @id:sf-012 |
| 141 | + Example: Check session with target shows transition conditions |
| 142 | + Given a session at a state with a guarded transition |
| 143 | + When the user runs flowr check --session <trigger-name> |
| 144 | + Then the output shows the conditions required for that transition |
| 145 | + |
| 146 | + Rule: Session-Aware States and Validate |
| 147 | + As a flowr user |
| 148 | + I want to list states and validate the current flow from session |
| 149 | + So that I can inspect my current (sub)flow context without specifying the flow name |
| 150 | + |
| 151 | + @id:sf-013 |
| 152 | + Example: States command with --session lists current flow's states |
| 153 | + Given a session inside architecture-flow |
| 154 | + When the user runs flowr states --session |
| 155 | + Then the output lists all states in architecture-flow |
| 156 | + |
| 157 | + @id:sf-014 |
| 158 | + Example: Validate command with --session validates current flow |
| 159 | + Given a session inside architecture-flow |
| 160 | + When the user runs flowr validate --session |
| 161 | + Then the output validates architecture-flow |
0 commit comments