# Rule DSL Extract Preservation 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:** Prevent the rule editor from deleting `extract` declarations when backend rule summaries are present.

**Architecture:** Parse the full YAML into the frontend pack first, then overlay backend rule summaries only for the rule list. Add a save-time guard so a lossy editor model cannot overwrite existing YAML sections with empty generated sections.

**Tech Stack:** Next.js frontend utilities, TypeScript, Node test runner, `yaml` package.

---

### Task 1: Preserve parsed YAML fields when summary rules are returned

**Files:**
- Modify: `legal-platform-frontend/lib/utils/rules-config-packs.server.ts`
- Test: `legal-platform-frontend/tests/govdoc-audit/rule-config-pack-summary-preserve.test.mts`

- [ ] **Step 1: Write failing test**

Create a test that calls `mapApiPackToRuleYamlPack` with both `yamlText` and `rules`, then asserts that `fields` still contains `委托方`.

- [ ] **Step 2: Run failing test**

Run: `cd legal-platform-frontend && node --import tsx --test tests/govdoc-audit/rule-config-pack-summary-preserve.test.mts`

Expected: FAIL because current summary branch returns `fields: []`.

- [ ] **Step 3: Implement minimal mapping fix**

Change `mapApiPackToRuleYamlPack` to always build `basePack = buildRuleYamlPack(...)`, then return `{ ...basePack, rules: normalizedRules, stats: { ...basePack.stats, ruleCount: normalizedRules.length } }`.

- [ ] **Step 4: Run passing test**

Run: `cd legal-platform-frontend && node --import tsx --test tests/govdoc-audit/rule-config-pack-summary-preserve.test.mts`

Expected: PASS.

### Task 2: Add save-time lossy section guard

**Files:**
- Modify: `legal-platform-frontend/lib/utils/rules-config-editor.ts`
- Test: `legal-platform-frontend/tests/govdoc-audit/rule-config-editor-preserve.test.mts`

- [ ] **Step 1: Write failing test**

Create a test that serializes a config with original `yamlSource.extract` but empty `fields`, and assert it throws a clear error instead of returning YAML with `extract: []`.

- [ ] **Step 2: Run failing test**

Run: `cd legal-platform-frontend && node --import tsx --test tests/govdoc-audit/rule-config-editor-preserve.test.mts`

Expected: FAIL because current serializer silently overwrites `extract`.

- [ ] **Step 3: Implement guard**

Before assigning `root.extract`, check whether the original YAML section exists and the editor model is empty. Throw `字段抽取配置未加载完成，已阻止保存，避免覆盖原 YAML extract。`.

- [ ] **Step 4: Run passing test**

Run: `cd legal-platform-frontend && node --import tsx --test tests/govdoc-audit/rule-config-editor-preserve.test.mts`

Expected: PASS.

### Task 3: Verify current JY rule remains valid after frontend serialization

**Files:**
- No production code changes expected.

- [ ] **Step 1: Run focused frontend tests**

Run both new tests plus existing rule YAML parser tests.

- [ ] **Step 2: Run backend validator smoke test**

Use `RuleValidator` on a representative YAML to confirm `extract` and rule field references are coherent.
