Files
cleveragents-core/features/definition_of_done.feature
T
2026-02-25 10:04:31 +00:00

186 lines
8.0 KiB
Gherkin

Feature: Definition-of-Done gating
As a plan executor
I want apply to be blocked unless all DoD criteria are met
So that only plans meeting completion criteria are committed
Background:
Given a definition of done test environment
# -- DoD parsing ---------------------------------------------------------
Scenario: Parse DoD text into criteria
When I parse the DoD text "All tests pass\nNo lint errors\nCoverage above 90%"
Then there should be 3 criteria parsed
And criterion 0 text should be "All tests pass"
And criterion 1 text should be "No lint errors"
Scenario: Parse DoD with bullet points
When I parse the DoD text "- Tests pass\n- No errors\n* Coverage ok"
Then there should be 3 criteria parsed
And criterion 0 text should be "Tests pass"
Scenario: Parse DoD with numbered items
When I parse the DoD text "1. Tests pass\n2. No errors"
Then there should be 2 criteria parsed
And criterion 0 text should be "Tests pass"
And criterion 1 text should be "No errors"
Scenario: Parse empty DoD returns no criteria
When I parse an empty DoD text
Then there should be 0 criteria parsed
# -- Template rendering --------------------------------------------------
Scenario: Render DoD template with plan arguments
When I render the DoD template "Tests for {module} must pass" with argument "module" as "auth"
Then the rendered DoD should be "Tests for auth must pass"
Scenario: Render DoD template preserves unmatched placeholders
When I render the DoD template "Deploy {service} to {env}" with argument "service" as "api"
Then the rendered DoD should contain "{env}"
# -- Text match evaluation -----------------------------------------------
Scenario: TextMatchEvaluator passes when context contains criterion text
Given DoD criteria from "All tests pass"
And evaluation context with key "status" value "all tests pass"
When I evaluate the criteria with TextMatchEvaluator
Then all criteria should have passed
Scenario: TextMatchEvaluator fails when context lacks criterion text
Given DoD criteria from "All tests pass"
And evaluation context with key "status" value "3 tests failed"
When I evaluate the criteria with TextMatchEvaluator
Then criterion 0 should have status "failed"
Scenario: TextMatchEvaluator with regex pattern passes on match
Given a DoD criterion with text "Coverage check" and pattern "coverage.*9[0-9]"
And evaluation context with key "coverage" value "coverage=95%"
When I evaluate the criteria with TextMatchEvaluator
Then all criteria should have passed
Scenario: TextMatchEvaluator with regex pattern fails on no match
Given a DoD criterion with text "Coverage check" and pattern "coverage.*9[0-9]"
And evaluation context with key "coverage" value "coverage=80%"
When I evaluate the criteria with TextMatchEvaluator
Then criterion 0 should have status "failed"
Scenario: TextMatchEvaluator skips when context is empty
Given DoD criteria from "All tests pass"
And an empty evaluation context
When I evaluate the criteria with TextMatchEvaluator
Then criterion 0 should have status "skipped"
Scenario: TextMatchEvaluator handles invalid regex gracefully
Given a DoD criterion with text "Bad regex" and pattern "[invalid"
And evaluation context with key "data" value "anything"
When I evaluate the criteria with TextMatchEvaluator
Then criterion 0 should have status "failed"
And criterion 0 reasoning should contain "Invalid regex"
# -- DoDSummary model ----------------------------------------------------
Scenario: DoDSummary reports all_passed when no failures
Given a DoDSummary with 2 passed and 0 failed
Then the summary should report all passed
And the DoD summary total should be 2
Scenario: DoDSummary reports not all passed when failures exist
Given a DoDSummary with 1 passed and 1 failed
Then the summary should not report all passed
And the summary failed count should be 1
Scenario: DoDSummary empty check
Given an empty DoDSummary
Then the summary should be empty
And the summary should not report all passed
Scenario: DoDSummary to_cli_dict has expected fields
Given a DoDSummary with 1 passed and 0 failed
Then the summary CLI dict should have key "total"
And the summary CLI dict should have key "all_passed"
And the summary CLI dict should have key "criteria"
Scenario: DoDSummary to_validation_summary is compatible
Given a DoDSummary with 2 passed and 1 failed
Then the validation summary should have required_passed 2
And the validation summary should have required_failed 1
And the validation summary should have dod_evaluated true
# -- Evaluation context matching -----------------------------------------
Scenario: TextMatchEvaluator matches criterion text in context keys
Given DoD criteria from "lint_errors"
And evaluation context with key "lint_errors" value "0"
When I evaluate the criteria with TextMatchEvaluator
Then all criteria should have passed
Scenario: Multiple criteria with mixed results
Given DoD criteria from "tests pass\nlint errors"
And evaluation context with key "result" value "tests pass, no issues"
When I evaluate the criteria with TextMatchEvaluator
Then criterion 0 should have status "passed"
And criterion 1 should have status "failed"
# -- Coverage: edge cases ------------------------------------------------
Scenario: Parse DoD with blank lines between criteria
When I parse the DoD text "Tests pass\n\nNo errors"
Then there should be 2 criteria parsed
Scenario: Parse DoD with whitespace only line
When I parse the DoD text " \n- Tests pass"
Then there should be 1 criteria parsed
And criterion 0 text should be "Tests pass"
Scenario: TextMatchEvaluator matches via individual key lookup
Given DoD criteria from "all_tests_passed"
And evaluation context with key "all_tests_passed" value "true"
When I evaluate the criteria with TextMatchEvaluator
Then all criteria should have passed
# -- T1: all-SKIPPED summary gate behavior --------------------------------
Scenario: DoDSummary all_passed is false when all criteria skipped
Given a DoDSummary with all criteria skipped
Then the summary should not report all passed
And the summary skipped count should be 2
# -- T2: bullet prefix yielding empty text --------------------------------
Scenario: Parse DoD with bullet prefix but no text
When I parse the DoD text "- \n- Tests pass"
Then there should be 1 criteria parsed
And criterion 0 text should be "Tests pass"
# -- T5: multi-argument template rendering --------------------------------
Scenario: Render DoD template with multiple arguments
When I render the DoD template "{svc} in {env} OK" with arguments "svc"="api" and "env"="prod"
Then the rendered DoD should be "api in prod OK"
Scenario: Render DoD template prevents injection via values
When I render the DoD template "Test {name}" with argument "name" as "{secret}"
Then the rendered DoD should be "Test {secret}"
# -- S3: length limit on template -----------------------------------------
Scenario: Render DoD rejects oversized template
Given a DoD template that is 11000 characters long
When I render the oversized DoD template with argument "x" as "y"
Then the DoD render should fail with "exceeds maximum"
Scenario: Render DoD rejects oversized output
Given a short DoD template with a huge argument value
When I render the DoD template that produces oversized output
Then the DoD render should fail with "exceeds maximum"
# -- S2: ReDoS protection -------------------------------------------------
Scenario: TextMatchEvaluator rejects oversized regex pattern
Given a DoD criterion with text "long regex" and pattern that is 600 chars
And evaluation context with key "data" value "anything"
When I evaluate the criteria with TextMatchEvaluator
Then criterion 0 should have status "failed"
And criterion 0 reasoning should contain "exceeds maximum"