Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -177,9 +177,9 @@ AGENTS.md

# Trigger CI run to verify linting fixes

# smith managed source:url:https://github.com/nullhack/temple8/archive/refs/tags/v8.0.0+20260501.tar.gz
AGENTS.md
# smith managed
.flowr/
.opencode/
.templates/
.flowr/
AGENTS.md
# end smith managed
16 changes: 14 additions & 2 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,14 @@
## Golden Rules

Post-mortem analysis shows these six practices prevent most project failures. Violating them triggers costly rework — defects caught later cost 10–100× more to fix (Boehm, 1981).

1. **Never skip a flow state.** Every state boundary goes through flowr check → dispatch to owner → flowr transition. No shortcuts, no manual session edits, no jumping ahead.
2. **Never bypass owner dispatch.** Each state has an owner agent. The orchestrator dispatches to that agent with skills loaded — it never does the work itself. One agent, one hat at a time.
3. **Never collapse progressive gates.** Multi-step gates (review: design → structure → conventions) are separate for a reason. Each one can fail independently and send work back.
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.

## Project Structure
- `.flowr/flows/` — YAML state machine definitions (source of truth for routing)
- `.flowr/sessions/` — runtime session state
Expand Down Expand Up @@ -110,7 +121,7 @@ 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 <flow> <state>` to see current state, owner, skills, and available transitions. 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 <flow> <state>` 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 <flow> <state> --evidence key=value` to see available paths. Choose the path that matches the work outcome. Run `python -m flowr transition <flow> <state> <trigger> --evidence key=value` to advance. Do not skip this step.
Expand All @@ -125,7 +136,8 @@ Announce the state once at the top, then go quiet:
- Files not in `out` must not be written to. If findings affect an artifact outside the output contract, flag them in output notes and defer the change to the step that owns that artifact.
- The flow contract must always be followed unless the stakeholder explicitly asks to break it.
- **Artifact existence guarantee:** When a flow state needs a file artifact that does not yet exist, it is created from the matching template in `.templates/` (if one exists). If no template exists for a non-Python file referenced in `in`/`out`, raise an error for the stakeholder to decide. Files are then updated when a state writes to them or their sections. Environment artifacts (e.g., `coverage_reports`, `test_output`, `linter_output`) are produced by tooling rather than flow states — they exist on disk after running the relevant tool and are referenced in `in` but not in any state's `out`.
- **Read inputs on demand, not eagerly.** When `in` lists artifacts, discover what's available first (`ls`, `find`), then read only the files and sections needed for the current task. The `in` list defines what you *may* read, not what you *must* read up front. This applies to all files — spec documents, production code, and test code. List directories first, read selectively.
- **Read inputs on demand, not eagerly.** When `in` lists artifacts, discover what's available first (`ls`, `find`), then read only the files and sections needed for the current task. The `in` list defines what you *may* read, not what you *must* read up front. This applies to all files — spec documents, production code, and test code. List directories first, read selectively. Loading all `in` artifacts before starting wastes context and causes middle-position attention degradation (Liu et al., 2023).
- **Specification documents are read-only during development.** During TDD and review cycles, the SE and reviewer may ONLY modify production code and test code. Spec document inconsistencies must be FLAGGED in output notes, not fixed directly. Spec docs are owned by other flow states and can only be changed through the appropriate flow step — after code is reviewed and approved.
- **Flag issues with precise citations.** When flagging a problem during review or adversarial analysis, include file:line references — e.g., "domain_model.md:23 conflicts with login.feature:15". Vague findings create rework.
- **Do the work with the fewest, quietest commands.** Suppress verbose output. If a command can be scoped with a flag, pipe, or limit — use it. Don't dump full files or directory listings when a targeted query answers the question.
- **No narration between steps.** The command and its output are the conversation. Don't echo what you're about to do or what you just did.
24 changes: 24 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,30 @@

All notable changes to this project will be documented in this file.

## [v0.4.0+20260502] - Refined Semolina - 2026-05-02

### Added

- **CLI flow name resolution**: short flow names resolved from `.flowr/flows/` directory; file paths still work (backward compatible); `--flows-dir` global flag overrides `pyproject.toml` `flows_dir`; `FlowNameNotFoundError` with clear error messages
- **Session management**: `session init <flow>`, `session show`, `session set-state <state>`, `session list` subcommands; `--session [NAME]` flag on `transition`, `next`, and `check` for session-aware state resolution; `--format yaml|json` on session commands; subflow push/pop stack for nested workflow tracking; atomic session file writes (temp-file-then-rename); `SessionNameNotFoundError` for session path resolution mirroring flow name resolution pattern
- **Configurable paths**: `flowr config` subcommand showing resolved configuration keys with source provenance (default / pyproject.toml / CLI); `--json` flag for machine-readable output; `resolve_config_with_sources()` tracking where each value comes from
- **README rewrite**: clear purpose, audience (Agent Operators, Developers, Tool Authors), show-don't-tell examples, architecture section
- **Documentation portal**: role-based `docs/index.html` with Stakeholder / Architect / Engineer sections using flowr's bakery palette

### Changed

- **`flowr/infrastructure/config.py`**: extracted `_read_pyproject`, `_resolve_values`, `_resolve_sources`, `_to_config` helpers for reduced complexity
- **`flowr/domain/session.py`**: `SessionStore` Protocol moved to domain layer (hexagonal architecture); `push_stack()` accepts `new_flow` parameter; `pop_stack()` restores parent flow from stack frame; `datetime.UTC` replaces `timezone.utc`
- **`flowr/__main__.py`**: `--session` flag on `transition`/`next`/`check`; `session` subcommand group; `config` subcommand; `--flows-dir` as global flag (was per-subcommand); flow name resolution via `DefaultFlowNameResolver`; exit code 1 for `FlowNameNotFoundError` (was 2)
- **`flowr/cli/session_cmd.py`**: state validation on `set-state` (rejects invalid states); `--name` and `--session` accept both short names and file paths
- **100% test coverage** across all modules with `# pragma: no cover` for unreachable Protocol stubs, Python version fallbacks, and main() dispatch paths tested via subprocess integration tests

