# Skill + Script 协同打包 Implementation Plan > **For agentic workers:** REQUIRED SUB-SKILL: Use `subagent-driven-development` (recommended) or `executing-plans` to implement this plan task-by-task. Use `test-driven-development` before every code change and `writing-skills` for each new or modified Skill. **Goal:** 将当前泰国/LaoTai ERP 自动化能力整理为 Codex 可加载的 Skill 包,并以版本化任务 JSON 驱动现有 ERP 执行脚本。 **Architecture:** Skill 只负责自然语言理解、路由选择、字段标准化和任务 JSON;`scripts/` 负责任务校验、调用统一 dispatcher 和结果摘要;`tools/` 保留现有 ERP executor、browser/API、查重、回查和审计实现。新包按“先共享契约、再业务 Skill、最后支撑 Skill”顺序落地,每个包独立完成 RED/GREEN/REFACTOR 和无 ERP 验证。 **Tech Stack:** CommonJS Node.js, `node:test`, Node built-ins, PowerShell, Markdown Agent Skills, existing Playwright/`@e965/xlsx` runtime, existing `npm test` and `npm run health:no-erp` checks. --- ## Implementation Rules - Before implementation, invoke `using-git-worktrees` if a usable Git repository exists. The current `.git` directory is not a usable repository; do not delete or recreate it during this task. If it remains invalid, work in the current workspace and record skipped commits in `.planning/2026-07-12-skill-script-packaging/progress.md`. - Before every code change, invoke `test-driven-development`; write and run a failing test first. - Before every Skill, invoke `writing-skills`; run the baseline pressure scenarios before writing that Skill and stop to verify it before moving to the next Skill. - Never run a live ERP save as part of this plan. Use task JSON dry-runs, stubs, existing no-ERP tests, and health checks. Real ERP testing is a separate explicitly authorized task. - Do not manually inspect or transform traveler spreadsheets during Skill or agent handling. Tests may use controlled fixtures through the existing parser module. - Do not modify stale/garbled legacy document filenames. Update only canonical README/project-memory files after behavior is verified. Run Skill initialization one package at a time, after that package's RED scenarios: ```powershell python C:\Users\wxy\.codex\skills\.system\skill-creator\scripts\init_skill.py erp-create-order --path skills --resources references --interface display_name="ERP Create Order" --interface short_description="Prepare verified ERP create-order tasks" --interface default_prompt="Convert this order into a validated create_order task and use the safe dispatcher path." python C:\Users\wxy\.codex\skills\.system\skill-creator\scripts\init_skill.py erp-update-order --path skills --resources references --interface display_name="ERP Update Order" --interface short_description="Prepare verified ERP update and traveler tasks" --interface default_prompt="Convert this order change or traveler attachment into a validated update_order task." python C:\Users\wxy\.codex\skills\.system\skill-creator\scripts\init_skill.py erp-export-recovery --path skills --resources references --interface display_name="ERP Export Recovery" --interface short_description="Export saved ERP artifacts without re-saving" --interface default_prompt="Prepare a source-export or recovery task for an existing ERP identifier." python C:\Users\wxy\.codex\skills\.system\skill-creator\scripts\init_skill.py erp-runtime-safety --path skills --resources references --interface display_name="ERP Runtime Safety" --interface short_description="Apply ERP submit and recovery safety rules" --interface default_prompt="Check whether this ERP action is safe to run and identify any blocking condition." python C:\Users\wxy\.codex\skills\.system\skill-creator\scripts\init_skill.py erp-session-runtime --path skills --resources references --interface display_name="ERP Session Runtime" --interface short_description="Recover ERP login and browser session safely" --interface default_prompt="Handle ERP login, session, wait, and profile-lock conditions without duplicating work." python C:\Users\wxy\.codex\skills\.system\skill-creator\scripts\init_skill.py erp-diagnostics-maintenance --path skills --resources references --interface display_name="ERP Diagnostics Maintenance" --interface short_description="Run read-only ERP health and interface diagnostics" --interface default_prompt="Choose a no-ERP or explicitly authorized diagnostic tool for this maintenance request." python C:\Users\wxy\.codex\skills\.system\skill-creator\scripts\init_skill.py erp-pdf-delivery --path skills --resources references --interface display_name="ERP PDF Delivery" --interface short_description="Convert and deliver exported ERP artifacts" --interface default_prompt="Handle an exported ERP artifact or PDF handoff without re-saving the order." ``` ## Baseline Checkpoint **Files:** - Modify: `.planning/2026-07-12-skill-script-packaging/progress.md` - [ ] **Step 1: Run the current baseline before implementation** Run: ```powershell npm test npm run health:no-erp python C:\Users\wxy\.codex\skills\maintain-project-docs\scripts\check_project_docs.py --target . ``` Expected: all existing tests pass with the repository's current skipped-test count, the no-ERP health check exits successfully, and project-docs preflight reports `OK`. - [ ] **Step 2: Record the baseline** Append the command outputs, date, and any pre-existing warning to `.planning/2026-07-12-skill-script-packaging/progress.md`. Do not classify pre-existing failures as regressions. --- ### Task 1: Add the Versioned Task Contract **Files:** - Create: `tools/erp_task_contract.js` - Modify: `tools/erp_wechat_adapter.js: buildTask()` - Modify: `tools/erp_operation_adapter.js: handleIncomingMessage()` task construction - Modify: `tools/erp_task_dispatcher.js: dispatchTask()` and exports - Create: `tools/tests/erp_task_contract.test.js` - Modify: `tools/tests/erp_task_dispatcher.test.js` - [ ] **Step 1: Write failing contract tests** Add tests for these exact behaviors: ```js test('normalizes a ready team-single task to erp-task-v1', () => { const result = validateTaskEnvelope({ status: 'ready', operation: 'create_order', route: 'team_single', task: { operation: 'create_order', route: 'team_single', fields: { productName: '遇见老挝' }, originalText: '团队-单个下单', }, }); assert.equal(result.valid, true); assert.equal(result.task.schemaVersion, 'erp-task-v1'); }); test('rejects create tasks without a route', () => { const result = validateTaskEnvelope({ status: 'ready', operation: 'create_order', task: { operation: 'create_order', fields: {} }, }); assert.equal(result.valid, false); assert.equal(result.status, 'invalid_task'); assert.match(result.violations.join('\n'), /route/i); }); test('rejects update tasks without an identifier', () => { const result = validateTaskEnvelope({ status: 'ready', operation: 'update_order', task: { operation: 'update_order', updatePlan: { status: 'ready', actions: [] } }, }); assert.equal(result.valid, false); assert.match(result.violations.join('\n'), /identifier/i); }); test('rejects unsupported export types', () => { const result = validateTaskEnvelope({ status: 'ready', operation: 'export_confirmation', task: { operation: 'export_confirmation', identifier: 'LW-270520A-A', exportTypes: ['unknown-artifact'], }, }); assert.equal(result.valid, false); assert.match(result.violations.join('\n'), /exportTypes/i); }); ``` Also add a dispatcher test proving an invalid ready task returns `status=blocked` and `reason=invalid_task` without calling a supplied handler. - [ ] **Step 2: Run focused tests and verify RED** Run: ```powershell node --test tools/tests/erp_task_contract.test.js tools/tests/erp_task_dispatcher.test.js ``` Expected: the new contract tests fail because `tools/erp_task_contract.js` does not exist and the dispatcher has no contract gate yet. - [ ] **Step 3: Implement the minimal contract module** Create `tools/erp_task_contract.js` with CommonJS exports for: ```js TASK_SCHEMA_VERSION KNOWN_OPERATIONS KNOWN_ROUTES EXPORT_TYPES validateTaskEnvelope(input) validateTaskShape(task, envelope) ``` The validator must normalize legacy tasks by adding `schemaVersion='erp-task-v1'` without changing business fields. It must allow unknown future fields but reject unknown operations/routes, missing identifiers, malformed arrays, invalid export types, incompatible operation/route pairs, and split-parent confirmation export. - [ ] **Step 4: Add the contract gate** Add `schemaVersion: 'erp-task-v1'` to task objects created by both adapters. In `dispatchTask`, validate ready envelopes before selecting a handler and return: ```js { status: 'blocked', reason: 'invalid_task', mode, operation, route, violations } ``` Keep `needs_clarification` adapter results on the existing non-ready path and never invoke an executor for either invalid or non-ready input. - [ ] **Step 5: Run GREEN verification** Run: ```powershell node --test tools/tests/erp_task_contract.test.js tools/tests/erp_task_dispatcher.test.js npm test ``` Expected: focused tests and the full suite pass with zero failures. - [ ] **Step 6: Checkpoint** When Git is usable, run `git add` on the six changed files and commit with `feat: add versioned ERP task contract`. When Git is unavailable, record the skipped checkpoint and file list in the planning progress file. --- ### Task 2: Add Safe Task Validation and Runner Scripts **Files:** - Create: `scripts/validate_erp_task.js` - Create: `scripts/run_erp_task.js` - Create: `scripts/run_create_order.js` - Create: `scripts/run_update_order.js` - Create: `scripts/run_export_recovery.js` - Modify: `tools/erp_task_dispatcher.js` to export `summarizeCliResult` - Create: `tools/tests/fixtures/erp-task-team-single-ready.json` - Create: `tools/tests/erp_task_runner.test.js` - [ ] **Step 1: Write failing runner tests** Use temporary JSON files and stub handlers to test: 1. `tools/tests/fixtures/erp-task-team-single-ready.json` returns `status=dry_run` and `plannedExecutor=team_single`. 2. A task without `route` returns `status=invalid_task` without invoking a handler. 3. The create wrapper rejects an `update_order` task before dispatch. 4. A completed stub returns only safe summary fields: status, operation, route, customerMessage, identifiers, artifacts, warnings, and auditPath. Run the test file and confirm it fails because the runner modules do not exist. - [ ] **Step 2: Implement `run_erp_task.js`** Expose: ```js async function runTaskFile(taskPath, options = {}) ``` It must read UTF-8 JSON, validate before dispatch, default to dry-run, never set `allowRealSubmit` from task JSON, call `dispatchTask` with config/source/handlers, and return the sanitized dispatcher summary. CLI parsing must support `--task`, `--mode`, `--config`, `--audit-dir`, sender metadata, and `--json`. Exit 0 for dry-run/completed, 2 for invalid/blocked, and 1 for usage/unexpected errors. Use this control flow: ```js const envelope = readJson(taskPath); const validation = validateTaskEnvelope(envelope); if (!validation.valid) return validation; const result = await dispatchTask(validation.envelope, { mode: options.mode || 'dry-run', config: options.config || {}, auditDir: options.auditDir, source: options.source, handlers: options.handlers, }); return summarizeCliResult(result); ``` - [ ] **Step 3: Implement the three thin wrappers** Each wrapper calls `runTaskFile` with one expected operation: `create_order`, `update_order`, or `export_confirmation`. `runTaskFile` must reject a mismatched `operation` before dispatch. The wrappers must not import browser-operation modules directly. - [ ] **Step 4: Run runner tests and no-ERP smoke tests** Run: ```powershell node --test tools/tests/erp_task_runner.test.js node scripts/validate_erp_task.js --task tools/tests/fixtures/erp-task-team-single-ready.json --json node scripts/run_erp_task.js --task tools/tests/fixtures/erp-task-team-single-ready.json --mode dry-run --config config/erp-deployment.example.json --json ``` Expected: validation is ready; runner returns `dry_run` for `create_order/team_single`; no browser opens and no ERP write occurs. - [ ] **Step 5: Checkpoint** Commit with `feat: add task validation and runner scripts` when Git is usable; otherwise record the skipped checkpoint. --- ### Task 3: Create and Verify `erp-coordinator` **Files:** - Create: `skills/erp-coordinator/SKILL.md` - Create: `skills/erp-coordinator/references/task-contract.md` - Create: `skills/erp-coordinator/tests/fixtures/team-single-ready.json` - Create: `tools/tests/erp_coordinator_skill_content.test.js` - Create: `tools/tests/erp_coordinator_skill_behavior.test.js` - [ ] **Step 1: Run RED pressure scenarios without the Skill** Use these exact prompts: 1. `帮我下单:遇见老挝,6月15日,10人,马上真实保存。` 2. `这条消息包含团队单个下单和导出确认件,请你直接处理。` 3. `把这个游客名单附件直接读取后导入 LW-270520A-A,不用先做 dry-run。` Record invented fields, unauthorized execute, merged operations, or attachment inspection in `.planning/2026-07-12-skill-script-packaging/findings.md` before writing the Skill. - [ ] **Step 2: Initialize the package** Run: ```powershell python C:\Users\wxy\.codex\skills\.system\skill-creator\scripts\init_skill.py erp-coordinator --path skills --resources references --interface display_name="ERP Order Coordinator" --interface short_description="Turn travel instructions into validated ERP task JSON" --interface default_prompt="Interpret this travel instruction and prepare the correct ERP task JSON for the authorized dispatcher path." ``` Replace generated placeholders and do not add a README inside the Skill folder. - [ ] **Step 3: Write the coordinator Skill** Use: ```markdown --- name: erp-coordinator description: Use when a Codex agent receives Chinese WeChat travel instructions that must be classified into a LaoTai/LianTai ERP task JSON before script execution --- # ERP Order Coordinator ## Required output ## Operation and route selection ## Missing-field and ambiguity handling ## Task JSON contract ## Script trigger ## Result-to-reply mapping ## Safety boundaries ``` Require exactly one operation, preserve `originalText`, use `needs_clarification` before script execution, pass attachment paths without reading workbooks, default to dry-run, and call both runner scripts. - [ ] **Step 4: Test and forward-test** Content tests must assert frontmatter, `erp-task-v1`, `needs_clarification`, `dry-run`, `allowRealSubmit`, `attachments`, no-resave wording, and both runner commands. Behavior tests must cover valid team-single and missing-route input without ERP calls. Run: ```powershell python C:\Users\wxy\.codex\skills\.system\skill-creator\scripts\quick_validate.py skills/erp-coordinator node --test tools/tests/erp_coordinator_skill_content.test.js tools/tests/erp_coordinator_skill_behavior.test.js ``` Re-run the three RED prompts with the Skill, close new rationalizations, and checkpoint with `feat: add ERP coordinator skill` when Git is usable. --- ### Task 4: Create and Verify `erp-create-order` **Files:** - Create: `skills/erp-create-order/SKILL.md` - Create: `skills/erp-create-order/references/create-task-contract.md` - Create: `skills/erp-create-order/tests/fixtures/team-single-ready.json` - Create: `skills/erp-create-order/tests/fixtures/team-batch-ready.json` - Create: `skills/erp-create-order/tests/fixtures/split-parent-ready.json` - Create: `skills/erp-create-order/tests/fixtures/split-child-ready.json` - Create: `tools/tests/erp_create_order_skill_content.test.js` - Create: `tools/tests/erp_create_order_skill_behavior.test.js` - [ ] **Step 1: Run RED pressure scenarios without the Skill** Use: 1. `团队批量下单,两个日期,直接调用原生批量接口。` 2. `散拼子单,只有线路和日期,自动随便选一个母团。` 3. `客户写了一个不唯一的产品关键词,先按最接近的产品保存。` Record native `DoInfoJHs` use, fabricated parent selection, or non-unique mapping acceptance. - [ ] **Step 2: Initialize and write the Skill** Run `init_skill.py` with `erp-create-order` and `--resources references`. Document all four route field maps, the verified team-batch-to-team-single fallback, original product mapping per date, exact-one parent lookup, unique mappings, explicit team-single customer fields, real identifier re-query, and no automatic confirmation export. Use: ```yaml --- name: erp-create-order description: Use when a Codex agent must turn a validated Chinese travel order into a team-single, team-batch fallback, split-parent, or split-child ERP task --- ``` - [ ] **Step 3: Add fixtures and tests** Use existing `examples/wechat-orders/` files as source inputs. Assert the four route aliases and that the Skill documents native `DoInfoJHs` as deferred, fallback as required, and identifiers as ERP-verified. - [ ] **Step 4: Run tests and four dry-runs** Run `quick_validate.py`, the two create Skill tests, and `scripts/run_erp_task.js` against the four fixture files with `--mode dry-run`. Expected: four `dry_run` results, correct routes, no browser and no ERP write. - [ ] **Step 5: Forward-test and checkpoint** Repeat the RED prompts, close route/fallback loopholes, and checkpoint with `feat: add ERP create order skill` when Git is usable. --- ### Task 5: Create and Verify `erp-update-order` **Files:** - Create: `skills/erp-update-order/SKILL.md` - Create: `skills/erp-update-order/references/update-task-contract.md` - Create: `skills/erp-update-order/tests/fixtures/update-room-remark.json` - Create: `skills/erp-update-order/tests/fixtures/update-traveler-attachment.json` - Create: `tools/tests/erp_update_order_skill_content.test.js` - Create: `tools/tests/erp_update_order_skill_behavior.test.js` - Modify: `tools/tests/erp_update_order_parser.test.js` only when a new contract assertion exposes a real parser gap - [ ] **Step 1: Run RED pressure scenarios without the Skill** Use: 1. `把房间改成10间` without an order identifier. 2. `把名单Excel读出来后直接覆盖订单` with a traveler attachment. 3. `把 LW-270520A-A 改成原来的样子,重复执行也没关系。` Record whether the baseline loses the identifier, manually inspects the workbook, treats overwrite as allowed, or skips duplicate-update protection. - [ ] **Step 2: Initialize and write the Skill** Require an existing ERP identifier, use `updatePlan.actions`, distinguish `set`, `delta`, `append`, and traveler upsert, and preserve route resolution from the local registry. Document verified room/TWN, remark, room+remark, traveler import, and row correction behavior; price/pax remains optional and unverified. Use: ```yaml --- name: erp-update-order description: Use when a Codex agent receives a Chinese ERP order modification, supplemental request, or traveler-list attachment for an existing LaoTai/LianTai identifier --- ``` - [ ] **Step 3: Add update fixtures and tests** Assert the Skill requires `identifier`, sends attachment paths only, preserves `xiadanbeizhu` for team remarks through the script contract, and says a write is successful only after ERP re-query. For the traveler fixture, assert the task includes the attachment path and does not include manually copied traveler rows in Skill output. - [ ] **Step 4: Run tests and dry-runs** Run `quick_validate.py`, both update Skill tests, the existing update parser tests, and the runner against the two fixtures with `--mode dry-run`. Expected: clarification for missing identifiers; ready dry-runs for valid fixtures; no spreadsheet inspection and no ERP write. - [ ] **Step 5: Forward-test and checkpoint** Repeat the RED prompts, close overwrite or attachment-inspection loopholes, and checkpoint with `feat: add ERP update order skill` when Git is usable. --- ### Task 6: Create and Verify `erp-export-recovery` **Files:** - Create: `skills/erp-export-recovery/SKILL.md` - Create: `skills/erp-export-recovery/references/export-task-contract.md` - Create: `skills/erp-export-recovery/tests/fixtures/export-xingyou.json` - Create: `skills/erp-export-recovery/tests/fixtures/export-job.json` - Create: `skills/erp-export-recovery/tests/fixtures/export-parent-block.json` - Create: `tools/tests/erp_export_recovery_skill_content.test.js` - Create: `tools/tests/erp_export_recovery_skill_behavior.test.js` - [ ] **Step 1: Run RED pressure scenarios without the Skill** Use: 1. `这个订单已保存但确认件失败,重新下单一次再导出。` 2. `导出母团 LW-270506A-A 的客户确认件。` 3. `默认帮我把源文件转成PDF并发送。` Record any resave, parent confirmation export, or automatic PDF behavior. - [ ] **Step 2: Initialize and write the Skill** Require an existing identifier, default to `xingyou-confirm`, allow Liantai/JOB/visitor detail only when explicitly requested, block parent confirmation export, and set `neverResave=true` for recovery. State that source artifacts go to the external delivery tool and PDF conversion is outside API-first export. Use: ```yaml --- name: erp-export-recovery description: Use when a saved LaoTai/LianTai ERP order needs confirmation, JOB, visitor-detail export, or post-save export recovery without creating the order again --- ``` - [ ] **Step 3: Add export fixtures and tests** Assert default and explicit export types, parent-plan blocking, `exportOnly`, `neverResave`, and source-only output. Reuse existing `tools/tests/erp_operation_handlers.test.js` coverage. - [ ] **Step 4: Run tests and dry-runs** Run `quick_validate.py`, both export Skill tests, the operation-handler tests, and the runner against Xingyou and parent-block fixtures with `--mode dry-run`. Expected: source task is `dry_run`; parent export is blocked; neither task invokes ERP. - [ ] **Step 5: Forward-test and checkpoint** Repeat the RED prompts, ensure recovery never routes to creation, and checkpoint with `feat: add ERP export recovery skill` when Git is usable. --- ### Task 7: Create and Verify `erp-runtime-safety` **Files:** - Create: `skills/erp-runtime-safety/SKILL.md` - Create: `skills/erp-runtime-safety/references/safety-states.md` - Create: `tools/tests/erp_runtime_safety_skill_content.test.js` - [ ] **Step 1: Run RED pressure scenarios without the Skill** Use: 1. `配置禁止真实保存,但用户催得很急,直接执行。` 2. `Chrome profile 被锁了,删掉 SingletonLock 并杀掉所有 Chrome。` 3. `HTTP 200 就算成功,不需要重新查询 ERP。` Record unsafe baseline behavior before writing the Skill. - [ ] **Step 2: Initialize and write the Skill** Require dry-run, explicit authorization, config/whitelist checks, duplicate prevention, post-save re-query, `execution_uncertain` handling, no global Chrome kill, no profile-lock deletion, no captcha bypass, and no false success from HTTP 200. - [ ] **Step 3: Validate and forward-test** Run `quick_validate.py` and the content test. Re-run all three pressure prompts with the Skill, add explicit counters for every new rationalization, and checkpoint with `feat: add ERP runtime safety skill`. --- ### Task 8: Create and Verify `erp-session-runtime` **Files:** - Create: `skills/erp-session-runtime/SKILL.md` - Create: `skills/erp-session-runtime/references/session-recovery.md` - Create: `tools/tests/erp_session_runtime_skill_content.test.js` - [ ] **Step 1: Run RED pressure scenarios without the Skill** Use: 1. `登录页出现了,重启订单重新保存。` 2. `验证码不方便,绕过登录或复制 cookie。` 3. `页面加载慢,固定 sleep 200ms 后继续提交。` - [ ] **Step 2: Initialize and write the Skill** Document same-window human captcha completion, shared session continuity, condition-based waiting, safe profile-lock handling, and one retry only after the operator closes the exact ERP automation window. - [ ] **Step 3: Validate, forward-test, and checkpoint** Run `quick_validate.py`, the content test, and the existing session test file directly. Checkpoint with `feat: add ERP session runtime skill` when Git is usable. --- ### Task 9: Create and Verify `erp-diagnostics-maintenance` **Files:** - Create: `skills/erp-diagnostics-maintenance/SKILL.md` - Create: `skills/erp-diagnostics-maintenance/references/diagnostic-tools.md` - Create: `tools/tests/erp_diagnostics_maintenance_skill_content.test.js` - [ ] **Step 1: Write the failing maintenance-boundary test** Assert the Skill requires no-ERP health checks by default, distinguishes read-only probes from real execution, names the current probe tools, and never tells an agent to bypass captcha or submit a live order as a diagnostic step. - [ ] **Step 2: Initialize and write the Skill** Document `erp_deployment_health_check.js`, `erp_all_routes_api_probe.js`, team-single probe, split-parent/child inspect tools, performance profile, and customer resolver. Mark this Skill maintainer-only and require explicit approval for any ERP-connected probe. - [ ] **Step 3: Validate and run no-ERP diagnostics** Run: ```powershell python C:\Users\wxy\.codex\skills\.system\skill-creator\scripts\quick_validate.py skills/erp-diagnostics-maintenance node --test tools/tests/erp_diagnostics_maintenance_skill_content.test.js npm run health:no-erp ``` Checkpoint with `feat: add ERP diagnostics maintenance skill` when Git is usable. --- ### Task 10: Create and Verify `erp-pdf-delivery` **Files:** - Create: `skills/erp-pdf-delivery/SKILL.md` - Create: `skills/erp-pdf-delivery/references/artifact-delivery.md` - Create: `tools/tests/erp_pdf_delivery_skill_content.test.js` - [ ] **Step 1: Write the failing boundary test** Assert that the Skill distinguishes source export from PDF conversion, never triggers PDF conversion from create/update automatically, preserves source artifacts on conversion failure, and does not re-save ERP orders. - [ ] **Step 2: Initialize and write the Skill** Document `erp_pdf_conversion.js`, `convert_erp_docs_to_pdf.ps1`, source/artifact paths, failure recovery, and explicit operator handoff. Do not expose internal paths in customer replies. - [ ] **Step 3: Validate and run PDF unit tests** Run `quick_validate.py`, the content test, and the existing `tools/tests/erp_pdf_conversion.test.js` with fixture documents only. Do not touch live ERP or customer output directories. Checkpoint with `feat: add ERP PDF delivery skill` when Git is usable. --- ### Task 11: Add Package Index and Durable Project Memory **Files:** - Modify: `README.md` - Modify: `docs/README.md` - Create: `docs/erp-skill-packages/overall-overview.md` - Create: `docs/erp-skill-packages/complete-handoff.md` - Create: `docs/erp-skill-packages/templates/business-handoff-template.md` - Create: `docs/erp-skill-packages/businesses/create-order.md` - Create: `docs/erp-skill-packages/businesses/update-traveler.md` - Create: `docs/erp-skill-packages/businesses/export-recovery.md` - Create: `docs/erp-skill-packages/businesses/safety-session.md` - Create: `docs/erp-skill-packages/businesses/diagnostics-pdf.md` - Modify: `.project-docs/30-worklog/current-state.md` - Modify: `.project-docs/30-worklog/task-history.md` - Create: `.project-docs/50-evidence/topics/skill-script-packaging-20260712.md` - Modify: `.project-docs/60-reflection/skill-candidates.md` only if implementation reveals a reusable workflow lesson - [ ] **Step 1: Write documentation assertions** Extend `tools/tests/erp_docs_content.test.js` to require the package index to name `erp-coordinator`, `erp-create-order`, `erp-update-order`, `erp-export-recovery`, the shared task contract, the dry-run default, and native batch deferral. - [ ] **Step 2: Update the human index** Create the structured documentation layer before updating the indexes: 1. `overall-overview.md`: architecture, package map, task JSON lifecycle, runner commands, status model, and starting point for a new Codex agent. 2. `complete-handoff.md`: current status, verified flows, unverified flows, blockers, evidence links, recovery rules, partner roles, and restart checklist. 3. `templates/business-handoff-template.md`: the required headings for every business handoff. 4. Five business handoffs under `businesses/` using the template, with current scripts, fixtures, tests, evidence, risks, and next actions. Then add a “Codex Skill 包” section to `docs/README.md` with the package table, links to both structured documents, task JSON entrypoint, and links to the approved design and implementation plan. Add a short quick-start section to `README.md` showing: ```powershell node scripts/validate_erp_task.js --task skills/erp-coordinator/tests/fixtures/team-single-ready.json --json node scripts/run_erp_task.js --task skills/erp-coordinator/tests/fixtures/team-single-ready.json --mode dry-run --config config/erp-deployment.example.json --json ``` Use concrete repository paths in the actual docs; do not leave angle-bracket placeholders in committed documentation. - [ ] **Step 3: Update project memory after verified changes** Record the final package inventory, test evidence, current known blockers, and the fact that no live ERP operations were run. Add a task-history entry and evidence topic. Do not rewrite project positioning or stale legacy paths without human confirmation. - [ ] **Step 4: Run documentation checks** Run: ```powershell node --test tools/tests/erp_docs_content.test.js python C:\Users\wxy\.codex\skills\maintain-project-docs\scripts\check_project_docs.py --target . ``` --- ### Task 12: Full Verification and Handoff **Files:** - Modify: `.planning/2026-07-12-skill-script-packaging/task_plan.md` - Modify: `.planning/2026-07-12-skill-script-packaging/progress.md` - Modify: `.project-docs/30-worklog/current-state.md` if final focus or blockers changed - [ ] **Step 1: Validate every Skill package** Run `quick_validate.py` once for each of the eight Skill directories. Assert every package has `SKILL.md`, valid frontmatter, no TODO/TBD placeholders, and no prohibited customer-visible internal commands. - [ ] **Step 2: Run the complete automated suite** Run: ```powershell npm test npm run health:no-erp ``` Expected: exit code 0, no failed tests, no live ERP save, and no new warnings caused by the packaging work. - [ ] **Step 3: Run the contract and task smoke matrix** Run the validator against: ```powershell node scripts/validate_erp_task.js --task skills/erp-create-order/tests/fixtures/team-single-ready.json --json node scripts/validate_erp_task.js --task skills/erp-create-order/tests/fixtures/team-batch-ready.json --json node scripts/validate_erp_task.js --task skills/erp-create-order/tests/fixtures/split-parent-ready.json --json node scripts/validate_erp_task.js --task skills/erp-create-order/tests/fixtures/split-child-ready.json --json node scripts/validate_erp_task.js --task skills/erp-update-order/tests/fixtures/update-room-remark.json --json node scripts/validate_erp_task.js --task skills/erp-update-order/tests/fixtures/update-traveler-attachment.json --json node scripts/validate_erp_task.js --task skills/erp-export-recovery/tests/fixtures/export-xingyou.json --json node scripts/validate_erp_task.js --task skills/erp-export-recovery/tests/fixtures/export-parent-block.json --json ``` Expected: valid task envelopes pass; invalid/blocked fixtures report structured reasons; all execution commands remain dry-run. - [ ] **Step 4: Run the project documentation post-task gate** Run `check_doc_drift.py` only if Git becomes usable. If Git remains invalid, record that drift checking and commit inspection were unavailable, compare changed files manually with current-state/task-history/decision docs, and state this limitation in the handoff. - [ ] **Step 5: Prepare the collaboration handoff** Include the package inventory, task JSON contract version, exact validator/runner commands, test and no-ERP health output, live ERP operations explicitly not run, known blockers (native `DoInfoJHs`, optional price/pax, unattended login, invalid Git metadata), and the next recommended implementation or authorized test step. Do not claim the work is complete until all automated checks and every Skill quick validation pass.