diff --git a/.flowr/flows/architecture-flow.yaml b/.flowr/flows/architecture-flow.yaml index 90e6cd2..5a830c9 100644 --- a/.flowr/flows/architecture-flow.yaml +++ b/.flowr/flows/architecture-flow.yaml @@ -1,5 +1,5 @@ flow: architecture-flow -version: 4.0.0 +version: 5.0.0 exits: - complete - needs_discovery @@ -9,6 +9,7 @@ states: attrs: description: "SA evaluates whether the feature requires new architecture or fits the existing system, potentially overriding deployment decisions" owner: SA + git: main skills: - assess-architecture in: @@ -54,6 +55,7 @@ states: attrs: description: "SA maps bounded context relationships, integration points, and anti-corruption layers" owner: SA + git: main skills: - map-contexts in: @@ -74,6 +76,7 @@ states: attrs: description: "SA designs the technical solution — architectural style, stack, module structure, API/event contracts, interface definitions — and updates the system overview" owner: SA + git: main skills: - design-technical-solution in: @@ -107,6 +110,7 @@ states: attrs: description: "SA documents architecturally significant decisions as ADRs and records key decisions and active constraints in system.md" owner: SA + git: main skills: - draft-adr in: @@ -128,6 +132,7 @@ states: attrs: description: "R independently verifies architecture alignment with domain model and requirements, and cross-document consistency, before implementation begins" owner: R + git: main skills: - review-architecture in: @@ -139,7 +144,17 @@ states: - domain_model.md - glossary.md out: [] + conditions: + architecture_approved: + alignment: ==domain_model_verified + adr_compliance: ==adrs_respected + committed_to_main_locally: + committed_to_main_locally: ==verified next: - approved: complete + approved: + to: complete + when: + - architecture_approved + - committed_to_main_locally inconsistent: architecture-assessment needs_discovery: needs_discovery \ No newline at end of file diff --git a/.flowr/flows/branding-flow.yaml b/.flowr/flows/branding-flow.yaml index 051c96c..3324a81 100644 --- a/.flowr/flows/branding-flow.yaml +++ b/.flowr/flows/branding-flow.yaml @@ -1,5 +1,5 @@ flow: branding-flow -version: 2.0.0 +version: 3.0.0 exits: - branded - cancelled @@ -9,6 +9,7 @@ states: attrs: description: "Interview stakeholder to establish brand identity: personality, visual metaphor, wording, and release naming" owner: Design Agent + git: main skills: - setup-branding in: [] @@ -25,6 +26,7 @@ states: attrs: description: "Select and validate a colour palette with WCAG contrast, dark-mode counterparts, and hue semantics" owner: Design Agent + git: main skills: - design-colors in: @@ -41,6 +43,7 @@ states: attrs: description: "Create logo and banner using favicon-first, monochrome-first, progressive-simplification process" owner: Design Agent + git: main skills: - design-assets in: @@ -55,7 +58,15 @@ states: logo_scalability: ==passes blur_passed: logo_blur_test: ==passes + assets_committed: + committed_to_main_locally: ==verified next: - approved: branded + approved: + to: branded + when: + - monochrome_passed + - scalability_passed + - blur_passed + - assets_committed revise: design-assets cancelled: cancelled \ No newline at end of file diff --git a/.flowr/flows/delivery-flow.yaml b/.flowr/flows/delivery-flow.yaml index 9110da0..fcbe68f 100644 --- a/.flowr/flows/delivery-flow.yaml +++ b/.flowr/flows/delivery-flow.yaml @@ -1,5 +1,6 @@ flow: delivery-flow -version: 4.0.0 +version: 5.0.0 +params: [feature_name] exits: - next-feature @@ -12,6 +13,7 @@ states: attrs: description: "PO validates business behavior against BDD scenarios and quality attributes" owner: PO + git: feature skills: - accept-feature - verify-traceability @@ -34,6 +36,7 @@ states: attrs: description: "SE squash-merges feature commits into local main and resolves any conflicts" owner: SE + git: main skills: - merge-local in: @@ -50,6 +53,7 @@ states: attrs: description: "PO decides whether to publish the accumulated batch as a PR or continue accumulating features on local main" owner: PO + git: main skills: - decide-batch-action in: @@ -63,6 +67,7 @@ states: attrs: description: "SE creates an administrative PR for changes already on local main" owner: SE + git: main skills: - create-pr in: diff --git a/.flowr/flows/development-flow.yaml b/.flowr/flows/development-flow.yaml index 23cf88d..6f9131e 100644 --- a/.flowr/flows/development-flow.yaml +++ b/.flowr/flows/development-flow.yaml @@ -1,5 +1,6 @@ flow: development-flow -version: 4.0.0 +version: 5.0.0 +params: [feature_name] exits: - done - needs_planning @@ -9,6 +10,7 @@ states: attrs: description: "SA creates the project skeleton — branch, package structure, port interfaces, aggregate root signatures — before any feature-specific stubs" owner: SA + git: feature skills: - structure-project in: @@ -28,8 +30,9 @@ states: - id: tdd-cycle attrs: description: "SE implements the feature through repeated RED-GREEN-REFACTOR cycles until all BDD examples pass" + git: feature flow: tdd-cycle-flow - flow-version: "^2" + flow-version: "^3" conditions: design_declared: yagni: ==no_premature_abstractions @@ -48,8 +51,9 @@ states: - id: review-gate attrs: description: "R independently verifies implementation across three tiers — design, structure, and conventions — before commit" + git: feature flow: review-gate-flow - flow-version: "^2" + flow-version: "^3" next: pass: commit fail: tdd-cycle @@ -58,6 +62,7 @@ states: attrs: description: "SE commits the reviewed, passing implementation with traceability to feature files" owner: SE + git: feature skills: - commit-implementation in: diff --git a/.flowr/flows/discovery-flow.yaml b/.flowr/flows/discovery-flow.yaml index d7aaecb..026f159 100644 --- a/.flowr/flows/discovery-flow.yaml +++ b/.flowr/flows/discovery-flow.yaml @@ -1,5 +1,5 @@ flow: discovery-flow -version: 3.0.0 +version: 4.0.0 exits: - complete @@ -8,6 +8,7 @@ states: attrs: description: "PO interviews stakeholders to understand pain points, business goals, and domain terms, then decides how much discovery is needed" owner: PO + git: main skills: - conduct-interview in: @@ -27,6 +28,7 @@ states: attrs: description: "DE facilitates an event storming workshop to surface domain events, commands, and aggregate candidates" owner: DE + git: main skills: - facilitate-event-storming in: @@ -44,6 +46,7 @@ states: attrs: description: "DE formalizes the ubiquitous language by defining domain terms into a glossary" owner: DE + git: main skills: - define-ubiquitous-language in: @@ -59,6 +62,7 @@ states: attrs: description: "DE formalizes candidates into proper bounded contexts, entities, relationships, and aggregate boundaries" owner: DE + git: main skills: - model-domain in: @@ -81,6 +85,7 @@ states: attrs: description: "PO defines what the product IS and IS NOT, who the users are, and the delivery order" owner: PO + git: main skills: - define-product-scope in: @@ -96,6 +101,11 @@ states: - delivery_order - quality_attributes - deployment + conditions: + committed_to_main_locally: + committed_to_main_locally: ==verified next: - done: complete + done: + to: complete + when: committed_to_main_locally needs_reinterview: stakeholder-interview \ No newline at end of file diff --git a/.flowr/flows/feature-development-flow.yaml b/.flowr/flows/feature-development-flow.yaml index 50119dc..9c512b4 100644 --- a/.flowr/flows/feature-development-flow.yaml +++ b/.flowr/flows/feature-development-flow.yaml @@ -1,5 +1,6 @@ flow: feature-development-flow -version: 6.0.0 +version: 7.0.0 +params: [feature_name] exits: - needs_architecture @@ -8,23 +9,32 @@ exits: states: - id: planning + attrs: + description: "Plan feature scope, specification, breakdown, and BDD scenarios" + git: main flow: planning-flow - flow-version: "^4" + flow-version: "^5" next: complete: development needs_architecture: needs_architecture no_features: completed - id: development + attrs: + description: "Implement the feature through TDD cycles, review, and commit" + git: feature flow: development-flow - flow-version: "^4" + flow-version: "^5" next: done: delivery needs_planning: planning - id: delivery + attrs: + description: "Accept, merge, and publish the completed feature" + git: feature flow: delivery-flow - flow-version: "^4" + flow-version: "^5" next: next-feature: planning rejected: post-mortem @@ -32,8 +42,11 @@ states: cancelled: cancelled - id: post-mortem + attrs: + description: "Investigate rejection, document findings, and determine corrective action" + git: main flow: post-mortem-flow - flow-version: "^2" + flow-version: "^3" next: complete: planning needs_architecture: needs_architecture diff --git a/.flowr/flows/main-flow.yaml b/.flowr/flows/main-flow.yaml index 43bfd59..fd01a88 100644 --- a/.flowr/flows/main-flow.yaml +++ b/.flowr/flows/main-flow.yaml @@ -1,21 +1,23 @@ flow: main-flow -version: 7.0.0 +version: 8.0.0 exits: [completed, cancelled] states: - id: discovery attrs: description: "Understand the domain, define scope, and establish ubiquitous language through stakeholder interviews and domain modeling" + git: main flow: discovery-flow - flow-version: "^3" + flow-version: "^4" next: complete: architecture - id: architecture attrs: description: "Design technical architecture, context boundaries, and API contracts for the entire project" + git: main flow: architecture-flow - flow-version: "^4" + flow-version: "^5" next: complete: feature-development needs_discovery: discovery @@ -23,8 +25,9 @@ states: - id: feature-development attrs: description: "Feature-level loop: Planning → Development → Acceptance → Delivery per feature" + git: feature flow: feature-development-flow - flow-version: "^6" + flow-version: "^7" next: needs_architecture: architecture cancelled: cancelled diff --git a/.flowr/flows/planning-flow.yaml b/.flowr/flows/planning-flow.yaml index 2a6a066..137b4ae 100644 --- a/.flowr/flows/planning-flow.yaml +++ b/.flowr/flows/planning-flow.yaml @@ -1,5 +1,6 @@ flow: planning-flow -version: 4.0.0 +version: 5.0.0 +params: [feature_name] exits: - complete - needs_architecture @@ -10,6 +11,7 @@ states: attrs: description: "PO picks the next feature to develop based on business priority and delivery order, verifying that architecture covers it" owner: PO + git: main skills: - select-feature in: @@ -25,6 +27,7 @@ states: attrs: description: "PO conducts a targeted conversation with stakeholders to capture feature-specific behavioral rules, scenarios, and acceptance criteria" owner: PO + git: main skills: - specify-feature in: @@ -42,6 +45,7 @@ states: attrs: description: "PO decomposes the selected feature into Rule blocks (user stories) within the feature file based on specification interview and domain constraints" owner: PO + git: main skills: - break-down-feature in: @@ -70,6 +74,7 @@ states: attrs: description: "PO writes concrete Given/When/Then Example blocks for each Rule in the feature file using ubiquitous language from the glossary" owner: PO + git: main skills: - write-bdd-features in: @@ -109,6 +114,7 @@ states: attrs: description: "SA creates minimum typed stubs and test stubs as domain model breadcrumbs for the current feature" owner: SA + git: main skills: - create-py-stubs in: @@ -129,6 +135,7 @@ states: attrs: description: "PO tailors the definition of done criteria based on the specific feature's requirements" owner: PO + git: main skills: - define-done in: @@ -144,6 +151,7 @@ states: attrs: description: "PO confirms all planning artifacts are complete and the feature is ready for development" owner: PO + git: main skills: - confirm-baseline in: @@ -153,7 +161,11 @@ states: conditions: feature_baselined: feature_status: ==BASELINED + committed_to_main_locally: + committed_to_main_locally: ==verified next: done: to: complete - when: feature_baselined \ No newline at end of file + when: + - feature_baselined + - committed_to_main_locally \ No newline at end of file diff --git a/.flowr/flows/post-mortem-flow.yaml b/.flowr/flows/post-mortem-flow.yaml index 065ae75..562413c 100644 --- a/.flowr/flows/post-mortem-flow.yaml +++ b/.flowr/flows/post-mortem-flow.yaml @@ -1,5 +1,5 @@ flow: post-mortem-flow -version: 2.0.0 +version: 3.0.0 exits: - complete - needs_architecture @@ -10,6 +10,7 @@ states: attrs: description: "R investigates why the PR was rejected, identifying the failure point and missed gate" owner: R + git: main skills: - analyze-root-cause in: [] @@ -23,6 +24,7 @@ states: attrs: description: "R records what failed, why, and which quality gate was missed" owner: R + git: main skills: - document-post-mortem in: @@ -39,6 +41,7 @@ states: attrs: description: "R determines the corrective fix and updates the post-mortem with remediation steps" owner: R + git: main skills: - extract-lessons in: @@ -53,6 +56,7 @@ states: attrs: description: "R determines whether the feature needs replanning, architecture changes, or should be abandoned" owner: R + git: main skills: - determine-action-items in: diff --git a/.flowr/flows/review-gate-flow.yaml b/.flowr/flows/review-gate-flow.yaml index d80f621..ad026c0 100644 --- a/.flowr/flows/review-gate-flow.yaml +++ b/.flowr/flows/review-gate-flow.yaml @@ -1,5 +1,6 @@ flow: review-gate-flow -version: 2.0.0 +version: 3.0.0 +params: [feature_name] exits: - pass - fail @@ -9,6 +10,7 @@ states: attrs: description: "R verifies implementation aligns with domain model, follows DDD patterns, and respects architectural decisions" owner: R + git: feature skills: - review-design in: @@ -36,6 +38,7 @@ states: attrs: description: "R verifies test coverage, BDD example pass rate, test coupling, and behavior-vs-structure testing" owner: R + git: feature skills: - review-structure - verify-traceability @@ -63,6 +66,7 @@ states: attrs: description: "R verifies formatting, docstrings, type hints, import ordering, and lint rules unrelated to design" owner: R + git: feature skills: - review-conventions in: @@ -80,4 +84,4 @@ states: pass: to: pass when: conventions_approved - fail: fail + fail: fail \ No newline at end of file diff --git a/.flowr/flows/setup-project-flow.yaml b/.flowr/flows/setup-project-flow.yaml index bccb6e7..ae5db2b 100644 --- a/.flowr/flows/setup-project-flow.yaml +++ b/.flowr/flows/setup-project-flow.yaml @@ -1,5 +1,5 @@ flow: setup-project-flow -version: 2.0.0 +version: 3.0.0 exits: [initialized, cancelled] states: @@ -7,6 +7,7 @@ states: attrs: description: "Interview user to understand project needs and assess parameters" owner: Setup Agent + git: main skills: - setup-assess in: [] @@ -20,6 +21,7 @@ states: attrs: description: "Gather and confirm project parameters based on assessment" owner: Setup Agent + git: main skills: - setup-configure in: @@ -44,6 +46,7 @@ states: attrs: description: "Apply all text substitutions, rename package, reset version" owner: Setup Agent + git: main skills: - setup-apply in: @@ -71,6 +74,7 @@ states: attrs: description: "Verify transformations, clean template artifacts, finalize project" owner: Setup Agent + git: main skills: - setup-verify in: @@ -82,8 +86,12 @@ states: tests_pass: ==verified imports_valid: ==verified artifacts_cleaned: ==verified + committed_to_main_locally: + committed_to_main_locally: ==verified next: initialized: to: initialized - when: verification_passed + when: + - verification_passed + - committed_to_main_locally failed: cancelled \ No newline at end of file diff --git a/.flowr/flows/tdd-cycle-flow.yaml b/.flowr/flows/tdd-cycle-flow.yaml index 297ce8c..c31f63e 100644 --- a/.flowr/flows/tdd-cycle-flow.yaml +++ b/.flowr/flows/tdd-cycle-flow.yaml @@ -1,5 +1,6 @@ flow: tdd-cycle-flow -version: 2.0.0 +version: 3.0.0 +params: [feature_name] exits: - all_green - blocked @@ -9,6 +10,7 @@ states: attrs: description: "SE writes a failing test body for one BDD example, specifying expected behavior before implementation exists" owner: SE + git: feature skills: - write-test in: @@ -24,6 +26,7 @@ states: attrs: description: "SE writes the minimum production code needed to make the failing test pass" owner: SE + git: feature skills: - implement-minimum in: @@ -38,6 +41,7 @@ states: attrs: description: "SE improves code structure while keeping all tests passing, then cycles to the next example or exits when all pass" owner: SE + git: feature skills: - refactor in: diff --git a/.flowr/sessions/.gitkeep b/.flowr/sessions/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/.opencode/knowledge/workflow/flowr-operations.md b/.opencode/knowledge/workflow/flowr-operations.md index 67dd0e3..3102ec1 100644 --- a/.opencode/knowledge/workflow/flowr-operations.md +++ b/.opencode/knowledge/workflow/flowr-operations.md @@ -1,7 +1,7 @@ --- domain: workflow -tags: [flowr, cli, commands, transitions, evidence, session] -last-updated: 2026-05-01 +tags: [flowr, cli, commands, transitions, evidence, session, config] +last-updated: 2026-05-02 --- # Flowr Operations @@ -12,6 +12,8 @@ last-updated: 2026-05-01 - Use `python -m flowr next --evidence key=value` to see which transitions pass given your evidence. - Use `python -m flowr transition --evidence key=value` to advance to the next state. - Use `python -m flowr check ` to see the conditions guarding a specific transition. +- Use `python -m flowr session init ` to create a session that tracks progress; use `--session` on check/next/transition to resolve flow and state automatically. +- Use `python -m flowr config` to show resolved configuration (flows_dir, sessions_dir, default_flow, default_session) with source tracking. - Set evidence based on work completed before advancing — guarded transitions will not pass without it. - Always activate the virtual environment first: `source .venv/bin/activate`. @@ -19,11 +21,15 @@ last-updated: 2026-05-01 **State Entry**: Before starting work, inspect the current state to confirm the owner, skills, input artifacts, output artifacts, and available transitions. -**Evidence**: Some transitions are guarded by conditions (e.g., `feature_accepted: ==ACCEPTED`, `all_ids_have_stubs: ==true`). Set evidence with `--evidence key=value` when advancing. If a transition is guarded and evidence is not set, the transition will fail. +**Evidence**: Some transitions are guarded by conditions (e.g., `feature_accepted: ==ACCEPTED`, `all_ids_have_stubs: ==true`). Set evidence with `--evidence key=value` or `--evidence-json '{"key":"value"}'` when advancing. If a transition is guarded and evidence is not set, the transition will fail. **Choosing a Path**: After completing work, use `next` with your evidence to see which transitions are available. Choose the path that matches your work outcome. Do not guess transition names — check first. -**Flow File Resolution**: Flow files are in `.flowr/flows/`. The flow name matches the YAML file stem (e.g., `planning-flow` for `.flowr/flows/planning-flow.yaml`). +**Flow Name Resolution**: Commands accept short flow names (e.g., `architecture-flow`) or full file paths (e.g., `.flowr/flows/architecture-flow.yaml`). Short names are resolved by searching the configured flows directory. + +**Sessions**: Sessions persist workflow progress (current flow, state, call stack for subflows) as YAML files in `.flowr/sessions/`. Use `--session ` on check/next/transition to resolve flow and state from the session. `transition --session` auto-updates the session after advancing. + +**Configuration**: flowr reads `[tool.flowr]` from `pyproject.toml` with keys: `flows_dir`, `sessions_dir`, `default_flow`, `default_session`. CLI flags override pyproject.toml which overrides defaults. Use `flowr config` to inspect resolved values. ## Content @@ -33,16 +39,51 @@ All commands require the virtual environment: `source .venv/bin/activate` | Command | Purpose | Example | |---------|---------|---------| -| `python -m flowr validate .yaml` | Validate a flow definition | `python -m flowr validate .flowr/flows/planning-flow.yaml` | -| `python -m flowr validate` | Validate all flows | `python -m flowr validate` (no arg) | -| `python -m flowr states .yaml` | List all states in a flow | `python -m flowr states .flowr/flows/planning-flow.yaml` | -| `python -m flowr check .yaml ` | Show state attrs, owner, skills, and transitions | `python -m flowr check .flowr/flows/planning-flow.yaml feature-selection` | -| `python -m flowr check .yaml ` | Show conditions for a specific transition target | `python -m flowr check .flowr/flows/planning-flow.yaml feature-breakdown bdd-features` | -| `python -m flowr next .yaml ` | Show which transitions are available (unguarded always shown) | `python -m flowr next .flowr/flows/planning-flow.yaml feature-selection` | -| `python -m flowr next .yaml --evidence key=value` | Show which transitions pass given evidence | `python -m flowr next .flowr/flows/planning-flow.yaml feature-breakdown --evidence independent=true` | -| `python -m flowr transition .yaml ` | Compute next state for a trigger | `python -m flowr transition .flowr/flows/planning-flow.yaml feature-selection selected` | -| `python -m flowr transition .yaml --evidence key=value` | Advance with evidence | `python -m flowr transition .flowr/flows/planning-flow.yaml feature-breakdown done --evidence independent=true valuable=true` | -| `python -m flowr mermaid .yaml` | Export flow as Mermaid diagram | `python -m flowr mermaid .flowr/flows/planning-flow.yaml` | +| `python -m flowr validate ` | Validate a flow definition | `python -m flowr validate architecture-flow` | +| `python -m flowr states ` | List all states in a flow | `python -m flowr states planning-flow` | +| `python -m flowr check ` | Show state attrs, owner, skills, and transitions | `python -m flowr check planning-flow feature-selection` | +| `python -m flowr check ` | Show conditions for a specific transition target | `python -m flowr check planning-flow feature-breakdown bdd-features` | +| `python -m flowr next ` | Show which transitions are available (unguarded always shown) | `python -m flowr next planning-flow feature-selection` | +| `python -m flowr next --evidence key=value` | Show which transitions pass given evidence | `python -m flowr next planning-flow feature-breakdown --evidence independent=true` | +| `python -m flowr transition ` | Compute next state for a trigger | `python -m flowr transition planning-flow feature-selection selected` | +| `python -m flowr transition --evidence key=value` | Advance with evidence | `python -m flowr transition planning-flow feature-breakdown done --evidence independent=true valuable=true` | +| `python -m flowr transition --session` | Advance using session (auto-resolves flow/state) | `python -m flowr transition done --session --evidence independent=true` | +| `python -m flowr check --session` | Show current session state (read-only) | `python -m flowr check --session` | +| `python -m flowr next --session` | Show available transitions from session state | `python -m flowr next --session --evidence independent=true` | +| `python -m flowr mermaid ` | Export flow as Mermaid diagram | `python -m flowr mermaid planning-flow` | +| `python -m flowr config` | Show resolved configuration with sources | `python -m flowr config` | +| `python -m flowr config --json` | Show resolved configuration as JSON | `python -m flowr config --json` | + +### Session Commands + +| Command | Purpose | +|---------|---------| +| `python -m flowr session init [--name ]` | Create a new session at the flow's initial state | +| `python -m flowr session show [--name ] [--format yaml\|json]` | Display current session state and call stack | +| `python -m flowr session set-state [--name ]` | Manually update session state (validates state exists in flow) | +| `python -m flowr session list [--format yaml\|json]` | List all sessions | + +### Configuration + +flowr reads configuration from `[tool.flowr]` in `pyproject.toml`, falling back to defaults: + +| Key | Default | Description | +|-----|---------|-------------| +| `flows_dir` | `.flowr/flows` | Directory containing flow YAML files | +| `sessions_dir` | `.flowr/sessions` | Directory for session YAML files | +| `default_flow` | `main-flow` | Flow name used when none specified | +| `default_session` | `default` | Session name used when `--session` is given without a value | + +CLI `--flows-dir` overrides `pyproject.toml` which overrides defaults. + +### Evidence Syntax + +Evidence can be provided two ways: + +- `--evidence key=value` — multiple flags for individual pairs +- `--evidence-json '{"key":"value"}'` — single JSON object for all pairs + +Condition operators: `==value`, `!=value`, `>=N`, `<=N`, `>N`, ` --evidence key=value` — see which paths are available. 5. **Advance**: `python -m flowr transition --evidence key=value` — move to the next state. +### Session-Based Workflow + +For ongoing work, use sessions to track progress: + +1. **Init**: `python -m flowr session init --name ` — create session at initial state. +2. **Check**: `python -m flowr check --session` — inspect current state (read-only). +3. **Work**: Execute the skill for the current state. +4. **Advance**: `python -m flowr transition --session --evidence key=value` — transition and auto-update session. + ### Session Protocol Integration - The `owner` field from `check` output determines which agent to dispatch to (PO → product-owner, SE → software-engineer, SA → system-architect, DE → domain-expert, R → reviewer, Design Agent → design-agent, Setup Agent → setup-agent). diff --git a/.opencode/knowledge/workflow/flowr-spec.md b/.opencode/knowledge/workflow/flowr-spec.md index 77fc1d3..0127daf 100644 --- a/.opencode/knowledge/workflow/flowr-spec.md +++ b/.opencode/knowledge/workflow/flowr-spec.md @@ -1,7 +1,7 @@ --- domain: workflow -tags: [fsm, state-machine, flow, yaml, flowr, transitions, conditions] -last-updated: 2026-04-29 +tags: [fsm, state-machine, flow, yaml, flowr, transitions, conditions, session, config] +last-updated: 2026-05-02 --- # Flowr Specification @@ -13,6 +13,9 @@ last-updated: 2026-04-29 - Use `conditions` blocks on states to define named condition groups; reference them in transitions with `when`. - Guarded transitions use `when` dicts with expression strings (`==true`, `>=80%`, `~=100`); conditions are AND-combined with no inheritance. - Carry runtime metadata in state-level `attrs` (agent, skills, input_artifacts, etc.); `attrs` is opaque to the engine. +- Sessions track workflow progress (flow, state, call stack) as YAML files in `.flowr/sessions/` with atomic writes; `--session` on check/next/transition resolves flow/state automatically. +- Configuration reads `[tool.flowr]` from `pyproject.toml` (flows_dir, sessions_dir, default_flow, default_session); CLI flags override pyproject.toml which overrides defaults. +- Flow name resolution: commands accept short names (e.g., `planning-flow`) resolved from the configured flows directory, or full file paths. - Immutable loaded flows, closed evidence schema, isolated subflow context, filesystem wins over session on conflict. ## Concepts @@ -120,13 +123,45 @@ Named condition references in `when` clauses must resolve to a key in the same s ### Validation Rules (Load-Time) -1. Every `next` target resolves to a state id or an exit name -2. No `next` target is ambiguous (matches both a state id and an exit name) -3. Parent `next` keys match child's `exits` list exactly -4. No cross-flow cycles (DFS detection) -5. Exit names in `exits` must have at least one state referencing them -6. Named condition references in `when` must resolve to the same state's `conditions` block -7. Params without defaults must be provided at invocation time +Violations are categorized by severity: **MUST** (blocking errors) and **SHOULD** (non-blocking warnings). + +1. (MUST) Every `next` target resolves to a state id or an exit name +2. (MUST) No `next` target is ambiguous (matches both a state id and an exit name) +3. (MUST) Parent `next` keys match child's `exits` list exactly +4. (MUST) No cross-flow cycles (DFS detection) +5. (SHOULD) Exit names in `exits` are referenced by at least one state transition +6. (MUST) Named condition references in `when` must resolve to the same state's `conditions` block +7. (SHOULD) All defined condition groups are referenced by at least one transition +8. (MUST) Flow definition has at least one exit +9. (MUST) Flow definition has at least one state +10. Params without defaults must be provided at invocation time + +### Session Model + +Sessions persist workflow progress as YAML files in `.flowr/sessions/` with atomic writes (temp-file-then-rename). Each session tracks: + +| Field | Description | +|-------|-------------| +| `flow` | Current flow name | +| `state` | Current state id | +| `name` | Session identifier (used as filename stem) | +| `created_at` | ISO 8601 timestamp | +| `updated_at` | ISO 8601 timestamp (updated on every transition) | +| `stack` | List of `{flow, state}` frames for subflow nesting | +| `params` | Per-flow parameter overrides | + +Subflow entry pushes a `SessionStackFrame(flow, state)` onto the stack and updates the session's flow/state to the subflow. Subflow exit pops the frame and restores the parent flow/state. + +### Configuration + +flowr reads `[tool.flowr]` from `pyproject.toml`. Resolution priority: CLI flags > pyproject.toml > defaults. + +| Key | Default | Description | +|-----|---------|-------------| +| `flows_dir` | `.flowr/flows` | Directory containing flow YAML files | +| `sessions_dir` | `.flowr/sessions` | Directory for session YAML files | +| `default_flow` | `main-flow` | Flow name used when none specified | +| `default_session` | `default` | Session name used with bare `--session` | ### Design Principles @@ -136,6 +171,7 @@ Named condition references in `when` clauses must resolve to a key in the same s 4. **Session truth assumption** — filesystem wins over session on conflict 5. **Thin enforcement** — validate only, no execution 6. **No auto-rollback** — no transition limits +7. **Atomic session writes** — temp-file-then-rename prevents corruption ## Related diff --git a/AGENTS.md b/AGENTS.md index 3a2f3c9..d3cd52b 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -8,6 +8,7 @@ Post-mortem analysis shows these six practices prevent most project failures. Vi 4. **Never decompose a feature without stakeholder approval.** If a feature is too large for INVEST, propose the split to the stakeholder with rationale. They decide what's core vs. deferred. 5. **Verify inputs exist before entering a state.** Every state's `in` artifacts must be readable on disk. If they're missing, stop and reconstruct them — don't proceed with assumed knowledge. 6. **A feature is not done until every interview requirement is traced.** Every stakeholder Q&A must map to either a passing @id test or an explicit stakeholder deferral. Untraced requirements = incomplete delivery. +7. **Respect git branch discipline.** Every state declares `git: main` or `git: feature` in its attrs. Work on `main` when the state says `main`, work on the feature branch when it says `feature`. Never switch branches mid-state. Before exiting a project-phase flow (discovery, architecture, branding, setup), set `committed_to_main_locally: ==verified` evidence — changes must be committed to main before advancing. ## Project Structure - `.flowr/flows/` — YAML state machine definitions (source of truth for routing) @@ -86,15 +87,25 @@ Artifact names in `in` and `out` lists use these conventions: All commands require the virtual environment: `source .venv/bin/activate`. See [[workflow/flowr-operations]] for full command reference and workflow pattern. +Commands accept short flow names (e.g., `planning-flow`) or full file paths. Use `--session ` to resolve flow/state from a session instead of specifying them explicitly. + | Command | Purpose | |---------|---------| | `python -m flowr check ` | Show state attrs, owner, skills, and transitions | | `python -m flowr check ` | Show conditions for a specific transition | +| `python -m flowr check --session` | Show current session state (read-only) | | `python -m flowr next [--evidence key=value]` | Show which transitions pass given evidence | +| `python -m flowr next --session [--evidence key=value]` | Show available transitions from session state | | `python -m flowr transition [--evidence key=value]` | Advance to the next state | +| `python -m flowr transition --session [--evidence key=value]` | Advance using session (auto-updates session) | | `python -m flowr validate []` | Validate flow definitions | | `python -m flowr states ` | List all states in a flow | | `python -m flowr mermaid ` | Export flow as Mermaid diagram | +| `python -m flowr config` | Show resolved configuration with sources | +| `python -m flowr session init [--name ]` | Create a session at the flow's initial state | +| `python -m flowr session show [--name ]` | Display current session state and call stack | +| `python -m flowr session set-state [--name ]` | Manually update session state | +| `python -m flowr session list` | List all sessions | | `task regenerate-flowviz` | Regenerate interactive D3.js visualization | ## Project Commands @@ -121,10 +132,28 @@ Linting and formatting: Every state transition must go through flowr. Do not skip steps or guess transitions. See [[workflow/flowr-operations]] for the full command reference. -1. **State entry:** Run `python -m flowr check ` to see current state, owner, skills, and available transitions. Verify all `in` artifacts exist on disk — if any are missing, stop and flag rather than proceeding with assumed knowledge. Announce the state in one line — e.g. `→ specify-feature`. No preamble, no recap of how you got here. +1. **State entry:** Run `python -m flowr check --session` (or `python -m flowr check `) to see current state, owner, skills, and available transitions. Verify all `in` artifacts exist on disk — if any are missing, stop and flag rather than proceeding with assumed knowledge. Announce the state in one line — e.g. `→ specify-feature`. No preamble, no recap of how you got here. 2. **Dispatch to owner agent:** The state's `owner` field names the responsible agent. Call that agent as a subagent with the state's `skills` loaded, passing the state attrs as context. Owner mapping: `PO` → product-owner, `DE` → domain-expert, `SE` → software-engineer, `SA` → system-architect, `R` → reviewer, `Design Agent` → design-agent, `Setup Agent` → setup-agent. -3. **Do the work:** Load and execute the skill(s) listed in the state's `skills` field. Read `in` artifacts on demand. Write only to `out` artifacts. -4. **State exit:** Set evidence for any guarded transitions based on work completed. Run `python -m flowr next --evidence key=value` to see available paths. Choose the path that matches the work outcome. Run `python -m flowr transition --evidence key=value` to advance. Do not skip this step. +3. **Do the work:** Load and execute the skill(s) listed in the state's `skills` field. Read `in` artifacts on demand. Write only to `out` artifacts. Commit changes to the branch indicated by the state's `git` attribute (`main` or `feature`). Never switch branches mid-state. +4. **State exit:** Set evidence for any guarded transitions based on work completed. Run `python -m flowr next --session --evidence key=value` to see available paths. Choose the path that matches the work outcome. Run `python -m flowr transition --session --evidence key=value` to advance. Do not skip this step. + +### Session Init + +Before starting a flow, create a session to track progress: + +```bash +python -m flowr session init --name +``` + +For project-level flows (discovery, architecture, branding, setup), use a descriptive name like `project`. For feature flows, use the feature name. The session tracks the current flow, state, call stack (for subflows), and params (including `feature_name`). + +### Branch Discipline + +States declare their git context in `attrs.git`: +- `git: main` — all changes are committed to the local main branch +- `git: feature` — all changes are committed to the current feature branch + +Before exiting a project-phase flow (discovery, architecture, branding, setup), the exit transition requires `committed_to_main_locally: ==verified` evidence. This ensures project artifacts are persisted before advancing to the next phase. ### Within a State diff --git a/docs/research/software-engineering/process/nullhack_flowr_0.4.0.md b/docs/research/software-engineering/process/nullhack_flowr_0.4.0.md new file mode 100644 index 0000000..1cfd315 --- /dev/null +++ b/docs/research/software-engineering/process/nullhack_flowr_0.4.0.md @@ -0,0 +1,59 @@ +# flowr 0.4.0 — Non-Deterministic State Machine Engine for Workflow Kneading + +## Citation + +nullhack/flowr. (2026). flowr v0.4.0. GitHub. https://github.com/nullhack/flowr + +## Source Type + +Software Release / Implementation + +## Method + +Implementation Analysis (source code review) + +## Verification Status + +Verified + +## Confidence + +High + +## Key Insight + +flowr 0.4.0 adds session management, configuration resolution, and flow name resolution — turning flowr from a stateless inspection tool into a workflow engine that tracks and persists agent progress through flow states. + +## Core Findings + +1. **Session Management**: New `session` subcommand group (`init`, `show`, `set-state`, `list`) persists workflow progress as YAML files in `.flowr/sessions/`. Sessions track current flow, state, call stack (for subflow nesting), and params. Atomic writes prevent corruption. + +2. **Session-Aware Commands**: `check`, `next`, and `transition` accept `--session ` to resolve flow/state from the session instead of requiring explicit arguments. `transition --session` auto-updates the session after transition — eliminates manual YAML editing. + +3. **Subflow Call Stack**: Sessions maintain a `stack` of `SessionStackFrame(flow, state)` entries. Entering a subflow pushes a frame; exiting pops it. Provides proper return-to-parent semantics. + +4. **Pyproject.toml Configuration**: `[tool.flowr]` section in `pyproject.toml` configures `flows_dir`, `sessions_dir`, `default_flow`, and `default_session`. CLI flags override pyproject.toml which overrides defaults. `flowr config` command shows resolved configuration with source tracking. + +5. **Flow Name Resolution**: Commands accept short flow names (e.g., `architecture-flow`) instead of requiring full file paths (e.g., `.flowr/flows/architecture-flow.yaml`). Resolution checks file path first, then searches the configured flows directory. + +6. **Named Condition Groups**: States define `conditions:` blocks with reusable condition sets. Transitions reference them by name in `when:` clauses instead of inlining all conditions. Unknown references are validation errors. + +7. **Enhanced Validation**: New validators: subflow contract checking (parent `next` keys must match child `exits`), cross-flow cycle detection (DFS), condition reference validation (named groups must exist), unused condition group warnings (SHOULD level). Violations have MUST/SHOULD severity. + +8. **Condition Operators**: Expanded beyond `==` to include `!=`, `>=`, `<=`, `>`, `<`, and `~=` (approximate numeric match within 5%). Numeric portion extracted from both condition and evidence before comparison. + +9. **JSON Evidence Input**: `--evidence-json` flag accepts evidence as a JSON object alongside `--evidence key=value` pairs. + +10. **Flow-Level `attrs` and `params`**: Flows declare arbitrary metadata in `attrs` and typed parameters in `params` (with optional defaults). + +## Mechanism + +flowr operates as a thin enforcement layer over YAML-defined state machines. Flows are immutable once loaded. Sessions are the mutable runtime state, persisted as YAML with atomic writes (temp-file-then-rename). The engine validates flow definitions at load time (MUST/SHOULD severity), resolves guard conditions from named groups, and tracks subflow entry/exit via a call stack. Configuration resolution follows CLI > pyproject.toml > defaults priority. + +## Relevance + +flowr is the workflow engine that powers temple8's flow-based delivery system. The 0.4.0 additions make the golden rules enforceable by tooling: session management replaces manual session editing (Rule 1), flow name resolution simplifies CLI usage, and configuration from pyproject.toml removes hardcoded paths. + +## Related Research + +Connects to finite state machine theory (Harel, 1987), workflow management patterns (Russell et al., 2006), and the temple8 knowledge files on flowr specification and operations. \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index cbe75ab..f93ec38 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "temple8" -version = "8.0.0" +version = "8.1.0" description = "Python template with some awesome tools to quickstart any Python project" readme = "README.md" requires-python = ">=3.13" @@ -29,11 +29,17 @@ dev = [ "hypothesis>=6.148.4", "pyright>=1.1.407", "ghp-import>=2.1.0", - "flowr>=0.3", + "flowr>=0.4", "gherkin-official>=39.0.0", "safety>=3.7.0", ] +[tool.flowr] +flows_dir = ".flowr/flows" +sessions_dir = ".flowr/sessions" +default_flow = "main-flow" +default_session = "default" + [tool.setuptools] packages = ["app"] diff --git a/uv.lock b/uv.lock index 0de9005..aac72b1 100644 --- a/uv.lock +++ b/uv.lock @@ -322,14 +322,14 @@ wheels = [ [[package]] name = "flowr" -version = "0.3.20260427" +version = "0.4.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "pyyaml" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/38/e1/6e1050ef5b7eaeb390d7c1500c6930b91e5a389ef5be357e0f56002f8ca4/flowr-0.3.20260427.tar.gz", hash = "sha256:5f98acfa1ff9494a2a6af6a84f7863c0b1285eb35d6471f4fc5aba2537ccdf39", size = 13605, upload-time = "2026-04-27T06:49:06.434Z" } +sdist = { url = "https://files.pythonhosted.org/packages/9c/12/1963adb845d53333de04d07b413981d7c7c02f27ae62a27f40147d09c688/flowr-0.4.0.tar.gz", hash = "sha256:e5bef7f54c3173dfb9e01cd2e8d67ee28c06248eefdd1a318106a6947d1425ab", size = 24737, upload-time = "2026-05-02T18:05:08.688Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/f4/6e/1912d7364694209829838a62d44d4ab02517ef11d8e1db39e41b37938dd9/flowr-0.3.20260427-py3-none-any.whl", hash = "sha256:a88bbf230e3492fc314108cb967dbd490313e8f4805150e83c017914378410e2", size = 13786, upload-time = "2026-04-27T06:49:05.194Z" }, + { url = "https://files.pythonhosted.org/packages/c7/dd/ceb7f110a4f7d62b1e5192cdd49de4ad42a9c17f550598a89b62695cadbc/flowr-0.4.0-py3-none-any.whl", hash = "sha256:03ac05eb929b63b372c2fedac95567c2968d5568cef1ab3ef9681f4bb6b7a126", size = 25116, upload-time = "2026-05-02T18:05:07.096Z" }, ] [[package]] @@ -1068,7 +1068,7 @@ wheels = [ [[package]] name = "temple8" -version = "8.0.0" +version = "8.1.0" source = { virtual = "." } [package.optional-dependencies] @@ -1090,7 +1090,7 @@ dev = [ [package.metadata] requires-dist = [ - { name = "flowr", marker = "extra == 'dev'", specifier = ">=0.3" }, + { name = "flowr", marker = "extra == 'dev'", specifier = ">=0.4" }, { name = "gherkin-official", marker = "extra == 'dev'", specifier = ">=39.0.0" }, { name = "ghp-import", marker = "extra == 'dev'", specifier = ">=2.1.0" }, { name = "hypothesis", marker = "extra == 'dev'", specifier = ">=6.148.4" },