# Steward Application Reimbursement State Implementation Plan > **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. **Goal:** Build a persistent ontology-bound steward state for travel application and travel reimbursement flows. **Architecture:** Keep the existing steward planning UI and assistant delegation flow. Add a backend state layer that stores `steward_state` in `AgentConversation.state_json`, merges LLM/rule output as patches, and rejects fields outside the ontology registry before downstream services consume them. **Tech Stack:** FastAPI, SQLAlchemy JSON state, Pydantic schemas, pytest in Docker `x-financial-main:/app`, Vue/Vite frontend. --- ### Task 1: Backend State Contract **Files:** - Modify: `server/src/app/schemas/steward.py` - Create: `server/src/app/services/steward_flow_state.py` - Test: `server/tests/test_steward_flow_state.py` - [ ] **Step 1: Write failing tests** ```python def test_state_merge_keeps_application_and_reimbursement_flows(): service = StewardFlowStateService() state = service.merge_state( {}, StewardFlowStatePatch( active_flow="travel_application", flow_id="travel_application", intent="travel_application_create", fields={"expense_type": "travel", "location": "上海"}, ), ) state = service.merge_state( state, StewardFlowStatePatch( active_flow="travel_reimbursement", flow_id="travel_reimbursement", intent="travel_reimbursement_draft", fields={"amount": "708", "invoice_no": "NO-1"}, ), ) assert state["flows"]["travel_application"]["fields"]["location"] == "上海" assert state["flows"]["travel_reimbursement"]["fields"]["amount"] == "708" ``` ```python def test_state_merge_filters_non_ontology_fields(): service = StewardFlowStateService() state = service.merge_state( {}, StewardFlowStatePatch( active_flow="travel_application", flow_id="travel_application", intent="travel_application_create", fields={"location": "上海", "invented_field": "x"}, ), ) assert state["flows"]["travel_application"]["fields"] == {"location": "上海"} ``` - [ ] **Step 2: Run red tests** Run: ```bash docker exec -w /app -e SERVER_VENV_DIR=/tmp/x-financial-server-venv x-financial-main /tmp/x-financial-server-venv/bin/pytest -q server/tests/test_steward_flow_state.py ``` Expected: fail because `steward_flow_state.py` does not exist. - [ ] **Step 3: Implement minimal state service** Create `StewardFlowStatePatch`, `StewardFlowStateService.merge_state`, ontology field filtering, and event append logic. - [ ] **Step 4: Run green tests** Run the same pytest command and expect pass. ### Task 2: Steward Plan Persistence **Files:** - Modify: `server/src/app/schemas/steward.py` - Modify: `server/src/app/api/v1/endpoints/steward.py` - Modify: `server/src/app/services/agent_conversations.py` - Test: `server/tests/test_steward_planner.py` - [ ] **Step 1: Write failing API/service test** Add a test proving `/steward/plans` response contains `conversation_id` and `steward_state` when `context_json.session_type = steward`, and the state contains two flows when the input contains one application and one reimbursement task. - [ ] **Step 2: Run red test** Run: ```bash docker exec -w /app -e SERVER_VENV_DIR=/tmp/x-financial-server-venv x-financial-main /tmp/x-financial-server-venv/bin/pytest -q server/tests/test_steward_planner.py ``` - [ ] **Step 3: Implement conversation state persistence** Add `conversation_id` and `steward_state` fields to response schemas, persist state through `AgentConversationService`, and merge planner tasks into `steward_state`. - [ ] **Step 4: Run green test** Run the same pytest command and expect pass. ### Task 3: Runtime Decision Reads Persistent State **Files:** - Modify: `server/src/app/services/steward_runtime_decision_agent.py` - Test: `server/tests/test_steward_runtime_decision_agent.py` - [ ] **Step 1: Write failing test** Add a test proving runtime decision uses `context_json.conversation_state.steward_state` when `runtime_state` is empty. - [ ] **Step 2: Implement minimal fallback hydration** Normalize runtime state by merging request runtime state with persisted steward state. - [ ] **Step 3: Run green test** Run: ```bash docker exec -w /app -e SERVER_VENV_DIR=/tmp/x-financial-server-venv x-financial-main /tmp/x-financial-server-venv/bin/pytest -q server/tests/test_steward_runtime_decision_agent.py ``` ### Task 4: Frontend State Carry **Files:** - Modify: `web/src/views/scripts/stewardPlanModel.js` - Modify: `web/src/views/scripts/TravelReimbursementCreateView.js` - Modify: `web/src/views/scripts/useTravelReimbursementSessionState.js` - [ ] **Step 1: Preserve steward state from backend responses** Normalize `conversation_id` and `steward_state` from plan/runtime responses into the local session model. - [ ] **Step 2: Send steward state in later requests** Include the current `steward_state` under `context_json` for plan and runtime decision calls. - [ ] **Step 3: Build frontend** Run: ```bash docker exec -w /app/web x-financial-main npm run build ``` Expected: build succeeds. ### Task 5: Final Verification - [ ] **Step 1: Run backend steward tests** ```bash docker exec -w /app -e SERVER_VENV_DIR=/tmp/x-financial-server-venv x-financial-main /tmp/x-financial-server-venv/bin/pytest -q server/tests/test_steward_flow_state.py server/tests/test_steward_planner.py server/tests/test_steward_runtime_decision_agent.py server/tests/test_steward_slot_decision_agent.py ``` - [ ] **Step 2: Run frontend build** ```bash docker exec -w /app/web x-financial-main npm run build ``` - [ ] **Step 3: Report workspace status** Run: ```bash git status --short ```