Files
cleveragents-core/features/e2e_porting_task.feature
T
freemo 2cb82f8acc feat(autonomy): E2E porting task completes autonomously
Implements M7 (v3.6.0) acceptance criterion: an end-to-end porting task
completes autonomously using the full CleverAgents pipeline.

Changes:
- Add reproducible E2E porting task fixture (examples/actions/e2e-porting.yaml)
  with invariants, typed arguments, and supervised automation profile
- Add E2EPortingService that ties together ACMS context assembly, plan
  lifecycle (Strategize → Execute → Apply), subplan decomposition,
  correction engine, and apply phase
- Add validate_ported_output() for Python 3 syntax, type annotation,
  and Python 2 construct checks
- Add _apply_stub_porting() deterministic Python 2→3 transformation
  for test path (no LLM required)
- Add Behave BDD tests (features/e2e_porting_task.feature) covering
  fixture validation, action registration, plan lifecycle, output
  validation, and lifecycle observability
- Add Robot Framework E2E acceptance test (robot/e2e/m7_e2e_porting.robot)
  covering all M7 acceptance criteria

Closes #857
2026-04-02 09:15:24 +00:00

180 lines
7.6 KiB
Gherkin

@m7 @e2e_porting
Feature: E2E porting task completes autonomously
As a CleverAgents user
I want to define a porting task as a YAML action config
So that the system autonomously strategizes, decomposes, executes, and applies
the porting transformation with full lifecycle observability
Background:
Given an E2E porting test environment
# ── Fixture validation ────────────────────────────────────────────────────
Scenario: E2E porting action fixture is valid YAML
When I load the e2e-porting action fixture from examples/actions/e2e-porting.yaml
Then the fixture should parse without errors
And the fixture name should be "local/e2e-porting"
And the fixture should have a strategy_actor
And the fixture should have an execution_actor
And the fixture should have a definition_of_done
Scenario: E2E porting action fixture has required invariants
When I load the e2e-porting action fixture from examples/actions/e2e-porting.yaml
Then the fixture invariants should include "valid Python 3 syntax"
And the fixture invariants should include "type annotations"
Scenario: E2E porting action fixture has source_module argument
When I load the e2e-porting action fixture from examples/actions/e2e-porting.yaml
Then the fixture should have an argument named "source_module"
And the "source_module" argument should be required
# ── Action registration ───────────────────────────────────────────────────
Scenario: Porting action can be registered with the lifecycle service
When I register the porting action with the lifecycle service
Then the action "local/e2e-porting" should be available
And the porting action state should be "available"
Scenario: Registering the porting action twice is idempotent
When I register the porting action with the lifecycle service
And I register the porting action with the lifecycle service again
Then the action "local/e2e-porting" should be available
And no error should have occurred
# ── Plan creation ─────────────────────────────────────────────────────────
Scenario: Using the porting action creates a plan in Strategize phase
Given the porting action is registered
When I use the porting action with source_module "legacy/calculator.py"
Then a porting plan should be created
And the porting plan phase should be "strategize"
And the porting plan processing_state should be "queued"
Scenario: Porting plan carries action invariants
Given the porting action is registered
When I use the porting action with source_module "legacy/calculator.py"
Then the porting plan invariants should include "valid Python 3 syntax"
# ── Full lifecycle ────────────────────────────────────────────────────────
Scenario: Porting task drives through full Strategize → Execute → Apply lifecycle
Given the porting action is registered
And a Python 2 source module is available
When I execute the porting task autonomously
Then the porting result should indicate success
And the lifecycle events should include a "strategize" phase event
And the lifecycle events should include an "execute" phase event
And the lifecycle events should include an "apply" phase event
Scenario: Porting lifecycle events are observable
Given the porting action is registered
And a Python 2 source module is available
When I execute the porting task autonomously
Then the lifecycle events should not be empty
And each lifecycle event should have a phase
And each lifecycle event should have a state
And each lifecycle event should have a timestamp
# ── Validation checks ─────────────────────────────────────────────────────
Scenario: Ported output passes Python 3 syntax validation
Given the porting action is registered
And a Python 2 source module is available
When I execute the porting task autonomously
Then the porting result validation should pass
And the ported output should be valid Python 3
Scenario: Ported output has no Python 2 constructs
Given the porting action is registered
And a Python 2 source module is available
When I execute the porting task autonomously
Then the ported output should not contain "xrange"
And the ported output should not contain "basestring"
And the ported output should not contain ".iteritems()"
Scenario: Ported output has type annotations
Given the porting action is registered
And a Python 2 source module is available
When I execute the porting task autonomously
Then the ported output should contain type annotations
# ── Validation helper ─────────────────────────────────────────────────────
Scenario: validate_ported_output accepts valid Python 3 with annotations
When I validate ported output:
"""
from __future__ import annotations
def add(a: int, b: int) -> int:
return a + b
"""
Then the porting validation should pass
And there should be no porting validation errors
Scenario: validate_ported_output rejects Python 2 print statement
When I validate ported output:
"""
def greet(name: str) -> None:
print "Hello " + name
"""
Then the porting validation should fail
And the validation errors should mention "print statement"
Scenario: validate_ported_output rejects xrange
When I validate ported output:
"""
def count(n: int) -> None:
for i in xrange(n):
pass
"""
Then the porting validation should fail
And the validation errors should mention "xrange"
Scenario: validate_ported_output rejects missing type annotations
When I validate ported output:
"""
def add(a, b):
return a + b
"""
Then the porting validation should fail
And the validation errors should mention "type annotations"
Scenario: validate_ported_output rejects syntax errors
When I validate ported output:
"""
def broken(:
pass
"""
Then the porting validation should fail
And the validation errors should mention "syntax error"
# ── Stub porting transformation ───────────────────────────────────────────
Scenario: Stub porting converts print statement to print function
When I apply stub porting to:
"""
def greet(name):
print "Hello " + name
"""
Then the stub output should contain "print("
And the stub output should not contain "print \""
Scenario: Stub porting converts xrange to range
When I apply stub porting to:
"""
def count(n):
for i in xrange(n):
pass
"""
Then the stub output should contain "range("
And the stub output should not contain "xrange("
Scenario: Stub porting adds return type annotation to bare def
When I apply stub porting to:
"""
def process(data):
return data
"""
Then the stub output should contain "-> None:"