# Full Business Structuring 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:** 把 PMFlow 的问答、推荐、澄清、闲聊和非 planmode 信号源写入升级成一套无硬性语义、可纠错、可停住、可直接执行的全量业务结构主链。 **Architecture:** 在现有 `InteractionBoundaryPacket / AnswerControlDecision` 基础上新增 `BusinessSemanticFrame / AnswerShapeContract / RecommendationCandidateSet / ClarificationDelta / OperationIntentContract`。统一语义规划层一次产出层级边界、业务目标、回答形状和操作意图;route/gateway/presenter/executor 只消费结构,不再各自用词面语义拍板。non-planmode 下,recommendation 后续动作默认走 `prepare_write -> confirm_write -> execute_write`,不再默认 `draft_pending_confirm`。 **Tech Stack:** Python 3.11, FastAPI, Pydantic v2, SQLAlchemy 2.x, AdaptiveRAG, AI PMO semantic planner, pytest --- ### Task 1: Add Business Semantic Frame Contracts **Files:** - Create: `backend/app/services/ai_pmo/semantic_context/business_frame_schema.py` - Modify: `backend/app/services/ai_pmo/semantic_context/decision_schema.py` - Modify: `backend/app/services/ai_pmo/semantic_context/__init__.py` - Test: `backend/tests/test_business_semantic_frame_contract.py` - [ ] **Step 1: Write the failing schema contract tests** ```python def test_business_semantic_frame_supports_signal_source_recommendation(): frame = BusinessSemanticFrame( goal_kind="recommendation", target_scope="current_project", resource_role="signal_source", source_kind="external", expected_answer_shape="ranked_candidates", conversation_posture="business_operating", ) assert frame.goal_kind == "recommendation" assert frame.resource_role == "signal_source" def test_operation_intent_contract_supports_non_plan_write_phases(): contract = OperationIntentContract( intent_phase="prepare_write", requires_confirmation=True, ) assert contract.intent_phase == "prepare_write" ``` - [ ] **Step 2: Run the tests to verify they fail** Run: ```bash backend/venv/bin/python -m pytest backend/tests/test_business_semantic_frame_contract.py -q ``` Expected: FAIL because `BusinessSemanticFrame` / `OperationIntentContract` do not exist yet. - [ ] **Step 3: Add minimal schema definitions** Implement: - `BusinessSemanticFrame` - `AnswerShapeContract` - `ClarificationDelta` - `CorrectionDelta` - `OperationIntentContract` Keep them in `business_frame_schema.py`, and only re-export them via `semantic_context/__init__.py`. - [ ] **Step 4: Re-run the tests** Run: ```bash backend/venv/bin/python -m pytest backend/tests/test_business_semantic_frame_contract.py -q ``` Expected: PASS. - [ ] **Step 5: Commit** ```bash git add backend/app/services/ai_pmo/semantic_context/business_frame_schema.py \ backend/app/services/ai_pmo/semantic_context/decision_schema.py \ backend/app/services/ai_pmo/semantic_context/__init__.py \ backend/tests/test_business_semantic_frame_contract.py git commit -m "feat: add business semantic frame contracts" ``` ### Task 2: Extend Planner Output With Structured Business Frame **Files:** - Modify: `backend/app/services/ai_pmo/workflow_semantic_planner/service.py` - Modify: `backend/app/services/ai_pmo/semantic_context/semantic_decision_service.py` - Modify: `backend/app/services/ai_pmo/semantic_context/packet_schema.py` - Test: `backend/tests/test_workflow_semantic_planner.py` - Test: `backend/tests/test_semantic_decision_service.py` - [ ] **Step 1: Add failing planner tests for business-frame output** Add tests that assert: - recommendation ask yields `goal_kind="recommendation"` - current-project external signal-source ask yields: - `resource_role="signal_source"` - `source_kind="external"` - `expected_answer_shape="ranked_candidates"` - casual chat yields: - `goal_kind="casual_chat"` - `expected_answer_shape="social_reply"` - [ ] **Step 2: Run the planner tests to verify they fail** Run: ```bash backend/venv/bin/python -m pytest \ backend/tests/test_workflow_semantic_planner.py \ backend/tests/test_semantic_decision_service.py -k "business_frame or casual_chat" -q ``` Expected: FAIL because planner bundle does not yet populate the new frame. - [ ] **Step 3: Implement minimal planner/frame wiring** Update planner and semantic decision service so bundle output can carry: - `interaction_boundary` - `business_frame` - `answer_shape_contract` - `operation_intent_contract` Do not add keyword lists or regex routing. Consume planner-structured output only. - [ ] **Step 4: Re-run the planner tests** Run: ```bash backend/venv/bin/python -m pytest \ backend/tests/test_workflow_semantic_planner.py \ backend/tests/test_semantic_decision_service.py -k "business_frame or casual_chat" -q ``` Expected: PASS. - [ ] **Step 5: Commit** ```bash git add backend/app/services/ai_pmo/workflow_semantic_planner/service.py \ backend/app/services/ai_pmo/semantic_context/semantic_decision_service.py \ backend/app/services/ai_pmo/semantic_context/packet_schema.py \ backend/tests/test_workflow_semantic_planner.py \ backend/tests/test_semantic_decision_service.py git commit -m "feat: add structured business frame to planner bundles" ``` ### Task 3: Persist Recommendation Candidate Sets **Files:** - Modify: `backend/app/services/external_query_service/schemas.py` - Modify: `backend/app/services/external_query_service/planner.py` - Modify: `backend/app/services/external_query_service/presenter.py` - Modify: `backend/app/services/adaptive_rag_service/mixin_answer_payload.py` - Test: `backend/tests/test_external_query_planner.py` - Test: `backend/tests/test_ai_pmo_qa_http_mainline_e2e.py` - [ ] **Step 1: Add failing tests for durable candidate sets** Add tests that assert recommendation answers now produce: - `candidate_set_id` - `project_binding` - at least 3 `candidates[]` - each candidate includes: - `candidate_ref` - `display_name` - `business_value` - `why_now` - [ ] **Step 2: Run the recommendation tests to verify they fail** Run: ```bash backend/venv/bin/python -m pytest \ backend/tests/test_external_query_planner.py \ backend/tests/test_ai_pmo_qa_http_mainline_e2e.py -k "candidate_set or recommendation" -q ``` Expected: FAIL because recommendation output is still mainly presentational. - [ ] **Step 3: Implement minimal candidate-set persistence** Update external-query schemas/planner/payload so recommendation results carry a structured `RecommendationCandidateSet`. The presenter should still render business Chinese, but payload must now preserve machine-consumable candidate refs for follow-up writes. - [ ] **Step 4: Re-run the recommendation tests** Run: ```bash backend/venv/bin/python -m pytest \ backend/tests/test_external_query_planner.py \ backend/tests/test_ai_pmo_qa_http_mainline_e2e.py -k "candidate_set or recommendation" -q ``` Expected: PASS. - [ ] **Step 5: Commit** ```bash git add backend/app/services/external_query_service/schemas.py \ backend/app/services/external_query_service/planner.py \ backend/app/services/external_query_service/presenter.py \ backend/app/services/adaptive_rag_service/mixin_answer_payload.py \ backend/tests/test_external_query_planner.py \ backend/tests/test_ai_pmo_qa_http_mainline_e2e.py git commit -m "feat: persist recommendation candidate sets" ``` ### Task 4: Make Clarification And Correction Update Structured Truth **Files:** - Modify: `backend/app/services/adaptive_rag_service/mixin_session_state.py` - Modify: `backend/app/services/adaptive_rag_service/mixin_followup_anchor.py` - Modify: `backend/app/services/adaptive_rag_service/mixin_answer_mainline.py` - Test: `backend/tests/test_adaptive_rag_external_followup_contract.py` - Test: `backend/tests/test_adaptive_rag_mainline_contract.py` - [ ] **Step 1: Add failing correction/clarify tests** Add tests that assert follow-up messages like: - `不是现状,我要推荐` - `不是这个项目,是 AI客服` - `别起草,现在直接写入` cause structured updates to: - `goal_kind` - `expected_answer_shape` - `project_binding` - `candidate_set_binding` - [ ] **Step 2: Run the tests to verify they fail** Run: ```bash backend/venv/bin/python -m pytest \ backend/tests/test_adaptive_rag_external_followup_contract.py \ backend/tests/test_adaptive_rag_mainline_contract.py -k "clarify or correction or candidate_set" -q ``` Expected: FAIL because current logic updates pending/session state more than structural truth. - [ ] **Step 3: Implement structural deltas** Add `ClarificationDelta / CorrectionDelta` handling so clarification/correction rewrites the current business frame rather than only appending chat-state hints. - [ ] **Step 4: Re-run the tests** Run: ```bash backend/venv/bin/python -m pytest \ backend/tests/test_adaptive_rag_external_followup_contract.py \ backend/tests/test_adaptive_rag_mainline_contract.py -k "clarify or correction or candidate_set" -q ``` Expected: PASS. - [ ] **Step 5: Commit** ```bash git add backend/app/services/adaptive_rag_service/mixin_session_state.py \ backend/app/services/adaptive_rag_service/mixin_followup_anchor.py \ backend/app/services/adaptive_rag_service/mixin_answer_mainline.py \ backend/tests/test_adaptive_rag_external_followup_contract.py \ backend/tests/test_adaptive_rag_mainline_contract.py git commit -m "feat: apply structural deltas for clarification and correction" ``` ### Task 5: Split Non-Planmode Direct Write From Drafting **Files:** - Modify: `backend/app/services/ai_pmo/ai_pmo_typed_executor_execute/mixin_execute_query_project.py` - Modify: `backend/app/services/ai_pmo/ai_pmo_typed_executor_execute/mixin_execute_signal_source.py` - Modify: `backend/app/services/adaptive_rag_service/mixin_query_route_gateway.py` - Test: `backend/tests/test_ai_pmo_ingress_mainline.py` - Test: `backend/tests/test_feishu_pipeline_queue_contract.py` - Test: `backend/tests/test_feishu_card_action_contract.py` - [ ] **Step 1: Add failing tests for non-plan write flow** Add tests that assert: - non-plan recommendation follow-up `把推荐的写入系统` enters `prepare_write`, not `draft_pending_confirm` - `确认入库` binds to the pending write object, not a fresh unrelated query - queue ack for this path is a write-confirmation, not a requirement draft ack - [ ] **Step 2: Run the non-plan write tests to verify they fail** Run: ```bash backend/venv/bin/python -m pytest \ backend/tests/test_ai_pmo_ingress_mainline.py \ backend/tests/test_feishu_pipeline_queue_contract.py \ backend/tests/test_feishu_card_action_contract.py -k "prepare_write or confirm_write or execute_write or non_plan" -q ``` Expected: FAIL because current runtime still defaults to draft-ish handling or loses confirm binding. - [ ] **Step 3: Implement `prepare_write -> confirm_write -> execute_write`** Update query/signal-source execution path so: - outside plan mode, signal-source writes do not default to draft - explicit recommendation follow-ups use candidate-set bindings - confirm messages resolve the pending write object through strong anchors - [ ] **Step 4: Re-run the non-plan write tests** Run: ```bash backend/venv/bin/python -m pytest \ backend/tests/test_ai_pmo_ingress_mainline.py \ backend/tests/test_feishu_pipeline_queue_contract.py \ backend/tests/test_feishu_card_action_contract.py -k "prepare_write or confirm_write or execute_write or non_plan" -q ``` Expected: PASS. - [ ] **Step 5: Commit** ```bash git add backend/app/services/ai_pmo/ai_pmo_typed_executor_execute/mixin_execute_query_project.py \ backend/app/services/ai_pmo/ai_pmo_typed_executor_execute/mixin_execute_signal_source.py \ backend/app/services/adaptive_rag_service/mixin_query_route_gateway.py \ backend/tests/test_ai_pmo_ingress_mainline.py \ backend/tests/test_feishu_pipeline_queue_contract.py \ backend/tests/test_feishu_card_action_contract.py git commit -m "feat: add non-plan signal-source write confirmation flow" ``` ### Task 6: Fold Casual Chat Into Structured Runtime **Files:** - Modify: `backend/app/services/ai_pmo/ai_pmo_typed_executor_execute/mixin_execute_query_project.py` - Modify: `backend/app/services/ai_pmo/workflow_semantic_planner/service.py` - Test: `backend/tests/test_ai_pmo_ingress_mainline.py` - Test: `backend/tests/test_feishu_pipeline_queue_contract.py` - [ ] **Step 1: Add failing casual-chat tests** Add tests that assert: - greetings produce `goal_kind="casual_chat"` and `expected_answer_shape="social_reply"` - casual chat no longer depends on local lexical semantic shortcuts - switching from casual chat back to business rebuilds business frame cleanly - [ ] **Step 2: Run the casual-chat tests to verify they fail** Run: ```bash backend/venv/bin/python -m pytest \ backend/tests/test_ai_pmo_ingress_mainline.py \ backend/tests/test_feishu_pipeline_queue_contract.py -k "casual_chat or social_reply" -q ``` Expected: FAIL because current direct shortcut logic is still present. - [ ] **Step 3: Implement structured casual-chat posture** Replace executor-local semantic shortcuts with planner-fed `goal_kind="casual_chat"` / `expected_answer_shape="social_reply"` handling. - [ ] **Step 4: Re-run the casual-chat tests** Run: ```bash backend/venv/bin/python -m pytest \ backend/tests/test_ai_pmo_ingress_mainline.py \ backend/tests/test_feishu_pipeline_queue_contract.py -k "casual_chat or social_reply" -q ``` Expected: PASS. - [ ] **Step 5: Commit** ```bash git add backend/app/services/ai_pmo/ai_pmo_typed_executor_execute/mixin_execute_query_project.py \ backend/app/services/ai_pmo/workflow_semantic_planner/service.py \ backend/tests/test_ai_pmo_ingress_mainline.py \ backend/tests/test_feishu_pipeline_queue_contract.py git commit -m "feat: route casual chat through structured business frame" ``` ### Task 7: Build Broad Scenario Regression Matrix And Docs Sync **Files:** - Modify: `backend/tests/test_ai_pmo_ingress_mainline.py` - Modify: `backend/tests/test_ai_pmo_qa_http_mainline_e2e.py` - Modify: `backend/tests/test_external_query_planner.py` - Modify: `backend/tests/test_feishu_card_action_contract.py` - Modify: `docs/architecture/RUNTIME_GUARDRAILS.md` - Modify: `docs/architecture/CODE_REFERENCE_INDEX.md` - Modify: `docs/architecture/ARCHITECTURE_INVENTORY.md` - Modify: `CLAUDE.md` - [ ] **Step 1: Add failing broad-matrix tests for the highest-risk cases** Select at least these first: - recommendation stays recommendation - recommendation survives correction - recommendation feeds direct write - confirm binds to prior write object - casual chat and business switch do not pollute each other - sparse project still produces bounded business reasoning - [ ] **Step 2: Run the matrix subset to verify it fails where expected** Run: ```bash backend/venv/bin/python -m pytest \ backend/tests/test_ai_pmo_ingress_mainline.py \ backend/tests/test_ai_pmo_qa_http_mainline_e2e.py \ backend/tests/test_external_query_planner.py \ backend/tests/test_feishu_card_action_contract.py -k "recommendation or confirm_write or casual_chat or sparse" -q ``` Expected: mixed FAIL until prior tasks are complete. - [ ] **Step 3: Finish doc sync** Update runtime docs to reflect: - no hard semantics / no regex semantic routing - BusinessSemanticFrame and CandidateSet truth sources - non-planmode direct write path - broad scenario matrix as the new quality baseline - [ ] **Step 4: Re-run the matrix subset and py_compile** Run: ```bash backend/venv/bin/python -m pytest \ backend/tests/test_ai_pmo_ingress_mainline.py \ backend/tests/test_ai_pmo_qa_http_mainline_e2e.py \ backend/tests/test_external_query_planner.py \ backend/tests/test_feishu_card_action_contract.py -k "recommendation or confirm_write or casual_chat or sparse" -q backend/venv/bin/python -m py_compile \ backend/app/services/ai_pmo/semantic_context/business_frame_schema.py \ backend/app/services/ai_pmo/workflow_semantic_planner/service.py \ backend/app/services/adaptive_rag_service/mixin_query_route_gateway.py \ backend/app/services/ai_pmo/ai_pmo_typed_executor_execute/mixin_execute_query_project.py \ backend/app/services/ai_pmo/ai_pmo_typed_executor_execute/mixin_execute_signal_source.py \ backend/app/services/external_query_service/planner.py ``` Expected: PASS. - [ ] **Step 5: Commit** ```bash git add backend/tests/test_ai_pmo_ingress_mainline.py \ backend/tests/test_ai_pmo_qa_http_mainline_e2e.py \ backend/tests/test_external_query_planner.py \ backend/tests/test_feishu_card_action_contract.py \ docs/architecture/RUNTIME_GUARDRAILS.md \ docs/architecture/CODE_REFERENCE_INDEX.md \ docs/architecture/ARCHITECTURE_INVENTORY.md \ CLAUDE.md git commit -m "test: add full-business structuring regression matrix" ```