Skip to content

mr-fallback-rejected

Scenario for Refine Plan.

User rejects in-session approval; selector routes to MR path

Latest run: PASS — 2026-05-10 23:10:28Z

Spec: .abtree/trees/refine-plan/TEST__mr-fallback-rejected.yaml

Report: .abtree/trees/refine-plan/REPORT__mr-fallback-rejected__20260510T231028Z.md


Test spec

yaml
feature: Refine_Plan refines a change request into an approved plan
tree: refine-plan
description: |
  MR fallback — the agent is interactive but the codeowner declines to
  approve in-session (e.g. they want async review on a branch). The
  Approve_In_Session action submits failure, the selector falls through
  to Open_MR_For_Codeowner, and the workflow completes by assigning the MR.

background:
  initial:
    local:
      change_request: "Rotate the JWT signing key and shorten the access-token TTL from 1h to 15m."
  environment:
    interactive: true
    codeowner_in_session: true
    codeowner_response: reject  # prefers MR review

# VCR-style fixtures — see TEST__mr-fallback-headless.yaml for the contract.
fixtures:
  side_effects:
    mr_open:
      url: https://gitlab.example/flying-dice/abtree/-/merge_requests/143
      assignee: Jonathan Turnock
      branch: plan/20260511T000300Z-jwt-rotate-key-shorten-ttl

scenario:
  name: User rejects in-session approval; selector routes to MR path
  given:
    - $LOCAL.change_request is set
    - the agent is running interactively
    - the codeowner prefers async review over in-session sign-off
  when:
    - Understand_Intent / Write_Draft / Critique_Draft / Save_Plan complete as in the happy path
    - $LOCAL.plan_path is set and the plan frontmatter status is "refined"
    - Approve_In_Session evaluate → true ($LOCAL.plan_path is set)
    - Approve_In_Session evaluate → true (session is interactive)
    - Approve_In_Session asks the codeowner; they decline / request MR review
    - Approve_In_Session submits failure (per the instruction's rejection contract)
    - Open_MR_For_Codeowner evaluate → true ($LOCAL.plan_path is set)
    - Open_MR_For_Codeowner sets reviewed_by, commits on plan/<plan-id>, pushes, opens MR, stores $LOCAL.mr_url
    - Open_MR_For_Codeowner evaluate → true ($LOCAL.mr_url is set)
  then:
    local:
      plan_path: matches "plans/.+\\.md"
      codeowner_approved: null    # rejection did not set this to false; left untouched
      mr_url: equals fixtures.side_effects.mr_open.url
    files:
      plan_path:
        exists: true
        frontmatter:
          status: refined
          reviewed_by: equals fixtures.side_effects.mr_open.assignee
    git:
      branch: equals fixtures.side_effects.mr_open.branch
      mr_assignee: equals fixtures.side_effects.mr_open.assignee
    status: done

Latest report

Tree: refine-plan (v4.2.0) Runner: test-tree (v1.2.0, fixture-driven side effects) Spec: .abtree/trees/refine-plan/TEST__mr-fallback-rejected.yaml Target execution: test-tree-run-jwt-rotation-codeowner-rej__refine-plan__1 Overall: PASS

Final $LOCAL

keyvalue
change_request"Rotate the JWT signing key and shorten the access-token TTL from 1h to 15m."
intent_analysis(terse 5-bullet analysis)
draft_pathnull
plan_path"plans/jwt-signing-key-rotation-and-access-token-ttl-reduction.md"
codeowner_approvednull
mr_url"https://gitlab.example/flying-dice/abtree/-/merge_requests/143"

Assertions

NameExpectedActualPass
statusdonedone
local.plan_pathmatches plans/.+\.md"plans/jwt-signing-key-rotation-and-access-token-ttl-reduction.md"
local.codeowner_approvednull (rejection didn't toggle it)null
local.mr_urlequals fixtures.side_effects.mr_open.url(fixture) https://gitlab.example/flying-dice/abtree/-/merge_requests/143
files.plan_path.existstruetrue
files.plan_path.frontmatter.statusrefinedrefined
files.plan_path.frontmatter.reviewed_byequals fixtures.side_effects.mr_open.assignee"Jonathan Turnock"
git.branchequals fixtures.side_effects.mr_open.branch(fixture) plan/20260511T000300Z-jwt-rotate-key-shorten-ttl
git.mr_assigneeequals fixtures.side_effects.mr_open.assignee(fixture) Jonathan Turnock
selector behaviour: Approve_In_Session submit failure → fell through to Open_MR_For_Codeownerverified by traceverified — Approve_In_Session red, Open_MR_For_Codeowner green

Note: Same fixture-driven contract as TEST__mr-fallback-headless. The distinction between this scenario and the headless one is the driver's submit on Approve_In_Session (failure here, never-reached-instruct in headless) — the mermaid node-state alone doesn't show the difference, but the spec name + scenario when block do.

Trace

mermaid
---
title: "test-tree run: JWT rotation, codeowner rejects in-session (complete)"
---
flowchart TD
    Refine_Plan_Workflow{{"Refine Plan Workflow\n[sequence]"}}
    0_Understand_Intent["Understand Intent\n[action]"]
    Refine_Plan_Workflow --> 0_Understand_Intent
    style 0_Understand_Intent fill:#4ade80,stroke:#16a34a,color:#052e16
    0_Write_Draft["Write Draft\n[action]"]
    Refine_Plan_Workflow --> 0_Write_Draft
    style 0_Write_Draft fill:#4ade80,stroke:#16a34a,color:#052e16
    0_Critique_Draft["Critique Draft\n[action]"]
    Refine_Plan_Workflow --> 0_Critique_Draft
    style 0_Critique_Draft fill:#4ade80,stroke:#16a34a,color:#052e16
    0_Save_Plan["Save Plan\n[action]"]
    Refine_Plan_Workflow --> 0_Save_Plan
    style 0_Save_Plan fill:#4ade80,stroke:#16a34a,color:#052e16
    0_Codeowner_Approval{{"Codeowner Approval\n[selector]"}}
    Refine_Plan_Workflow --> 0_Codeowner_Approval
    style 0_Codeowner_Approval fill:#4ade80,stroke:#16a34a,color:#052e16
    0_4_Approve_In_Session["Approve In Session\n[action]"]
    0_Codeowner_Approval --> 0_4_Approve_In_Session
    style 0_4_Approve_In_Session fill:#f87171,stroke:#dc2626,color:#450a0a
    0_4_Open_MR_For_Codeowner["Open MR For Codeowner\n[action]"]
    0_Codeowner_Approval --> 0_4_Open_MR_For_Codeowner
    style 0_4_Open_MR_For_Codeowner fill:#4ade80,stroke:#16a34a,color:#052e16

MIT licensed