Files
LWLT-AI/progress.md
2026-07-13 19:57:46 +08:00

341 lines
47 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# LTJT Business Module API Research Progress
## 2026-07-12 — External Agent Parsing Refactor
- Confirmed implementation scope with the user: external service replaces only raw-input parsing; ERP/plugin work remains unchanged.
- Confirmed preserved `operation` JSON contract, one independent external session per task, SSE transport, server-only environment credentials, external published prompt ownership, and complete removal of local Agent configuration/terminology.
- Started implementation from the existing `mock-business-system/server.mjs` and `app.js` chain. No secret has been written to the workspace.
- Added `mock-business-system/external-agent-client.mjs` with Bearer auth, CSRF double-submit headers, task-scoped idempotency keys, SSE parsing, timeout/error mapping, operation normalization, and safe contract-mismatch blocking.
- Replaced the local model/prompt proxy with `/api/parse`, removed the browser configuration/prompt dialogs, deleted the local prompt file, and added server-only `.env.example`/`.gitignore` guidance.
- Added `external-agent-client.test.mjs`; all 10 contract/HTTP tests pass. Local no-key startup and `/api/parse` smoke checks pass on port 18765.
- Ran real synthetic parser smoke calls with the user's private environment file. Auth/session/SSE succeeded, but the current published Profile returned a generic response shape rather than the required `operation`; no ERP operation was attempted.
- Final local verification: all four relevant Node files pass `node --check`; all 10 external-parser contract/HTTP tests pass; the actual supplied key is absent from workspace scans; the obsolete local prompt file and `/api/agent/*`/browser configuration surface are gone.
- Added parser request observability: the UI immediately shows `parse_sending`, then renders the external request stage and technical JSON in the right-side task detail. Local/API failures now persist to the task card with an explicit failure status. Cache-busted assets were verified through the running server on port 8765.
- Diagnosed a real business-input failure: the external session and SSE completed, but the published Profile returned `skill_error:ltjt_business_operation` with no `operation`. Updated the UI to label this as an external Skill block and show the business blocker separately from transport errors.
## 2026-07-12 — Task deletion and cancellation completed
- Added `删除任务` to the right task panel. It requires browser confirmation, cancels confirmed/handed-off tasks through the bridge, then removes the selected business-system card, logs, and persisted task ID.
- Removed the top-level `查询反馈` and `清空任务` controls and their event bindings. Automatic polling for accepted tasks remains internal.
- Added `DELETE_TASK` to `business-bridge.js`, including cleanup of the selected task and batch child records from extension storage.
- Added `LTJT_CANCEL_TASK` and cancellation guards to `background.js`; cancellation stops future tab/frame/preflight/verification phases and suppresses late result writes after the business task is removed.
- Bumped the extension to `0.2.15` and rebuilt `chrome-extension/ltjt-order-assistant.zip`.
- Verification passed: affected JavaScript syntax checks, operation-plan tests 12/12, focused deletion/cancellation assertions, local page HTTP 200 checks on port 18767, and ZIP integrity.
## 2026-07-12 — AI workbench header refinement completed
- Copied the supplied logo to `mock-business-system/assets/ltjt-platform-logo.png` and placed it at the top-left with horizontal crop styling to remove the source image's large white margins.
- Replaced `下单任务工作台` / `模拟业务系统` with a stretched horizontal header menu; `AI操作台` is the active page menu and the document title was updated.
- Moved clickable `AI状态` and `插件状态` status tags to the far right. AI refresh calls `/api/status`; plugin refresh calls the existing bridge PING path. Both expose only green `已开启` and red `未连接` states.
- Added PNG MIME handling to the local static server. Header assertions, syntax checks, API response, logo HTTP load, and app/CSS resource checks passed.
## 2026-07-12 — AI connectivity probe correction
- Replaced the AI status check based only on local Key presence with a real server-side external API probe.
- The probe sends an authenticated empty validation request with CSRF headers; it does not create an Agent Session or task. Validated `400/422` responses mean the API and credentials are reachable; `401/403`, timeout, and network errors remain red `未连接`.
- Added `ai_connected` to `/api/status`, switched the browser to that field, added five-second polling, and kept click-to-refresh behavior.
- Regression verification passed: 13/13 external parser and HTTP tests plus JavaScript syntax checks.
## 2026-07-12 — Three-stage project status UI started
- Confirmed the right panel currently renders only the terminal-like task log; existing task data already carries parse status, handoff status, execution status, and `erp_receipt`/verification results.
- Started a three-stage status surface: Agent处理, 业务系统处理, and 获取回执, with stage-specific small status labels driven from the existing task/result contract.
## 2026-07-12 — AI status runtime diagnosis
- Investigated a report that AI remained `未连接` despite the external service being available.
- Confirmed the active process on port 8765 served the new static frontend but returned `404 Not Found` for `GET /api/status`, proving the Node process had not been restarted after the server route was added. No application code change is required for this incident; restart the service with the server environment loaded.
- Restarted the business-system service on port 8765 as PID 61781. The new `/api/status` route now responds correctly; this execution environment has no `.env` or `DEERFLOW_OPEN_API_KEY`, so the response correctly reports `ai_connected: false` with `external_service_not_configured`.
- After the private `/Users/inmanx/.env` was updated, restarted the service again as PID 64750 with `node --env-file=/Users/inmanx/.env server.mjs`. `/api/status` now reports `ai_configured: true` and `ai_connected: true` with an authenticated probe response.
- The detached background process was later reaped by the local runtime, causing the browser to see connection refused. Relaunched the service in a persistent terminal session (PID/session 21906), verified page HTTP 200 and `ai_connected: true`, and opened `http://127.0.0.1:8765/` in the default browser.
## 2026-07-12 — Confirmation action relocation completed
- Removed the card-level `确认提交` button and added `确认执行` to the right task-detail header beside the task state and delete action.
- The right-side button is shown only for a selected task that still requires manual confirmation. It calls the existing `confirmTask()` flow, so handoff and plugin execution behavior are unchanged.
- Updated the waiting-state guidance to tell operators to confirm from the right task detail. Syntax and static assertions passed.
## 2026-07-12 — Input area copy refinement completed
- Renamed the left panel heading from `原始指令` to `输入区域`.
- Removed the `编辑发送区` helper text.
- Renamed the bottom action from `发送解析并创建任务` to `创建任务`; the existing click behavior is unchanged.
- Verified syntax, served-page markers, and cache-busted input-area assets.
- Centered the left input area's `创建任务` button with a scoped `.instruction-panel .actions` rule and verified the served stylesheet.
- Renamed the successful top-right AI/plugin status label from `已开启` to `已连接`; detection and red `未连接` behavior are unchanged.
- Added the stage board above the log with the requested sub-statuses: Agent `已提交/已成功/已失败`, business system `已接单/处理中/已完成`, and receipt `待获取/已获取回执`.
- Added automatic visual mapping for empty, parse-failed, queued/accepted/running, blocked, completed, saved-unverified, and receipt-present task states. Browser screenshot verification passed at the desktop layout; existing terminal log and delete action remain intact.
## 2026-07-12 — Task deletion and cancellation
- User confirmed that deleting the selected task must remove the business-system card/logs and cancel the matching plugin task.
- Existing bridge supports only whole-queue `CLEAR_TASKS`; no single-task cancellation message exists yet.
- Existing background executor tracks active task IDs in `runningTasks` but has no cancellation flag or phase-boundary guard.
## 2026-07-12 — Agent Design Specification
- Confirmed the target architecture with the user: one cloud Agent digital-employee prompt for raw instruction decomposition plus one unified business-behavior Skill with internal references.
- Created the project-root management directory `agent设计规范/` with the external Profile prompt draft, Skill package, references, examples, and a root index.
- The canonical Agent output remains the local business-system `agent_parse_passed`/`agent_parse_blocked` wrapper around the seven-action `operation` object. Handoff `erp-task-v1` is documented as internal Skill compatibility input only.
- Recorded the current schema/runtime alignment gate: `operation-plans.js` consumes `data.test_marker` and `data.order_mode`, while the root JSON Schema does not yet declare both; transport metadata must remain outside the canonical operation.
- Validation: `quick_validate.py` passed for `ltjt-business-operation`; root `tools/operation-plans.test.mjs` passed 12/12; relevant current JavaScript syntax checks passed. No cloud Agent or ERP runtime was changed.
## 2026-07-07
- Confirmed user logged into a dedicated collaboration Chrome window on `127.0.0.1:9223`.
- Confirmed logged-in main URL and visible business-module menu items.
- Created research plan and findings log.
- Added `tools/cdp_lwlt_probe.mjs` to query the temporary Chrome collaboration window directly.
- Ran authenticated page map before logout and extracted business menu URLs plus homepage shortcut URLs.
- Captured cookie metadata without values.
- Main-page reload redirected the collaboration window back to login, so further interactive capture requires re-login.
- Checked public JS and unauthenticated business URLs. Public JS is mostly form validation/helpers; unauthenticated business URLs return login-timeout script.
- Documented login request shape from the public login page: `POST /system/dat/AjaxCommand.asp` with `Action=CheckSystemLogin` plus CAPTCHA and generated `session_id`.
- Extended `tools/cdp_lwlt_probe.mjs` with iframe navigation and richer page-map extraction for business pages.
- Added a `clickmenu` capture mode to trigger the system's real menu click path by visible menu label.
- Captured 产品管理 via real menu click. Found `/System/dat/product.asp` list XHR and `/System/dat/AjaxPublicFun.asp` autocomplete/metadata XHR.
- Learned module pages are loaded into additional iframes (e.g. `jidiao40`) rather than replacing `Iframe_Home`.
- Added `batchmenus` mode to collect menu page request and structure summaries sequentially.
- Sanitized temporary capture outputs and updated the probe to redact login parameters (`UserName`, `UserPwd`, `Code`, `session_id`) and avoid storing business data rows as table headers.
- Captured core list endpoints for product, independent group orders, shared group plans, teams, tickets, filing, returns, and customer follow-up.
- Added `api_inventory.md` with endpoint inventory, parameter shapes, related pages, permission-sensitive pages, and integration feasibility notes.
- Checked repository files for secrets and business rows. No credentials, cookie values, CAPTCHA values, or obvious business data rows are stored in the project files.
- Recorded the page-context/session sensitivity issue in `findings.md` for future adapter design.
- Opened the independent group `下单` dialog read-only and captured its add-page route, submit endpoint, primary required fields, lookup endpoints, and attachment helper pages.
- Extracted `SubmitInfoForm()` and add-form field statistics. Confirmed `Act=DoInfoJH` is the save action and the form is a large browser-form contract rather than a small JSON-style API.
- Generated full independent-order add-form schema: `schemas/orders_add_form_schema.json` and `schemas/orders_add_form_schema.md` covering 825 controls, 92 field groups, and 14 required fields.
- Added `adapter_design.md` documenting that production runtime must be deterministic and must not depend on AI/LLM decisions.
- Reviewed the pure business background document from `/Users/inmanx/Desktop/业务背景流程与客户指令模板-纯业务版-20260707.md` and extracted the LTJT-facing system-operation scope.
- Added `system_operation_scope.md` to separate upstream business interpretation from deterministic LTJT operations, map the six business scenarios to known/unknown system endpoints, and preserve submit preconditions.
- Added `schemas/standard_system_operation.schema.json` as the first deterministic input contract for system operations, including the current priority action `team_order_create`.
- Confirmed architecture assumption with the user: their own business system and database will maintain/support the pending field data. Updated `task_plan.md`, `system_operation_scope.md`, and `adapter_design.md` so the LTJT adapter consumes a validated standard operation object instead of inferring fields at runtime.
- Added `mappings/orders_add.mapping.json` for the first `team_order_create` -> `orders_add.asp` field mapping, separating direct field assignment from LTJT lookup-required fields.
- Updated `schemas/standard_system_operation.schema.json` so `team_order_create` and batch create require `route`, `trip`, and `order_number`, matching the LTJT add-form required fields.
- Added `tools/dry_run_order_create.mjs`, a deterministic local dry-run serializer that reads a standard operation JSON file, validates blockers, maps fields, and outputs `Act=DoInfoJH&` plus the serialized form payload without calling LTJT.
- Added `samples/team_order_create.dry-run.example.json` with fake-only sample values and generated `reports/team_order_create.dry-run.example.report.json` plus `reports/team_order_create.dry-run.example.payload.txt`.
- Verified JSON validity with `jq`, script syntax with `node --check`, sample schema validity with Python `jsonschema`, and the dry-run sample with zero blockers/warnings.
- Added `tools/browser_order_add_dry_run.mjs` to read a local dry-run report, fill the live LTJT `orders_add.asp` form in a CDP-controlled browser, compare mapped values against browser `ListForm.serialize()`, redact `session_id` by default, and never submit.
- Verified the browser dry-run script syntax/help path. A read-only CDP target probe failed because `127.0.0.1:9223` is currently offline, so live browser comparison is waiting on a fresh collaboration Chrome login.
- Reopened the collaboration Chrome on port `9223` after user login and confirmed authenticated `System/Mainlt.asp`.
- Ran browser-context dry-run against the live `orders_add.asp` page with fake-only sample values. No submit was attempted.
- Found that the live form serializes `yaobeian=要备案`; updated `schemas/standard_system_operation.schema.json`, `mappings/orders_add.mapping.json`, `samples/team_order_create.dry-run.example.json`, and `tools/dry_run_order_create.mjs` so the local serializer includes `filing_required` / `yaobeian`.
- Hardened `tools/browser_order_add_dry_run.mjs` so `--open-form` forces a fresh `orders_add.asp` URL timestamp and waits for the full `ListForm` before filling.
- Final browser dry-run result: `browser_dry_run_passed`, 58 mapped fields, 822 local fields, 822 live browser fields, zero missing elements, zero mismatches, no `DoInfoJH` submit.
- User flagged the real production risk that many fields are SelectBox-bound choices and auto-fill linked fields. Confirmed this from live page scripts.
- Added `tools/inspect_orders_add_selectboxes.mjs` to inspect SelectBox bindings, lookup endpoints, linked `SetVal` targets, and data shape without storing real option values.
- Confirmed LTJT SelectBox protocol from the browser-loaded `SelectBox.min.js`: rows are separated by `◇`, columns by `◆`.
- Added `tools/validate_order_add_lookups.mjs` to validate standard operation values against existing LTJT SelectBox choices. Fake sample data is now correctly blocked: `TianShu=4D3N` matches, but fake route/product/customer/OP/sales do not.
- Updated `mappings/orders_add.mapping.json` with the SelectBox contract, observed row/column counts, critical linked fields, and a stricter rule that upstream `resolved=true` is not sufficient without runtime exact-match lookup validation.
- Added `tools/resolve_order_add_lookups.mjs`, which applies LTJT SelectBox `SetVal` rules after exact-match lookup. Default output redacts resolved values; actual resolved fields are written only via explicit `--resolved-out` and only when all critical lookups pass.
- Updated `tools/dry_run_order_create.mjs` with `--lookup-resolution`. When supplied, dry-run payload generation is blocked unless lookup resolution has passed and can provide real resolved fields. The fake sample now correctly blocks the stricter dry-run with the lookup report.
- Added `tools/inspect_order_add_product_effect.mjs` to execute `Find_product()` / `GetProduct(cpm)` in the browser without submitting and report only redacted field-change metadata.
- Verified fake sample product side-effect inspection blocks because the fake product has zero LTJT matches.
- Ran a redacted, non-submit sample against the first existing LTJT product option. `GetProduct` returned successfully and changed 135 form fields: core fields, itinerary text, resource rows, and receivable/pricing rows.
- Added `tools/browser_order_add_preflight.mjs`, the closest-to-submit dry run: it exact-matches LTJT lookups, runs product side effects, validates product-template consistency, clears/rebuilds standard-owned receivable rows, and serializes the live browser form without calling `DoInfoJH`.
- Verified browser preflight blocks the fake sample before product side effects: `TianShu=4D3N` matches once, while fake route/product/customer/OP/sales values match zero LTJT rows.
- Updated `task_plan.md`, `findings.md`, `adapter_design.md`, `system_operation_scope.md`, and `mappings/orders_add.mapping.json` with the product-template-first preflight contract.
- Added `tools/browser_order_add_submit_intercept.mjs`, which patches `jQuery.ajax` before calling `SubmitInfoForm()` so page validation and the submit branch can be tested without allowing `DoInfoJH` to reach the network.
- Refilled the live browser form with fake-only dry-run values and ran submit intercept. It captured one prevented `Act=DoInfoJH` request, zero validation alerts, 822 fields, and no live submit.
- Added `tools/browser_order_add_template_selftest.mjs` to prove the non-writing pipeline with actual existing LTJT options while keeping product/customer/route/staff values in browser memory only.
- Ran the template self-test with `--open-form --intercept-submit`. It passed: product/trip/route/customer/staff exact-match counts were each 1, product side effects changed 135 fields, required fields were filled, final serialized field count was 822, and one `DoInfoJH` submit branch was intercepted/prevented.
- Added `tools/browser_order_add_submit_approved.mjs`, the guarded live-submit tool. It requires a real `browser_preflight_passed` report, a separate `submit_intercept_captured` report with matching payload SHA-256, `--execute-live-submit`, and approval token `APPROVE-LTJT-DOINFOJH-SUBMIT`.
- Verified the guarded submit tool refuses before browser access when given the template self-test report instead of real preflight/intercept reports.
- Final validation for this pass: all JSON reports/mappings parse with `jq`, all Node tools pass `node --check`, the standard operation sample passes the JSON Schema validator, and sensitive-value scanning found only endpoint templates, redacted `cpm`, and explicitly fake dry-run payloads.
- Updated template self-test compatible reports to account for the fact that `SubmitInfoForm()` mutates the final `DoInfoJH` payload. The preflight-compatible report now includes the actual submit payload SHA-256 from the intercepted request.
- Ran a controlled live test submit using the approved submit tool with `--execute-live-submit` and approval token. The actual `DoInfoJH` request hash matched the intercepted approved hash, one POST completed, the response had a success hint, and no login-timeout or permission text was detected.
- Added `tools/verify_order_marker.mjs` and verified the submitted test marker `AI-DRYRUN-NO-SUBMIT` through `JH_OrderList` for departure date `2026-8-1`. The authorized list response contained the marker, proving the test order is visible after submit.
## 2026-07-09
- Shifted the product direction from a developer-operated Chrome extension popup to a business-system-driven task workflow: business users create and track tasks in the mock business system; the extension acts as a browser-session adapter.
- Built the mock business-system UI around a single raw-instruction input, task cards, task detail/progress views, and local task persistence.
- Added model-agent support to the mock system through `mock-business-system/server.mjs`: configurable OpenAI-compatible endpoint/model/API key, MiniMax China/Global presets, and `/api/agent/parse` plus `/api/agent/ping` proxy endpoints.
- Added `mock-business-system/agent_prompt.md` and UI controls to view/edit/save/reload the parsing prompt used to teach the agent LTJT field semantics and raw text decomposition.
- Diagnosed MiniMax API connectivity failures. The failing `https://api.minimax.io/v1/chat/completions` calls returned HTTP 401 `invalid api key`; switching to `https://api.minimaxi.com/v1/chat/completions` with the correct Pay-as-you-go key reached HTTP 200.
- Extended the Chrome extension bridge (`business-bridge.js`) so the mock system can create tasks, poll task results, clear tasks, and detect bridge readiness through page `postMessage`.
- Moved normal automation into the extension background executor: after receiving a business task, it finds/opens the logged-in LTJT ERP page, opens the order form, runs preflight/intercept, submits the obvious test order, verifies the marker, and publishes task status back to `chrome.storage.local`.
- Added automatic result feedback to the business system task cards: queued, accepted, running, saved/verification, completed, blocked, paused, and waiting-extension states.
- Reduced the extension popup to a minimal status panel with one operator switch: "允许插件操作 ERP". The popup no longer exposes raw instruction entry, manual preflight, submit, or verification controls to normal business users.
- Added an ERP-operation disable path: when the switch is off, the business system can still see the plugin but tasks are marked paused and are not handed to the ERP executor until the switch is enabled again.
- Added bridge-state propagation so `PING` and `BRIDGE_READY` include `erp_automation_enabled`; the mock business system displays "插件已连接ERP 操作已开启/已关闭" instead of a generic connection state.
- Changed the post-save ERP behavior so after successful verification the extension returns the ERP order-entry frame to the independent-order list, filtered by departure date and test marker, instead of leaving the operator looking at the completed entry page.
- Iterated on connection reliability. Version `0.2.11` added active popup-to-business-page bridge ping. Version `0.2.12` added reinjection tolerance for `Extension context invalidated` after extension reloads.
- Clarified current browser boundary: the page bridge works within the same Chrome/browser profile. Cross-browser or multi-profile operation needs a local bridge hub service or backend queue rather than direct extension/page messaging.
- Current packaged extension is `chrome-extension/ltjt-order-assistant.zip`; current extension version is `0.2.12`.
## 2026-07-12 — Incremental business-system and browser-plugin absorption
- Confirmed the scope for this pass: do not integrate or redesign the external Agent; absorb the handoff package into the root business system and Chrome plugin.
- Added `chrome-extension/ltjt-order-assistant/operation-plans.js` as a pure, browser-independent operation rule layer. It maps the handoff `create_order/update_order/export_confirmation` forms to the root operation matrix, validates identifiers and required fields, normalizes export aliases, preserves the `visitor-detail` boundary, and records no-write/fallback status.
- Added `tools/operation-plans.test.mjs` with 7 passing tests covering team-single, team-batch fallback, handoff task normalization, update planning, export safety, and fail-closed unknown operations.
- Updated `chrome-extension/ltjt-order-assistant/background.js` to load the rule layer, publish capability plans to business tasks, fail closed for unconnected routes, and execute team-batch test tasks sequentially through the verified team-single browser path. Native `DoInfoJHs` remains deferred.
- Updated `mock-business-system/app.js` to display operation type, identifier, capability route, no-write state, fallback, warnings, and planning status in task cards/details. The external Agent parsing path was not changed.
- Updated the extension README and rebuilt `chrome-extension/ltjt-order-assistant.zip` to include `operation-plans.js`.
- Verification: all root JavaScript/ES module syntax checks passed; operation-plan tests passed 7/7. No live ERP operation was executed in this increment; the new batch loop still requires a separately authorized browser test.
## 2026-07-12 — Handoff business expansion and read-only browser probes
- After the root regression gate passed, absorbed the remaining handoff task shapes into the root operation layer: split parent, split child, structured order update, traveler-list attachment/update, and export/recovery tasks now normalize without inventing ERP identifiers or values.
- Expanded `schemas/standard_system_operation.schema.json` with structured update actions, export-only types/recovery flags, attachment paths, and parent/child ERP reference fields so the business-system contract covers the handoff operations.
- Updated `operation-plans.js` to preserve parent-group and child-order references, planned capacity, plans-per-date, cycle, supplemental data, update actions, attachment metadata, export aliases, and `neverResave` recovery semantics.
- Added pure update preview logic for `set`, `delta`, and `append` actions. It reads a supplied ERP snapshot, rejects missing delta baselines/negative results/unsupported targets, and always reports `no_erp_write=true`.
- Added read-only page probes to `inpage.js` for the independent-order list, split-plan pages, and split-child context. The probe reports login/page mismatch/candidate ambiguity and extracts only safe order-link metadata; it does not fill, submit, import, or download.
- Updated the background executor to run those probes for all non-team-single routes and publish browser probe status, export-only source paths, and no-write state back to the business system. The task detail now shows the selected dry-run adapter, candidate count, and export recovery policy.
- Bumped the extension to `0.2.13` and rebuilt the packaged ZIP.
- Verification: `tools/operation-plans.test.mjs` passes 12/12; all root JS/MJS files pass `node --check`; handoff fixtures normalize to the expected six operation families; the standard-operation schema parses as JSON; ZIP integrity passes. The handoff package's full `npm test` remains environment-incomplete (missing `@e965/xlsx`/`playwright-core` and intentionally omitted legacy docs), so it is recorded separately from the root absorption gate.
## 2026-07-12 — Authorized full ERP/plugin live test and handoff completion
- User authorized temporary ERP order creation for end-to-end verification; cleanup remains manual and no test records were deleted automatically.
- Revalidated the existing team-single route and sequential team-batch fallback. Confirmed groups: `LLW-260811CDP-PLUGIN-TEST-20260712-1783842347475-A`, `LLW-260901BATCHT0712-D20260901-1783843465676-A`, and `LLW-260908BATCHT0712-D20260908-1783843475645-A`.
- Completed guarded live split creation through the business-system bridge: parent `LW-260916PLUGSP0712R2-A` (capacity 4), followed by child order `D14271` with pax `2+1+1`. A prior direct split test remains `LW-260915SPT0712-A` with child `D14269`.
- Completed source-only confirmation export for Xingyou, Liantai, and JOB. The plugin used the correct `ddid/tid` mapping and verified HTTP 200 Word-like responses without saving or delivering files.
- Update and traveler routes were exercised safely but remain dry-run/read-only: update responses were HTTP 200 empty/non-persisting; traveler import revealed a native phone-field offset and was not saved.
- Final verification passed: loaded plugin `0.2.14`/bridge `PING`, syntax checks, operation-plan tests 12/12, schema validation, and packaged ZIP integrity. The extension package is [ltjt-order-assistant.zip](/Users/inmanx/Documents/lwltAPI/ltjt-order-assistant.zip).
## 2026-07-12 — Separate task logs and return JSON
- Confirmed the right panel had a data-display gap: `renderTaskDetail()` only rendered `task.logs`, while `setOutput()` retained only a short message/status line and the full parser/plugin responses were not visible.
- Updated `mock-business-system/app.js` to preserve the full external parser response, combine parser/operation/handoff/executor data into a formatted JSON payload, and render it below a separate real-time log box.
- Added display redaction for API keys, authorization/cookie/password/secret fields, session identifiers, and idempotency keys; the returned business fields remain visible.
- Added cache-busting versions for the updated app and stylesheet in `mock-business-system/index.html`.
- Verification passed: `node --check` for the changed/server/extension scripts, `mock-business-system/external-agent-client.test.mjs` 13/13, and a local static UI resource smoke check.
## 2026-07-12 — Project Development and Maintenance Standard
- Added root document `开发维护规范.md` for business and technical maintainers.
- Defined the maintenance chain: exact first-line business command -> Agent routing -> unified Skill/reference -> task-ready operation -> ERP product-template resolution and exact lookup -> preflight/dry-run -> authorized submit and post-operation re-query.
- Recorded field ownership: Agent/Skill extracts user facts; ERP derives or validates customer, route, trip, currency, route prefix, hidden IDs, and form values; scripts must not make AI decisions at runtime.
- Defined the initial command registry for team single/batch, split parent/child, order update, traveler import, and confirmation export/recovery.
- Marked first-line command enforcement as the next implementation phase; this document does not yet change the Prompt or business-system input validator.
## 2026-07-12 — Production platform scope discovery
- Performed a read-only architecture scan for the newly requested productionization scope.
- Confirmed the current business system is a browser-local mock/task loop, the Chrome extension is a local browser-session adapter, and no durable backend/database/plugin-management runtime is present yet.
- Paused before implementation because the system-of-record choice materially changes the platform schema, synchronization strategy, migration plan, and plugin contract.
## 2026-07-12 — Repository cleanup audit
- Read-only inventory found five mixed categories in the root: active Agent/Skill and ERP adapter source, legacy handoff code, validation reports, generated packages, and planning/history logs.
- The root `交接包/` is not referenced by current runtime code. Its old `erp-task-v1`, eight legacy Skills, scripts, and tools remain useful as comparison/compatibility material, but its README/docs reference missing `.project-docs`, deployment paths, and old task entrypoints.
- `交接包/runtime`, `交接包/diagnostics`, `交接包/tools/runtime`, and root `reports/` contain runtime residue, exported documents, test artifacts, and technical fields; they must be quarantined or archived rather than treated as source.
- Root has no README, no root `.gitignore`, and no usable `.git` repository. The next cleanup step must be non-destructive: create a manifest and target archive layout before moving or deleting anything.
- Current active maintenance authority remains `开发维护规范.md`, `agent设计规范/`, root schemas/mappings, root ERP-control tools, extension source, and the mock business-system integration tests. Historical architecture docs and long planning logs should be marked as history before relocation.
## 2026-07-12 — Repository cleanup execution started
- User confirmed the proposed cleanup and authorized deletion of historical material with no current dependency.
- Dependency scan found no active-code import of `交接包/`; `reports/` is only an output location referenced by CLI help text. The report files can be removed while the empty output directory remains available.
- Planned mutations: create root README/ignore rules and archive manifests; move the old handoff package to a dated archive; remove handoff runtime/diagnostics/output residue, root reports, temporary health files, and `.DS_Store`; move the extension ZIP into `dist/`.
- Active source, schemas, mappings, scripts, extension source, mock system, samples, and planning files are preserved.
## 2026-07-12 — Repository cleanup completed
- Added the root project entrypoint and maintenance boundaries: `README.md`, `.gitignore`, `archive/README.md`, `dist/README.md`, `quarantine/README.md`, and `reports/README.md`.
- Moved the reusable legacy handoff to `archive/handoff/2026-07-12/legacy-erp-handoff/` and removed its runtime, diagnostics, and generated output subtrees.
- Deleted 22 historical root validation report files and both `.DS_Store` files. The empty `reports/` directory remains as a generated-output location.
- Moved the verified extension package to `dist/ltjt-order-assistant.zip`.
- Removed stale live-report claims from `adapter_design.md` and `system_operation_scope.md`; both now require a fresh gated report for any future write.
- Verification after cleanup: 25/25 Node tests passed; changed JavaScript files passed `node --check`; current JSON contracts parsed; Skill quick validation passed; `unzip -t dist/ltjt-order-assistant.zip` passed.
- User confirmed: keep LTJT as the initial external source of truth and perform architecture hardening only; do not add business features or alter existing workflows.
- User confirmed: phase one is a single-company, single-tenant private deployment, with future organization isolation reserved in the model but no full SaaS multi-tenancy now.
- User confirmed: use a centralized backend/database control plane with an authenticated Chrome plugin Worker; deploy the service in a persistent Linux/Docker environment and treat browser-local state as non-authoritative.
- User confirmed: PostgreSQL is the primary durable database; any Redis use remains optional and non-authoritative for cache, locks, or transient transport only.
- User confirmed: phase one will not integrate enterprise SSO; the platform must provide its own account login, with the security and lifecycle policy still to be finalized.
- User confirmed: accounts are administrator-created/invited, public registration is disabled, and the first administrator is created through deployment bootstrap.
- User confirmed: phase one has only one human administrator role with full permissions; multi-role RBAC is deferred, but plugin Workers remain separately identifiable.
- User confirmed: use revocable server-side administrator sessions with secure HttpOnly/SameSite cookies; do not persist long-lived JWTs in browser storage.
- User explicitly declined MFA for phase one; compensating controls and a controlled password-recovery procedure remain required.
- User confirmed password recovery is server-side/operator-controlled only; no email self-service recovery will be added in phase one.
- User confirmed the plugin remains a session-bound adapter with no independent registration, pairing code, or Worker credential in phase one.
- User confirmed the execution safety invariant: preflight/dry-run -> explicit administrator confirmation -> one submit -> ERP re-query; uncertain outcomes require reconciliation and cannot be retried automatically.
- User confirmed a clean production database initialization with no migration of prototype tasks, caches, reports, or test orders; only schemas, configuration structure, and operation contracts are retained.
- User confirmed direct production deployment without a separate test/staging environment; offline verification, no-write defaults, release prechecks, and backups become mandatory safeguards.
- User confirmed automated PostgreSQL backups, pre-migration backups, independent storage, and verified restore procedures.
- User confirmed structured redacted logs, health checks, and key failure alerts for the private deployment, with no third-party monitoring platform in phase one.
- User confirmed protected deployment-host secret injection and server-side rotation; secrets must not enter source, images, logs, database, frontend, or extension storage.
## 2026-07-12 — Consolidated production hardening baseline
- Re-read the active root after cleanup and confirmed the current implementation remains a browser-local prototype around the existing Agent/Skill/schema/mapping/ERP adapter.
- Consolidated the user-confirmed scope and technical defaults in `task_plan.md`: PostgreSQL control plane, native admin login, DB-backed task state/leases/audit, session-bound extension, direct production deployment, backups, observability, and no new business capabilities.
- Waiting for the user's explicit final confirmation before modifying application code or deployment files.
## 2026-07-12 — Architecture hardening implementation
- User confirmed the consolidated scope and explicitly authorized implementation.
- Added root production package/lock, TypeScript configuration, PostgreSQL migration, encrypted field helper, DB connection/transaction layer, admin authentication/session service, task service, Fastify server, admin CLI, retention job, Dockerfile, Compose, Caddy config, backup/restore scripts, and predeploy checks.
- Added login panel and server-backed task synchronization to the existing operation page; browser local storage is no longer the task authority. Added backend claim/result/heartbeat calls around the existing session-bound plugin handoff.
- Rebuilt `dist/ltjt-order-assistant.zip` with extension version `0.3.0`; retained the existing ERP operation logic and safety gates.
- Verification: `npm test` passes 25 tests, `npm run build` passes, changed browser/extension scripts pass `node --check`, and backup scripts pass `sh -n`.
- Environment limitation: this Mac has no `psql` or Docker executable, so PostgreSQL migration/restore and Compose tests are pending on the target production host.
- Migration smoke was attempted and failed as expected with `ECONNREFUSED 127.0.0.1:5432`; the failure is explicit and fail-closed, with no partial migration claim.
## 2026-07-12 — Final local verification
- `npm test`: 25 tests passed, including 5 control-plane tests and all existing parser/operation-plan regressions.
- `npm run build`: passed; browser/extension scripts and backup scripts pass syntax checks.
- `npm audit --omit=dev --audit-level=high`: 0 vulnerabilities after upgrading `@fastify/static` to the patched major.
- Control plane starts, serves the login page and `/health/live`; `/health/ready` correctly returns 503 while PostgreSQL is absent instead of claiming readiness.
- `dist/ltjt-order-assistant.zip` passes `unzip -t` and contains extension version `0.3.0`.
- Remaining target-host gates: run PostgreSQL migration, bootstrap the administrator, configure HTTPS/secrets, create and verify an independent backup, run restore-check, then perform a no-write browser preflight before enabling any ERP submit.
## 2026-07-13 — Login gate visual fix
- Fixed the login/workbench overlap caused by the workbench grid's `display` rule overriding the HTML `hidden` attribute.
- Added the explicit hidden-state CSS rule, updated the CSS cache-buster, and verified the served page contains the fix and the workbench remains marked `hidden`.
## 2026-07-13 — Remote PostgreSQL startup and admin bootstrap
- Connected to the supplied PostgreSQL host `192.168.3.211:5433`, database `postgres`, without writing the credential into the repository.
- Ran migration `001_initial` successfully.
- Created administrator `xqkadmin` using the generated 20-character password; no password value was logged or persisted in project files.
- Restarted the control plane against the remote database at `http://127.0.0.1:8786`.
- Verified `/health/ready` returns database-ready and administrator login plus `/api/auth/me` both return HTTP 200.
- External parser credentials were not supplied, so AI parsing remains disconnected until `DEERFLOW_OPEN_API_KEY` is injected into the runtime environment.
## 2026-07-13 — Automatic environment loading completed
- Added a root local `.env` with mode `0600`, combining the current control-plane database configuration and private external Agent configuration; its values were not printed or logged.
- Updated root `package.json`: `dev`, `start`, `db:migrate`, `admin`, and `data:retention` now automatically load `.env`; `start:mock` continues to load `mock-business-system/.env`.
- Restarted the control plane through `npm run dev`; `http://127.0.0.1:8786/api/status` now reports `database_ready:true`, `ai_configured:true`, and `ai_connected:true` with authenticated HTTP 200 probe.
- Regression gate passed: typecheck, 5 control-plane tests, and 20 legacy/parser tests (25 total).
- The actual administrator password was not changed. Login should use the existing bootstrapped account; password recovery remains the separate admin reset path.
## 2026-07-13 — Parse stall hardening completed
- Replaced the state-changing Agent health probe with read-only `GET /health`; added a 30-second server-side cache and reduced browser status refresh to 30 seconds.
- Added a 180-second total parser deadline, terminal SSE/[DONE] handling, and tests proving a terminal event does not wait for stream closure.
- Updated parse claiming to exclude tasks already active in the current process, set the durable message to `任务正在解析。`, and require the current lease owner when persisting parse results.
- `npm test` passed all 26 tests and `npm run build` passed. The control plane was restarted as the new process and `/health/live`, `/health/ready`, and `/api/status` all returned HTTP 200; `/api/status` now reports `probe: health_endpoint` and no external HTTPS session connection remained after the status checks.
- The previously stuck task had already been cancelled before restart and was intentionally not recreated or resubmitted.
## 2026-07-13 — Delete task visibility fix
- Fixed the apparent no-op after clicking “删除任务”: cancelled tasks are now excluded from the default control-plane task list, so the SSE refresh cannot add the cancelled card back.
- Added a defensive frontend filter for cancelled rows returned by stale servers or in-flight event refreshes.
- Kept the backend cancellation record and audit trail intact; this change hides cancelled items from the active task-card view rather than deleting history.
- Bumped the frontend cache-buster to `20260713-delete-task-1`; `npm test` (26 tests), `npm run build`, served-resource checks, and `/health/live` plus `/health/ready` all pass after restarting the control plane.
## 2026-07-13 — Parse reliability and full live-flow verification completed
- Reproduced the persistence failure with a real Agent response and captured PostgreSQL SQLSTATE `22P02`: the system Worker's empty actor ID was invalid for the UUID column.
- Fixed system-event actor handling, added durable parse attempts, Worker watchdog/abort propagation, bounded SSE cancellation, persistence retries, lease-expiry terminal recovery, stale-result protection, terminal lease cleanup, and SSE refresh coalescing.
- Applied migrations `002_parse_reliability` and `003_terminal_lease_cleanup` to the configured PostgreSQL database.
- Verified a fresh real Agent task completes in one attempt and reaches `awaiting_confirmation` with the expected standard operation and full encrypted response.
- Verified the remaining backend state machine through authenticated/CSRF-protected API routes in an isolated no-write run: `confirmed -> queued -> completed`, with `no_erp_write=true` and no ERP action.
- Final gates pass: 27/27 tests, TypeScript build, JavaScript and shell syntax checks, dependency audit with 0 vulnerabilities, live/ready/status endpoints, database invariants, browser-extension heartbeat, and compiled `npm start` runtime.
## 2026-07-13 — ERP duplicate dispatch and stuck receipt fully remediated
- Immediately stopped the prior control-plane process to prevent additional claims. Database evidence confirmed four `task.browser_claimed` events for `TASK-20260713103736-9tLJa4w` and no persisted terminal plugin result.
- Created `/Users/inmanx/Documents/lwltAPI-backups/ltjt-platform-20260713T112103Z.dump`, verified its SHA-256 and archive listing, then applied migration `004_erp_execution_idempotency`.
- Added a unique partial index enforcing one ERP attempt per task and an execution-lease watchdog that moves expired browser executions to reconciliation rather than reclaiming them.
- Reworked claim/result APIs around a server-issued execution UUID, strict browser ownership, idempotent result hashes, monotonic terminal states, and no cancellation after an ERP attempt exists.
- Reordered the page flow to claim before extension delivery; removed refresh/reconnect/heartbeat auto-handoff and the “重交” action; expanded polling to all active claimed states; and added a minimum extension-version gate.
- Added `execution-guard.js` and extension-side durable execution state. Task payload and execution acquisition are written atomically, duplicate messages cannot overwrite a running task, and a real ERP operation records `write_started` before invoking the page action.
- Suppressed unsafe replay of native ERP dialog callbacks; explicit verification and return-to-list remain authoritative. Cleared the old diagnostic error after reload and verified zero extension runtime/manifest errors.
- Marked the incident task `reconciliation_pending` with `duplicate_execution_detected`, cleared its lease, disabled deletion, and displayed explicit manual-requery guidance. It was not marked completed and was not sent to ERP again.
- Rebuilt `dist/ltjt-order-assistant.zip` at version `0.3.1`, verified archive integrity, and reloaded the unpacked extension in the active Chrome session. The control plane records the connected version as `0.3.1`.
- No-write live verification proved: first claim accepted, replay claim returned `claimed=false`, exactly one ERP attempt existed, an identical result added zero events, and a running result after completion was rejected as `result_after_terminal`. Verification data was removed afterward.
- Browser refresh verification kept the incident claim count at exactly four before and after reload; the page remained `待回查`, plugin stayed connected/compatible, and delete remained disabled.
- Final gate: 30/30 tests, TypeScript build, JavaScript syntax, ZIP integrity, health/readiness, dependency audit with zero vulnerabilities, and compiled production runtime all pass.