471 lines
17 KiB
Markdown
471 lines
17 KiB
Markdown
# 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"
|
||
```
|