### Fixed

- **Exit code for flow name not found**: changed from 2 (usage error) to 1 (command failed) per ADR_20260426_cli_io_convention
- **`--flows-dir` flag scope**: moved from per-subcommand to global argument per technical design constraint
- **Convention violations from review**: `FlowNameNotFound` renamed to `FlowNameNotFoundError` (N818), added `__init__` docstring (D107), trailing newlines (W292), line length (E501), nested `with` combined (SIM117)

## [v0.3.20260427] - 2026-04-27 - Coarse Grind

### Fixed
Expand Down
6 changes: 3 additions & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "flowr"
version = "0.3.20260427"
version = "0.4.0"
description = "non-deterministic state machine specification to knead workflows"
readme = "README.md"
requires-python = ">=3.13"
Expand Down Expand Up @@ -31,7 +31,7 @@ dev = [
"hypothesis>=6.148.4",
"pyright>=1.1.407",
"ghp-import>=2.1.0",
"agents-smith>=0.3.0",
"agents-smith>=1.0.0",
"safety>=3.7.0",
]

Expand Down Expand Up @@ -157,7 +157,7 @@ release-check = "python scripts/check_version.py && task lint && task static-che

[dependency-groups]
dev = [
"agents-smith>=0.3.0",
"agents-smith>=1.0.0",
"safety>=3.7.0",
]

Expand Down
7 changes: 6 additions & 1 deletion scripts/check_version.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,12 @@ def main() -> int:
print(f"Checking release v{version}")

# 2. Check CHANGELOG.md has entry for this version
if f"## [v{version}]" not in changelog.read_text():
# Accepts both `## [v{version}]` and `## [v{version}+{date}]` formats
changelog_text = changelog.read_text()
if (
f"## [v{version}]" not in changelog_text
and f"## [v{version}+" not in changelog_text
):
print(f"ERROR: CHANGELOG.md has no entry for v{version}")
return 1
print(" OK: CHANGELOG.md entry found")
Expand Down
12 changes: 6 additions & 6 deletions uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading